From 9d2628be78db14b9f86d5a2e6cdc76f6dc0f640b Mon Sep 17 00:00:00 2001 From: j Date: Mon, 14 Mar 2016 14:40:39 +0100 Subject: [PATCH] install zeroconf --- .../PyPDF2-1.25.1.dist-info/RECORD | 10 +- .../PySocks-1.5.6.dist-info/RECORD | 2 +- .../DESCRIPTION.rst | 0 .../INSTALLER | 0 .../_markerlib-0.0.0.dist-info/METADATA | 263 ++ .../_markerlib-0.0.0.dist-info/RECORD | 104 + .../WHEEL | 2 +- .../dependency_links.txt | 0 .../entry_points.txt | 61 + .../_markerlib-0.0.0.dist-info/metadata.json | 1 + .../top_level.txt | 0 .../zip-safe | 0 .../backports_abc-0.4.dist-info/RECORD | 2 +- .../chardet-2.3.0.dist-info/RECORD | 66 +- .../DESCRIPTION.rst | 9 + .../INSTALLER | 0 .../enum_compat-0.0.2.dist-info/METADATA | 30 + .../enum_compat-0.0.2.dist-info/RECORD | 7 + .../enum_compat-0.0.2.dist-info/WHEEL | 5 + .../enum_compat-0.0.2.dist-info/metadata.json | 1 + .../top_level.txt} | 0 .../feedparser-5.2.1.dist-info/RECORD | 2 +- .../html5lib-0.9999999.dist-info/RECORD | 60 +- .../PKG-INFO | 2 +- .../SOURCES.txt | 1 + .../dependency_links.txt | 1 + .../installed-files.txt | 6 +- .../requires.txt | 0 .../top_level.txt | 0 .../python3.4/site-packages/ox/__init__.py | 1 + .../python3.4/site-packages/ox/__version.py | 2 +- Shared/lib/python3.4/site-packages/ox/file.py | 2 +- Shared/lib/python3.4/site-packages/ox/srt.py | 39 +- Shared/lib/python3.4/site-packages/ox/vtt.py | 32 + .../DESCRIPTION.rst | 4 +- .../INSTALLER} | 0 .../METADATA | 7 +- .../RECORD | 154 +- .../site-packages/pip-8.1.0.dist-info/WHEEL | 6 + .../entry_points.txt | 2 +- .../metadata.json | 2 +- .../pip-8.1.0.dist-info/top_level.txt | 1 + .../python3.4/site-packages/pip/__init__.py | 6 +- .../site-packages/pip/_vendor/__init__.py | 30 +- .../site-packages/pip/commands/__init__.py | 6 +- .../site-packages/pip/commands/completion.py | 3 +- .../site-packages/pip/commands/freeze.py | 17 +- .../site-packages/pip/commands/install.py | 20 +- .../site-packages/pip/commands/search.py | 11 +- .../site-packages/pip/commands/show.py | 23 + .../site-packages/pip/compat/__init__.py | 12 +- .../site-packages/pip/compat/ordereddict.py | 129 + .../python3.4/site-packages/pip/download.py | 21 +- .../python3.4/site-packages/pip/exceptions.py | 17 +- .../lib/python3.4/site-packages/pip/index.py | 23 +- .../site-packages/pip/operations/freeze.py | 20 +- .../python3.4/site-packages/pip/pep425tags.py | 158 +- .../site-packages/pip/req/req_file.py | 4 + .../site-packages/pip/req/req_install.py | 112 +- .../site-packages/pip/req/req_set.py | 3 +- .../site-packages/pip/utils/__init__.py | 66 +- .../site-packages/pip/utils/deprecation.py | 32 +- .../site-packages/pip/utils/encoding.py | 23 + .../python3.4/site-packages/pip/utils/ui.py | 5 + .../python3.4/site-packages/pip/vcs/git.py | 7 +- .../lib/python3.4/site-packages/pip/wheel.py | 9 +- .../DESCRIPTION.rst | 3 + .../pkg_resources-0.0.0.dist-info/INSTALLER | 1 + .../pkg_resources-0.0.0.dist-info/METADATA | 13 + .../pkg_resources-0.0.0.dist-info/RECORD | 26 + .../pkg_resources-0.0.0.dist-info/WHEEL | 6 + .../metadata.json | 1 + .../_vendor/packaging/markers.py | 273 ++ .../_vendor/packaging/requirements.py | 127 + .../pkg_resources/_vendor/packaging/utils.py | 14 + .../pkg_resources/_vendor/pyparsing.py | 3805 +++++++++++++++++ .../python_stdnum-1.2.dist-info/RECORD | 308 +- .../requests-2.9.1.dist-info/RECORD | 150 +- .../DESCRIPTION.rst | 238 ++ .../setuptools-20.2.2.dist-info/INSTALLER | 1 + .../METADATA | 2 +- .../RECORD | 146 +- .../WHEEL | 0 .../dependency_links.txt | 2 + .../entry_points.txt | 0 .../metadata.json | 2 +- .../setuptools-20.2.2.dist-info/top_level.txt | 3 + .../setuptools-20.2.2.dist-info/zip-safe | 1 + .../setuptools/command/easy_install.py | 62 +- .../setuptools/command/install_egg_info.py | 22 +- .../setuptools/command/install_lib.py | 27 + .../site-packages/six-1.10.0.dist-info/RECORD | 2 +- .../sqlitedict-1.4.0.dist-info/RECORD | 2 +- .../site-packages/stem-1.4.0.dist-info/RECORD | 70 +- .../tornado-4.3.dist-info/RECORD | 146 +- .../wheel-0.29.0.dist-info/LICENSE.txt | 22 - .../wheel-0.29.0.dist-info/RECORD | 59 +- .../wheel-0.29.0.dist-info/metadata.json | 2 +- .../test/test-1.0-py2.py3-none-win32.whl | Bin 5226 -> 5224 bytes .../zeroconf-0.17.4.dist-info/DESCRIPTION.rst | 277 ++ .../zeroconf-0.17.4.dist-info/INSTALLER | 1 + .../zeroconf-0.17.4.dist-info/METADATA | 310 ++ .../zeroconf-0.17.4.dist-info/RECORD | 10 + .../zeroconf-0.17.4.dist-info/WHEEL | 6 + .../zeroconf-0.17.4.dist-info/metadata.json | 1 + .../zeroconf-0.17.4.dist-info/pbr.json | 1 + .../zeroconf-0.17.4.dist-info/top_level.txt | 1 + .../lib/python3.4/site-packages/zeroconf.py | 1679 ++++++++ 108 files changed, 8626 insertions(+), 840 deletions(-) rename Shared/lib/python3.4/site-packages/{setuptools-20.1.1.dist-info => _markerlib-0.0.0.dist-info}/DESCRIPTION.rst (100%) rename Shared/lib/python3.4/site-packages/{pip-8.0.2.dist-info => _markerlib-0.0.0.dist-info}/INSTALLER (100%) create mode 100644 Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/METADATA create mode 100644 Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/RECORD rename Shared/lib/python3.4/site-packages/{setuptools-20.1.1.dist-info => _markerlib-0.0.0.dist-info}/WHEEL (70%) rename Shared/lib/python3.4/site-packages/{setuptools-20.1.1.dist-info => _markerlib-0.0.0.dist-info}/dependency_links.txt (100%) create mode 100644 Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/entry_points.txt create mode 100644 Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/metadata.json rename Shared/lib/python3.4/site-packages/{setuptools-20.1.1.dist-info => _markerlib-0.0.0.dist-info}/top_level.txt (100%) rename Shared/lib/python3.4/site-packages/{setuptools-20.1.1.dist-info => _markerlib-0.0.0.dist-info}/zip-safe (100%) create mode 100644 Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/DESCRIPTION.rst rename Shared/lib/python3.4/site-packages/{setuptools-20.1.1.dist-info => enum_compat-0.0.2.dist-info}/INSTALLER (100%) create mode 100644 Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/METADATA create mode 100644 Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/RECORD create mode 100644 Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/WHEEL create mode 100644 Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/metadata.json rename Shared/lib/python3.4/site-packages/{ox-2.3.b_783_-py3.4.egg-info/dependency_links.txt => enum_compat-0.0.2.dist-info/top_level.txt} (100%) rename Shared/lib/python3.4/site-packages/{ox-2.3.b_783_-py3.4.egg-info => ox-2.3.b_786_-py3.4.egg-info}/PKG-INFO (96%) rename Shared/lib/python3.4/site-packages/{ox-2.3.b_783_-py3.4.egg-info => ox-2.3.b_786_-py3.4.egg-info}/SOURCES.txt (97%) create mode 100644 Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/dependency_links.txt rename Shared/lib/python3.4/site-packages/{ox-2.3.b_783_-py3.4.egg-info => ox-2.3.b_786_-py3.4.egg-info}/installed-files.txt (98%) rename Shared/lib/python3.4/site-packages/{ox-2.3.b_783_-py3.4.egg-info => ox-2.3.b_786_-py3.4.egg-info}/requires.txt (100%) rename Shared/lib/python3.4/site-packages/{ox-2.3.b_783_-py3.4.egg-info => ox-2.3.b_786_-py3.4.egg-info}/top_level.txt (100%) create mode 100644 Shared/lib/python3.4/site-packages/ox/vtt.py rename Shared/lib/python3.4/site-packages/{pip-8.0.2.dist-info => pip-8.1.0.dist-info}/DESCRIPTION.rst (86%) rename Shared/lib/python3.4/site-packages/{pip-8.0.2.dist-info/top_level.txt => pip-8.1.0.dist-info/INSTALLER} (100%) rename Shared/lib/python3.4/site-packages/{pip-8.0.2.dist-info => pip-8.1.0.dist-info}/METADATA (90%) rename Shared/lib/python3.4/site-packages/{pip-8.0.2.dist-info => pip-8.1.0.dist-info}/RECORD (61%) create mode 100644 Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/WHEEL rename Shared/lib/python3.4/site-packages/{pip-8.0.2.dist-info => pip-8.1.0.dist-info}/entry_points.txt (73%) rename Shared/lib/python3.4/site-packages/{pip-8.0.2.dist-info => pip-8.1.0.dist-info}/metadata.json (67%) create mode 100644 Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/top_level.txt create mode 100644 Shared/lib/python3.4/site-packages/pip/compat/ordereddict.py create mode 100644 Shared/lib/python3.4/site-packages/pip/utils/encoding.py create mode 100644 Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/DESCRIPTION.rst create mode 100644 Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER create mode 100644 Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/METADATA create mode 100644 Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/RECORD create mode 100644 Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/WHEEL create mode 100644 Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/metadata.json create mode 100644 Shared/lib/python3.4/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 Shared/lib/python3.4/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 Shared/lib/python3.4/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 Shared/lib/python3.4/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/DESCRIPTION.rst create mode 100644 Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/INSTALLER rename Shared/lib/python3.4/site-packages/{setuptools-20.1.1.dist-info => setuptools-20.2.2.dist-info}/METADATA (99%) rename Shared/lib/python3.4/site-packages/{setuptools-20.1.1.dist-info => setuptools-20.2.2.dist-info}/RECORD (74%) rename Shared/lib/python3.4/site-packages/{pip-8.0.2.dist-info => setuptools-20.2.2.dist-info}/WHEEL (100%) create mode 100644 Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/dependency_links.txt rename Shared/lib/python3.4/site-packages/{setuptools-20.1.1.dist-info => setuptools-20.2.2.dist-info}/entry_points.txt (100%) rename Shared/lib/python3.4/site-packages/{setuptools-20.1.1.dist-info => setuptools-20.2.2.dist-info}/metadata.json (98%) create mode 100644 Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/top_level.txt create mode 100644 Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/zip-safe delete mode 100644 Shared/lib/python3.4/site-packages/wheel-0.29.0.dist-info/LICENSE.txt create mode 100644 Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/DESCRIPTION.rst create mode 100644 Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/INSTALLER create mode 100644 Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/METADATA create mode 100644 Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/RECORD create mode 100644 Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/WHEEL create mode 100644 Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/metadata.json create mode 100644 Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/pbr.json create mode 100644 Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/top_level.txt create mode 100644 Shared/lib/python3.4/site-packages/zeroconf.py diff --git a/Shared/lib/python3.4/site-packages/PyPDF2-1.25.1.dist-info/RECORD b/Shared/lib/python3.4/site-packages/PyPDF2-1.25.1.dist-info/RECORD index b06e630..8c29a0e 100644 --- a/Shared/lib/python3.4/site-packages/PyPDF2-1.25.1.dist-info/RECORD +++ b/Shared/lib/python3.4/site-packages/PyPDF2-1.25.1.dist-info/RECORD @@ -13,13 +13,13 @@ PyPDF2-1.25.1.dist-info/RECORD,, PyPDF2-1.25.1.dist-info/WHEEL,sha256=lCqt3ViRAf9c8mCs6o7ffkwROUdYSy8_YHn5f_rulB4,93 PyPDF2-1.25.1.dist-info/metadata.json,sha256=gaK0QZPmK8xsUqrxEf3uGaJQXIevQ5Z5ZfV-NfIhVc4,692 PyPDF2-1.25.1.dist-info/top_level.txt,sha256=BERWrwqdvKXaVKhpnMbtO6b11qPA-mBt2r9a0VPF-Ow,7 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/lib/python3.4/site-packages/PyPDF2-1.25.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +PyPDF2-1.25.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +PyPDF2/__pycache__/pagerange.cpython-34.pyc,, PyPDF2/__pycache__/xmp.cpython-34.pyc,, +PyPDF2/__pycache__/_version.cpython-34.pyc,, +PyPDF2/__pycache__/__init__.cpython-34.pyc,, +PyPDF2/__pycache__/utils.cpython-34.pyc,, PyPDF2/__pycache__/pdf.cpython-34.pyc,, PyPDF2/__pycache__/generic.cpython-34.pyc,, PyPDF2/__pycache__/filters.cpython-34.pyc,, -PyPDF2/__pycache__/pagerange.cpython-34.pyc,, -PyPDF2/__pycache__/_version.cpython-34.pyc,, -PyPDF2/__pycache__/__init__.cpython-34.pyc,, PyPDF2/__pycache__/merger.cpython-34.pyc,, -PyPDF2/__pycache__/utils.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/PySocks-1.5.6.dist-info/RECORD b/Shared/lib/python3.4/site-packages/PySocks-1.5.6.dist-info/RECORD index 93f49da..214cd97 100644 --- a/Shared/lib/python3.4/site-packages/PySocks-1.5.6.dist-info/RECORD +++ b/Shared/lib/python3.4/site-packages/PySocks-1.5.6.dist-info/RECORD @@ -6,6 +6,6 @@ PySocks-1.5.6.dist-info/RECORD,, PySocks-1.5.6.dist-info/WHEEL,sha256=lCqt3ViRAf9c8mCs6o7ffkwROUdYSy8_YHn5f_rulB4,93 PySocks-1.5.6.dist-info/metadata.json,sha256=1YIXTsL7gr8l01o_J6_5NIv29fVrNchGX8t-w1bmPKA,498 PySocks-1.5.6.dist-info/top_level.txt,sha256=TKSOIfCFBoK9EY8FBYbYqC3PWd3--G15ph9n8-QHPDk,19 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/lib/python3.4/site-packages/PySocks-1.5.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +PySocks-1.5.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 __pycache__/sockshandler.cpython-34.pyc,, __pycache__/socks.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/DESCRIPTION.rst b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/DESCRIPTION.rst similarity index 100% rename from Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/DESCRIPTION.rst rename to Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/DESCRIPTION.rst diff --git a/Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/INSTALLER b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/INSTALLER similarity index 100% rename from Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/INSTALLER rename to Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/INSTALLER diff --git a/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/METADATA b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/METADATA new file mode 100644 index 0000000..2a37585 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/METADATA @@ -0,0 +1,263 @@ +Metadata-Version: 2.0 +Name: setuptools +Version: 20.1.1 +Summary: Easily download, build, install, upgrade, and uninstall Python packages +Home-page: https://bitbucket.org/pypa/setuptools +Author: Python Packaging Authority +Author-email: distutils-sig@python.org +License: UNKNOWN +Keywords: CPAN PyPI distutils eggs package management +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: System :: Archiving :: Packaging +Classifier: Topic :: System :: Systems Administration +Classifier: Topic :: Utilities + +=============================== +Installing and Using Setuptools +=============================== + +.. contents:: **Table of Contents** + + +`Change History `_. + +------------------------- +Installation Instructions +------------------------- + +The recommended way to bootstrap setuptools on any system is to download +`ez_setup.py`_ and run it using the target Python environment. Different +operating systems have different recommended techniques to accomplish this +basic routine, so below are some examples to get you started. + +Setuptools requires Python 2.6 or later. To install setuptools +on Python 2.4 or Python 2.5, use the `bootstrap script for Setuptools 1.x +`_. + +The link provided to ez_setup.py is a bookmark to bootstrap script for the +latest known stable release. + +.. _ez_setup.py: https://bootstrap.pypa.io/ez_setup.py + +Windows (Powershell 3 or later) +=============================== + +For best results, uninstall previous versions FIRST (see `Uninstalling`_). + +Using Windows 8 (which includes PowerShell 3) or earlier versions of Windows +with PowerShell 3 installed, it's possible to install with one simple +Powershell command. Start up Powershell and paste this command:: + + > (Invoke-WebRequest https://bootstrap.pypa.io/ez_setup.py).Content | python - + +You must start the Powershell with Administrative privileges or you may choose +to install a user-local installation:: + + > (Invoke-WebRequest https://bootstrap.pypa.io/ez_setup.py).Content | python - --user + +If you have Python 3.3 or later, you can use the ``py`` command to install to +different Python versions. For example, to install to Python 3.3 if you have +Python 2.7 installed:: + + > (Invoke-WebRequest https://bootstrap.pypa.io/ez_setup.py).Content | py -3 - + +The recommended way to install setuptools on Windows is to download +`ez_setup.py`_ and run it. The script will download the appropriate +distribution file and install it for you. + +Once installation is complete, you will find an ``easy_install`` program in +your Python ``Scripts`` subdirectory. For simple invocation and best results, +add this directory to your ``PATH`` environment variable, if it is not already +present. If you did a user-local install, the ``Scripts`` subdirectory is +``$env:APPDATA\Python\Scripts``. + + +Windows (simplified) +==================== + +For Windows without PowerShell 3 or for installation without a command-line, +download `ez_setup.py`_ using your preferred web browser or other technique +and "run" that file. + + +Unix (wget) +=========== + +Most Linux distributions come with wget. + +Download `ez_setup.py`_ and run it using the target Python version. The script +will download the appropriate version and install it for you:: + + > wget https://bootstrap.pypa.io/ez_setup.py -O - | python + +Note that you will may need to invoke the command with superuser privileges to +install to the system Python:: + + > wget https://bootstrap.pypa.io/ez_setup.py -O - | sudo python + +Alternatively, Setuptools may be installed to a user-local path:: + + > wget https://bootstrap.pypa.io/ez_setup.py -O - | python - --user + +Note that on some older systems (noted on Debian 6 and CentOS 5 installations), +`wget` may refuse to download `ez_setup.py`, complaining that the certificate common name `*.c.ssl.fastly.net` +does not match the host name `bootstrap.pypa.io`. In addition, the `ez_setup.py` script may then encounter similar problems using +`wget` internally to download `setuptools-x.y.zip`, complaining that the certificate common name of `www.python.org` does not match the +host name `pypi.python.org`. Those are known issues, related to a bug in the older versions of `wget` +(see `Issue 59 `_). If you happen to encounter them, +install Setuptools as follows:: + + > wget --no-check-certificate https://bootstrap.pypa.io/ez_setup.py + > python ez_setup.py --insecure + + +Unix including Mac OS X (curl) +============================== + +If your system has curl installed, follow the ``wget`` instructions but +replace ``wget`` with ``curl`` and ``-O`` with ``-o``. For example:: + + > curl https://bootstrap.pypa.io/ez_setup.py -o - | python + + +Advanced Installation +===================== + +For more advanced installation options, such as installing to custom +locations or prefixes, download and extract the source +tarball from `Setuptools on PyPI `_ +and run setup.py with any supported distutils and Setuptools options. +For example:: + + setuptools-x.x$ python setup.py install --prefix=/opt/setuptools + +Use ``--help`` to get a full options list, but we recommend consulting +the `EasyInstall manual`_ for detailed instructions, especially `the section +on custom installation locations`_. + +.. _EasyInstall manual: https://pythonhosted.org/setuptools/EasyInstall +.. _the section on custom installation locations: https://pythonhosted.org/setuptools/EasyInstall#custom-installation-locations + + +Downloads +========= + +All setuptools downloads can be found at `the project's home page in the Python +Package Index`_. Scroll to the very bottom of the page to find the links. + +.. _the project's home page in the Python Package Index: https://pypi.python.org/pypi/setuptools + +In addition to the PyPI downloads, the development version of ``setuptools`` +is available from the `Bitbucket repo`_, and in-development versions of the +`0.6 branch`_ are available as well. + +.. _Bitbucket repo: https://bitbucket.org/pypa/setuptools/get/default.tar.gz#egg=setuptools-dev +.. _0.6 branch: http://svn.python.org/projects/sandbox/branches/setuptools-0.6/#egg=setuptools-dev06 + +Uninstalling +============ + +On Windows, if Setuptools was installed using an ``.exe`` or ``.msi`` +installer, simply use the uninstall feature of "Add/Remove Programs" in the +Control Panel. + +Otherwise, to uninstall Setuptools or Distribute, regardless of the Python +version, delete all ``setuptools*`` and ``distribute*`` files and +directories from your system's ``site-packages`` directory +(and any other ``sys.path`` directories) FIRST. + +If you are upgrading or otherwise plan to re-install Setuptools or Distribute, +nothing further needs to be done. If you want to completely remove Setuptools, +you may also want to remove the 'easy_install' and 'easy_install-x.x' scripts +and associated executables installed to the Python scripts directory. + +-------------------------------- +Using Setuptools and EasyInstall +-------------------------------- + +Here are some of the available manuals, tutorials, and other resources for +learning about Setuptools, Python Eggs, and EasyInstall: + +* `The EasyInstall user's guide and reference manual`_ +* `The setuptools Developer's Guide`_ +* `The pkg_resources API reference`_ +* `The Internal Structure of Python Eggs`_ + +Questions, comments, and bug reports should be directed to the `distutils-sig +mailing list`_. If you have written (or know of) any tutorials, documentation, +plug-ins, or other resources for setuptools users, please let us know about +them there, so this reference list can be updated. If you have working, +*tested* patches to correct problems or add features, you may submit them to +the `setuptools bug tracker`_. + +.. _setuptools bug tracker: https://bitbucket.org/pypa/setuptools/issues +.. _The Internal Structure of Python Eggs: https://pythonhosted.org/setuptools/formats.html +.. _The setuptools Developer's Guide: https://pythonhosted.org/setuptools/setuptools.html +.. _The pkg_resources API reference: https://pythonhosted.org/setuptools/pkg_resources.html +.. _The EasyInstall user's guide and reference manual: https://pythonhosted.org/setuptools/easy_install.html +.. _distutils-sig mailing list: http://mail.python.org/pipermail/distutils-sig/ + + +------- +Credits +------- + +* The original design for the ``.egg`` format and the ``pkg_resources`` API was + co-created by Phillip Eby and Bob Ippolito. Bob also implemented the first + version of ``pkg_resources``, and supplied the OS X operating system version + compatibility algorithm. + +* Ian Bicking implemented many early "creature comfort" features of + easy_install, including support for downloading via Sourceforge and + Subversion repositories. Ian's comments on the Web-SIG about WSGI + application deployment also inspired the concept of "entry points" in eggs, + and he has given talks at PyCon and elsewhere to inform and educate the + community about eggs and setuptools. + +* Jim Fulton contributed time and effort to build automated tests of various + aspects of ``easy_install``, and supplied the doctests for the command-line + ``.exe`` wrappers on Windows. + +* Phillip J. Eby is the seminal author of setuptools, and + first proposed the idea of an importable binary distribution format for + Python application plug-ins. + +* Significant parts of the implementation of setuptools were funded by the Open + Source Applications Foundation, to provide a plug-in infrastructure for the + Chandler PIM application. In addition, many OSAF staffers (such as Mike + "Code Bear" Taylor) contributed their time and stress as guinea pigs for the + use of eggs and setuptools, even before eggs were "cool". (Thanks, guys!) + +* Tarek Ziadé is the principal author of the Distribute fork, which + re-invigorated the community on the project, encouraged renewed innovation, + and addressed many defects. + +* Since the merge with Distribute, Jason R. Coombs is the + maintainer of setuptools. The project is maintained in coordination with + the Python Packaging Authority (PyPA) and the larger Python community. + +.. _files: + + +--------------- +Code of Conduct +--------------- + +Everyone interacting in the setuptools project's codebases, issue trackers, +chat rooms, and mailing lists is expected to follow the +`PyPA Code of Conduct`_. + +.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + + diff --git a/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/RECORD b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/RECORD new file mode 100644 index 0000000..43ba25f --- /dev/null +++ b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/RECORD @@ -0,0 +1,104 @@ +easy_install.py,sha256=MDC9vt5AxDsXX5qcKlBz2TnW6Tpuv_AobnfhCJ9X3PM,126 +_markerlib/__init__.py,sha256=GSmhZqvAitLJHhSgtqqusfq2nJ_ClP3oy3Lm0uZLIsU,552 +_markerlib/markers.py,sha256=YuFp0-osufFIoqnzG3L0Z2fDCx4Vln3VUDeXJ2DA_1I,3979 +_markerlib-0.0.0.dist-info/DESCRIPTION.rst,sha256=MDsJej8DPV2OKpAKpu74g-2xksRd-uGTeZn4W7D1dnI,9940 +_markerlib-0.0.0.dist-info/METADATA,sha256=l8LCWR8HLdKmOz1QMU2JQREbM9o4dCsMPkBdBSi_Jgo,10997 +_markerlib-0.0.0.dist-info/RECORD,, +_markerlib-0.0.0.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110 +_markerlib-0.0.0.dist-info/dependency_links.txt,sha256=oUNXJEArClXFiSSvfFwUKY8TYjeIXhuFfCpXn5K0DCE,226 +_markerlib-0.0.0.dist-info/entry_points.txt,sha256=S6yRfyEABPIKq4cNMNO_7LHXzFVZW-exLSrKSI6kgNU,2779 +_markerlib-0.0.0.dist-info/metadata.json,sha256=OwUAZgU-PBMGwfXh2QKg7ec1Kh9aGVfWnOB5mrc48HA,4242 +_markerlib-0.0.0.dist-info/top_level.txt,sha256=7780fzudMJkykiTcIrAQ8m8Lll6kot3EEePye3VJgEE,49 +_markerlib-0.0.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +setuptools/__init__.py,sha256=WEGb6BRGN2dz3eJTbNRUfInUAhb6_OZJyYAndPGJm6w,5440 +setuptools/archive_util.py,sha256=N30WE5ZQjkytzhAodAXw4FkK-9J5AP1ChrClHnZthOA,6609 +setuptools/depends.py,sha256=WyJIhjIX7D5-JpGSnMAPHEoDcVPQxaO0405keTQT6jM,6418 +setuptools/dist.py,sha256=txOleyyt2xCSTkUjCGW4MYZB8a1xsbC8MulDhSnoivQ,35701 +setuptools/extension.py,sha256=YvsyGHWVWzhNOXMHU239FR14wxw2WwdMLLzWsRP6_IY,1694 +setuptools/launch.py,sha256=hP3qZxDNu5Hf9C-VAkEP4IC_YYfR1XfxMTj6EguxxCg,730 +setuptools/lib2to3_ex.py,sha256=6jPF9sJuHiz0cyg4cwIBLl2VMAxcl3GYSZwWAOuJplU,1998 +setuptools/msvc9_support.py,sha256=fo2vjb-dna1SEuHezQCTuelCo6XFBv5cqaI56ABJ1vw,2187 +setuptools/package_index.py,sha256=T6tZGPHApup6Gl3kz1sCLtY7kmMUXLBKweSAORYS2Qc,39490 +setuptools/py26compat.py,sha256=1Vvuf-hj5bTM3OAXv6vgJQImulne12ann053caOgikU,481 +setuptools/py27compat.py,sha256=CGj-jZcFgHUkrEdLvArkxHj96tAaMbG2-yJtUVU7QVI,306 +setuptools/py31compat.py,sha256=cqYSVBd2pxvKl75185z40htfEr6EKC29KvSBiSoqHOA,1636 +setuptools/sandbox.py,sha256=tuMRu_8R0_w6Qer9VqDiOTqKy1qr_GjHi-2QAg7TMz0,14210 +setuptools/script (dev).tmpl,sha256=f7MR17dTkzaqkCMSVseyOCMVrPVSMdmTQsaB8cZzfuI,201 +setuptools/script.tmpl,sha256=WGTt5piezO27c-Dbx6l5Q4T3Ff20A5z7872hv3aAhYY,138 +setuptools/site-patch.py,sha256=K-0-cAx36mX_PG-qPZwosG9ZLCliRjquKQ4nHiJvvzg,2389 +setuptools/ssl_support.py,sha256=tAFeeyFPVle_GgarPkNrdfnCJgP9PyN_QYGXTgypoyc,8119 +setuptools/unicode_utils.py,sha256=8zVyrL_MFc6P5AmErs21rr7z-3N1pZ_NkOcDC7BPElU,995 +setuptools/utils.py,sha256=08Z7mt-9mvrx-XvmS5EyKoRn2lxNTlgFsUwBU3Eq9JQ,293 +setuptools/version.py,sha256=E3F8rAlTgCNpmTTY2YGy4T_1iQn3gKsePB7TVIcObu0,23 +setuptools/windows_support.py,sha256=5GrfqSP2-dLGJoZTq2g6dCKkyQxxa2n5IQiXlJCoYEE,714 +setuptools/command/__init__.py,sha256=1AM3hv_zCixE7kTXA-onWfK_2KF8GC8fUw3WSxzi5Fg,564 +setuptools/command/alias.py,sha256=KjpE0sz_SDIHv3fpZcIQK-sCkJz-SrC6Gmug6b9Nkc8,2426 +setuptools/command/bdist_egg.py,sha256=Km4CsGbevhvej6kKEfvTYxfkPoQijUyXmImNifrO4Tg,17184 +setuptools/command/bdist_rpm.py,sha256=B7l0TnzCGb-0nLlm6rS00jWLkojASwVmdhW2w5Qz_Ak,1508 +setuptools/command/bdist_wininst.py,sha256=_6dz3lpB1tY200LxKPLM7qgwTCceOMgaWFF-jW2-pm0,637 +setuptools/command/build_ext.py,sha256=pkQ8xp3YPVGGLkGv-SvfxC_GqFpboph1AFEoMFOgQMo,11964 +setuptools/command/build_py.py,sha256=HvJ88JuougDccaowYlfMV12kYtd0GLahg2DR2vQRqL4,7983 +setuptools/command/develop.py,sha256=VxSYbpM2jQqtRBn5klIjPVBo3sWKNZMlSbHHiRLUlZo,7383 +setuptools/command/easy_install.py,sha256=WDidYAhIEWCT-63bVvoazy8HcITEWDn4Xzgrj3YZgz0,88492 +setuptools/command/egg_info.py,sha256=0_8eI8hgLAlGt8Xk5kiodY_d9lxG6_RSescJISKBJgA,16890 +setuptools/command/install.py,sha256=QwaFiZRU3ytIHoPh8uJ9EqV3Fu9C4ca4B7UGAo95tws,4685 +setuptools/command/install_egg_info.py,sha256=fEqU1EplTs_vUjAzwiEB7LrtdZBQ3BefwuUZLZBDEQ0,5027 +setuptools/command/install_lib.py,sha256=5IZM251t4DzOdZAXCezdROr3X0SeeE41eyV059RNgZ4,5011 +setuptools/command/install_scripts.py,sha256=vX2JC6v7l090N7CrTfihWBklNbPvfNKAY2LRtukM9XE,2231 +setuptools/command/register.py,sha256=bHlMm1qmBbSdahTOT8w6UhA-EgeQIz7p6cD-qOauaiI,270 +setuptools/command/rotate.py,sha256=QGZS2t4CmBl7t79KQijNCjRMU50lu3nRhu4FXWB5LIE,2038 +setuptools/command/saveopts.py,sha256=za7QCBcQimKKriWcoCcbhxPjUz30gSB74zuTL47xpP4,658 +setuptools/command/sdist.py,sha256=kQetnPMw6ao3nurWGJZgS4HkOH4AknzMOSvqbVA6jGA,7050 +setuptools/command/setopt.py,sha256=cygJaJWJmiVhR0e_Uh_0_fWyCxMJIqK-Bu6K0LyYUtU,5086 +setuptools/command/test.py,sha256=N2f5RwxkjwU3YQzFYHtzHr636-pdX9XJDuPg5Y92kSo,6888 +setuptools/command/upload.py,sha256=OjAryq4ZoARZiaTN_MpuG1X8Pu9CJNCKmmbMg-gab5I,649 +setuptools/command/upload_docs.py,sha256=htXpASci5gKP0RIrGZRRmbll7RnTRuwvKWZkYsBlDMM,6815 +setuptools/extern/__init__.py,sha256=mTrrj4yLMdFeEwwnqKnSuvZM5RM-HPZ1iXLgaYDlB9o,132 +../../../bin/easy_install,sha256=4bXVXBoSo_A1XK3Ga5UMkOREdCSnh8FZIYqtJVSWCa4,298 +../../../bin/easy_install-3.4,sha256=4bXVXBoSo_A1XK3Ga5UMkOREdCSnh8FZIYqtJVSWCa4,298 +_markerlib-0.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +setuptools/__pycache__/py27compat.cpython-34.pyc,, +setuptools/__pycache__/sandbox.cpython-34.pyc,, +setuptools/__pycache__/version.cpython-34.pyc,, +setuptools/__pycache__/launch.cpython-34.pyc,, +setuptools/command/__pycache__/install_egg_info.cpython-34.pyc,, +setuptools/__pycache__/py26compat.cpython-34.pyc,, +setuptools/command/__pycache__/rotate.cpython-34.pyc,, +setuptools/command/__pycache__/install_scripts.cpython-34.pyc,, +setuptools/command/__pycache__/setopt.cpython-34.pyc,, +setuptools/command/__pycache__/alias.cpython-34.pyc,, +setuptools/__pycache__/unicode_utils.cpython-34.pyc,, +_markerlib/__pycache__/markers.cpython-34.pyc,, +setuptools/__pycache__/package_index.cpython-34.pyc,, +setuptools/__pycache__/depends.cpython-34.pyc,, +setuptools/__pycache__/lib2to3_ex.cpython-34.pyc,, +__pycache__/easy_install.cpython-34.pyc,, +setuptools/__pycache__/__init__.cpython-34.pyc,, +setuptools/command/__pycache__/bdist_wininst.cpython-34.pyc,, +setuptools/command/__pycache__/upload_docs.cpython-34.pyc,, +setuptools/command/__pycache__/register.cpython-34.pyc,, +setuptools/__pycache__/dist.cpython-34.pyc,, +setuptools/command/__pycache__/bdist_rpm.cpython-34.pyc,, +setuptools/__pycache__/archive_util.cpython-34.pyc,, +setuptools/__pycache__/extension.cpython-34.pyc,, +setuptools/command/__pycache__/test.cpython-34.pyc,, +setuptools/command/__pycache__/__init__.cpython-34.pyc,, +setuptools/__pycache__/utils.cpython-34.pyc,, +setuptools/command/__pycache__/develop.cpython-34.pyc,, +setuptools/extern/__pycache__/__init__.cpython-34.pyc,, +setuptools/__pycache__/windows_support.cpython-34.pyc,, +setuptools/command/__pycache__/build_ext.cpython-34.pyc,, +setuptools/command/__pycache__/sdist.cpython-34.pyc,, +setuptools/command/__pycache__/saveopts.cpython-34.pyc,, +setuptools/command/__pycache__/bdist_egg.cpython-34.pyc,, +setuptools/__pycache__/site-patch.cpython-34.pyc,, +setuptools/command/__pycache__/install.cpython-34.pyc,, +_markerlib/__pycache__/__init__.cpython-34.pyc,, +setuptools/command/__pycache__/egg_info.cpython-34.pyc,, +setuptools/command/__pycache__/easy_install.cpython-34.pyc,, +setuptools/__pycache__/msvc9_support.cpython-34.pyc,, +setuptools/__pycache__/ssl_support.cpython-34.pyc,, +setuptools/command/__pycache__/build_py.cpython-34.pyc,, +setuptools/command/__pycache__/install_lib.cpython-34.pyc,, +setuptools/__pycache__/py31compat.cpython-34.pyc,, +setuptools/command/__pycache__/upload.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/WHEEL b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/WHEEL similarity index 70% rename from Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/WHEEL rename to Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/WHEEL index 0de529b..8b6dd1b 100644 --- a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/WHEEL +++ b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/WHEEL @@ -1,5 +1,5 @@ Wheel-Version: 1.0 -Generator: bdist_wheel (0.26.0) +Generator: bdist_wheel (0.29.0) Root-Is-Purelib: true Tag: py2-none-any Tag: py3-none-any diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/dependency_links.txt b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/dependency_links.txt similarity index 100% rename from Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/dependency_links.txt rename to Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/dependency_links.txt diff --git a/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/entry_points.txt b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/entry_points.txt new file mode 100644 index 0000000..5270e4a --- /dev/null +++ b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/entry_points.txt @@ -0,0 +1,61 @@ +[console_scripts] +easy_install = setuptools.command.easy_install:main + +[distutils.commands] +alias = setuptools.command.alias:alias +bdist_egg = setuptools.command.bdist_egg:bdist_egg +bdist_rpm = setuptools.command.bdist_rpm:bdist_rpm +bdist_wininst = setuptools.command.bdist_wininst:bdist_wininst +build_ext = setuptools.command.build_ext:build_ext +build_py = setuptools.command.build_py:build_py +develop = setuptools.command.develop:develop +easy_install = setuptools.command.easy_install:easy_install +egg_info = setuptools.command.egg_info:egg_info +install = setuptools.command.install:install +install_egg_info = setuptools.command.install_egg_info:install_egg_info +install_lib = setuptools.command.install_lib:install_lib +install_scripts = setuptools.command.install_scripts:install_scripts +register = setuptools.command.register:register +rotate = setuptools.command.rotate:rotate +saveopts = setuptools.command.saveopts:saveopts +sdist = setuptools.command.sdist:sdist +setopt = setuptools.command.setopt:setopt +test = setuptools.command.test:test +upload = setuptools.command.upload:upload +upload_docs = setuptools.command.upload_docs:upload_docs + +[distutils.setup_keywords] +convert_2to3_doctests = setuptools.dist:assert_string_list +dependency_links = setuptools.dist:assert_string_list +eager_resources = setuptools.dist:assert_string_list +entry_points = setuptools.dist:check_entry_points +exclude_package_data = setuptools.dist:check_package_data +extras_require = setuptools.dist:check_extras +include_package_data = setuptools.dist:assert_bool +install_requires = setuptools.dist:check_requirements +namespace_packages = setuptools.dist:check_nsp +package_data = setuptools.dist:check_package_data +packages = setuptools.dist:check_packages +setup_requires = setuptools.dist:check_requirements +test_loader = setuptools.dist:check_importable +test_runner = setuptools.dist:check_importable +test_suite = setuptools.dist:check_test_suite +tests_require = setuptools.dist:check_requirements +use_2to3 = setuptools.dist:assert_bool +use_2to3_exclude_fixers = setuptools.dist:assert_string_list +use_2to3_fixers = setuptools.dist:assert_string_list +zip_safe = setuptools.dist:assert_bool + +[egg_info.writers] +PKG-INFO = setuptools.command.egg_info:write_pkg_info +dependency_links.txt = setuptools.command.egg_info:overwrite_arg +depends.txt = setuptools.command.egg_info:warn_depends_obsolete +eager_resources.txt = setuptools.command.egg_info:overwrite_arg +entry_points.txt = setuptools.command.egg_info:write_entries +namespace_packages.txt = setuptools.command.egg_info:overwrite_arg +requires.txt = setuptools.command.egg_info:write_requirements +top_level.txt = setuptools.command.egg_info:write_toplevel_names + +[setuptools.installation] +eggsecutable = setuptools.command.easy_install:bootstrap + diff --git a/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/metadata.json b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/metadata.json new file mode 100644 index 0000000..885b5f3 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: System :: Archiving :: Packaging", "Topic :: System :: Systems Administration", "Topic :: Utilities"], "extensions": {"python.commands": {"wrap_console": {"easy_install": "setuptools.command.easy_install:main"}}, "python.details": {"contacts": [{"email": "distutils-sig@python.org", "name": "Python Packaging Authority", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://bitbucket.org/pypa/setuptools"}}, "python.exports": {"console_scripts": {"easy_install": "setuptools.command.easy_install:main"}, "distutils.commands": {"alias": "setuptools.command.alias:alias", "bdist_egg": "setuptools.command.bdist_egg:bdist_egg", "bdist_rpm": "setuptools.command.bdist_rpm:bdist_rpm", "bdist_wininst": "setuptools.command.bdist_wininst:bdist_wininst", "build_ext": "setuptools.command.build_ext:build_ext", "build_py": "setuptools.command.build_py:build_py", "develop": "setuptools.command.develop:develop", "easy_install": "setuptools.command.easy_install:easy_install", "egg_info": "setuptools.command.egg_info:egg_info", "install": "setuptools.command.install:install", "install_egg_info": "setuptools.command.install_egg_info:install_egg_info", "install_lib": "setuptools.command.install_lib:install_lib", "install_scripts": "setuptools.command.install_scripts:install_scripts", "register": "setuptools.command.register:register", "rotate": "setuptools.command.rotate:rotate", "saveopts": "setuptools.command.saveopts:saveopts", "sdist": "setuptools.command.sdist:sdist", "setopt": "setuptools.command.setopt:setopt", "test": "setuptools.command.test:test", "upload": "setuptools.command.upload:upload", "upload_docs": "setuptools.command.upload_docs:upload_docs"}, "distutils.setup_keywords": {"convert_2to3_doctests": "setuptools.dist:assert_string_list", "dependency_links": "setuptools.dist:assert_string_list", "eager_resources": "setuptools.dist:assert_string_list", "entry_points": "setuptools.dist:check_entry_points", "exclude_package_data": "setuptools.dist:check_package_data", "extras_require": "setuptools.dist:check_extras", "include_package_data": "setuptools.dist:assert_bool", "install_requires": "setuptools.dist:check_requirements", "namespace_packages": "setuptools.dist:check_nsp", "package_data": "setuptools.dist:check_package_data", "packages": "setuptools.dist:check_packages", "setup_requires": "setuptools.dist:check_requirements", "test_loader": "setuptools.dist:check_importable", "test_runner": "setuptools.dist:check_importable", "test_suite": "setuptools.dist:check_test_suite", "tests_require": "setuptools.dist:check_requirements", "use_2to3": "setuptools.dist:assert_bool", "use_2to3_exclude_fixers": "setuptools.dist:assert_string_list", "use_2to3_fixers": "setuptools.dist:assert_string_list", "zip_safe": "setuptools.dist:assert_bool"}, "egg_info.writers": {"PKG-INFO": "setuptools.command.egg_info:write_pkg_info", "dependency_links.txt": "setuptools.command.egg_info:overwrite_arg", "depends.txt": "setuptools.command.egg_info:warn_depends_obsolete", "eager_resources.txt": "setuptools.command.egg_info:overwrite_arg", "entry_points.txt": "setuptools.command.egg_info:write_entries", "namespace_packages.txt": "setuptools.command.egg_info:overwrite_arg", "requires.txt": "setuptools.command.egg_info:write_requirements", "top_level.txt": "setuptools.command.egg_info:write_toplevel_names"}, "setuptools.installation": {"eggsecutable": "setuptools.command.easy_install:bootstrap"}}}, "generator": "bdist_wheel (0.29.0)", "keywords": ["CPAN", "PyPI", "distutils", "eggs", "package", "management"], "metadata_version": "2.0", "name": "setuptools", "summary": "Easily download, build, install, upgrade, and uninstall Python packages", "version": "20.1.1"} \ No newline at end of file diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/top_level.txt b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/top_level.txt similarity index 100% rename from Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/top_level.txt rename to Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/top_level.txt diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/zip-safe b/Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/zip-safe similarity index 100% rename from Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/zip-safe rename to Shared/lib/python3.4/site-packages/_markerlib-0.0.0.dist-info/zip-safe diff --git a/Shared/lib/python3.4/site-packages/backports_abc-0.4.dist-info/RECORD b/Shared/lib/python3.4/site-packages/backports_abc-0.4.dist-info/RECORD index 24d9269..a1f42ef 100644 --- a/Shared/lib/python3.4/site-packages/backports_abc-0.4.dist-info/RECORD +++ b/Shared/lib/python3.4/site-packages/backports_abc-0.4.dist-info/RECORD @@ -5,5 +5,5 @@ backports_abc-0.4.dist-info/top_level.txt,sha256=VrQEXq17Ce9X1jfsstW6gYD3gyq3Kji backports_abc-0.4.dist-info/RECORD,, backports_abc-0.4.dist-info/metadata.json,sha256=AIEgf2dZKeoBWp4UUzRRrUljLI9o_lXFgb09KXQXG3w,760 backports_abc-0.4.dist-info/WHEEL,sha256=AvR0WeTpDaxT645bl5FQxUK6NPsTls2ttpcGJg3j1Xg,110 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/lib/python3.4/site-packages/backports_abc-0.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +backports_abc-0.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 __pycache__/backports_abc.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/chardet-2.3.0.dist-info/RECORD b/Shared/lib/python3.4/site-packages/chardet-2.3.0.dist-info/RECORD index 1334287..6b7b70b 100644 --- a/Shared/lib/python3.4/site-packages/chardet-2.3.0.dist-info/RECORD +++ b/Shared/lib/python3.4/site-packages/chardet-2.3.0.dist-info/RECORD @@ -43,43 +43,43 @@ chardet-2.3.0.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34 chardet-2.3.0.dist-info/entry_points.txt,sha256=2T00JXwbiQBZQFSKyCFxud4LEQ3_8TKuOwUsSXT-kUI,56 chardet-2.3.0.dist-info/metadata.json,sha256=ptG9BSXYY-lmHsq-i6SjRfvRXYfuvmZz8rZfxrO4Pjs,1225 chardet-2.3.0.dist-info/top_level.txt,sha256=AowzBbZy4x8EirABDdJSLJZMkJ_53iIag8xfKR6D7kI,8 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/bin/chardetect,sha256=GQPhfifvGgQPjka4kP_i-SYM5X_TEW0Hu3SV937PX2o,285 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/lib/python3.4/site-packages/chardet-2.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -chardet/__pycache__/sbcsgroupprober.cpython-34.pyc,, +../../../bin/chardetect,sha256=GQPhfifvGgQPjka4kP_i-SYM5X_TEW0Hu3SV937PX2o,285 +chardet-2.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 chardet/__pycache__/universaldetector.cpython-34.pyc,, -chardet/__pycache__/codingstatemachine.cpython-34.pyc,, -chardet/__pycache__/langbulgarianmodel.cpython-34.pyc,, chardet/__pycache__/euckrprober.cpython-34.pyc,, -chardet/__pycache__/utf8prober.cpython-34.pyc,, -chardet/__pycache__/euctwprober.cpython-34.pyc,, -chardet/__pycache__/hebrewprober.cpython-34.pyc,, -chardet/__pycache__/jpcntx.cpython-34.pyc,, -chardet/__pycache__/latin1prober.cpython-34.pyc,, -chardet/__pycache__/cp949prober.cpython-34.pyc,, -chardet/__pycache__/langthaimodel.cpython-34.pyc,, -chardet/__pycache__/eucjpprober.cpython-34.pyc,, -chardet/__pycache__/sbcharsetprober.cpython-34.pyc,, -chardet/__pycache__/charsetprober.cpython-34.pyc,, -chardet/__pycache__/euctwfreq.cpython-34.pyc,, -chardet/__pycache__/compat.cpython-34.pyc,, -chardet/__pycache__/gb2312prober.cpython-34.pyc,, -chardet/__pycache__/euckrfreq.cpython-34.pyc,, -chardet/__pycache__/chardistribution.cpython-34.pyc,, +chardet/__pycache__/sjisprober.cpython-34.pyc,, chardet/__pycache__/mbcsgroupprober.cpython-34.pyc,, -chardet/__pycache__/gb2312freq.cpython-34.pyc,, +chardet/__pycache__/compat.cpython-34.pyc,, +chardet/__pycache__/chardistribution.cpython-34.pyc,, +chardet/__pycache__/cp949prober.cpython-34.pyc,, +chardet/__pycache__/big5prober.cpython-34.pyc,, +chardet/__pycache__/gb2312prober.cpython-34.pyc,, chardet/__pycache__/mbcharsetprober.cpython-34.pyc,, chardet/__pycache__/escprober.cpython-34.pyc,, -chardet/__pycache__/sjisprober.cpython-34.pyc,, -chardet/__pycache__/chardetect.cpython-34.pyc,, -chardet/__pycache__/charsetgroupprober.cpython-34.pyc,, -chardet/__pycache__/__init__.cpython-34.pyc,, -chardet/__pycache__/langhungarianmodel.cpython-34.pyc,, -chardet/__pycache__/escsm.cpython-34.pyc,, chardet/__pycache__/mbcssm.cpython-34.pyc,, -chardet/__pycache__/langcyrillicmodel.cpython-34.pyc,, -chardet/__pycache__/langgreekmodel.cpython-34.pyc,, -chardet/__pycache__/jisfreq.cpython-34.pyc,, -chardet/__pycache__/langhebrewmodel.cpython-34.pyc,, -chardet/__pycache__/big5prober.cpython-34.pyc,, -chardet/__pycache__/constants.cpython-34.pyc,, +chardet/__pycache__/langbulgarianmodel.cpython-34.pyc,, chardet/__pycache__/big5freq.cpython-34.pyc,, +chardet/__pycache__/latin1prober.cpython-34.pyc,, +chardet/__pycache__/escsm.cpython-34.pyc,, +chardet/__pycache__/sbcsgroupprober.cpython-34.pyc,, +chardet/__pycache__/langhungarianmodel.cpython-34.pyc,, +chardet/__pycache__/euctwprober.cpython-34.pyc,, +chardet/__pycache__/hebrewprober.cpython-34.pyc,, +chardet/__pycache__/langthaimodel.cpython-34.pyc,, +chardet/__pycache__/__init__.cpython-34.pyc,, +chardet/__pycache__/charsetprober.cpython-34.pyc,, +chardet/__pycache__/chardetect.cpython-34.pyc,, +chardet/__pycache__/euctwfreq.cpython-34.pyc,, +chardet/__pycache__/langhebrewmodel.cpython-34.pyc,, +chardet/__pycache__/charsetgroupprober.cpython-34.pyc,, +chardet/__pycache__/constants.cpython-34.pyc,, +chardet/__pycache__/euckrfreq.cpython-34.pyc,, +chardet/__pycache__/langgreekmodel.cpython-34.pyc,, +chardet/__pycache__/utf8prober.cpython-34.pyc,, +chardet/__pycache__/codingstatemachine.cpython-34.pyc,, +chardet/__pycache__/jpcntx.cpython-34.pyc,, +chardet/__pycache__/langcyrillicmodel.cpython-34.pyc,, +chardet/__pycache__/sbcharsetprober.cpython-34.pyc,, +chardet/__pycache__/gb2312freq.cpython-34.pyc,, +chardet/__pycache__/eucjpprober.cpython-34.pyc,, +chardet/__pycache__/jisfreq.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/DESCRIPTION.rst b/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..aa749cf --- /dev/null +++ b/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/DESCRIPTION.rst @@ -0,0 +1,9 @@ + +enum-compat +=========== + +This is a virtual package, its whole purpose is to install enum34 on +Python older than 3.4. On Python 3.4+ it's a no-op. + + + diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/INSTALLER b/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/INSTALLER similarity index 100% rename from Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/INSTALLER rename to Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/INSTALLER diff --git a/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/METADATA b/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/METADATA new file mode 100644 index 0000000..ff8aca4 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/METADATA @@ -0,0 +1,30 @@ +Metadata-Version: 2.0 +Name: enum-compat +Version: 0.0.2 +Summary: enum/enum34 compatibility package +Home-page: https://github.com/jstasiak/enum-compat +Author: Jakub Stasiak +Author-email: jakub@stasiak.at +License: MIT +Keywords: enum,compatibility,enum34 +Platform: UNKNOWN +Classifier: Intended Audience :: Developers +Classifier: Topic :: Software Development :: Libraries +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 + + +enum-compat +=========== + +This is a virtual package, its whole purpose is to install enum34 on +Python older than 3.4. On Python 3.4+ it's a no-op. + + + diff --git a/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/RECORD b/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/RECORD new file mode 100644 index 0000000..3ded787 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/RECORD @@ -0,0 +1,7 @@ +enum_compat-0.0.2.dist-info/DESCRIPTION.rst,sha256=ZUxgOYtR8j28PbCHss1PpZ8wDHJxnfb_LZB7HO4RciE,150 +enum_compat-0.0.2.dist-info/METADATA,sha256=tuKXeC1xCg2NlzhUoupS_zEYriQ-0Vg8nBI1alGFVqA,908 +enum_compat-0.0.2.dist-info/RECORD,, +enum_compat-0.0.2.dist-info/WHEEL,sha256=lCqt3ViRAf9c8mCs6o7ffkwROUdYSy8_YHn5f_rulB4,93 +enum_compat-0.0.2.dist-info/metadata.json,sha256=_55lhugqrWFsIqTavHtPEOhjQApHbMVyvYnCuJgE514,884 +enum_compat-0.0.2.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +enum_compat-0.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 diff --git a/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/WHEEL b/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/WHEEL new file mode 100644 index 0000000..6d9801a --- /dev/null +++ b/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.29.0) +Root-Is-Purelib: true +Tag: cp34-none-any + diff --git a/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/metadata.json b/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/metadata.json new file mode 100644 index 0000000..ea0ddf2 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Intended Audience :: Developers", "Topic :: Software Development :: Libraries", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5"], "extensions": {"python.details": {"contacts": [{"email": "jakub@stasiak.at", "name": "Jakub Stasiak", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/jstasiak/enum-compat"}}}, "generator": "bdist_wheel (0.29.0)", "keywords": ["enum", "compatibility", "enum34"], "license": "MIT", "metadata_version": "2.0", "name": "enum-compat", "summary": "enum/enum34 compatibility package", "version": "0.0.2"} \ No newline at end of file diff --git a/Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/dependency_links.txt b/Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/top_level.txt similarity index 100% rename from Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/dependency_links.txt rename to Shared/lib/python3.4/site-packages/enum_compat-0.0.2.dist-info/top_level.txt diff --git a/Shared/lib/python3.4/site-packages/feedparser-5.2.1.dist-info/RECORD b/Shared/lib/python3.4/site-packages/feedparser-5.2.1.dist-info/RECORD index 3f34a7d..b3a7a1d 100644 --- a/Shared/lib/python3.4/site-packages/feedparser-5.2.1.dist-info/RECORD +++ b/Shared/lib/python3.4/site-packages/feedparser-5.2.1.dist-info/RECORD @@ -5,5 +5,5 @@ feedparser-5.2.1.dist-info/RECORD,, feedparser-5.2.1.dist-info/WHEEL,sha256=lCqt3ViRAf9c8mCs6o7ffkwROUdYSy8_YHn5f_rulB4,93 feedparser-5.2.1.dist-info/metadata.json,sha256=RMB2LpClHHZBGHSDdUKjdJEieOWn-T0t7Bh6BLaqNrA,1359 feedparser-5.2.1.dist-info/top_level.txt,sha256=V8OMyOFfOWI46em2E-SGpIywuPZEYtMPOcPua_gzvUk,11 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/lib/python3.4/site-packages/feedparser-5.2.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +feedparser-5.2.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 __pycache__/feedparser.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/html5lib-0.9999999.dist-info/RECORD b/Shared/lib/python3.4/site-packages/html5lib-0.9999999.dist-info/RECORD index 53ecae2..831d998 100644 --- a/Shared/lib/python3.4/site-packages/html5lib-0.9999999.dist-info/RECORD +++ b/Shared/lib/python3.4/site-packages/html5lib-0.9999999.dist-info/RECORD @@ -40,40 +40,40 @@ html5lib-0.9999999.dist-info/RECORD,, html5lib-0.9999999.dist-info/WHEEL,sha256=lCqt3ViRAf9c8mCs6o7ffkwROUdYSy8_YHn5f_rulB4,93 html5lib-0.9999999.dist-info/metadata.json,sha256=ptJ1V8e-ESI9H736RKJ5AJZ3I0T31YwhyIB0Zu2ru4o,1116 html5lib-0.9999999.dist-info/top_level.txt,sha256=XEX6CHpskSmvjJB4tP6m4Q5NYXhIf_0ceMc0PNbzJPQ,9 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/lib/python3.4/site-packages/html5lib-0.9999999.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -html5lib/treeadapters/__pycache__/__init__.cpython-34.pyc,, -html5lib/serializer/__pycache__/__init__.cpython-34.pyc,, -html5lib/serializer/__pycache__/htmlserializer.cpython-34.pyc,, -html5lib/__pycache__/tokenizer.cpython-34.pyc,, -html5lib/treewalkers/__pycache__/_base.cpython-34.pyc,, -html5lib/trie/__pycache__/py.cpython-34.pyc,, -html5lib/filters/__pycache__/lint.cpython-34.pyc,, -html5lib/treewalkers/__pycache__/pulldom.cpython-34.pyc,, +html5lib-0.9999999.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 html5lib/treebuilders/__pycache__/etree_lxml.cpython-34.pyc,, -html5lib/__pycache__/sanitizer.cpython-34.pyc,, -html5lib/treebuilders/__pycache__/__init__.cpython-34.pyc,, -html5lib/treebuilders/__pycache__/dom.cpython-34.pyc,, -html5lib/__pycache__/utils.cpython-34.pyc,, -html5lib/filters/__pycache__/__init__.cpython-34.pyc,, -html5lib/treebuilders/__pycache__/etree.cpython-34.pyc,, +html5lib/serializer/__pycache__/htmlserializer.cpython-34.pyc,, html5lib/filters/__pycache__/sanitizer.cpython-34.pyc,, -html5lib/treebuilders/__pycache__/_base.cpython-34.pyc,, -html5lib/__pycache__/constants.cpython-34.pyc,, -html5lib/filters/__pycache__/whitespace.cpython-34.pyc,, -html5lib/trie/__pycache__/__init__.cpython-34.pyc,, +html5lib/__pycache__/utils.cpython-34.pyc,, html5lib/filters/__pycache__/optionaltags.cpython-34.pyc,, html5lib/treewalkers/__pycache__/dom.cpython-34.pyc,, -html5lib/trie/__pycache__/_base.cpython-34.pyc,, -html5lib/__pycache__/inputstream.cpython-34.pyc,, -html5lib/__pycache__/__init__.cpython-34.pyc,, -html5lib/treewalkers/__pycache__/etree.cpython-34.pyc,, +html5lib/__pycache__/constants.cpython-34.pyc,, html5lib/treewalkers/__pycache__/lxmletree.cpython-34.pyc,, -html5lib/filters/__pycache__/_base.cpython-34.pyc,, -html5lib/treeadapters/__pycache__/sax.cpython-34.pyc,, html5lib/treewalkers/__pycache__/genshistream.cpython-34.pyc,, -html5lib/filters/__pycache__/alphabeticalattributes.cpython-34.pyc,, -html5lib/treewalkers/__pycache__/__init__.cpython-34.pyc,, -html5lib/__pycache__/html5parser.cpython-34.pyc,, -html5lib/__pycache__/ihatexml.cpython-34.pyc,, -html5lib/filters/__pycache__/inject_meta_charset.cpython-34.pyc,, html5lib/trie/__pycache__/datrie.cpython-34.pyc,, +html5lib/treewalkers/__pycache__/__init__.cpython-34.pyc,, +html5lib/treebuilders/__pycache__/__init__.cpython-34.pyc,, +html5lib/trie/__pycache__/_base.cpython-34.pyc,, +html5lib/treewalkers/__pycache__/pulldom.cpython-34.pyc,, +html5lib/filters/__pycache__/whitespace.cpython-34.pyc,, +html5lib/filters/__pycache__/inject_meta_charset.cpython-34.pyc,, +html5lib/treewalkers/__pycache__/_base.cpython-34.pyc,, +html5lib/treebuilders/__pycache__/_base.cpython-34.pyc,, +html5lib/trie/__pycache__/__init__.cpython-34.pyc,, +html5lib/filters/__pycache__/lint.cpython-34.pyc,, +html5lib/__pycache__/sanitizer.cpython-34.pyc,, +html5lib/filters/__pycache__/alphabeticalattributes.cpython-34.pyc,, +html5lib/treewalkers/__pycache__/etree.cpython-34.pyc,, +html5lib/treebuilders/__pycache__/dom.cpython-34.pyc,, +html5lib/__pycache__/html5parser.cpython-34.pyc,, +html5lib/__pycache__/inputstream.cpython-34.pyc,, +html5lib/treebuilders/__pycache__/etree.cpython-34.pyc,, +html5lib/filters/__pycache__/_base.cpython-34.pyc,, +html5lib/trie/__pycache__/py.cpython-34.pyc,, +html5lib/__pycache__/tokenizer.cpython-34.pyc,, +html5lib/treeadapters/__pycache__/sax.cpython-34.pyc,, +html5lib/__pycache__/ihatexml.cpython-34.pyc,, +html5lib/treeadapters/__pycache__/__init__.cpython-34.pyc,, +html5lib/__pycache__/__init__.cpython-34.pyc,, +html5lib/filters/__pycache__/__init__.cpython-34.pyc,, +html5lib/serializer/__pycache__/__init__.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/PKG-INFO b/Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/PKG-INFO similarity index 96% rename from Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/PKG-INFO rename to Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/PKG-INFO index ce2b19c..05a31b9 100644 --- a/Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/PKG-INFO +++ b/Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: ox -Version: 2.3.b-783- +Version: 2.3.b-786- Summary: python-ox - the web in a dict Home-page: https://wiki.0x2620.org/wiki/python-ox Author: 0x2620 diff --git a/Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/SOURCES.txt b/Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/SOURCES.txt similarity index 97% rename from Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/SOURCES.txt rename to Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/SOURCES.txt index fd737f4..0eabe7d 100644 --- a/Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/SOURCES.txt +++ b/Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/SOURCES.txt @@ -21,6 +21,7 @@ ox/oembed.py ox/srt.py ox/text.py ox/utils.py +ox/vtt.py ox.egg-info/PKG-INFO ox.egg-info/SOURCES.txt ox.egg-info/dependency_links.txt diff --git a/Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/dependency_links.txt b/Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/installed-files.txt b/Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/installed-files.txt similarity index 98% rename from Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/installed-files.txt rename to Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/installed-files.txt index d389212..634e938 100644 --- a/Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/installed-files.txt +++ b/Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/installed-files.txt @@ -19,6 +19,7 @@ ../ox/srt.py ../ox/text.py ../ox/utils.py +../ox/vtt.py ../ox/__version.py ../ox/torrent/__init__.py ../ox/torrent/bencode.py @@ -84,6 +85,7 @@ ../ox/__pycache__/srt.cpython-34.pyc ../ox/__pycache__/text.cpython-34.pyc ../ox/__pycache__/utils.cpython-34.pyc +../ox/__pycache__/vtt.cpython-34.pyc ../ox/__pycache__/__version.cpython-34.pyc ../ox/torrent/__pycache__/__init__.cpython-34.pyc ../ox/torrent/__pycache__/bencode.cpython-34.pyc @@ -128,8 +130,8 @@ ../ox/web/__pycache__/vimeo.cpython-34.pyc ../ox/web/__pycache__/wikipedia.cpython-34.pyc ../ox/web/__pycache__/youtube.cpython-34.pyc -PKG-INFO dependency_links.txt -requires.txt +PKG-INFO top_level.txt +requires.txt SOURCES.txt diff --git a/Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/requires.txt b/Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/requires.txt similarity index 100% rename from Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/requires.txt rename to Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/requires.txt diff --git a/Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/top_level.txt b/Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/top_level.txt similarity index 100% rename from Shared/lib/python3.4/site-packages/ox-2.3.b_783_-py3.4.egg-info/top_level.txt rename to Shared/lib/python3.4/site-packages/ox-2.3.b_786_-py3.4.egg-info/top_level.txt diff --git a/Shared/lib/python3.4/site-packages/ox/__init__.py b/Shared/lib/python3.4/site-packages/ox/__init__.py index 4ddaab8..98402fb 100644 --- a/Shared/lib/python3.4/site-packages/ox/__init__.py +++ b/Shared/lib/python3.4/site-packages/ox/__init__.py @@ -13,6 +13,7 @@ from . import jsonc from . import net from . import srt from . import utils +from . import vtt from .api import * from .file import * diff --git a/Shared/lib/python3.4/site-packages/ox/__version.py b/Shared/lib/python3.4/site-packages/ox/__version.py index dfc8433..7e67bfd 100644 --- a/Shared/lib/python3.4/site-packages/ox/__version.py +++ b/Shared/lib/python3.4/site-packages/ox/__version.py @@ -1 +1 @@ -VERSION="2.3.b'783'" \ No newline at end of file +VERSION="2.3.b'786'" \ No newline at end of file diff --git a/Shared/lib/python3.4/site-packages/ox/file.py b/Shared/lib/python3.4/site-packages/ox/file.py index 9c9955e..1791061 100644 --- a/Shared/lib/python3.4/site-packages/ox/file.py +++ b/Shared/lib/python3.4/site-packages/ox/file.py @@ -29,7 +29,7 @@ EXTENSIONS = { 'video': [ '3gp', 'avi', 'divx', 'dv', 'flv', 'm2t', 'm4v', 'mkv', 'mov', 'mp4', - 'mpeg', 'mpg', 'mts', 'ogm', 'ogv', 'rm', 'vob', 'webm', 'wmv', + 'mpeg', 'mpg', 'mts', 'ogm', 'ogv', 'rm', 'rmvb', 'vob', 'webm', 'wmv', 'mod', 'tod', # http://en.wikipedia.org/wiki/MOD_and_TOD 'mxf', 'ts' ], diff --git a/Shared/lib/python3.4/site-packages/ox/srt.py b/Shared/lib/python3.4/site-packages/ox/srt.py index ee5a982..1b3f8b3 100644 --- a/Shared/lib/python3.4/site-packages/ox/srt.py +++ b/Shared/lib/python3.4/site-packages/ox/srt.py @@ -51,11 +51,12 @@ def _detect_encoding(fp): def load(filename, offset=0): - ''' - filename path to an srt file - offset in seconds shift all in/out points by offset + '''Parses an srt file - returns list with objects that have in,out,value and id + filename: path to an srt file + offset (float, seconds): shift all in/out points by offset + + Returns list with dicts that have in, out, value and id ''' srt = [] @@ -87,20 +88,30 @@ def load(filename, offset=0): i += 1 return srt + +def _srt_timecode(t): + return ox.format_duration(t * 1000, years=False).replace('.', ',') + + def encode(data): - ''' - encodes list of objects with in,out,value into srt - result is utf-8 encoded bytestring - ''' + """Encodes subtitles into SRT format + + data: list of dicts with 'in', 'out': float and 'value': unicode + + Returns: a UTF-8-encoded bytestring + + >>> encode([{'in': 1.25, 'out': 60 * 60 + 1, 'value': u'touch\\u00E9'}]) + '\\xef\\xbb\\xbf1\\r\\n00:00:01,250 --> 01:00:01,000\\r\\ntouch\\xc3\\xa9\\r\\n\\r\\n' + """ + srt = u'' - i = 1 - for s in data: + + for i, s in enumerate(data, 1): srt += '%d\r\n%s --> %s\r\n%s\r\n\r\n' % ( i, - ox.format_duration(s['in']*1000, years=False).replace('.', ','), - ox.format_duration(s['out']*1000, years=False).replace('.', ','), + _srt_timecode(s['in']), + _srt_timecode(s['out']), s['value'].replace('\n', '\r\n').strip() ) - i += 1 - return codecs.BOM_UTF8 + srt.encode('utf-8') + return codecs.BOM_UTF8 + srt.encode('utf-8') diff --git a/Shared/lib/python3.4/site-packages/ox/vtt.py b/Shared/lib/python3.4/site-packages/ox/vtt.py new file mode 100644 index 0000000..6dd7070 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/ox/vtt.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# vi:si:et:sw=4:sts=4:ts=4 +import codecs + +import ox + + +def _webvtt_timecode(t): + return ox.format_duration(t * 1000, years=False) + + +def encode(data, webvtt=False): + """Encodes subtitles into WebVTT format + + data: list of dicts with 'in', 'out': float and 'value': unicode + + Returns: a UTF-8-encoded bytestring + + >>> encode([{'in': 1.25, 'out': 60 * 60 + 1, 'value': u'touch\\u00E9'}]) + '\\xef\\xbb\\xbfWEBVTT\\r\\n\\r\\n1\\r\\n00:00:01.250 --> 01:00:01.000\\r\\ntouch\\xc3\\xa9\\r\\n\\r\\n' + """ + srt = u'WEBVTT\r\n\r\n' + + for i, s in enumerate(data, 1): + srt += '%d\r\n%s --> %s\r\n%s\r\n\r\n' % ( + i, + _webvtt_timecode(s['in']), + _webvtt_timecode(s['out']), + s['value'].replace('\n', '\r\n').strip() + ) + + return codecs.BOM_UTF8 + srt.encode('utf-8') diff --git a/Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/DESCRIPTION.rst b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/DESCRIPTION.rst similarity index 86% rename from Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/DESCRIPTION.rst rename to Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/DESCRIPTION.rst index 2c149b7..39586d2 100644 --- a/Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/DESCRIPTION.rst +++ b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/DESCRIPTION.rst @@ -17,11 +17,13 @@ tool for installing Python packages. .. image:: https://img.shields.io/pypi/v/pip.svg - :target: https://pypi.python.org/pypi/pip + :target: https://pypi.python.org/pypi/pip .. image:: https://img.shields.io/travis/pypa/pip/develop.svg :target: http://travis-ci.org/pypa/pip +.. image:: https://readthedocs.org/projects/pip/badge/?version=stable + :target: https://pip.pypa.io/en/stable Code of Conduct --------------- diff --git a/Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/top_level.txt b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/INSTALLER similarity index 100% rename from Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/top_level.txt rename to Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/INSTALLER diff --git a/Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/METADATA b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/METADATA similarity index 90% rename from Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/METADATA rename to Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/METADATA index a49cee5..2a5912c 100644 --- a/Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/METADATA +++ b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.0 Name: pip -Version: 8.0.2 +Version: 8.1.0 Summary: The PyPA recommended tool for installing Python packages. Home-page: https://pip.pypa.io/ Author: The pip developers @@ -22,6 +22,7 @@ Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: Implementation :: PyPy Provides-Extra: testing Requires-Dist: mock; extra == 'testing' +Requires-Dist: pretend; extra == 'testing' Requires-Dist: pytest; extra == 'testing' Requires-Dist: scripttest (>=1.3); extra == 'testing' Requires-Dist: virtualenv (>=1.10); extra == 'testing' @@ -45,11 +46,13 @@ tool for installing Python packages. .. image:: https://img.shields.io/pypi/v/pip.svg - :target: https://pypi.python.org/pypi/pip + :target: https://pypi.python.org/pypi/pip .. image:: https://img.shields.io/travis/pypa/pip/develop.svg :target: http://travis-ci.org/pypa/pip +.. image:: https://readthedocs.org/projects/pip/badge/?version=stable + :target: https://pip.pypa.io/en/stable Code of Conduct --------------- diff --git a/Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/RECORD b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/RECORD similarity index 61% rename from Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/RECORD rename to Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/RECORD index e8288c9..5d24ea6 100644 --- a/Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/RECORD +++ b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/RECORD @@ -1,113 +1,117 @@ -pip/__init__.py,sha256=mPGsfFwpIvtXlWhanTBtjdVYuTc0KNDvb2Tr-gHZBvU,10431 +pip/__init__.py,sha256=5_Hqv55mmr33A0LuCQpbLFyrUwiJ2kophGibMYYTcyw,10273 pip/__main__.py,sha256=V6Kh-IEDEFpt1cahRE6MajUF_14qJR_Qsvn4MjWZXzE,584 pip/basecommand.py,sha256=Zlg6SE42TIjRyt1mct0LCkgNxcKKnss3xvASJyDqucE,11429 pip/baseparser.py,sha256=Nlc7Un9gat27xtB24SnKL_3pZZOoh62gNNRdS6tDRZY,10465 pip/cmdoptions.py,sha256=OJhbVR6zQ8kbbGcnv0RTZyvwvFqzKxtmO4lPYymMBKM,15877 -pip/download.py,sha256=srwSU5WnOa59_TPGaCfEWODDSZSRBJUHgU5jkC467MY,31715 -pip/exceptions.py,sha256=4KrgxMQuOpP8JlWc90S0vsJ_Ch-EBeD026knOgk9U8A,7741 -pip/index.py,sha256=VzgEo93kTlHeoPrlgPDg24h2ly0jzdg92OBjkG--gMg,36776 +pip/download.py,sha256=oJ3sZ8I6ct9X3eoXQ9xm_Ne0e6N85G_rWaERmMCVF2k,31722 +pip/exceptions.py,sha256=GdDhHOROBj-kW2rgerLJYXsxN8ENy1BX5RUb_Vs9TXM,7980 +pip/index.py,sha256=kpyj_O5c0VVlvhg5VuVm4oAGGh6RvD7Xr0syPN-eGa0,37191 pip/locations.py,sha256=MqUzS8YI2wDa7oFzTQw4zM4s0Hci05yubxfU_kTXXlU,5632 -pip/pep425tags.py,sha256=nXeMZN4d3h14oVovpI0WholWCNCR0MD2mAERl3YHs08,7240 +pip/pep425tags.py,sha256=4PNr9hd8OsXnKYR2q2oLzfDDhF5bFBwUZA-ZQxAClSI,11318 pip/status_codes.py,sha256=F6uDG6Gj7RNKQJUDnd87QKqI16Us-t-B0wPF_4QMpWc,156 -pip/wheel.py,sha256=e3iaG7X6Z6eQvfChzGiZHK4yw12Z_PqLSRCi6_AUf4s,32030 -pip/_vendor/__init__.py,sha256=OuNX6SjnmNk4mvSyZXarkqf7LtKke3IH7CWoAi_w-5o,4229 -pip/commands/__init__.py,sha256=BSfOTIkMIBWElsuWJ_uAuCmDQS8b-OHYiyOkk77tWSU,2215 -pip/commands/completion.py,sha256=7JkLif3DF0QGpjMaUjHvF8knJ3IumcED2gWRvMRpFy0,1991 +pip/wheel.py,sha256=qg1DgjXtiQCnY-IJY5HC5VgpeQm9WCjDKYmefSfOjq0,32088 +pip/_vendor/__init__.py,sha256=9EPZ-JLxtXMt71Fp5_pKTTe1QbJZZVlN81rsRYEvlpA,4781 +pip/commands/__init__.py,sha256=naZ1iIWRutNznOVpLj8qyn1GPE0B5rhCWCrSUOZSt4M,2145 +pip/commands/completion.py,sha256=2BEUY3jowgemiIGgUP3rpk6A9My4Eu8rTPosFxlESOE,1967 pip/commands/download.py,sha256=dMRtH0JMBhNGlJWr1qC29vOeiBzG2K0OjOAfzdxSVgA,4804 -pip/commands/freeze.py,sha256=_wHnuHYXC4V0zBLD7LfDhgI_bWL6KdcCgzzQ9bXwDkU,2330 +pip/commands/freeze.py,sha256=KmQoLf-HruqBDzc-F2-ganGVn2lboNQqppfyrMsx3SU,2774 pip/commands/hash.py,sha256=MCt4jEFyfoce0lVeNEz1x49uaTY-VDkKiBvvxrVcHkw,1597 pip/commands/help.py,sha256=84HWkEdnGP_AEBHnn8gJP2Te0XTXRKFoXqXopbOZTNo,982 -pip/commands/install.py,sha256=8MOsH3IlL3ovZhTQtZwHhJb19pnkr8eKNE_9klVJ3PU,14971 +pip/commands/install.py,sha256=DvRVVwfUy6LV-AtNcxl9kLl7XOc7G7087ZhdD4QbP60,15628 pip/commands/list.py,sha256=u76U5TLODQ2g53sSUA4q6WhYus7usbuWuITQJsCnP3E,7412 -pip/commands/search.py,sha256=dJe9rcam1TEfNp9-Gi36WjHc3l4mdj8gheVjqK5BrR0,4605 -pip/commands/show.py,sha256=yxghAwGYaYphL2LJdJbYXVLFr8tBMHnuH8n8s2fWMr4,4903 +pip/commands/search.py,sha256=9ClAcFzkJ_7AksTkNrUed5qzsplpBtMlJByJLqiZFqw,4777 +pip/commands/show.py,sha256=dytBbI9XV-ChpV51tsuBygZJJO-QaO2Gtz5kbLkBCZE,5815 pip/commands/uninstall.py,sha256=tz8cXz4WdpUdnt3RvpdQwH6_SNMB50egBIZWa1dwfcc,2884 pip/commands/wheel.py,sha256=iT92Uo8qpVILl_Yk8L7AtkFVYGmY0ep5oDeyQSpwkLs,7528 -pip/compat/__init__.py,sha256=-k3m7JYe8ztMz2GGCPMc-XK7Uo-RiLdV00dSxWKMjfg,4536 +pip/compat/__init__.py,sha256=7WN0B0XMYIldfminnT679VoEJLxNQPi9MFwCIt1_llU,4669 pip/compat/dictconfig.py,sha256=dRrelPDWrceDSzFT51RTEVY2GuM7UDyc5Igh_tn4Fvk,23096 +pip/compat/ordereddict.py,sha256=6RQCd4PyTE4tvLUoAnsygvrreOSTV4BRDbc_4gCSkTs,4110 pip/models/__init__.py,sha256=0Rs7_RA4DxeOkWT5Cq4CQzDrSEhvYcN3TH2cazr72PE,71 pip/models/index.py,sha256=pUfbO__v3mD9j-2n_ClwPS8pVyx4l2wIwyvWt8GMCRA,487 pip/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/operations/freeze.py,sha256=Px8en5guEfc6mhYh0cATtT6tlFzqTzLj4ad8gqAkIqw,3925 +pip/operations/freeze.py,sha256=H6xpxe1XgoNm5f3UXK47kNy0OQfM5jzo4UUwQu7G-Lo,4048 pip/req/__init__.py,sha256=vFwZY8_Vc1WU1zFAespg1My_r_AT3n7cN0W9eX0EFqk,276 -pip/req/req_file.py,sha256=h1YmFfD7Opb_ulTTyEp7Osv2d8gbQJ1KGWMptEl_S08,11764 -pip/req/req_install.py,sha256=DYLV95E3U81nRJy4q8qs0fozLiCQZbG8Yg-CbUTwA2w,46670 -pip/req/req_set.py,sha256=0ncBet1v7gbsKeTUPpBj_-6Kowxx-iskw0_kLMGObi4,32236 +pip/req/req_file.py,sha256=3eaVnPMUAjikLdC5i8hZUAf8aAOby2UxmAVFf94FOXY,11928 +pip/req/req_install.py,sha256=aG0_hj8WqLLUH5tO40OFIncIxU50Vm4rFqYcx5hmoYk,45589 +pip/req/req_set.py,sha256=Xwia1h7o2Z3Qogae3RHIDCGlXS3w2AeQPG8LBz7GmFM,32312 pip/req/req_uninstall.py,sha256=fdH2VgCjEC8NRYDS7fRu3ZJaBBUEy-N5muwxDX5MBNM,6897 -pip/utils/__init__.py,sha256=4Tz09B6nsZm6bQ3mR7K-AeDjlMLMFjnehaXH4vG_E-0,26759 +pip/utils/__init__.py,sha256=SSixMJeh2SdjNgra_50jaC0jdmXFewLkFh_-a3tw9ks,28256 pip/utils/appdirs.py,sha256=KTpZANfjYw5K2tZ0_jNNdP_kMxQAns79qZWelwaJo0c,7896 pip/utils/build.py,sha256=4smLRrfSCmXmjEnVnMFh2tBEpNcSLRe6J0ejZJ-wWJE,1312 -pip/utils/deprecation.py,sha256=0y-RdGVpnt-_byop0WJOOb509f8jjOzSmKghHorTclU,2282 +pip/utils/deprecation.py,sha256=DR3cKqzovYu9Pif7c9bT2KmwekfW95N3BsI45_5u38I,2239 +pip/utils/encoding.py,sha256=rRSzAWfZTyOM-9u5LqwAVijcmoj2BRRQgP9d2IpEHQM,643 pip/utils/filesystem.py,sha256=ZEVBuYM3fqr2_lgOESh4Y7fPFszGD474zVm_M3Mb5Tk,899 pip/utils/hashes.py,sha256=oMk7cd3PbJgzpSQyXq1MytMud5f6H5Oa2YY5hYuCq6I,2866 pip/utils/logging.py,sha256=7yWu4gZw-Qclj7X80QVdpGWkdTWGKT4LiUVKcE04pro,3327 pip/utils/outdated.py,sha256=fNwOCL5r2EftPGhgCYGMKu032HC8cV-JAr9lp0HmToM,5455 pip/utils/setuptools_build.py,sha256=8IGop-SZ6lxUl5HMOjLRaDlORPugIH_b_b2Y67x4jQc,240 -pip/utils/ui.py,sha256=fY7lHmQg3Pdnsgkge2mpZMNU9e1jg6unYYs2Ryfulhk,11320 +pip/utils/ui.py,sha256=pbDkSAeumZ6jdZcOJ2yAbx8iBgeP2zfpqNnLJK1gskQ,11597 pip/vcs/__init__.py,sha256=lnea41zMq9HqB1Qo7hxy2IjUzk5WtBvnoloCCMR6Vk4,12349 pip/vcs/bazaar.py,sha256=tYTwc4b4off8mr0O2o8SiGejqBDJxcbDBMSMd9-ISYc,3803 -pip/vcs/git.py,sha256=jN3vZCn1DqE-RdKGfMqlDhObZ3WFjC21dEav29M62xI,10054 +pip/vcs/git.py,sha256=u16VCiNW_a9AaYqLri2b8-f4lOZlOYwsGpHHV3uv_dQ,10218 pip/vcs/mercurial.py,sha256=xG6rDiwHCRytJEs23SIHBXl_SwQo2jkkdD_6rVVP5h4,3472 pip/vcs/subversion.py,sha256=mGT7sAzuVc1u-9MPoXJNyShnRzhdJpDdGNuhhzUPv6w,8687 -pip-8.0.2.dist-info/DESCRIPTION.rst,sha256=_rptqJIyCNNmh7m8q-4qZfQDc9gqAjMxVITAEfItc08,1060 -pip-8.0.2.dist-info/METADATA,sha256=0KwLFgIzCAQ506gjLJ_VyrUxbw2NC8b-kUbTM8Uo42Y,2212 -pip-8.0.2.dist-info/RECORD,, -pip-8.0.2.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 -pip-8.0.2.dist-info/entry_points.txt,sha256=1-e4WB_Fe8mWHrMi1YQo_s5knbh0lu_uRmd8Wb6MJfY,68 -pip-8.0.2.dist-info/metadata.json,sha256=Sl2y0vogC_Ro8peVqn3OBZJQ_kV0PdQ9QfraUV3XPj0,1393 -pip-8.0.2.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/bin/pip,sha256=tirEqfn4_1wbMXwJJlFXKaCNMvF9Ha-hQeGqLUeRl10,270 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/bin/pip3,sha256=tirEqfn4_1wbMXwJJlFXKaCNMvF9Ha-hQeGqLUeRl10,270 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/bin/pip3.4,sha256=tirEqfn4_1wbMXwJJlFXKaCNMvF9Ha-hQeGqLUeRl10,270 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/lib/python3.4/site-packages/pip-8.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pip/commands/__pycache__/freeze.cpython-34.pyc,, -pip/utils/__pycache__/logging.cpython-34.pyc,, -pip/commands/__pycache__/hash.cpython-34.pyc,, -pip/req/__pycache__/req_uninstall.cpython-34.pyc,, -pip/__pycache__/basecommand.cpython-34.pyc,, -pip/utils/__pycache__/deprecation.cpython-34.pyc,, -pip/_vendor/__pycache__/__init__.cpython-34.pyc,, -pip/commands/__pycache__/list.cpython-34.pyc,, -pip/utils/__pycache__/setuptools_build.cpython-34.pyc,, -pip/utils/__pycache__/hashes.cpython-34.pyc,, -pip/vcs/__pycache__/__init__.cpython-34.pyc,, +pip-8.1.0.dist-info/DESCRIPTION.rst,sha256=jSvW1qOjwzndvm_p_DexGCVJfwgg3rWPMJWzf6Rmsfc,1167 +pip-8.1.0.dist-info/METADATA,sha256=NIsJafU0Eg3jm5vpz5ntbIXKUUIhMqJpjuV_OVpPlCo,2362 +pip-8.1.0.dist-info/RECORD,, +pip-8.1.0.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110 +pip-8.1.0.dist-info/entry_points.txt,sha256=GWc-Wb9WUKZ1EuVWNz-G0l3BeIpbNJLx0OJbZ61AAV0,68 +pip-8.1.0.dist-info/metadata.json,sha256=zCqgFRL4piTEzAhAk_56ay7wvcWRWZkDtEj0eHkT6g8,1513 +pip-8.1.0.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +../../../bin/pip,sha256=tirEqfn4_1wbMXwJJlFXKaCNMvF9Ha-hQeGqLUeRl10,270 +../../../bin/pip3,sha256=tirEqfn4_1wbMXwJJlFXKaCNMvF9Ha-hQeGqLUeRl10,270 +../../../bin/pip3.4,sha256=tirEqfn4_1wbMXwJJlFXKaCNMvF9Ha-hQeGqLUeRl10,270 +pip-8.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pip/__pycache__/baseparser.cpython-34.pyc,, +pip/__pycache__/index.cpython-34.pyc,, +pip/utils/__pycache__/encoding.cpython-34.pyc,, +pip/commands/__pycache__/search.cpython-34.pyc,, +pip/utils/__pycache__/__init__.cpython-34.pyc,, +pip/operations/__pycache__/freeze.cpython-34.pyc,, +pip/commands/__pycache__/download.cpython-34.pyc,, +pip/__pycache__/pep425tags.cpython-34.pyc,, +pip/__pycache__/wheel.cpython-34.pyc,, pip/utils/__pycache__/appdirs.cpython-34.pyc,, +pip/__pycache__/status_codes.cpython-34.pyc,, +pip/req/__pycache__/req_file.cpython-34.pyc,, +pip/vcs/__pycache__/__init__.cpython-34.pyc,, +pip/req/__pycache__/req_uninstall.cpython-34.pyc,, +pip/req/__pycache__/req_set.cpython-34.pyc,, +pip/commands/__pycache__/completion.cpython-34.pyc,, +pip/utils/__pycache__/build.cpython-34.pyc,, +pip/commands/__pycache__/list.cpython-34.pyc,, pip/__pycache__/__main__.cpython-34.pyc,, pip/vcs/__pycache__/subversion.cpython-34.pyc,, -pip/operations/__pycache__/__init__.cpython-34.pyc,, -pip/commands/__pycache__/uninstall.cpython-34.pyc,, -pip/req/__pycache__/req_install.cpython-34.pyc,, -pip/utils/__pycache__/__init__.cpython-34.pyc,, -pip/utils/__pycache__/ui.cpython-34.pyc,, -pip/commands/__pycache__/completion.cpython-34.pyc,, -pip/utils/__pycache__/outdated.cpython-34.pyc,, -pip/__pycache__/baseparser.cpython-34.pyc,, pip/__pycache__/download.cpython-34.pyc,, -pip/__pycache__/pep425tags.cpython-34.pyc,, -pip/utils/__pycache__/build.cpython-34.pyc,, -pip/operations/__pycache__/freeze.cpython-34.pyc,, -pip/req/__pycache__/req_file.cpython-34.pyc,, -pip/__pycache__/locations.cpython-34.pyc,, +pip/__pycache__/cmdoptions.cpython-34.pyc,, +pip/_vendor/__pycache__/__init__.cpython-34.pyc,, +pip/vcs/__pycache__/git.cpython-34.pyc,, +pip/utils/__pycache__/setuptools_build.cpython-34.pyc,, +pip/utils/__pycache__/deprecation.cpython-34.pyc,, +pip/req/__pycache__/req_install.cpython-34.pyc,, +pip/commands/__pycache__/uninstall.cpython-34.pyc,, pip/utils/__pycache__/filesystem.cpython-34.pyc,, -pip/req/__pycache__/req_set.cpython-34.pyc,, -pip/commands/__pycache__/search.cpython-34.pyc,, -pip/__pycache__/status_codes.cpython-34.pyc,, -pip/commands/__pycache__/__init__.cpython-34.pyc,, +pip/models/__pycache__/index.cpython-34.pyc,, +pip/vcs/__pycache__/bazaar.cpython-34.pyc,, +pip/commands/__pycache__/help.cpython-34.pyc,, +pip/req/__pycache__/__init__.cpython-34.pyc,, +pip/compat/__pycache__/__init__.cpython-34.pyc,, +pip/commands/__pycache__/freeze.cpython-34.pyc,, +pip/operations/__pycache__/__init__.cpython-34.pyc,, +pip/commands/__pycache__/wheel.cpython-34.pyc,, +pip/compat/__pycache__/dictconfig.cpython-34.pyc,, +pip/compat/__pycache__/ordereddict.cpython-34.pyc,, +pip/__pycache__/__init__.cpython-34.pyc,, +pip/utils/__pycache__/outdated.cpython-34.pyc,, +pip/commands/__pycache__/install.cpython-34.pyc,, +pip/utils/__pycache__/logging.cpython-34.pyc,, pip/models/__pycache__/__init__.cpython-34.pyc,, pip/__pycache__/exceptions.cpython-34.pyc,, +pip/commands/__pycache__/hash.cpython-34.pyc,, +pip/utils/__pycache__/hashes.cpython-34.pyc,, +pip/utils/__pycache__/ui.cpython-34.pyc,, +pip/commands/__pycache__/__init__.cpython-34.pyc,, +pip/__pycache__/basecommand.cpython-34.pyc,, pip/vcs/__pycache__/mercurial.cpython-34.pyc,, -pip/__pycache__/cmdoptions.cpython-34.pyc,, -pip/__pycache__/__init__.cpython-34.pyc,, -pip/compat/__pycache__/dictconfig.cpython-34.pyc,, -pip/commands/__pycache__/download.cpython-34.pyc,, -pip/vcs/__pycache__/git.cpython-34.pyc,, -pip/__pycache__/index.cpython-34.pyc,, +pip/__pycache__/locations.cpython-34.pyc,, pip/commands/__pycache__/show.cpython-34.pyc,, -pip/__pycache__/wheel.cpython-34.pyc,, -pip/commands/__pycache__/help.cpython-34.pyc,, -pip/vcs/__pycache__/bazaar.cpython-34.pyc,, -pip/req/__pycache__/__init__.cpython-34.pyc,, -pip/commands/__pycache__/wheel.cpython-34.pyc,, -pip/commands/__pycache__/install.cpython-34.pyc,, -pip/models/__pycache__/index.cpython-34.pyc,, -pip/compat/__pycache__/__init__.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/WHEEL b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/WHEEL new file mode 100644 index 0000000..8b6dd1b --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.29.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/entry_points.txt b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/entry_points.txt similarity index 73% rename from Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/entry_points.txt rename to Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/entry_points.txt index a237b5e..c02a8d5 100644 --- a/Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/entry_points.txt +++ b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/entry_points.txt @@ -1,5 +1,5 @@ [console_scripts] pip = pip:main pip3 = pip:main -pip3.4 = pip:main +pip3.5 = pip:main diff --git a/Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/metadata.json b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/metadata.json similarity index 67% rename from Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/metadata.json rename to Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/metadata.json index ccc2ef2..d25f0fc 100644 --- a/Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/metadata.json +++ b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/metadata.json @@ -1 +1 @@ -{"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Topic :: Software Development :: Build Tools", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: Implementation :: PyPy"], "extensions": {"python.commands": {"wrap_console": {"pip": "pip:main", "pip3": "pip:main", "pip3.4": "pip:main"}}, "python.details": {"contacts": [{"email": "python-virtualenv@groups.google.com", "name": "The pip developers", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://pip.pypa.io/"}}, "python.exports": {"console_scripts": {"pip": "pip:main", "pip3": "pip:main", "pip3.4": "pip:main"}}}, "extras": ["testing"], "generator": "bdist_wheel (0.26.0)", "keywords": ["easy_install", "distutils", "setuptools", "egg", "virtualenv"], "license": "MIT", "metadata_version": "2.0", "name": "pip", "run_requires": [{"extra": "testing", "requires": ["mock", "pytest", "scripttest (>=1.3)", "virtualenv (>=1.10)"]}], "summary": "The PyPA recommended tool for installing Python packages.", "version": "8.0.2"} \ No newline at end of file +{"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Topic :: Software Development :: Build Tools", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: Implementation :: PyPy"], "extensions": {"python.commands": {"wrap_console": {"pip": "pip:main", "pip3": "pip:main", "pip3.5": "pip:main"}}, "python.details": {"contacts": [{"email": "python-virtualenv@groups.google.com", "name": "The pip developers", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://pip.pypa.io/"}}, "python.exports": {"console_scripts": {"pip": "pip:main", "pip3": "pip:main", "pip3.5": "pip:main"}}}, "extras": ["testing"], "generator": "bdist_wheel (0.29.0)", "keywords": ["easy_install", "distutils", "setuptools", "egg", "virtualenv"], "license": "MIT", "metadata_version": "2.0", "name": "pip", "run_requires": [{"extra": "testing", "requires": ["mock", "pretend", "pytest", "scripttest (>=1.3)", "virtualenv (>=1.10)"]}], "summary": "The PyPA recommended tool for installing Python packages.", "test_requires": [{"requires": ["mock", "pretend", "pytest", "scripttest (>=1.3)", "virtualenv (>=1.10)"]}], "version": "8.1.0"} \ No newline at end of file diff --git a/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/top_level.txt b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/top_level.txt new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pip-8.1.0.dist-info/top_level.txt @@ -0,0 +1 @@ +pip diff --git a/Shared/lib/python3.4/site-packages/pip/__init__.py b/Shared/lib/python3.4/site-packages/pip/__init__.py index 0603ca1..c688a5a 100644 --- a/Shared/lib/python3.4/site-packages/pip/__init__.py +++ b/Shared/lib/python3.4/site-packages/pip/__init__.py @@ -30,7 +30,7 @@ import pip.cmdoptions cmdoptions = pip.cmdoptions # The version as used in the setup.py and the docs conf.py -__version__ = "8.0.2" +__version__ = "8.1.0" logger = logging.getLogger(__name__) @@ -197,10 +197,6 @@ def main(args=None): if args is None: args = sys.argv[1:] - # Enable our Deprecation Warnings - for deprecation_warning in deprecation.DEPRECATIONS: - warnings.simplefilter("default", deprecation_warning) - # Configure our deprecation warnings to be sent through loggers deprecation.install_warning_logger() diff --git a/Shared/lib/python3.4/site-packages/pip/_vendor/__init__.py b/Shared/lib/python3.4/site-packages/pip/_vendor/__init__.py index c64896a..a822a5b 100644 --- a/Shared/lib/python3.4/site-packages/pip/_vendor/__init__.py +++ b/Shared/lib/python3.4/site-packages/pip/_vendor/__init__.py @@ -32,10 +32,22 @@ def vendored(modulename): try: __import__(vendored_name, globals(), locals(), level=0) except ImportError: - __import__(modulename, globals(), locals(), level=0) - sys.modules[vendored_name] = sys.modules[modulename] - base, head = vendored_name.rsplit(".", 1) - setattr(sys.modules[base], head, sys.modules[modulename]) + try: + __import__(modulename, globals(), locals(), level=0) + except ImportError: + # We can just silently allow import failures to pass here. If we + # got to this point it means that ``import pip._vendor.whatever`` + # failed and so did ``import whatever``. Since we're importing this + # upfront in an attempt to alias imports, not erroring here will + # just mean we get a regular import error whenever pip *actually* + # tries to import one of these modules to use it, which actually + # gives us a better error message than we would have otherwise + # gotten. + pass + else: + sys.modules[vendored_name] = sys.modules[modulename] + base, head = vendored_name.rsplit(".", 1) + setattr(sys.modules[base], head, sys.modules[modulename]) # If we're operating in a debundled setup, then we want to go ahead and trigger @@ -70,14 +82,8 @@ if DEBUNDLED: vendored("requests.packages.urllib3.connection") vendored("requests.packages.urllib3.connectionpool") vendored("requests.packages.urllib3.contrib") - try: - vendored("requests.packages.urllib3.contrib.ntlmpool") - except ImportError: - pass - try: - vendored("requests.packages.urllib3.contrib.pyopenssl") - except ImportError: - pass + vendored("requests.packages.urllib3.contrib.ntlmpool") + vendored("requests.packages.urllib3.contrib.pyopenssl") vendored("requests.packages.urllib3.exceptions") vendored("requests.packages.urllib3.fields") vendored("requests.packages.urllib3.filepost") diff --git a/Shared/lib/python3.4/site-packages/pip/commands/__init__.py b/Shared/lib/python3.4/site-packages/pip/commands/__init__.py index 6910f51..92b7ff5 100644 --- a/Shared/lib/python3.4/site-packages/pip/commands/__init__.py +++ b/Shared/lib/python3.4/site-packages/pip/commands/__init__.py @@ -41,11 +41,12 @@ commands_order = [ SearchCommand, WheelCommand, HashCommand, + CompletionCommand, HelpCommand, ] -def get_summaries(ignore_hidden=True, ordered=True): +def get_summaries(ordered=True): """Yields sorted (command name, command summary) tuples.""" if ordered: @@ -54,9 +55,6 @@ def get_summaries(ignore_hidden=True, ordered=True): cmditems = commands_dict.items() for name, command_class in cmditems: - if ignore_hidden and command_class.hidden: - continue - yield (name, command_class.summary) diff --git a/Shared/lib/python3.4/site-packages/pip/commands/completion.py b/Shared/lib/python3.4/site-packages/pip/commands/completion.py index 10f19e3..dc80af3 100644 --- a/Shared/lib/python3.4/site-packages/pip/commands/completion.py +++ b/Shared/lib/python3.4/site-packages/pip/commands/completion.py @@ -32,8 +32,7 @@ compctl -K _pip_completion pip class CompletionCommand(Command): """A helper command to be used for command completion.""" name = 'completion' - summary = 'A helper command to be used for command completion' - hidden = True + summary = 'A helper command used for command completion' def __init__(self, *args, **kw): super(CompletionCommand, self).__init__(*args, **kw) diff --git a/Shared/lib/python3.4/site-packages/pip/commands/freeze.py b/Shared/lib/python3.4/site-packages/pip/commands/freeze.py index ef4c624..0485d5f 100644 --- a/Shared/lib/python3.4/site-packages/pip/commands/freeze.py +++ b/Shared/lib/python3.4/site-packages/pip/commands/freeze.py @@ -3,11 +3,15 @@ from __future__ import absolute_import import sys import pip +from pip.compat import stdlib_pkgs from pip.basecommand import Command from pip.operations.freeze import freeze from pip.wheel import WheelCache +DEV_PKGS = ('pip', 'setuptools', 'distribute', 'wheel') + + class FreezeCommand(Command): """ Output installed packages in requirements format. @@ -52,12 +56,22 @@ class FreezeCommand(Command): action='store_true', default=False, help='Only output packages installed in user-site.') + self.cmd_opts.add_option( + '--all', + dest='freeze_all', + action='store_true', + help='Do not skip these packages in the output:' + ' %s' % ', '.join(DEV_PKGS)) self.parser.insert_option_group(0, self.cmd_opts) def run(self, options, args): format_control = pip.index.FormatControl(set(), set()) wheel_cache = WheelCache(options.cache_dir, format_control) + skip = set(stdlib_pkgs) + if not options.freeze_all: + skip.update(DEV_PKGS) + freeze_kwargs = dict( requirement=options.requirement, find_links=options.find_links, @@ -65,7 +79,8 @@ class FreezeCommand(Command): user_only=options.user, skip_regex=options.skip_requirements_regex, isolated=options.isolated_mode, - wheel_cache=wheel_cache) + wheel_cache=wheel_cache, + skip=skip) for line in freeze(**freeze_kwargs): sys.stdout.write(line + '\n') diff --git a/Shared/lib/python3.4/site-packages/pip/commands/install.py b/Shared/lib/python3.4/site-packages/pip/commands/install.py index 7ddde93..13b328f 100644 --- a/Shared/lib/python3.4/site-packages/pip/commands/install.py +++ b/Shared/lib/python3.4/site-packages/pip/commands/install.py @@ -24,6 +24,7 @@ from pip.utils.deprecation import RemovedInPip10Warning from pip.utils.filesystem import check_path_owner from pip.wheel import WheelCache, WheelBuilder +from pip.locations import running_under_virtualenv logger = logging.getLogger(__name__) @@ -54,6 +55,12 @@ class InstallCommand(RequirementCommand): def __init__(self, *args, **kw): super(InstallCommand, self).__init__(*args, **kw) + default_user = True + if running_under_virtualenv(): + default_user = False + if os.geteuid() == 0: + default_user = False + cmd_opts = self.cmd_opts cmd_opts.add_option(cmdoptions.constraints()) @@ -103,6 +110,7 @@ class InstallCommand(RequirementCommand): '-I', '--ignore-installed', dest='ignore_installed', action='store_true', + default=default_user, help='Ignore the installed packages (reinstalling instead).') cmd_opts.add_option(cmdoptions.no_deps()) @@ -114,10 +122,20 @@ class InstallCommand(RequirementCommand): '--user', dest='use_user_site', action='store_true', + default=default_user, help="Install to the Python user install directory for your " "platform. Typically ~/.local/, or %APPDATA%\Python on " "Windows. (See the Python documentation for site.USER_BASE " - "for full details.)") + "for full details.) On Debian systems, this is the " + "default when running outside of a virtual environment " + "and not as root.") + + cmd_opts.add_option( + '--system', + dest='use_user_site', + action='store_false', + help="Install using the system scheme (overrides --user on " + "Debian systems)") cmd_opts.add_option( '--egg', diff --git a/Shared/lib/python3.4/site-packages/pip/commands/search.py b/Shared/lib/python3.4/site-packages/pip/commands/search.py index 977eb36..3155e18 100644 --- a/Shared/lib/python3.4/site-packages/pip/commands/search.py +++ b/Shared/lib/python3.4/site-packages/pip/commands/search.py @@ -105,11 +105,16 @@ def print_results(hits, name_column_width=None, terminal_width=None): if not hits: return if name_column_width is None: - name_column_width = max((len(hit['name']) for hit in hits)) + 4 + name_column_width = max([ + len(hit['name']) + len(hit.get('versions', ['-'])[-1]) + for hit in hits + ]) + 4 + installed_packages = [p.project_name for p in pkg_resources.working_set] for hit in hits: name = hit['name'] summary = hit['summary'] or '' + version = hit.get('versions', ['-'])[-1] if terminal_width is not None: # wrap and indent summary to fit terminal summary = textwrap.wrap( @@ -117,7 +122,9 @@ def print_results(hits, name_column_width=None, terminal_width=None): terminal_width - name_column_width - 5, ) summary = ('\n' + ' ' * (name_column_width + 3)).join(summary) - line = '%s - %s' % (name.ljust(name_column_width), summary) + + line = '%-*s - %s' % (name_column_width, + '%s (%s)' % (name, version), summary) try: logger.info(line) if name in installed_packages: diff --git a/Shared/lib/python3.4/site-packages/pip/commands/show.py b/Shared/lib/python3.4/site-packages/pip/commands/show.py index 9df0cc5..52a673a 100644 --- a/Shared/lib/python3.4/site-packages/pip/commands/show.py +++ b/Shared/lib/python3.4/site-packages/pip/commands/show.py @@ -85,6 +85,14 @@ def search_packages_info(query): entry_points = dist.get_metadata_lines('entry_points.txt') package['entry_points'] = entry_points + installer = None + if dist.has_metadata('INSTALLER'): + for line in dist.get_metadata_lines('INSTALLER'): + if line.strip(): + installer = line.strip() + break + package['installer'] = installer + # @todo: Should pkg_resources.Distribution have a # `get_pkg_info` method? feed_parser = FeedParser() @@ -94,6 +102,16 @@ def search_packages_info(query): 'home-page', 'author', 'author-email', 'license'): package[key] = pkg_info_dict.get(key) + # It looks like FeedParser can not deal with repeated headers + classifiers = [] + for line in metadata.splitlines(): + if not line: + break + # Classifier: License :: OSI Approved :: MIT License + if line.startswith('Classifier: '): + classifiers.append(line[len('Classifier: '):]) + package['classifiers'] = classifiers + if file_list: package['files'] = sorted(file_list) yield package @@ -114,9 +132,14 @@ def print_results(distributions, list_all_files): logger.info("Home-page: %s", dist.get('home-page')) logger.info("Author: %s", dist.get('author')) logger.info("Author-email: %s", dist.get('author-email')) + if dist['installer'] is not None: + logger.info("Installer: %s", dist['installer']) logger.info("License: %s", dist.get('license')) logger.info("Location: %s", dist['location']) logger.info("Requires: %s", ', '.join(dist['requires'])) + logger.info("Classifiers:") + for classifier in dist['classifiers']: + logger.info(" %s", classifier) if list_all_files: logger.info("Files:") if 'files' in dist: diff --git a/Shared/lib/python3.4/site-packages/pip/compat/__init__.py b/Shared/lib/python3.4/site-packages/pip/compat/__init__.py index 3b01763..703852b 100644 --- a/Shared/lib/python3.4/site-packages/pip/compat/__init__.py +++ b/Shared/lib/python3.4/site-packages/pip/compat/__init__.py @@ -12,6 +12,11 @@ try: except ImportError: from pip.compat.dictconfig import dictConfig as logging_dictConfig +try: + from collections import OrderedDict +except ImportError: + from pip.compat.ordereddict import OrderedDict + try: import ipaddress except ImportError: @@ -45,7 +50,8 @@ except ImportError: __all__ = [ "logging_dictConfig", "ipaddress", "uses_pycache", "console_to_str", - "native_str", "get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile" + "native_str", "get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", + "OrderedDict", ] @@ -138,9 +144,9 @@ def expanduser(path): # dist.location (py27:`sysconfig.get_paths()['stdlib']`, # py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may # make this ineffective, so hard-coding -stdlib_pkgs = ['python', 'wsgiref'] +stdlib_pkgs = ('python', 'wsgiref') if sys.version_info >= (2, 7): - stdlib_pkgs.extend(['argparse']) + stdlib_pkgs += ('argparse',) # windows detection, covers cpython and ironpython diff --git a/Shared/lib/python3.4/site-packages/pip/compat/ordereddict.py b/Shared/lib/python3.4/site-packages/pip/compat/ordereddict.py new file mode 100644 index 0000000..6eb3ba4 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pip/compat/ordereddict.py @@ -0,0 +1,129 @@ +# Copyright (c) 2009 Raymond Hettinger +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the "Software"), to deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +# flake8: noqa + +from UserDict import DictMixin + +class OrderedDict(dict, DictMixin): + + def __init__(self, *args, **kwds): + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__end + except AttributeError: + self.clear() + self.update(*args, **kwds) + + def clear(self): + self.__end = end = [] + end += [None, end, end] # sentinel node for doubly linked list + self.__map = {} # key --> [key, prev, next] + dict.clear(self) + + def __setitem__(self, key, value): + if key not in self: + end = self.__end + curr = end[1] + curr[2] = end[1] = self.__map[key] = [key, curr, end] + dict.__setitem__(self, key, value) + + def __delitem__(self, key): + dict.__delitem__(self, key) + key, prev, next = self.__map.pop(key) + prev[2] = next + next[1] = prev + + def __iter__(self): + end = self.__end + curr = end[2] + while curr is not end: + yield curr[0] + curr = curr[2] + + def __reversed__(self): + end = self.__end + curr = end[1] + while curr is not end: + yield curr[0] + curr = curr[1] + + def popitem(self, last=True): + if not self: + raise KeyError('dictionary is empty') + if last: + key = reversed(self).next() + else: + key = iter(self).next() + value = self.pop(key) + return key, value + + def __reduce__(self): + items = [[k, self[k]] for k in self] + tmp = self.__map, self.__end + del self.__map, self.__end + inst_dict = vars(self).copy() + self.__map, self.__end = tmp + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def keys(self): + return list(self) + + setdefault = DictMixin.setdefault + update = DictMixin.update + pop = DictMixin.pop + values = DictMixin.values + items = DictMixin.items + iterkeys = DictMixin.iterkeys + itervalues = DictMixin.itervalues + iteritems = DictMixin.iteritems + + def __repr__(self): + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + + def copy(self): + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + if isinstance(other, OrderedDict): + if len(self) != len(other): + return False + for p, q in zip(self.items(), other.items()): + if p != q: + return False + return True + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other diff --git a/Shared/lib/python3.4/site-packages/pip/download.py b/Shared/lib/python3.4/site-packages/pip/download.py index e447b01..bbef9ea 100644 --- a/Shared/lib/python3.4/site-packages/pip/download.py +++ b/Shared/lib/python3.4/site-packages/pip/download.py @@ -29,6 +29,7 @@ from pip.models import PyPI from pip.utils import (splitext, rmtree, format_size, display_path, backup_dir, ask_path_exists, unpack_file, ARCHIVE_EXTENSIONS, consume, call_subprocess) +from pip.utils.encoding import auto_decode from pip.utils.filesystem import check_path_owner from pip.utils.logging import indent_log from pip.utils.setuptools_build import SETUPTOOLS_SHIM @@ -38,7 +39,7 @@ from pip.vcs import vcs from pip._vendor import requests, six from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter from pip._vendor.requests.auth import AuthBase, HTTPBasicAuth -from pip._vendor.requests.models import Response +from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response from pip._vendor.requests.structures import CaseInsensitiveDict from pip._vendor.requests.packages import urllib3 from pip._vendor.cachecontrol import CacheControlAdapter @@ -407,14 +408,10 @@ def get_file_content(url, comes_from=None, session=None): # FIXME: catch some errors resp = session.get(url) resp.raise_for_status() - - if six.PY3: - return resp.url, resp.text - else: - return resp.url, resp.content + return resp.url, resp.text try: - with open(url) as f: - content = f.read() + with open(url, 'rb') as f: + content = auto_decode(f.read()) except IOError as exc: raise InstallationError( 'Could not open requirements file: %s' % str(exc) @@ -588,8 +585,12 @@ def _download_url(resp, link, content_file, hashes): logger.debug('Downloading from URL %s', link) - downloaded_chunks = written_chunks(progress_indicator(resp_read(4096), - 4096)) + downloaded_chunks = written_chunks( + progress_indicator( + resp_read(CONTENT_CHUNK_SIZE), + CONTENT_CHUNK_SIZE + ) + ) if hashes: hashes.check_against_chunks(downloaded_chunks) else: diff --git a/Shared/lib/python3.4/site-packages/pip/exceptions.py b/Shared/lib/python3.4/site-packages/pip/exceptions.py index e9b639f..a529e40 100644 --- a/Shared/lib/python3.4/site-packages/pip/exceptions.py +++ b/Shared/lib/python3.4/site-packages/pip/exceptions.py @@ -160,13 +160,16 @@ class HashMissing(HashError): def body(self): from pip.utils.hashes import FAVORITE_HASH # Dodge circular import. - package_name = (self.req.req if self.req and - # In case someone feeds something - # downright stupid to - # InstallRequirement's constructor: - getattr(self.req, 'req', None) - else 'unknown package') - return ' %s --hash=%s:%s' % (package_name, + package = None + if self.req: + # In the case of URL-based requirements, display the original URL + # seen in the requirements file rather than the package name, + # so the output can be directly copied into the requirements file. + package = (self.req.original_link if self.req.original_link + # In case someone feeds something downright stupid + # to InstallRequirement's constructor. + else getattr(self.req, 'req', None)) + return ' %s --hash=%s:%s' % (package or 'unknown package', FAVORITE_HASH, self.gotten_hash) diff --git a/Shared/lib/python3.4/site-packages/pip/index.py b/Shared/lib/python3.4/site-packages/pip/index.py index 18c8fc6..ba0bd6c 100644 --- a/Shared/lib/python3.4/site-packages/pip/index.py +++ b/Shared/lib/python3.4/site-packages/pip/index.py @@ -18,8 +18,9 @@ from pip._vendor.six.moves.urllib import request as urllib_request from pip.compat import ipaddress from pip.utils import ( cached_property, splitext, normalize_path, - ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, canonicalize_name) -from pip.utils.deprecation import RemovedInPip9Warning + ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, +) +from pip.utils.deprecation import RemovedInPip9Warning, RemovedInPip10Warning from pip.utils.logging import indent_log from pip.exceptions import ( DistributionNotFound, BestVersionAlreadyInstalled, InvalidWheelFilename, @@ -30,6 +31,7 @@ from pip.wheel import Wheel, wheel_ext from pip.pep425tags import supported_tags from pip._vendor import html5lib, requests, six from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.requests.exceptions import SSLError @@ -291,7 +293,9 @@ class PackageFinder(object): except ValueError: # We don't have both a valid address or a valid network, so # we'll check this origin against hostnames. - if origin[1] != secure_origin[1] and secure_origin[1] != "*": + if (origin[1] and + origin[1].lower() != secure_origin[1].lower() and + secure_origin[1] != "*"): continue else: # We have a valid address and network, so see if the address @@ -919,7 +923,7 @@ class Link(object): scheme, netloc, path, query, fragment = urllib_parse.urlsplit(self.url) return urllib_parse.urlunsplit((scheme, netloc, path, query, None)) - _egg_fragment_re = re.compile(r'#egg=([^&]*)') + _egg_fragment_re = re.compile(r'[#&]egg=([^&]*)') @property def egg_fragment(self): @@ -928,6 +932,15 @@ class Link(object): return None return match.group(1) + _subdirectory_fragment_re = re.compile(r'[#&]subdirectory=([^&]*)') + + @property + def subdirectory_fragment(self): + match = self._subdirectory_fragment_re.search(self.url) + if not match: + return None + return match.group(1) + _hash_re = re.compile( r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)' ) @@ -1019,7 +1032,7 @@ def fmt_ctl_no_use_wheel(fmt_ctl): fmt_ctl_no_binary(fmt_ctl) warnings.warn( '--no-use-wheel is deprecated and will be removed in the future. ' - ' Please use --no-binary :all: instead.', DeprecationWarning, + ' Please use --no-binary :all: instead.', RemovedInPip10Warning, stacklevel=2) diff --git a/Shared/lib/python3.4/site-packages/pip/operations/freeze.py b/Shared/lib/python3.4/site-packages/pip/operations/freeze.py index 74ff7d3..086922e 100644 --- a/Shared/lib/python3.4/site-packages/pip/operations/freeze.py +++ b/Shared/lib/python3.4/site-packages/pip/operations/freeze.py @@ -4,29 +4,27 @@ import logging import re import pip -from pip.compat import stdlib_pkgs from pip.req import InstallRequirement from pip.utils import get_installed_distributions from pip._vendor import pkg_resources +from pip._vendor.packaging.utils import canonicalize_name logger = logging.getLogger(__name__) -# packages to exclude from freeze output -freeze_excludes = stdlib_pkgs + ['setuptools', 'pip', 'distribute'] - def freeze( requirement=None, find_links=None, local_only=None, user_only=None, skip_regex=None, default_vcs=None, isolated=False, - wheel_cache=None): + wheel_cache=None, + skip=()): find_links = find_links or [] skip_match = None if skip_regex: - skip_match = re.compile(skip_regex) + skip_match = re.compile(skip_regex).search dependency_links = [] @@ -42,7 +40,7 @@ def freeze( yield '-f %s' % link installations = {} for dist in get_installed_distributions(local_only=local_only, - skip=freeze_excludes, + skip=(), user_only=user_only): req = pip.FrozenRequirement.from_dist( dist, @@ -55,12 +53,15 @@ def freeze( for line in req_file: if (not line.strip() or line.strip().startswith('#') or - (skip_match and skip_match.search(line)) or + (skip_match and skip_match(line)) or line.startswith(( '-r', '--requirement', '-Z', '--always-unzip', '-f', '--find-links', '-i', '--index-url', + '--pre', + '--trusted-host', + '--process-dependency-links', '--extra-index-url'))): yield line.rstrip() continue @@ -109,4 +110,5 @@ def freeze( ) for installation in sorted( installations.values(), key=lambda x: x.name.lower()): - yield str(installation).rstrip() + if canonicalize_name(installation.name) not in skip: + yield str(installation).rstrip() diff --git a/Shared/lib/python3.4/site-packages/pip/pep425tags.py b/Shared/lib/python3.4/site-packages/pip/pep425tags.py index 2d91ccc..e118457 100644 --- a/Shared/lib/python3.4/site-packages/pip/pep425tags.py +++ b/Shared/lib/python3.4/site-packages/pip/pep425tags.py @@ -6,6 +6,7 @@ import sys import warnings import platform import logging +import ctypes try: import sysconfig @@ -14,10 +15,11 @@ except ImportError: # pragma nocover import distutils.sysconfig as sysconfig import distutils.util +from pip.compat import OrderedDict + logger = logging.getLogger(__name__) - _osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') @@ -114,6 +116,10 @@ def get_abi_tag(): return abi +def _is_running_32bit(): + return sys.maxsize == 2147483647 + + def get_platform(): """Return our platform name 'win32', 'linux_x86_64'""" if sys.platform == 'darwin': @@ -122,9 +128,129 @@ def get_platform(): # be signficantly older than the user's current machine. release, _, machine = platform.mac_ver() split_ver = release.split('.') + + if machine == "x86_64" and _is_running_32bit(): + machine = "i386" + elif machine == "ppc64" and _is_running_32bit(): + machine = "ppc" + return 'macosx_{0}_{1}_{2}'.format(split_ver[0], split_ver[1], machine) + # XXX remove distutils dependency - return distutils.util.get_platform().replace('.', '_').replace('-', '_') + result = distutils.util.get_platform().replace('.', '_').replace('-', '_') + if result == "linux_x86_64" and _is_running_32bit(): + # 32 bit Python program (running on a 64 bit Linux): pip should only + # install and run 32 bit compiled extensions in that case. + result = "linux_i686" + + return result + + +def is_manylinux1_compatible(): + # Only Linux, and only x86-64 / i686 + if get_platform() not in ("linux_x86_64", "linux_i686"): + return False + + # Check for presence of _manylinux module + try: + import _manylinux + return bool(_manylinux.manylinux1_compatible) + except (ImportError, AttributeError): + # Fall through to heuristic check below + pass + + # Check glibc version. CentOS 5 uses glibc 2.5. + return have_compatible_glibc(2, 5) + + +def have_compatible_glibc(major, minimum_minor): + # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen + # manpage says, "If filename is NULL, then the returned handle is for the + # main program". This way we can let the linker do the work to figure out + # which libc our process is actually using. + process_namespace = ctypes.CDLL(None) + try: + gnu_get_libc_version = process_namespace.gnu_get_libc_version + except AttributeError: + # Symbol doesn't exist -> therefore, we are not linked to + # glibc. + return False + + # Call gnu_get_libc_version, which returns a string like "2.5". + gnu_get_libc_version.restype = ctypes.c_char_p + version_str = gnu_get_libc_version() + # py2 / py3 compatibility: + if not isinstance(version_str, str): + version_str = version_str.decode("ascii") + + # Parse string and check against requested version. + version = [int(piece) for piece in version_str.split(".")] + if len(version) < 2: + warnings.warn("Expected glibc version with 2 components major.minor," + " got: %s" % version_str, RuntimeWarning) + return False + return version[0] == major and version[1] >= minimum_minor + + +def get_darwin_arches(major, minor, machine): + """Return a list of supported arches (including group arches) for + the given major, minor and machine architecture of an OS X machine. + """ + arches = [] + + def _supports_arch(major, minor, arch): + # Looking at the application support for OS X versions in the chart + # provided by https://en.wikipedia.org/wiki/OS_X#Versions it appears + # our timeline looks roughly like: + # + # 10.0 - Introduces ppc support. + # 10.4 - Introduces ppc64, i386, and x86_64 support, however the ppc64 + # and x86_64 support is CLI only, and cannot be used for GUI + # applications. + # 10.5 - Extends ppc64 and x86_64 support to cover GUI applications. + # 10.6 - Drops support for ppc64 + # 10.7 - Drops support for ppc + # + # Given that we do not know if we're installing a CLI or a GUI + # application, we must be conservative and assume it might be a GUI + # application and behave as if ppc64 and x86_64 support did not occur + # until 10.5. + # + # Note: The above information is taken from the "Application support" + # column in the chart not the "Processor support" since I believe + # that we care about what instruction sets an application can use + # not which processors the OS supports. + if arch == 'ppc': + return (major, minor) <= (10, 5) + if arch == 'ppc64': + return (major, minor) == (10, 5) + if arch == 'i386': + return (major, minor) >= (10, 4) + if arch == 'x86_64': + return (major, minor) >= (10, 5) + if arch in groups: + for garch in groups[arch]: + if _supports_arch(major, minor, garch): + return True + return False + + groups = OrderedDict([ + ("fat", ("i386", "ppc")), + ("intel", ("x86_64", "i386")), + ("fat64", ("x86_64", "ppc64")), + ("fat32", ("x86_64", "i386", "ppc")), + ]) + + if _supports_arch(major, minor, machine): + arches.append(machine) + + for garch in groups: + if machine in groups[garch] and _supports_arch(major, minor, garch): + arches.append(garch) + + arches.append('universal') + + return arches def get_supported(versions=None, noarch=False): @@ -170,25 +296,16 @@ def get_supported(versions=None, noarch=False): match = _osx_arch_pat.match(arch) if match: name, major, minor, actual_arch = match.groups() - actual_arches = [actual_arch] - if actual_arch in ('i386', 'ppc'): - actual_arches.append('fat') - if actual_arch in ('i386', 'x86_64'): - actual_arches.append('intel') - if actual_arch in ('ppc64', 'x86_64'): - actual_arches.append('fat64') - if actual_arch in ('i386', 'ppc', 'x86_64'): - actual_arches.append('fat32') - if actual_arch in ('i386', 'x86_64', 'intel', 'ppc', 'ppc64'): - actual_arches.append('universal') tpl = '{0}_{1}_%i_%s'.format(name, major) arches = [] for m in reversed(range(int(minor) + 1)): - for a in actual_arches: + for a in get_darwin_arches(int(major), m, actual_arch): arches.append(tpl % (m, a)) else: # arch pattern didn't match (?!) arches = [arch] + elif is_manylinux1_compatible(): + arches = [arch.replace('linux', 'manylinux1'), arch] else: arches = [arch] @@ -198,15 +315,14 @@ def get_supported(versions=None, noarch=False): supported.append(('%s%s' % (impl, versions[0]), abi, arch)) # Has binaries, does not use the Python API: - supported.append(('py%s' % (versions[0][0]), 'none', arch)) + for arch in arches: + supported.append(('py%s' % (versions[0][0]), 'none', arch)) # No abi / arch, but requires our implementation: - for i, version in enumerate(versions): - supported.append(('%s%s' % (impl, version), 'none', 'any')) - if i == 0: - # Tagged specifically as being cross-version compatible - # (with just the major version specified) - supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any')) + supported.append(('%s%s' % (impl, versions[0]), 'none', 'any')) + # Tagged specifically as being cross-version compatible + # (with just the major version specified) + supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any')) # No abi / arch, generic Python for i, version in enumerate(versions): diff --git a/Shared/lib/python3.4/site-packages/pip/req/req_file.py b/Shared/lib/python3.4/site-packages/pip/req/req_file.py index c92c930..2cfb479 100644 --- a/Shared/lib/python3.4/site-packages/pip/req/req_file.py +++ b/Shared/lib/python3.4/site-packages/pip/req/req_file.py @@ -7,6 +7,7 @@ from __future__ import absolute_import import os import re import shlex +import sys import optparse import warnings @@ -133,6 +134,9 @@ def process_line(line, filename, line_number, finder=None, comes_from=None, # `finder.format_control` will be updated during parsing defaults.format_control = finder.format_control args_str, options_str = break_args_options(line) + if sys.version_info < (2, 7, 3): + # Priori to 2.7.3, shlex can not deal with unicode entries + options_str = options_str.encode('utf8') opts, _ = parser.parse_args(shlex.split(options_str), defaults) # preserve for the nested code path diff --git a/Shared/lib/python3.4/site-packages/pip/req/req_install.py b/Shared/lib/python3.4/site-packages/pip/req/req_install.py index 3b48431..caeda76 100644 --- a/Shared/lib/python3.4/site-packages/pip/req/req_install.py +++ b/Shared/lib/python3.4/site-packages/pip/req/req_install.py @@ -17,6 +17,7 @@ from email.parser import FeedParser from pip._vendor import pkg_resources, six from pip._vendor.distlib.markers import interpret as markers_interpret from pip._vendor.packaging import specifiers +from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.six.moves import configparser import pip.wheel @@ -33,11 +34,11 @@ from pip.utils import ( display_path, rmtree, ask_path_exists, backup_dir, is_installable_dir, dist_in_usersite, dist_in_site_packages, egg_link_path, call_subprocess, read_text_file, FakeFile, _make_build_dir, ensure_dir, - get_installed_version, canonicalize_name, normalize_path, dist_is_local, + get_installed_version, normalize_path, dist_is_local, ) from pip.utils.hashes import Hashes -from pip.utils.deprecation import RemovedInPip10Warning +from pip.utils.deprecation import RemovedInPip9Warning, RemovedInPip10Warning from pip.utils.logging import indent_log from pip.utils.setuptools_build import SETUPTOOLS_SHIM from pip.utils.ui import open_spinner @@ -67,7 +68,7 @@ def _strip_extras(path): class InstallRequirement(object): def __init__(self, req, comes_from, source_dir=None, editable=False, - link=None, as_egg=False, update=True, editable_options=None, + link=None, as_egg=False, update=True, pycompile=True, markers=None, isolated=False, options=None, wheel_cache=None, constraint=False): self.extras = () @@ -91,10 +92,6 @@ class InstallRequirement(object): self.source_dir = source_dir self.editable = editable - if editable_options is None: - editable_options = {} - - self.editable_options = editable_options self._wheel_cache = wheel_cache self.link = self.original_link = link self.as_egg = as_egg @@ -135,7 +132,7 @@ class InstallRequirement(object): constraint=False): from pip.index import Link - name, url, extras_override, editable_options = parse_editable( + name, url, extras_override = parse_editable( editable_req, default_vcs) if url.startswith('file:'): source_dir = url_to_path(url) @@ -146,7 +143,6 @@ class InstallRequirement(object): editable=True, link=Link(url), constraint=constraint, - editable_options=editable_options, isolated=isolated, options=options if options else {}, wheel_cache=wheel_cache) @@ -368,6 +364,12 @@ class InstallRequirement(object): return None return native_str(self.req.project_name) + @property + def setup_py_dir(self): + return os.path.join( + self.source_dir, + self.link and self.link.subdirectory_fragment or '') + @property def setup_py(self): assert self.source_dir, "No source dir for %s" % self @@ -384,15 +386,7 @@ class InstallRequirement(object): "install from a source distribution.\n%s" % add_msg ) - setup_file = 'setup.py' - - if self.editable_options and 'subdirectory' in self.editable_options: - setup_py = os.path.join(self.source_dir, - self.editable_options['subdirectory'], - setup_file) - - else: - setup_py = os.path.join(self.source_dir, setup_file) + setup_py = os.path.join(self.setup_py_dir, 'setup.py') # Python2 __file__ should not be unicode if six.PY2 and isinstance(setup_py, six.text_type): @@ -425,16 +419,12 @@ class InstallRequirement(object): if self.editable: egg_base_option = [] else: - egg_info_dir = os.path.join(self.source_dir, 'pip-egg-info') + egg_info_dir = os.path.join(self.setup_py_dir, 'pip-egg-info') ensure_dir(egg_info_dir) egg_base_option = ['--egg-base', 'pip-egg-info'] - cwd = self.source_dir - if self.editable_options and \ - 'subdirectory' in self.editable_options: - cwd = os.path.join(cwd, self.editable_options['subdirectory']) call_subprocess( egg_info_cmd + egg_base_option, - cwd=cwd, + cwd=self.setup_py_dir, show_stdout=False, command_level=logging.DEBUG, command_desc='python setup.py egg_info') @@ -481,7 +471,7 @@ class InstallRequirement(object): if self.editable: base = self.source_dir else: - base = os.path.join(self.source_dir, 'pip-egg-info') + base = os.path.join(self.setup_py_dir, 'pip-egg-info') filenames = os.listdir(base) if self.editable: filenames = [] @@ -727,7 +717,11 @@ class InstallRequirement(object): # find console_scripts if dist.has_metadata('entry_points.txt'): - config = configparser.SafeConfigParser() + if six.PY2: + options = {} + else: + options = {"delimiters": ('=', )} + config = configparser.SafeConfigParser(**options) config.readfp( FakeFile(dist.get_metadata_lines('entry_points.txt')) ) @@ -795,7 +789,7 @@ class InstallRequirement(object): archive_path, 'w', zipfile.ZIP_DEFLATED, allowZip64=True ) - dir = os.path.normcase(os.path.abspath(self.source_dir)) + dir = os.path.normcase(os.path.abspath(self.setup_py_dir)) for dirpath, dirnames, filenames in os.walk(dir): if 'pip-egg-info' in dirnames: dirnames.remove('pip-egg-info') @@ -885,7 +879,7 @@ class InstallRequirement(object): with indent_log(): call_subprocess( install_args + install_options, - cwd=self.source_dir, + cwd=self.setup_py_dir, show_stdout=False, spinner=spinner, ) @@ -977,10 +971,6 @@ class InstallRequirement(object): with indent_log(): # FIXME: should we do --install-headers here too? - cwd = self.source_dir - if self.editable_options and \ - 'subdirectory' in self.editable_options: - cwd = os.path.join(cwd, self.editable_options['subdirectory']) call_subprocess( [ sys.executable, @@ -991,7 +981,7 @@ class InstallRequirement(object): ['develop', '--no-deps'] + list(install_options), - cwd=cwd, + cwd=self.setup_py_dir, show_stdout=False) self.install_succeeded = True @@ -1100,33 +1090,19 @@ def _build_req_from_url(url): parts = [p for p in url.split('#', 1)[0].split('/') if p] req = None - if parts[-2] in ('tags', 'branches', 'tag', 'branch'): + if len(parts) > 2 and parts[-2] in ('tags', 'branches', 'tag', 'branch'): req = parts[-3] - elif parts[-1] == 'trunk': + elif len(parts) > 1 and parts[-1] == 'trunk': req = parts[-2] + if req: + warnings.warn( + 'Sniffing the requirement name from the url is deprecated and ' + 'will be removed in the future. Please specify an #egg segment ' + 'instead.', RemovedInPip9Warning, + stacklevel=2) return req -def _build_editable_options(req): - - """ - This method generates a dictionary of the query string - parameters contained in a given editable URL. - """ - regexp = re.compile(r"[\?#&](?P[^&=]+)=(?P[^&=]+)") - matched = regexp.findall(req) - - if matched: - ret = dict() - for option in matched: - (name, value) = option - if name in ret: - raise Exception("%s option already defined" % name) - ret[name] = value - return ret - return None - - def parse_editable(editable_req, default_vcs=None): """Parses an editable requirement into: - a requirement name @@ -1169,10 +1145,9 @@ def parse_editable(editable_req, default_vcs=None): pkg_resources.Requirement.parse( '__placeholder__' + extras ).extras, - {}, ) else: - return package_name, url_no_extras, None, {} + return package_name, url_no_extras, None for version_control in vcs: if url.lower().startswith('%s:' % version_control): @@ -1197,21 +1172,12 @@ def parse_editable(editable_req, default_vcs=None): ' is currently supported' raise InstallationError(error_message) - try: - options = _build_editable_options(editable_req) - except Exception as exc: + package_name = Link(url).egg_fragment + if not package_name: + package_name = _build_req_from_url(editable_req) + if not package_name: raise InstallationError( - '--editable=%s error in editable options:%s' % (editable_req, exc) + '--editable=%s is not the right format; it must have ' + '#egg=Package' % editable_req ) - if not options or 'egg' not in options: - req = _build_req_from_url(editable_req) - if not req: - raise InstallationError( - '--editable=%s is not the right format; it must have ' - '#egg=Package' % editable_req - ) - else: - req = options['egg'] - - package = _strip_postfix(req) - return package, url, None, options + return _strip_postfix(package_name), url, None diff --git a/Shared/lib/python3.4/site-packages/pip/req/req_set.py b/Shared/lib/python3.4/site-packages/pip/req/req_set.py index b484dd9..e7a8d87 100644 --- a/Shared/lib/python3.4/site-packages/pip/req/req_set.py +++ b/Shared/lib/python3.4/site-packages/pip/req/req_set.py @@ -242,7 +242,8 @@ class RequirementSet(object): existing_req = None if (parent_req_name is None and existing_req and not existing_req.constraint and - existing_req.extras == install_req.extras): + existing_req.extras == install_req.extras and not + existing_req.req.specs == install_req.req.specs): raise InstallationError( 'Double requirement given: %s (already in %s, name=%r)' % (install_req, existing_req, name)) diff --git a/Shared/lib/python3.4/site-packages/pip/utils/__init__.py b/Shared/lib/python3.4/site-packages/pip/utils/__init__.py index 7bf8de4..8ea2e38 100644 --- a/Shared/lib/python3.4/site-packages/pip/utils/__init__.py +++ b/Shared/lib/python3.4/site-packages/pip/utils/__init__.py @@ -3,6 +3,7 @@ from __future__ import absolute_import from collections import deque import contextlib import errno +import io import locale # we have a submodule named 'logging' which would shadow this if we used the # regular name: @@ -38,7 +39,7 @@ __all__ = ['rmtree', 'display_path', 'backup_dir', 'format_size', 'is_installable_dir', 'is_svn_page', 'file_contents', 'split_leading_dir', 'has_leading_dir', - 'normalize_path', 'canonicalize_name', + 'normalize_path', 'renames', 'get_terminal_size', 'get_prog', 'unzip_file', 'untar_file', 'unpack_file', 'call_subprocess', 'captured_stdout', 'remove_tracebacks', 'ensure_dir', @@ -199,7 +200,7 @@ def file_contents(filename): return fp.read().decode('utf-8') -def read_chunks(file, size=4096): +def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): """Yield pieces of data from a file-like object until EOF.""" while True: chunk = file.read(size) @@ -653,6 +654,31 @@ def call_subprocess(cmd, show_stdout=True, cwd=None, on_returncode='raise', command_level=std_logging.DEBUG, command_desc=None, extra_environ=None, spinner=None): + # This function's handling of subprocess output is confusing and I + # previously broke it terribly, so as penance I will write a long comment + # explaining things. + # + # The obvious thing that affects output is the show_stdout= + # kwarg. show_stdout=True means, let the subprocess write directly to our + # stdout. Even though it is nominally the default, it is almost never used + # inside pip (and should not be used in new code without a very good + # reason); as of 2016-02-22 it is only used in a few places inside the VCS + # wrapper code. Ideally we should get rid of it entirely, because it + # creates a lot of complexity here for a rarely used feature. + # + # Most places in pip set show_stdout=False. What this means is: + # - We connect the child stdout to a pipe, which we read. + # - By default, we hide the output but show a spinner -- unless the + # subprocess exits with an error, in which case we show the output. + # - If the --verbose option was passed (= loglevel is DEBUG), then we show + # the output unconditionally. (But in this case we don't want to show + # the output a second time if it turns out that there was an error.) + # + # stderr is always merged with stdout (even if show_stdout=True). + if show_stdout: + stdout = None + else: + stdout = subprocess.PIPE if command_desc is None: cmd_parts = [] for part in cmd: @@ -666,24 +692,28 @@ def call_subprocess(cmd, show_stdout=True, cwd=None, env.update(extra_environ) try: proc = subprocess.Popen( - cmd, stderr=subprocess.STDOUT, stdin=None, stdout=subprocess.PIPE, + cmd, stderr=subprocess.STDOUT, stdin=None, stdout=stdout, cwd=cwd, env=env) except Exception as exc: logger.critical( "Error %s while executing command %s", exc, command_desc, ) raise - all_output = [] - while True: - line = console_to_str(proc.stdout.readline()) - if not line: - break - line = line.rstrip() - all_output.append(line + '\n') - if show_stdout: - logger.debug(line) - if spinner is not None: - spinner.spin() + if stdout is not None: + all_output = [] + while True: + line = console_to_str(proc.stdout.readline()) + if not line: + break + line = line.rstrip() + all_output.append(line + '\n') + if logger.getEffectiveLevel() <= std_logging.DEBUG: + # Show the line immediately + logger.debug(line) + else: + # Update the spinner + if spinner is not None: + spinner.spin() proc.wait() if spinner is not None: if proc.returncode: @@ -692,7 +722,8 @@ def call_subprocess(cmd, show_stdout=True, cwd=None, spinner.finish("done") if proc.returncode: if on_returncode == 'raise': - if all_output: + if (logger.getEffectiveLevel() > std_logging.DEBUG and + not show_stdout): logger.info( 'Complete output from command %s:', command_desc, ) @@ -842,11 +873,6 @@ def get_installed_version(dist_name): return dist.version if dist else None -def canonicalize_name(name): - """Convert an arbitrary string to a canonical name used for comparison""" - return pkg_resources.safe_name(name).lower() - - def consume(iterator): """Consume an iterable at C speed.""" deque(iterator, maxlen=0) diff --git a/Shared/lib/python3.4/site-packages/pip/utils/deprecation.py b/Shared/lib/python3.4/site-packages/pip/utils/deprecation.py index d336cee..2fb1d1e 100644 --- a/Shared/lib/python3.4/site-packages/pip/utils/deprecation.py +++ b/Shared/lib/python3.4/site-packages/pip/utils/deprecation.py @@ -11,23 +11,20 @@ class PipDeprecationWarning(Warning): pass -class RemovedInPip9Warning(PipDeprecationWarning, DeprecationWarning): +class Pending(object): pass -class RemovedInPip10Warning(PipDeprecationWarning, PendingDeprecationWarning): +class RemovedInPip9Warning(PipDeprecationWarning): pass -class Python26DeprecationWarning( - PipDeprecationWarning, PendingDeprecationWarning -): +class RemovedInPip10Warning(PipDeprecationWarning, Pending): pass -DEPRECATIONS = [ - RemovedInPip9Warning, RemovedInPip10Warning, Python26DeprecationWarning -] +class Python26DeprecationWarning(PipDeprecationWarning, Pending): + pass # Warnings <-> Logging Integration @@ -53,15 +50,15 @@ def _showwarning(message, category, filename, lineno, file=None, line=None): # want it to appear as if someone typed this entire message out. log_message = "DEPRECATION: %s" % message - # Things that are DeprecationWarnings will be removed in the very - # next version of pip. We want these to be more obvious so we - # use the ERROR logging level while the PendingDeprecationWarnings - # are still have at least 2 versions to go until they are removed - # so they can just be warnings. - if issubclass(category, DeprecationWarning): - logger.error(log_message) - else: + # PipDeprecationWarnings that are Pending still have at least 2 + # versions to go until they are removed so they can just be + # warnings. Otherwise, they will be removed in the very next + # version of pip. We want these to be more obvious so we use the + # ERROR logging level. + if issubclass(category, Pending): logger.warning(log_message) + else: + logger.error(log_message) else: _warnings_showwarning( message, category, filename, lineno, file, line, @@ -69,6 +66,9 @@ def _showwarning(message, category, filename, lineno, file=None, line=None): def install_warning_logger(): + # Enable our Deprecation Warnings + warnings.simplefilter("default", PipDeprecationWarning, append=True) + global _warnings_showwarning if _warnings_showwarning is None: diff --git a/Shared/lib/python3.4/site-packages/pip/utils/encoding.py b/Shared/lib/python3.4/site-packages/pip/utils/encoding.py new file mode 100644 index 0000000..b272a0b --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pip/utils/encoding.py @@ -0,0 +1,23 @@ +import codecs +import locale + + +BOMS = [ + (codecs.BOM_UTF8, 'utf8'), + (codecs.BOM_UTF16, 'utf16'), + (codecs.BOM_UTF16_BE, 'utf16-be'), + (codecs.BOM_UTF16_LE, 'utf16-le'), + (codecs.BOM_UTF32, 'utf32'), + (codecs.BOM_UTF32_BE, 'utf32-be'), + (codecs.BOM_UTF32_LE, 'utf32-le'), +] + + +def auto_decode(data): + """Check a bytes string for a BOM to correctly detect the encoding + + Fallback to locale.getpreferredencoding(False) like open() on Python3""" + for bom, encoding in BOMS: + if data.startswith(bom): + return data[len(bom):].decode(encoding) + return data.decode(locale.getpreferredencoding(False)) diff --git a/Shared/lib/python3.4/site-packages/pip/utils/ui.py b/Shared/lib/python3.4/site-packages/pip/utils/ui.py index 973bc64..bba73e3 100644 --- a/Shared/lib/python3.4/site-packages/pip/utils/ui.py +++ b/Shared/lib/python3.4/site-packages/pip/utils/ui.py @@ -219,6 +219,11 @@ def hidden_cursor(file): # even via colorama. So don't even try. if WINDOWS: yield + # We don't want to clutter the output with control characters if we're + # writing to a file, or if the user is running with --quiet. + # See https://github.com/pypa/pip/issues/3418 + elif not file.isatty() or logger.getEffectiveLevel() > logging.INFO: + yield else: file.write(HIDE_CURSOR) try: diff --git a/Shared/lib/python3.4/site-packages/pip/vcs/git.py b/Shared/lib/python3.4/site-packages/pip/vcs/git.py index baee7e8..24528de 100644 --- a/Shared/lib/python3.4/site-packages/pip/vcs/git.py +++ b/Shared/lib/python3.4/site-packages/pip/vcs/git.py @@ -135,9 +135,12 @@ class Git(VersionControl): self.update_submodules(dest) def get_url(self, location): - url = self.run_command( - ['config', 'remote.origin.url'], + """Return URL of the first remote encountered.""" + remotes = self.run_command( + ['config', '--get-regexp', 'remote\..*\.url'], show_stdout=False, cwd=location) + first_remote = remotes.splitlines()[0] + url = first_remote.split(' ')[1] return url.strip() def get_revision(self, location): diff --git a/Shared/lib/python3.4/site-packages/pip/wheel.py b/Shared/lib/python3.4/site-packages/pip/wheel.py index ffda773..3e12402 100644 --- a/Shared/lib/python3.4/site-packages/pip/wheel.py +++ b/Shared/lib/python3.4/site-packages/pip/wheel.py @@ -31,13 +31,14 @@ from pip.exceptions import ( from pip.locations import distutils_scheme, PIP_DELETE_MARKER_FILENAME from pip import pep425tags from pip.utils import ( - call_subprocess, ensure_dir, captured_stdout, rmtree, canonicalize_name, - read_chunks) + call_subprocess, ensure_dir, captured_stdout, rmtree, read_chunks, +) from pip.utils.ui import open_spinner from pip.utils.logging import indent_log from pip.utils.setuptools_build import SETUPTOOLS_SHIM from pip._vendor.distlib.scripts import ScriptMaker from pip._vendor import pkg_resources +from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.six.moves import configparser @@ -519,7 +520,7 @@ if __name__ == '__main__': writer.writerow(row) for f in generated: h, l = rehash(f) - writer.writerow((f, h, l)) + writer.writerow((normpath(f, lib_dir), h, l)) for f in installed: writer.writerow((installed[f], '', '')) shutil.move(temp_record, record) @@ -715,7 +716,7 @@ class WheelBuilder(object): wheel_args += ["--python-tag", python_tag] try: - call_subprocess(wheel_args, cwd=req.source_dir, + call_subprocess(wheel_args, cwd=req.setup_py_dir, show_stdout=False, spinner=spinner) return True except: diff --git a/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/DESCRIPTION.rst b/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..e118723 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/DESCRIPTION.rst @@ -0,0 +1,3 @@ +UNKNOWN + + diff --git a/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER b/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/METADATA b/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/METADATA new file mode 100644 index 0000000..7a50487 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/METADATA @@ -0,0 +1,13 @@ +Metadata-Version: 2.0 +Name: pkg_resources +Version: 0.0.0 +Summary: UNKNOWN +Home-page: UNKNOWN +Author: UNKNOWN +Author-email: UNKNOWN +License: UNKNOWN +Platform: UNKNOWN + +UNKNOWN + + diff --git a/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/RECORD b/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/RECORD new file mode 100644 index 0000000..d7509e8 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/RECORD @@ -0,0 +1,26 @@ +pkg_resources/__init__.py,sha256=bucu_98c11mzrGldEJeqxArn14F7ZmURsb-8CaNSbVo,108616 +pkg_resources/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pkg_resources/_vendor/six.py,sha256=A6hdJZVjI3t_geebZ9BzUvwRrIXo0lfwzQlM2LcKyas,30098 +pkg_resources/_vendor/packaging/__about__.py,sha256=YzdrW-1lWmyCBDyrcNkZbJo4tiDWXpoiqPjfyCYMzIE,1073 +pkg_resources/_vendor/packaging/__init__.py,sha256=2V8n-eEpSgBuXlV8hlMmhU7ZklpsrrusWMZNp2gC4Hs,906 +pkg_resources/_vendor/packaging/_compat.py,sha256=wofog8iYo_zudt_10i6JiXKHDs5GhCuXC09hCuSJiv4,1253 +pkg_resources/_vendor/packaging/_structures.py,sha256=93YvgrEE2HgFp8AdXy0pwCRVnZeutRHO_-puJ7T0cPw,1809 +pkg_resources/_vendor/packaging/specifiers.py,sha256=UV9T01_kKloA8PSeMI3HTYBSJ_4KLs00yLvrlciZ3yU,28079 +pkg_resources/_vendor/packaging/version.py,sha256=dEGrWZJZ6sef1xMxSfDCego2hS3Q86by0hUIFVk-AGc,11949 +pkg_resources/extern/__init__.py,sha256=azKvXDutMVFe3c641wdiwndjtku92Bl3_iGVAIMKnsM,2461 +pkg_resources-0.0.0.dist-info/DESCRIPTION.rst,sha256=OCTuuN6LcWulhHS3d5rfjdsQtW22n7HENFRh6jC6ego,10 +pkg_resources-0.0.0.dist-info/METADATA,sha256=FOYDX6cmnDUkWo-yhqWQYtjKIMZR2IW2G1GFZhA6gUQ,177 +pkg_resources-0.0.0.dist-info/RECORD,, +pkg_resources-0.0.0.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110 +pkg_resources-0.0.0.dist-info/metadata.json,sha256=8ZVRFU96pY_wnWouockCkvXw981Y0iDB5nQFFGq8ZiY,221 +pkg_resources-0.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/version.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-34.pyc,, +pkg_resources/_vendor/__pycache__/six.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-34.pyc,, +pkg_resources/extern/__pycache__/__init__.cpython-34.pyc,, +pkg_resources/__pycache__/__init__.cpython-34.pyc,, +pkg_resources/_vendor/__pycache__/__init__.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/WHEEL b/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/WHEEL new file mode 100644 index 0000000..8b6dd1b --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.29.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/metadata.json b/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/metadata.json new file mode 100644 index 0000000..f7d360a --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pkg_resources-0.0.0.dist-info/metadata.json @@ -0,0 +1 @@ +{"extensions": {"python.details": {"document_names": {"description": "DESCRIPTION.rst"}}}, "generator": "bdist_wheel (0.29.0)", "metadata_version": "2.0", "name": "pkg_resources", "summary": "UNKNOWN", "version": "0.0.0"} \ No newline at end of file diff --git a/Shared/lib/python3.4/site-packages/pkg_resources/_vendor/packaging/markers.py b/Shared/lib/python3.4/site-packages/pkg_resources/_vendor/packaging/markers.py new file mode 100644 index 0000000..9e90601 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pkg_resources/_vendor/packaging/markers.py @@ -0,0 +1,273 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import operator +import os +import platform +import sys + +from pkg_resources.extern.pyparsing import ParseException, ParseResults, stringStart, stringEnd +from pkg_resources.extern.pyparsing import ZeroOrMore, Group, Forward, QuotedString +from pkg_resources.extern.pyparsing import Literal as L # noqa + +from ._compat import string_types +from .specifiers import Specifier, InvalidSpecifier + + +__all__ = [ + "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName", + "Marker", "default_environment", +] + + +class InvalidMarker(ValueError): + """ + An invalid marker was found, users should refer to PEP 508. + """ + + +class UndefinedComparison(ValueError): + """ + An invalid operation was attempted on a value that doesn't support it. + """ + + +class UndefinedEnvironmentName(ValueError): + """ + A name was attempted to be used that does not exist inside of the + environment. + """ + + +class Node(object): + + def __init__(self, value): + self.value = value + + def __str__(self): + return str(self.value) + + def __repr__(self): + return "<{0}({1!r})>".format(self.__class__.__name__, str(self)) + + +class Variable(Node): + pass + + +class Value(Node): + pass + + +VARIABLE = ( + L("implementation_version") | + L("platform_python_implementation") | + L("implementation_name") | + L("python_full_version") | + L("platform_release") | + L("platform_version") | + L("platform_machine") | + L("platform_system") | + L("python_version") | + L("sys_platform") | + L("os_name") | + L("extra") +) +VARIABLE.setParseAction(lambda s, l, t: Variable(t[0])) + +VERSION_CMP = ( + L("===") | + L("==") | + L(">=") | + L("<=") | + L("!=") | + L("~=") | + L(">") | + L("<") +) + +MARKER_OP = VERSION_CMP | L("not in") | L("in") + +MARKER_VALUE = QuotedString("'") | QuotedString('"') +MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) + +BOOLOP = L("and") | L("or") + +MARKER_VAR = VARIABLE | MARKER_VALUE + +MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) +MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) + +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() + +MARKER_EXPR = Forward() +MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) +MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) + +MARKER = stringStart + MARKER_EXPR + stringEnd + + +def _coerce_parse_result(results): + if isinstance(results, ParseResults): + return [_coerce_parse_result(i) for i in results] + else: + return results + + +def _format_marker(marker, first=True): + assert isinstance(marker, (list, tuple, string_types)) + + # Sometimes we have a structure like [[...]] which is a single item list + # where the single item is itself it's own list. In that case we want skip + # the rest of this function so that we don't get extraneous () on the + # outside. + if (isinstance(marker, list) and len(marker) == 1 and + isinstance(marker[0], (list, tuple))): + return _format_marker(marker[0]) + + if isinstance(marker, list): + inner = (_format_marker(m, first=False) for m in marker) + if first: + return " ".join(inner) + else: + return "(" + " ".join(inner) + ")" + elif isinstance(marker, tuple): + return '{0} {1} "{2}"'.format(*marker) + else: + return marker + + +_operators = { + "in": lambda lhs, rhs: lhs in rhs, + "not in": lambda lhs, rhs: lhs not in rhs, + "<": operator.lt, + "<=": operator.le, + "==": operator.eq, + "!=": operator.ne, + ">=": operator.ge, + ">": operator.gt, +} + + +def _eval_op(lhs, op, rhs): + try: + spec = Specifier("".join([op, rhs])) + except InvalidSpecifier: + pass + else: + return spec.contains(lhs) + + oper = _operators.get(op) + if oper is None: + raise UndefinedComparison( + "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) + ) + + return oper(lhs, rhs) + + +_undefined = object() + + +def _get_env(environment, name): + value = environment.get(name, _undefined) + + if value is _undefined: + raise UndefinedEnvironmentName( + "{0!r} does not exist in evaluation environment.".format(name) + ) + + return value + + +def _evaluate_markers(markers, environment): + groups = [[]] + + for marker in markers: + assert isinstance(marker, (list, tuple, string_types)) + + if isinstance(marker, list): + groups[-1].append(_evaluate_markers(marker, environment)) + elif isinstance(marker, tuple): + lhs, op, rhs = marker + + if isinstance(lhs, Variable): + lhs_value = _get_env(environment, lhs.value) + rhs_value = rhs.value + else: + lhs_value = lhs.value + rhs_value = _get_env(environment, rhs.value) + + groups[-1].append(_eval_op(lhs_value, op, rhs_value)) + else: + assert marker in ["and", "or"] + if marker == "or": + groups.append([]) + + return any(all(item) for item in groups) + + +def format_full_version(info): + version = '{0.major}.{0.minor}.{0.micro}'.format(info) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + +def default_environment(): + if hasattr(sys, 'implementation'): + iver = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + iver = '0' + implementation_name = '' + + return { + "implementation_name": implementation_name, + "implementation_version": iver, + "os_name": os.name, + "platform_machine": platform.machine(), + "platform_release": platform.release(), + "platform_system": platform.system(), + "platform_version": platform.version(), + "python_full_version": platform.python_version(), + "platform_python_implementation": platform.python_implementation(), + "python_version": platform.python_version()[:3], + "sys_platform": sys.platform, + } + + +class Marker(object): + + def __init__(self, marker): + try: + self._markers = _coerce_parse_result(MARKER.parseString(marker)) + except ParseException as e: + err_str = "Invalid marker: {0!r}, parse error at {1!r}".format( + marker, marker[e.loc:e.loc + 8]) + raise InvalidMarker(err_str) + + def __str__(self): + return _format_marker(self._markers) + + def __repr__(self): + return "".format(str(self)) + + def evaluate(self, environment=None): + """Evaluate a marker. + + Return the boolean from evaluating the given marker against the + environment. environment is an optional argument to override all or + part of the determined environment. + + The environment is determined from the current Python process. + """ + current_environment = default_environment() + if environment is not None: + current_environment.update(environment) + + return _evaluate_markers(self._markers, current_environment) diff --git a/Shared/lib/python3.4/site-packages/pkg_resources/_vendor/packaging/requirements.py b/Shared/lib/python3.4/site-packages/pkg_resources/_vendor/packaging/requirements.py new file mode 100644 index 0000000..0c8c4a3 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pkg_resources/_vendor/packaging/requirements.py @@ -0,0 +1,127 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import string +import re + +from pkg_resources.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException +from pkg_resources.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine +from pkg_resources.extern.pyparsing import Literal as L # noqa +from pkg_resources.extern.six.moves.urllib import parse as urlparse + +from .markers import MARKER_EXPR, Marker +from .specifiers import LegacySpecifier, Specifier, SpecifierSet + + +class InvalidRequirement(ValueError): + """ + An invalid requirement was found, users should refer to PEP 508. + """ + + +ALPHANUM = Word(string.ascii_letters + string.digits) + +LBRACKET = L("[").suppress() +RBRACKET = L("]").suppress() +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() +COMMA = L(",").suppress() +SEMICOLON = L(";").suppress() +AT = L("@").suppress() + +PUNCTUATION = Word("-_.") +IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) +IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) + +NAME = IDENTIFIER("name") +EXTRA = IDENTIFIER + +URI = Regex(r'[^ ]+')("url") +URL = (AT + URI) + +EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) +EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") + +VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) +VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) + +VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY +VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), + joinString=",", adjacent=False)("_raw_spec") +_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) +_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '') + +VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") +VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) + +MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") +MARKER_EXPR.setParseAction( + lambda s, l, t: Marker(s[t._original_start:t._original_end]) +) +MARKER_SEPERATOR = SEMICOLON +MARKER = MARKER_SEPERATOR + MARKER_EXPR + +VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) +URL_AND_MARKER = URL + Optional(MARKER) + +NAMED_REQUIREMENT = \ + NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) + +REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd + + +class Requirement(object): + """Parse a requirement. + + Parse a given requirement string into its parts, such as name, specifier, + URL, and extras. Raises InvalidRequirement on a badly-formed requirement + string. + """ + + # TODO: Can we test whether something is contained within a requirement? + # If so how do we do that? Do we need to test against the _name_ of + # the thing as well as the version? What about the markers? + # TODO: Can we normalize the name and extra name? + + def __init__(self, requirement_string): + try: + req = REQUIREMENT.parseString(requirement_string) + except ParseException as e: + raise InvalidRequirement( + "Invalid requirement, parse error at \"{0!r}\"".format( + requirement_string[e.loc:e.loc + 8])) + + self.name = req.name + if req.url: + parsed_url = urlparse.urlparse(req.url) + if not (parsed_url.scheme and parsed_url.netloc) or ( + not parsed_url.scheme and not parsed_url.netloc): + raise InvalidRequirement("Invalid URL given") + self.url = req.url + else: + self.url = None + self.extras = set(req.extras.asList() if req.extras else []) + self.specifier = SpecifierSet(req.specifier) + self.marker = req.marker if req.marker else None + + def __str__(self): + parts = [self.name] + + if self.extras: + parts.append("[{0}]".format(",".join(sorted(self.extras)))) + + if self.specifier: + parts.append(str(self.specifier)) + + if self.url: + parts.append("@ {0}".format(self.url)) + + if self.marker: + parts.append("; {0}".format(self.marker)) + + return "".join(parts) + + def __repr__(self): + return "".format(str(self)) diff --git a/Shared/lib/python3.4/site-packages/pkg_resources/_vendor/packaging/utils.py b/Shared/lib/python3.4/site-packages/pkg_resources/_vendor/packaging/utils.py new file mode 100644 index 0000000..942387c --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pkg_resources/_vendor/packaging/utils.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import re + + +_canonicalize_regex = re.compile(r"[-_.]+") + + +def canonicalize_name(name): + # This is taken from PEP 503. + return _canonicalize_regex.sub("-", name).lower() diff --git a/Shared/lib/python3.4/site-packages/pkg_resources/_vendor/pyparsing.py b/Shared/lib/python3.4/site-packages/pkg_resources/_vendor/pyparsing.py new file mode 100644 index 0000000..3e02dbe --- /dev/null +++ b/Shared/lib/python3.4/site-packages/pkg_resources/_vendor/pyparsing.py @@ -0,0 +1,3805 @@ +# module pyparsing.py +# +# Copyright (c) 2003-2015 Paul T. McGuire +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__doc__ = \ +""" +pyparsing module - Classes and methods to define and execute parsing grammars + +The pyparsing module is an alternative approach to creating and executing simple grammars, +vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you +don't need to learn a new syntax for defining grammars or matching expressions - the parsing module +provides a library of classes that you use to construct the grammar directly in Python. + +Here is a program to parse "Hello, World!" (or any greeting of the form C{", !"}):: + + from pyparsing import Word, alphas + + # define grammar of a greeting + greet = Word( alphas ) + "," + Word( alphas ) + "!" + + hello = "Hello, World!" + print (hello, "->", greet.parseString( hello )) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the self-explanatory +class names, and the use of '+', '|' and '^' operators. + +The parsed results returned from C{parseString()} can be accessed as a nested list, a dictionary, or an +object with named attributes. + +The pyparsing module handles some of the problems that are typically vexing when writing text parsers: + - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) + - quoted strings + - embedded comments +""" + +__version__ = "2.0.6" +__versionTime__ = "9 Nov 2015 19:03" +__author__ = "Paul McGuire " + +import string +from weakref import ref as wkref +import copy +import sys +import warnings +import re +import sre_constants +import collections +import pprint +import functools +import itertools + +#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) + +__all__ = [ +'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', +'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', +'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', +'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', +'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', +'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', 'Upcase', +'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', +'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', +'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', +'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums', +'htmlComment', 'javaStyleComment', 'keepOriginalText', 'line', 'lineEnd', 'lineStart', 'lineno', +'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', +'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', +'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', +'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', +'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', +'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass', +] + +PY_3 = sys.version.startswith('3') +if PY_3: + _MAX_INT = sys.maxsize + basestring = str + unichr = chr + _ustr = str + + # build list of single arg builtins, that can be used as parse actions + singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] + +else: + _MAX_INT = sys.maxint + range = xrange + + def _ustr(obj): + """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries + str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It + then < returns the unicode object | encodes it with the default encoding | ... >. + """ + if isinstance(obj,unicode): + return obj + + try: + # If this works, then _ustr(obj) has the same behaviour as str(obj), so + # it won't break any existing code. + return str(obj) + + except UnicodeEncodeError: + # The Python docs (http://docs.python.org/ref/customization.html#l2h-182) + # state that "The return value must be a string object". However, does a + # unicode object (being a subclass of basestring) count as a "string + # object"? + # If so, then return a unicode object: + return unicode(obj) + # Else encode it... but how? There are many choices... :) + # Replace unprintables with escape codes? + #return unicode(obj).encode(sys.getdefaultencoding(), 'backslashreplace_errors') + # Replace unprintables with question marks? + #return unicode(obj).encode(sys.getdefaultencoding(), 'replace') + # ... + + # build list of single arg builtins, tolerant of Python version, that can be used as parse actions + singleArgBuiltins = [] + import __builtin__ + for fname in "sum len sorted reversed list tuple set any all min max".split(): + try: + singleArgBuiltins.append(getattr(__builtin__,fname)) + except AttributeError: + continue + +_generatorType = type((y for y in range(1))) + +def _xml_escape(data): + """Escape &, <, >, ", ', etc. in a string of data.""" + + # ampersand must be replaced first + from_symbols = '&><"\'' + to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split()) + for from_,to_ in zip(from_symbols, to_symbols): + data = data.replace(from_, to_) + return data + +class _Constants(object): + pass + +alphas = string.ascii_lowercase + string.ascii_uppercase +nums = "0123456789" +hexnums = nums + "ABCDEFabcdef" +alphanums = alphas + nums +_bslash = chr(92) +printables = "".join(c for c in string.printable if c not in string.whitespace) + +class ParseBaseException(Exception): + """base exception class for all parsing runtime exceptions""" + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, pstr, loc=0, msg=None, elem=None ): + self.loc = loc + if msg is None: + self.msg = pstr + self.pstr = "" + else: + self.msg = msg + self.pstr = pstr + self.parserElement = elem + + def __getattr__( self, aname ): + """supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + """ + if( aname == "lineno" ): + return lineno( self.loc, self.pstr ) + elif( aname in ("col", "column") ): + return col( self.loc, self.pstr ) + elif( aname == "line" ): + return line( self.loc, self.pstr ) + else: + raise AttributeError(aname) + + def __str__( self ): + return "%s (at char %d), (line:%d, col:%d)" % \ + ( self.msg, self.loc, self.lineno, self.column ) + def __repr__( self ): + return _ustr(self) + def markInputline( self, markerString = ">!<" ): + """Extracts the exception line from the input string, and marks + the location of the exception with a special symbol. + """ + line_str = self.line + line_column = self.column - 1 + if markerString: + line_str = "".join((line_str[:line_column], + markerString, line_str[line_column:])) + return line_str.strip() + def __dir__(self): + return "loc msg pstr parserElement lineno col line " \ + "markInputline __str__ __repr__".split() + +class ParseException(ParseBaseException): + """exception thrown when parse expressions don't match class; + supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + """ + pass + +class ParseFatalException(ParseBaseException): + """user-throwable exception thrown when inconsistent parse content + is found; stops all parsing immediately""" + pass + +class ParseSyntaxException(ParseFatalException): + """just like C{L{ParseFatalException}}, but thrown internally when an + C{L{ErrorStop}} ('-' operator) indicates that parsing is to stop immediately because + an unbacktrackable syntax error has been found""" + def __init__(self, pe): + super(ParseSyntaxException, self).__init__( + pe.pstr, pe.loc, pe.msg, pe.parserElement) + +#~ class ReparseException(ParseBaseException): + #~ """Experimental class - parse actions can raise this exception to cause + #~ pyparsing to reparse the input string: + #~ - with a modified input string, and/or + #~ - with a modified start location + #~ Set the values of the ReparseException in the constructor, and raise the + #~ exception in a parse action to cause pyparsing to use the new string/location. + #~ Setting the values as None causes no change to be made. + #~ """ + #~ def __init_( self, newstring, restartLoc ): + #~ self.newParseText = newstring + #~ self.reparseLoc = restartLoc + +class RecursiveGrammarException(Exception): + """exception thrown by C{validate()} if the grammar could be improperly recursive""" + def __init__( self, parseElementList ): + self.parseElementTrace = parseElementList + + def __str__( self ): + return "RecursiveGrammarException: %s" % self.parseElementTrace + +class _ParseResultsWithOffset(object): + def __init__(self,p1,p2): + self.tup = (p1,p2) + def __getitem__(self,i): + return self.tup[i] + def __repr__(self): + return repr(self.tup) + def setOffset(self,i): + self.tup = (self.tup[0],i) + +class ParseResults(object): + """Structured parse results, to provide multiple means of access to the parsed data: + - as a list (C{len(results)}) + - by list index (C{results[0], results[1]}, etc.) + - by attribute (C{results.}) + """ + def __new__(cls, toklist, name=None, asList=True, modal=True ): + if isinstance(toklist, cls): + return toklist + retobj = object.__new__(cls) + retobj.__doinit = True + return retobj + + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, toklist, name=None, asList=True, modal=True, isinstance=isinstance ): + if self.__doinit: + self.__doinit = False + self.__name = None + self.__parent = None + self.__accumNames = {} + if isinstance(toklist, list): + self.__toklist = toklist[:] + elif isinstance(toklist, _generatorType): + self.__toklist = list(toklist) + else: + self.__toklist = [toklist] + self.__tokdict = dict() + + if name is not None and name: + if not modal: + self.__accumNames[name] = 0 + if isinstance(name,int): + name = _ustr(name) # will always return a str, but use _ustr for consistency + self.__name = name + if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): + if isinstance(toklist,basestring): + toklist = [ toklist ] + if asList: + if isinstance(toklist,ParseResults): + self[name] = _ParseResultsWithOffset(toklist.copy(),0) + else: + self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) + self[name].__name = name + else: + try: + self[name] = toklist[0] + except (KeyError,TypeError,IndexError): + self[name] = toklist + + def __getitem__( self, i ): + if isinstance( i, (int,slice) ): + return self.__toklist[i] + else: + if i not in self.__accumNames: + return self.__tokdict[i][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[i] ]) + + def __setitem__( self, k, v, isinstance=isinstance ): + if isinstance(v,_ParseResultsWithOffset): + self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] + sub = v[0] + elif isinstance(k,int): + self.__toklist[k] = v + sub = v + else: + self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] + sub = v + if isinstance(sub,ParseResults): + sub.__parent = wkref(self) + + def __delitem__( self, i ): + if isinstance(i,(int,slice)): + mylen = len( self.__toklist ) + del self.__toklist[i] + + # convert int to slice + if isinstance(i, int): + if i < 0: + i += mylen + i = slice(i, i+1) + # get removed indices + removed = list(range(*i.indices(mylen))) + removed.reverse() + # fixup indices in token dictionary + #~ for name in self.__tokdict: + #~ occurrences = self.__tokdict[name] + #~ for j in removed: + #~ for k, (value, position) in enumerate(occurrences): + #~ occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) + for name,occurrences in self.__tokdict.items(): + for j in removed: + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) + else: + del self.__tokdict[i] + + def __contains__( self, k ): + return k in self.__tokdict + + def __len__( self ): return len( self.__toklist ) + def __bool__(self): return len( self.__toklist ) > 0 + __nonzero__ = __bool__ + def __iter__( self ): return iter( self.__toklist ) + def __reversed__( self ): return iter( self.__toklist[::-1] ) + def iterkeys( self ): + """Returns all named result keys.""" + if hasattr(self.__tokdict, "iterkeys"): + return self.__tokdict.iterkeys() + else: + return iter(self.__tokdict) + + def itervalues( self ): + """Returns all named result values.""" + return (self[k] for k in self.iterkeys()) + + def iteritems( self ): + return ((k, self[k]) for k in self.iterkeys()) + + if PY_3: + keys = iterkeys + values = itervalues + items = iteritems + else: + def keys( self ): + """Returns all named result keys.""" + return list(self.iterkeys()) + + def values( self ): + """Returns all named result values.""" + return list(self.itervalues()) + + def items( self ): + """Returns all named result keys and values as a list of tuples.""" + return list(self.iteritems()) + + def haskeys( self ): + """Since keys() returns an iterator, this method is helpful in bypassing + code that looks for the existence of any defined results names.""" + return bool(self.__tokdict) + + def pop( self, *args, **kwargs): + """Removes and returns item at specified index (default=last). + Supports both list and dict semantics for pop(). If passed no + argument or an integer argument, it will use list semantics + and pop tokens from the list of parsed tokens. If passed a + non-integer argument (most likely a string), it will use dict + semantics and pop the corresponding value from any defined + results names. A second default return value argument is + supported, just as in dict.pop().""" + if not args: + args = [-1] + for k,v in kwargs.items(): + if k == 'default': + args = (args[0], v) + else: + raise TypeError("pop() got an unexpected keyword argument '%s'" % k) + if (isinstance(args[0], int) or + len(args) == 1 or + args[0] in self): + index = args[0] + ret = self[index] + del self[index] + return ret + else: + defaultvalue = args[1] + return defaultvalue + + def get(self, key, defaultValue=None): + """Returns named result matching the given key, or if there is no + such name, then returns the given C{defaultValue} or C{None} if no + C{defaultValue} is specified.""" + if key in self: + return self[key] + else: + return defaultValue + + def insert( self, index, insStr ): + """Inserts new element at location index in the list of parsed tokens.""" + self.__toklist.insert(index, insStr) + # fixup indices in token dictionary + #~ for name in self.__tokdict: + #~ occurrences = self.__tokdict[name] + #~ for k, (value, position) in enumerate(occurrences): + #~ occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) + for name,occurrences in self.__tokdict.items(): + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) + + def append( self, item ): + """Add single element to end of ParseResults list of elements.""" + self.__toklist.append(item) + + def extend( self, itemseq ): + """Add sequence of elements to end of ParseResults list of elements.""" + if isinstance(itemseq, ParseResults): + self += itemseq + else: + self.__toklist.extend(itemseq) + + def clear( self ): + """Clear all elements and results names.""" + del self.__toklist[:] + self.__tokdict.clear() + + def __getattr__( self, name ): + try: + return self[name] + except KeyError: + return "" + + if name in self.__tokdict: + if name not in self.__accumNames: + return self.__tokdict[name][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[name] ]) + else: + return "" + + def __add__( self, other ): + ret = self.copy() + ret += other + return ret + + def __iadd__( self, other ): + if other.__tokdict: + offset = len(self.__toklist) + addoffset = lambda a: offset if a<0 else a+offset + otheritems = other.__tokdict.items() + otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) + for (k,vlist) in otheritems for v in vlist] + for k,v in otherdictitems: + self[k] = v + if isinstance(v[0],ParseResults): + v[0].__parent = wkref(self) + + self.__toklist += other.__toklist + self.__accumNames.update( other.__accumNames ) + return self + + def __radd__(self, other): + if isinstance(other,int) and other == 0: + return self.copy() + + def __repr__( self ): + return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) + + def __str__( self ): + return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' + + def _asStringList( self, sep='' ): + out = [] + for item in self.__toklist: + if out and sep: + out.append(sep) + if isinstance( item, ParseResults ): + out += item._asStringList() + else: + out.append( _ustr(item) ) + return out + + def asList( self ): + """Returns the parse results as a nested list of matching tokens, all converted to strings.""" + return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist] + + def asDict( self ): + """Returns the named parse results as dictionary.""" + if PY_3: + return dict( self.items() ) + else: + return dict( self.iteritems() ) + + def copy( self ): + """Returns a new copy of a C{ParseResults} object.""" + ret = ParseResults( self.__toklist ) + ret.__tokdict = self.__tokdict.copy() + ret.__parent = self.__parent + ret.__accumNames.update( self.__accumNames ) + ret.__name = self.__name + return ret + + def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): + """Returns the parse results as XML. Tags are created for tokens and lists that have defined results names.""" + nl = "\n" + out = [] + namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items() + for v in vlist) + nextLevelIndent = indent + " " + + # collapse out indents if formatting is not desired + if not formatted: + indent = "" + nextLevelIndent = "" + nl = "" + + selfTag = None + if doctag is not None: + selfTag = doctag + else: + if self.__name: + selfTag = self.__name + + if not selfTag: + if namedItemsOnly: + return "" + else: + selfTag = "ITEM" + + out += [ nl, indent, "<", selfTag, ">" ] + + for i,res in enumerate(self.__toklist): + if isinstance(res,ParseResults): + if i in namedItems: + out += [ res.asXML(namedItems[i], + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + out += [ res.asXML(None, + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + # individual token, see if there is a name for it + resTag = None + if i in namedItems: + resTag = namedItems[i] + if not resTag: + if namedItemsOnly: + continue + else: + resTag = "ITEM" + xmlBodyText = _xml_escape(_ustr(res)) + out += [ nl, nextLevelIndent, "<", resTag, ">", + xmlBodyText, + "" ] + + out += [ nl, indent, "" ] + return "".join(out) + + def __lookup(self,sub): + for k,vlist in self.__tokdict.items(): + for v,loc in vlist: + if sub is v: + return k + return None + + def getName(self): + """Returns the results name for this token expression.""" + if self.__name: + return self.__name + elif self.__parent: + par = self.__parent() + if par: + return par.__lookup(self) + else: + return None + elif (len(self) == 1 and + len(self.__tokdict) == 1 and + self.__tokdict.values()[0][0][1] in (0,-1)): + return self.__tokdict.keys()[0] + else: + return None + + def dump(self,indent='',depth=0): + """Diagnostic method for listing out the contents of a C{ParseResults}. + Accepts an optional C{indent} argument so that this string can be embedded + in a nested display of other data.""" + out = [] + NL = '\n' + out.append( indent+_ustr(self.asList()) ) + if self.haskeys(): + items = sorted(self.items()) + for k,v in items: + if out: + out.append(NL) + out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) + if isinstance(v,ParseResults): + if v: + out.append( v.dump(indent,depth+1) ) + else: + out.append(_ustr(v)) + else: + out.append(_ustr(v)) + elif any(isinstance(vv,ParseResults) for vv in self): + v = self + for i,vv in enumerate(v): + if isinstance(vv,ParseResults): + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),vv.dump(indent,depth+1) )) + else: + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) + + return "".join(out) + + def pprint(self, *args, **kwargs): + """Pretty-printer for parsed results as a list, using the C{pprint} module. + Accepts additional positional or keyword args as defined for the + C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint})""" + pprint.pprint(self.asList(), *args, **kwargs) + + # add support for pickle protocol + def __getstate__(self): + return ( self.__toklist, + ( self.__tokdict.copy(), + self.__parent is not None and self.__parent() or None, + self.__accumNames, + self.__name ) ) + + def __setstate__(self,state): + self.__toklist = state[0] + (self.__tokdict, + par, + inAccumNames, + self.__name) = state[1] + self.__accumNames = {} + self.__accumNames.update(inAccumNames) + if par is not None: + self.__parent = wkref(par) + else: + self.__parent = None + + def __dir__(self): + return dir(super(ParseResults,self)) + list(self.keys()) + +collections.MutableMapping.register(ParseResults) + +def col (loc,strg): + """Returns current column within a string, counting newlines as line separators. + The first column is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}} for more information + on parsing strings containing C{}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + s = strg + return 1 if loc} for more information + on parsing strings containing C{}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + return strg.count("\n",0,loc) + 1 + +def line( loc, strg ): + """Returns the line of text containing loc within a string, counting newlines as line separators. + """ + lastCR = strg.rfind("\n", 0, loc) + nextCR = strg.find("\n", loc) + if nextCR >= 0: + return strg[lastCR+1:nextCR] + else: + return strg[lastCR+1:] + +def _defaultStartDebugAction( instring, loc, expr ): + print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))) + +def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): + print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) + +def _defaultExceptionDebugAction( instring, loc, expr, exc ): + print ("Exception raised:" + _ustr(exc)) + +def nullDebugAction(*args): + """'Do-nothing' debug action, to suppress debugging output during parsing.""" + pass + +# Only works on Python 3.x - nonlocal is toxic to Python 2 installs +#~ 'decorator to trim function calls to match the arity of the target' +#~ def _trim_arity(func, maxargs=3): + #~ if func in singleArgBuiltins: + #~ return lambda s,l,t: func(t) + #~ limit = 0 + #~ foundArity = False + #~ def wrapper(*args): + #~ nonlocal limit,foundArity + #~ while 1: + #~ try: + #~ ret = func(*args[limit:]) + #~ foundArity = True + #~ return ret + #~ except TypeError: + #~ if limit == maxargs or foundArity: + #~ raise + #~ limit += 1 + #~ continue + #~ return wrapper + +# this version is Python 2.x-3.x cross-compatible +'decorator to trim function calls to match the arity of the target' +def _trim_arity(func, maxargs=2): + if func in singleArgBuiltins: + return lambda s,l,t: func(t) + limit = [0] + foundArity = [False] + def wrapper(*args): + while 1: + try: + ret = func(*args[limit[0]:]) + foundArity[0] = True + return ret + except TypeError: + if limit[0] <= maxargs and not foundArity[0]: + limit[0] += 1 + continue + raise + return wrapper + +class ParserElement(object): + """Abstract base level parser element class.""" + DEFAULT_WHITE_CHARS = " \n\t\r" + verbose_stacktrace = False + + @staticmethod + def setDefaultWhitespaceChars( chars ): + """Overrides the default whitespace chars + """ + ParserElement.DEFAULT_WHITE_CHARS = chars + + @staticmethod + def inlineLiteralsUsing(cls): + """ + Set class to be used for inclusion of string literals into a parser. + """ + ParserElement.literalStringClass = cls + + def __init__( self, savelist=False ): + self.parseAction = list() + self.failAction = None + #~ self.name = "" # don't define self.name, let subclasses try/except upcall + self.strRepr = None + self.resultsName = None + self.saveAsList = savelist + self.skipWhitespace = True + self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + self.copyDefaultWhiteChars = True + self.mayReturnEmpty = False # used when checking for left-recursion + self.keepTabs = False + self.ignoreExprs = list() + self.debug = False + self.streamlined = False + self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index + self.errmsg = "" + self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) + self.debugActions = ( None, None, None ) #custom debug actions + self.re = None + self.callPreparse = True # used to avoid redundant calls to preParse + self.callDuringTry = False + + def copy( self ): + """Make a copy of this C{ParserElement}. Useful for defining different parse actions + for the same parsing pattern, using copies of the original parse element.""" + cpy = copy.copy( self ) + cpy.parseAction = self.parseAction[:] + cpy.ignoreExprs = self.ignoreExprs[:] + if self.copyDefaultWhiteChars: + cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + return cpy + + def setName( self, name ): + """Define name for this expression, for use in debugging.""" + self.name = name + self.errmsg = "Expected " + self.name + if hasattr(self,"exception"): + self.exception.msg = self.errmsg + return self + + def setResultsName( self, name, listAllMatches=False ): + """Define name for referencing matching tokens as a nested attribute + of the returned parse results. + NOTE: this returns a *copy* of the original C{ParserElement} object; + this is so that the client can define a basic element, such as an + integer, and reference it in multiple places with different names. + + You can also set results names using the abbreviated syntax, + C{expr("name")} in place of C{expr.setResultsName("name")} - + see L{I{__call__}<__call__>}. + """ + newself = self.copy() + if name.endswith("*"): + name = name[:-1] + listAllMatches=True + newself.resultsName = name + newself.modalResults = not listAllMatches + return newself + + def setBreak(self,breakFlag = True): + """Method to invoke the Python pdb debugger when this element is + about to be parsed. Set C{breakFlag} to True to enable, False to + disable. + """ + if breakFlag: + _parseMethod = self._parse + def breaker(instring, loc, doActions=True, callPreParse=True): + import pdb + pdb.set_trace() + return _parseMethod( instring, loc, doActions, callPreParse ) + breaker._originalParseMethod = _parseMethod + self._parse = breaker + else: + if hasattr(self._parse,"_originalParseMethod"): + self._parse = self._parse._originalParseMethod + return self + + def setParseAction( self, *fns, **kwargs ): + """Define action to perform when successfully matching parse element definition. + Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)}, + C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: + - s = the original string being parsed (see note below) + - loc = the location of the matching substring + - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object + If the functions in fns modify the tokens, they can return them as the return + value from fn, and the modified list of tokens will replace the original. + Otherwise, fn does not need to return any value. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{parseString}} for more information + on parsing strings containing C{}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + self.parseAction = list(map(_trim_arity, list(fns))) + self.callDuringTry = kwargs.get("callDuringTry", False) + return self + + def addParseAction( self, *fns, **kwargs ): + """Add parse action to expression's list of parse actions. See L{I{setParseAction}}.""" + self.parseAction += list(map(_trim_arity, list(fns))) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def addCondition(self, *fns, **kwargs): + """Add a boolean predicate function to expression's list of parse actions. See + L{I{setParseAction}}. Optional keyword argument C{message} can + be used to define a custom message to be used in the raised exception.""" + msg = kwargs.get("message") or "failed user-defined condition" + for fn in fns: + def pa(s,l,t): + if not bool(_trim_arity(fn)(s,l,t)): + raise ParseException(s,l,msg) + return t + self.parseAction.append(pa) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def setFailAction( self, fn ): + """Define action to perform if parsing fails at this expression. + Fail acton fn is a callable function that takes the arguments + C{fn(s,loc,expr,err)} where: + - s = string being parsed + - loc = location where expression match was attempted and failed + - expr = the parse expression that failed + - err = the exception thrown + The function returns no value. It may throw C{L{ParseFatalException}} + if it is desired to stop parsing immediately.""" + self.failAction = fn + return self + + def _skipIgnorables( self, instring, loc ): + exprsFound = True + while exprsFound: + exprsFound = False + for e in self.ignoreExprs: + try: + while 1: + loc,dummy = e._parse( instring, loc ) + exprsFound = True + except ParseException: + pass + return loc + + def preParse( self, instring, loc ): + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + + if self.skipWhitespace: + wt = self.whiteChars + instrlen = len(instring) + while loc < instrlen and instring[loc] in wt: + loc += 1 + + return loc + + def parseImpl( self, instring, loc, doActions=True ): + return loc, [] + + def postParse( self, instring, loc, tokenlist ): + return tokenlist + + #~ @profile + def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): + debugging = ( self.debug ) #and doActions ) + + if debugging or self.failAction: + #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) + if (self.debugActions[0] ): + self.debugActions[0]( instring, loc, self ) + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + try: + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + except ParseBaseException as err: + #~ print ("Exception raised:", err) + if self.debugActions[2]: + self.debugActions[2]( instring, tokensStart, self, err ) + if self.failAction: + self.failAction( instring, tokensStart, self, err ) + raise + else: + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + if self.mayIndexError or loc >= len(instring): + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + else: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + + tokens = self.postParse( instring, loc, tokens ) + + retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) + if self.parseAction and (doActions or self.callDuringTry): + if debugging: + try: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + except ParseBaseException as err: + #~ print "Exception raised in user parse action:", err + if (self.debugActions[2] ): + self.debugActions[2]( instring, tokensStart, self, err ) + raise + else: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + + if debugging: + #~ print ("Matched",self,"->",retTokens.asList()) + if (self.debugActions[1] ): + self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) + + return loc, retTokens + + def tryParse( self, instring, loc ): + try: + return self._parse( instring, loc, doActions=False )[0] + except ParseFatalException: + raise ParseException( instring, loc, self.errmsg, self) + + # this method gets repeatedly called during backtracking with the same arguments - + # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression + def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): + lookup = (self,instring,loc,callPreParse,doActions) + if lookup in ParserElement._exprArgCache: + value = ParserElement._exprArgCache[ lookup ] + if isinstance(value, Exception): + raise value + return (value[0],value[1].copy()) + else: + try: + value = self._parseNoCache( instring, loc, doActions, callPreParse ) + ParserElement._exprArgCache[ lookup ] = (value[0],value[1].copy()) + return value + except ParseBaseException as pe: + pe.__traceback__ = None + ParserElement._exprArgCache[ lookup ] = pe + raise + + _parse = _parseNoCache + + # argument cache for optimizing repeated calls when backtracking through recursive expressions + _exprArgCache = {} + @staticmethod + def resetCache(): + ParserElement._exprArgCache.clear() + + _packratEnabled = False + @staticmethod + def enablePackrat(): + """Enables "packrat" parsing, which adds memoizing to the parsing logic. + Repeated parse attempts at the same string location (which happens + often in many complex grammars) can immediately return a cached value, + instead of re-executing parsing/validating code. Memoizing is done of + both valid results and parsing exceptions. + + This speedup may break existing programs that use parse actions that + have side-effects. For this reason, packrat parsing is disabled when + you first import pyparsing. To activate the packrat feature, your + program must call the class method C{ParserElement.enablePackrat()}. If + your program uses C{psyco} to "compile as you go", you must call + C{enablePackrat} before calling C{psyco.full()}. If you do not do this, + Python will crash. For best results, call C{enablePackrat()} immediately + after importing pyparsing. + """ + if not ParserElement._packratEnabled: + ParserElement._packratEnabled = True + ParserElement._parse = ParserElement._parseCache + + def parseString( self, instring, parseAll=False ): + """Execute the parse expression with the given string. + This is the main interface to the client code, once the complete + expression has been built. + + If you want the grammar to require that the entire input string be + successfully parsed, then set C{parseAll} to True (equivalent to ending + the grammar with C{L{StringEnd()}}). + + Note: C{parseString} implicitly calls C{expandtabs()} on the input string, + in order to report proper column numbers in parse actions. + If the input string contains tabs and + the grammar uses parse actions that use the C{loc} argument to index into the + string being parsed, you can ensure you have a consistent view of the input + string by: + - calling C{parseWithTabs} on your grammar before calling C{parseString} + (see L{I{parseWithTabs}}) + - define your parse action using the full C{(s,loc,toks)} signature, and + reference the input string using the parse action's C{s} argument + - explictly expand the tabs in your input string before calling + C{parseString} + """ + ParserElement.resetCache() + if not self.streamlined: + self.streamline() + #~ self.saveAsList = True + for e in self.ignoreExprs: + e.streamline() + if not self.keepTabs: + instring = instring.expandtabs() + try: + loc, tokens = self._parse( instring, 0 ) + if parseAll: + loc = self.preParse( instring, loc ) + se = Empty() + StringEnd() + se._parse( instring, loc ) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + else: + return tokens + + def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ): + """Scan the input string for expression matches. Each match will return the + matching tokens, start location, and end location. May be called with optional + C{maxMatches} argument, to clip scanning after 'n' matches are found. If + C{overlap} is specified, then overlapping matches will be reported. + + Note that the start and end locations are reported relative to the string + being parsed. See L{I{parseString}} for more information on parsing + strings with embedded tabs.""" + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + + if not self.keepTabs: + instring = _ustr(instring).expandtabs() + instrlen = len(instring) + loc = 0 + preparseFn = self.preParse + parseFn = self._parse + ParserElement.resetCache() + matches = 0 + try: + while loc <= instrlen and matches < maxMatches: + try: + preloc = preparseFn( instring, loc ) + nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) + except ParseException: + loc = preloc+1 + else: + if nextLoc > loc: + matches += 1 + yield tokens, preloc, nextLoc + if overlap: + nextloc = preparseFn( instring, loc ) + if nextloc > loc: + loc = nextLoc + else: + loc += 1 + else: + loc = nextLoc + else: + loc = preloc+1 + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def transformString( self, instring ): + """Extension to C{L{scanString}}, to modify matching text with modified tokens that may + be returned from a parse action. To use C{transformString}, define a grammar and + attach a parse action to it that modifies the returned token list. + Invoking C{transformString()} on a target string will then scan for matches, + and replace the matched text patterns according to the logic in the parse + action. C{transformString()} returns the resulting transformed string.""" + out = [] + lastE = 0 + # force preservation of s, to minimize unwanted transformation of string, and to + # keep string locs straight between transformString and scanString + self.keepTabs = True + try: + for t,s,e in self.scanString( instring ): + out.append( instring[lastE:s] ) + if t: + if isinstance(t,ParseResults): + out += t.asList() + elif isinstance(t,list): + out += t + else: + out.append(t) + lastE = e + out.append(instring[lastE:]) + out = [o for o in out if o] + return "".join(map(_ustr,_flatten(out))) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def searchString( self, instring, maxMatches=_MAX_INT ): + """Another extension to C{L{scanString}}, simplifying the access to the tokens found + to match the given parse expression. May be called with optional + C{maxMatches} argument, to clip searching after 'n' matches are found. + """ + try: + return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def __add__(self, other ): + """Implementation of + operator - returns C{L{And}}""" + if isinstance( other, basestring ): + other = ParserElement.literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return And( [ self, other ] ) + + def __radd__(self, other ): + """Implementation of + operator when left operand is not a C{L{ParserElement}}""" + if isinstance( other, basestring ): + other = ParserElement.literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other + self + + def __sub__(self, other): + """Implementation of - operator, returns C{L{And}} with error stop""" + if isinstance( other, basestring ): + other = ParserElement.literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return And( [ self, And._ErrorStop(), other ] ) + + def __rsub__(self, other ): + """Implementation of - operator when left operand is not a C{L{ParserElement}}""" + if isinstance( other, basestring ): + other = ParserElement.literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other - self + + def __mul__(self,other): + """Implementation of * operator, allows use of C{expr * 3} in place of + C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer + tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples + may also include C{None} as in: + - C{expr*(n,None)} or C{expr*(n,)} is equivalent + to C{expr*n + L{ZeroOrMore}(expr)} + (read as "at least n instances of C{expr}") + - C{expr*(None,n)} is equivalent to C{expr*(0,n)} + (read as "0 to n instances of C{expr}") + - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)} + - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)} + + Note that C{expr*(None,n)} does not raise an exception if + more than n exprs exist in the input stream; that is, + C{expr*(None,n)} does not enforce a maximum number of expr + occurrences. If this behavior is desired, then write + C{expr*(None,n) + ~expr} + + """ + if isinstance(other,int): + minElements, optElements = other,0 + elif isinstance(other,tuple): + other = (other + (None, None))[:2] + if other[0] is None: + other = (0, other[1]) + if isinstance(other[0],int) and other[1] is None: + if other[0] == 0: + return ZeroOrMore(self) + if other[0] == 1: + return OneOrMore(self) + else: + return self*other[0] + ZeroOrMore(self) + elif isinstance(other[0],int) and isinstance(other[1],int): + minElements, optElements = other + optElements -= minElements + else: + raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) + else: + raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) + + if minElements < 0: + raise ValueError("cannot multiply ParserElement by negative value") + if optElements < 0: + raise ValueError("second tuple value must be greater or equal to first tuple value") + if minElements == optElements == 0: + raise ValueError("cannot multiply ParserElement by 0 or (0,0)") + + if (optElements): + def makeOptionalList(n): + if n>1: + return Optional(self + makeOptionalList(n-1)) + else: + return Optional(self) + if minElements: + if minElements == 1: + ret = self + makeOptionalList(optElements) + else: + ret = And([self]*minElements) + makeOptionalList(optElements) + else: + ret = makeOptionalList(optElements) + else: + if minElements == 1: + ret = self + else: + ret = And([self]*minElements) + return ret + + def __rmul__(self, other): + return self.__mul__(other) + + def __or__(self, other ): + """Implementation of | operator - returns C{L{MatchFirst}}""" + if isinstance( other, basestring ): + other = ParserElement.literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return MatchFirst( [ self, other ] ) + + def __ror__(self, other ): + """Implementation of | operator when left operand is not a C{L{ParserElement}}""" + if isinstance( other, basestring ): + other = ParserElement.literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other | self + + def __xor__(self, other ): + """Implementation of ^ operator - returns C{L{Or}}""" + if isinstance( other, basestring ): + other = ParserElement.literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Or( [ self, other ] ) + + def __rxor__(self, other ): + """Implementation of ^ operator when left operand is not a C{L{ParserElement}}""" + if isinstance( other, basestring ): + other = ParserElement.literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other ^ self + + def __and__(self, other ): + """Implementation of & operator - returns C{L{Each}}""" + if isinstance( other, basestring ): + other = ParserElement.literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Each( [ self, other ] ) + + def __rand__(self, other ): + """Implementation of & operator when left operand is not a C{L{ParserElement}}""" + if isinstance( other, basestring ): + other = ParserElement.literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other & self + + def __invert__( self ): + """Implementation of ~ operator - returns C{L{NotAny}}""" + return NotAny( self ) + + def __call__(self, name=None): + """Shortcut for C{L{setResultsName}}, with C{listAllMatches=default}:: + userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") + could be written as:: + userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") + + If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be + passed as C{True}. + + If C{name} is omitted, same as calling C{L{copy}}. + """ + if name is not None: + return self.setResultsName(name) + else: + return self.copy() + + def suppress( self ): + """Suppresses the output of this C{ParserElement}; useful to keep punctuation from + cluttering up returned output. + """ + return Suppress( self ) + + def leaveWhitespace( self ): + """Disables the skipping of whitespace before matching the characters in the + C{ParserElement}'s defined pattern. This is normally only used internally by + the pyparsing module, but may be needed in some whitespace-sensitive grammars. + """ + self.skipWhitespace = False + return self + + def setWhitespaceChars( self, chars ): + """Overrides the default whitespace chars + """ + self.skipWhitespace = True + self.whiteChars = chars + self.copyDefaultWhiteChars = False + return self + + def parseWithTabs( self ): + """Overrides default behavior to expand C{}s to spaces before parsing the input string. + Must be called before C{parseString} when the input grammar contains elements that + match C{} characters.""" + self.keepTabs = True + return self + + def ignore( self, other ): + """Define expression to be ignored (e.g., comments) while doing pattern + matching; may be called repeatedly, to define multiple comment or other + ignorable patterns. + """ + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + self.ignoreExprs.append( other.copy() ) + else: + self.ignoreExprs.append( Suppress( other.copy() ) ) + return self + + def setDebugActions( self, startAction, successAction, exceptionAction ): + """Enable display of debugging messages while doing pattern matching.""" + self.debugActions = (startAction or _defaultStartDebugAction, + successAction or _defaultSuccessDebugAction, + exceptionAction or _defaultExceptionDebugAction) + self.debug = True + return self + + def setDebug( self, flag=True ): + """Enable display of debugging messages while doing pattern matching. + Set C{flag} to True to enable, False to disable.""" + if flag: + self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) + else: + self.debug = False + return self + + def __str__( self ): + return self.name + + def __repr__( self ): + return _ustr(self) + + def streamline( self ): + self.streamlined = True + self.strRepr = None + return self + + def checkRecursion( self, parseElementList ): + pass + + def validate( self, validateTrace=[] ): + """Check defined expressions for valid structure, check for infinite recursive definitions.""" + self.checkRecursion( [] ) + + def parseFile( self, file_or_filename, parseAll=False ): + """Execute the parse expression on the given file or filename. + If a filename is specified (instead of a file object), + the entire file is opened, read, and closed before parsing. + """ + try: + file_contents = file_or_filename.read() + except AttributeError: + f = open(file_or_filename, "r") + file_contents = f.read() + f.close() + try: + return self.parseString(file_contents, parseAll) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def __eq__(self,other): + if isinstance(other, ParserElement): + return self is other or self.__dict__ == other.__dict__ + elif isinstance(other, basestring): + try: + self.parseString(_ustr(other), parseAll=True) + return True + except ParseBaseException: + return False + else: + return super(ParserElement,self)==other + + def __ne__(self,other): + return not (self == other) + + def __hash__(self): + return hash(id(self)) + + def __req__(self,other): + return self == other + + def __rne__(self,other): + return not (self == other) + + def runTests(self, tests, parseAll=False): + """Execute the parse expression on a series of test strings, showing each + test, the parsed results or where the parse failed. Quick and easy way to + run a parse expression against a list of sample strings. + + Parameters: + - tests - a list of separate test strings, or a multiline string of test strings + - parseAll - (default=False) - flag to pass to C{L{parseString}} when running tests + """ + if isinstance(tests, basestring): + tests = map(str.strip, tests.splitlines()) + for t in tests: + out = [t] + try: + out.append(self.parseString(t, parseAll=parseAll).dump()) + except ParseException as pe: + if '\n' in t: + out.append(line(pe.loc, t)) + out.append(' '*(col(pe.loc,t)-1) + '^') + else: + out.append(' '*pe.loc + '^') + out.append(str(pe)) + out.append('') + print('\n'.join(out)) + + +class Token(ParserElement): + """Abstract C{ParserElement} subclass, for defining atomic matching patterns.""" + def __init__( self ): + super(Token,self).__init__( savelist=False ) + + +class Empty(Token): + """An empty token, will always match.""" + def __init__( self ): + super(Empty,self).__init__() + self.name = "Empty" + self.mayReturnEmpty = True + self.mayIndexError = False + + +class NoMatch(Token): + """A token that will never match.""" + def __init__( self ): + super(NoMatch,self).__init__() + self.name = "NoMatch" + self.mayReturnEmpty = True + self.mayIndexError = False + self.errmsg = "Unmatchable token" + + def parseImpl( self, instring, loc, doActions=True ): + raise ParseException(instring, loc, self.errmsg, self) + + +class Literal(Token): + """Token to exactly match a specified string.""" + def __init__( self, matchString ): + super(Literal,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Literal; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.__class__ = Empty + self.name = '"%s"' % _ustr(self.match) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + + # Performance tuning: this routine gets called a *lot* + # if this is a single character match string and the first character matches, + # short-circuit as quickly as possible, and avoid calling startswith + #~ @profile + def parseImpl( self, instring, loc, doActions=True ): + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) +_L = Literal +ParserElement.literalStringClass = Literal + +class Keyword(Token): + """Token to exactly match a specified string as a keyword, that is, it must be + immediately followed by a non-keyword character. Compare with C{L{Literal}}:: + Literal("if") will match the leading C{'if'} in C{'ifAndOnlyIf'}. + Keyword("if") will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'} + Accepts two optional constructor arguments in addition to the keyword string: + C{identChars} is a string of characters that would be valid identifier characters, + defaulting to all alphanumerics + "_" and "$"; C{caseless} allows case-insensitive + matching, default is C{False}. + """ + DEFAULT_KEYWORD_CHARS = alphanums+"_$" + + def __init__( self, matchString, identChars=DEFAULT_KEYWORD_CHARS, caseless=False ): + super(Keyword,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Keyword; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.name = '"%s"' % self.match + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + self.caseless = caseless + if caseless: + self.caselessmatch = matchString.upper() + identChars = identChars.upper() + self.identChars = set(identChars) + + def parseImpl( self, instring, loc, doActions=True ): + if self.caseless: + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and + (loc == 0 or instring[loc-1].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + else: + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and + (loc == 0 or instring[loc-1] not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + + def copy(self): + c = super(Keyword,self).copy() + c.identChars = Keyword.DEFAULT_KEYWORD_CHARS + return c + + @staticmethod + def setDefaultKeywordChars( chars ): + """Overrides the default Keyword chars + """ + Keyword.DEFAULT_KEYWORD_CHARS = chars + +class CaselessLiteral(Literal): + """Token to match a specified string, ignoring case of letters. + Note: the matched results will always be in the case of the given + match string, NOT the case of the input text. + """ + def __init__( self, matchString ): + super(CaselessLiteral,self).__init__( matchString.upper() ) + # Preserve the defining literal. + self.returnString = matchString + self.name = "'%s'" % self.returnString + self.errmsg = "Expected " + self.name + + def parseImpl( self, instring, loc, doActions=True ): + if instring[ loc:loc+self.matchLen ].upper() == self.match: + return loc+self.matchLen, self.returnString + raise ParseException(instring, loc, self.errmsg, self) + +class CaselessKeyword(Keyword): + def __init__( self, matchString, identChars=Keyword.DEFAULT_KEYWORD_CHARS ): + super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) + + def parseImpl( self, instring, loc, doActions=True ): + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + +class Word(Token): + """Token for matching words composed of allowed character sets. + Defined with string containing all allowed initial characters, + an optional string containing allowed body characters (if omitted, + defaults to the initial character set), and an optional minimum, + maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. An optional + C{exclude} parameter can list characters that might be found in + the input C{bodyChars} string; useful to define a word of all printables + except for one or two characters, for instance. + """ + def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ): + super(Word,self).__init__() + if excludeChars: + initChars = ''.join(c for c in initChars if c not in excludeChars) + if bodyChars: + bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) + self.initCharsOrig = initChars + self.initChars = set(initChars) + if bodyChars : + self.bodyCharsOrig = bodyChars + self.bodyChars = set(bodyChars) + else: + self.bodyCharsOrig = initChars + self.bodyChars = set(initChars) + + self.maxSpecified = max > 0 + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.asKeyword = asKeyword + + if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): + if self.bodyCharsOrig == self.initCharsOrig: + self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) + elif len(self.initCharsOrig) == 1: + self.reString = "%s[%s]*" % \ + (re.escape(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + else: + self.reString = "[%s][%s]*" % \ + (_escapeRegexRangeChars(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + if self.asKeyword: + self.reString = r"\b"+self.reString+r"\b" + try: + self.re = re.compile( self.reString ) + except: + self.re = None + + def parseImpl( self, instring, loc, doActions=True ): + if self.re: + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + return loc, result.group() + + if not(instring[ loc ] in self.initChars): + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + instrlen = len(instring) + bodychars = self.bodyChars + maxloc = start + self.maxLen + maxloc = min( maxloc, instrlen ) + while loc < maxloc and instring[loc] in bodychars: + loc += 1 + + throwException = False + if loc - start < self.minLen: + throwException = True + if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: + throwException = True + if self.asKeyword: + if (start>0 and instring[start-1] in bodychars) or (loc4: + return s[:4]+"..." + else: + return s + + if ( self.initCharsOrig != self.bodyCharsOrig ): + self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) + else: + self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) + + return self.strRepr + + +class Regex(Token): + """Token for matching strings that match a given regular expression. + Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. + """ + compiledREtype = type(re.compile("[A-Z]")) + def __init__( self, pattern, flags=0): + """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags.""" + super(Regex,self).__init__() + + if isinstance(pattern, basestring): + if len(pattern) == 0: + warnings.warn("null string passed to Regex; use Empty() instead", + SyntaxWarning, stacklevel=2) + + self.pattern = pattern + self.flags = flags + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % pattern, + SyntaxWarning, stacklevel=2) + raise + + elif isinstance(pattern, Regex.compiledREtype): + self.re = pattern + self.pattern = \ + self.reString = str(pattern) + self.flags = flags + + else: + raise ValueError("Regex may only be constructed with a string or a compiled RE object") + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + d = result.groupdict() + ret = ParseResults(result.group()) + if d: + for k in d: + ret[k] = d[k] + return loc,ret + + def __str__( self ): + try: + return super(Regex,self).__str__() + except: + pass + + if self.strRepr is None: + self.strRepr = "Re:(%s)" % repr(self.pattern) + + return self.strRepr + + +class QuotedString(Token): + """Token for matching strings that are delimited by quoting characters. + """ + def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None): + """ + Defined with the following parameters: + - quoteChar - string of one or more characters defining the quote delimiting string + - escChar - character to escape quotes, typically backslash (default=None) + - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=None) + - multiline - boolean indicating whether quotes can span multiple lines (default=C{False}) + - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True}) + - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar) + """ + super(QuotedString,self).__init__() + + # remove white space from quote chars - wont work anyway + quoteChar = quoteChar.strip() + if len(quoteChar) == 0: + warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + if endQuoteChar is None: + endQuoteChar = quoteChar + else: + endQuoteChar = endQuoteChar.strip() + if len(endQuoteChar) == 0: + warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + self.quoteChar = quoteChar + self.quoteCharLen = len(quoteChar) + self.firstQuoteChar = quoteChar[0] + self.endQuoteChar = endQuoteChar + self.endQuoteCharLen = len(endQuoteChar) + self.escChar = escChar + self.escQuote = escQuote + self.unquoteResults = unquoteResults + + if multiline: + self.flags = re.MULTILINE | re.DOTALL + self.pattern = r'%s(?:[^%s%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + else: + self.flags = 0 + self.pattern = r'%s(?:[^%s\n\r%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + if len(self.endQuoteChar) > 1: + self.pattern += ( + '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]), + _escapeRegexRangeChars(self.endQuoteChar[i])) + for i in range(len(self.endQuoteChar)-1,0,-1)) + ')' + ) + if escQuote: + self.pattern += (r'|(?:%s)' % re.escape(escQuote)) + if escChar: + self.pattern += (r'|(?:%s.)' % re.escape(escChar)) + self.escCharReplacePattern = re.escape(self.escChar)+"(.)" + self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, + SyntaxWarning, stacklevel=2) + raise + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = result.group() + + if self.unquoteResults: + + # strip off quotes + ret = ret[self.quoteCharLen:-self.endQuoteCharLen] + + if isinstance(ret,basestring): + # replace escaped characters + if self.escChar: + ret = re.sub(self.escCharReplacePattern,"\g<1>",ret) + + # replace escaped quotes + if self.escQuote: + ret = ret.replace(self.escQuote, self.endQuoteChar) + + return loc, ret + + def __str__( self ): + try: + return super(QuotedString,self).__str__() + except: + pass + + if self.strRepr is None: + self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) + + return self.strRepr + + +class CharsNotIn(Token): + """Token for matching words composed of characters *not* in a given set. + Defined with string containing all disallowed characters, and an optional + minimum, maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. + """ + def __init__( self, notChars, min=1, max=0, exact=0 ): + super(CharsNotIn,self).__init__() + self.skipWhitespace = False + self.notChars = notChars + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = ( self.minLen == 0 ) + self.mayIndexError = False + + def parseImpl( self, instring, loc, doActions=True ): + if instring[loc] in self.notChars: + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + notchars = self.notChars + maxlen = min( start+self.maxLen, len(instring) ) + while loc < maxlen and \ + (instring[loc] not in notchars): + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(CharsNotIn, self).__str__() + except: + pass + + if self.strRepr is None: + if len(self.notChars) > 4: + self.strRepr = "!W:(%s...)" % self.notChars[:4] + else: + self.strRepr = "!W:(%s)" % self.notChars + + return self.strRepr + +class White(Token): + """Special matching class for matching whitespace. Normally, whitespace is ignored + by pyparsing grammars. This class is included when some whitespace structures + are significant. Define with a string containing the whitespace characters to be + matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, + as defined for the C{L{Word}} class.""" + whiteStrs = { + " " : "", + "\t": "", + "\n": "", + "\r": "", + "\f": "", + } + def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): + super(White,self).__init__() + self.matchWhite = ws + self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) ) + #~ self.leaveWhitespace() + self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) + self.mayReturnEmpty = True + self.errmsg = "Expected " + self.name + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + def parseImpl( self, instring, loc, doActions=True ): + if not(instring[ loc ] in self.matchWhite): + raise ParseException(instring, loc, self.errmsg, self) + start = loc + loc += 1 + maxloc = start + self.maxLen + maxloc = min( maxloc, len(instring) ) + while loc < maxloc and instring[loc] in self.matchWhite: + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + +class _PositionToken(Token): + def __init__( self ): + super(_PositionToken,self).__init__() + self.name=self.__class__.__name__ + self.mayReturnEmpty = True + self.mayIndexError = False + +class GoToColumn(_PositionToken): + """Token to advance to a specific column of input text; useful for tabular report scraping.""" + def __init__( self, colno ): + super(GoToColumn,self).__init__() + self.col = colno + + def preParse( self, instring, loc ): + if col(loc,instring) != self.col: + instrlen = len(instring) + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : + loc += 1 + return loc + + def parseImpl( self, instring, loc, doActions=True ): + thiscol = col( loc, instring ) + if thiscol > self.col: + raise ParseException( instring, loc, "Text not in expected column", self ) + newloc = loc + self.col - thiscol + ret = instring[ loc: newloc ] + return newloc, ret + +class LineStart(_PositionToken): + """Matches if current position is at the beginning of a line within the parse string""" + def __init__( self ): + super(LineStart,self).__init__() + self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) + self.errmsg = "Expected start of line" + + def preParse( self, instring, loc ): + preloc = super(LineStart,self).preParse(instring,loc) + if instring[preloc] == "\n": + loc += 1 + return loc + + def parseImpl( self, instring, loc, doActions=True ): + if not( loc==0 or + (loc == self.preParse( instring, 0 )) or + (instring[loc-1] == "\n") ): #col(loc, instring) != 1: + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class LineEnd(_PositionToken): + """Matches if current position is at the end of a line within the parse string""" + def __init__( self ): + super(LineEnd,self).__init__() + self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) + self.errmsg = "Expected end of line" + + def parseImpl( self, instring, loc, doActions=True ): + if loc len(instring): + return loc, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class WordStart(_PositionToken): + """Matches if the current position is at the beginning of a Word, and + is not preceded by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of + the string being parsed, or at the beginning of a line. + """ + def __init__(self, wordChars = printables): + super(WordStart,self).__init__() + self.wordChars = set(wordChars) + self.errmsg = "Not at the start of a word" + + def parseImpl(self, instring, loc, doActions=True ): + if loc != 0: + if (instring[loc-1] in self.wordChars or + instring[loc] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class WordEnd(_PositionToken): + """Matches if the current position is at the end of a Word, and + is not followed by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of + the string being parsed, or at the end of a line. + """ + def __init__(self, wordChars = printables): + super(WordEnd,self).__init__() + self.wordChars = set(wordChars) + self.skipWhitespace = False + self.errmsg = "Not at the end of a word" + + def parseImpl(self, instring, loc, doActions=True ): + instrlen = len(instring) + if instrlen>0 and loc maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + else: + # save match among all matches, to retry longest to shortest + matches.append((loc2, e)) + + if matches: + matches.sort(key=lambda x: -x[0]) + for _,e in matches: + try: + return e._parse( instring, loc, doActions ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + + def __ixor__(self, other ): + if isinstance( other, basestring ): + other = ParserElement.literalStringClass( other ) + return self.append( other ) #Or( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class MatchFirst(ParseExpression): + """Requires that at least one C{ParseExpression} is found. + If two expressions match, the first one listed is the one that will match. + May be constructed using the C{'|'} operator. + """ + def __init__( self, exprs, savelist = False ): + super(MatchFirst,self).__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + for e in self.exprs: + try: + ret = e._parse( instring, loc, doActions ) + return ret + except ParseException as err: + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + + # only got here if no expression matched, raise exception for match that made it the furthest + else: + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + def __ior__(self, other ): + if isinstance( other, basestring ): + other = ParserElement.literalStringClass( other ) + return self.append( other ) #MatchFirst( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class Each(ParseExpression): + """Requires all given C{ParseExpression}s to be found, but in any order. + Expressions may be separated by whitespace. + May be constructed using the C{'&'} operator. + """ + def __init__( self, exprs, savelist = True ): + super(Each,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.skipWhitespace = True + self.initExprGroups = True + + def parseImpl( self, instring, loc, doActions=True ): + if self.initExprGroups: + self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional)) + opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ] + opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)] + self.optionals = opt1 + opt2 + self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] + self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] + self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] + self.required += self.multirequired + self.initExprGroups = False + tmpLoc = loc + tmpReqd = self.required[:] + tmpOpt = self.optionals[:] + matchOrder = [] + + keepMatching = True + while keepMatching: + tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired + failed = [] + for e in tmpExprs: + try: + tmpLoc = e.tryParse( instring, tmpLoc ) + except ParseException: + failed.append(e) + else: + matchOrder.append(self.opt1map.get(id(e),e)) + if e in tmpReqd: + tmpReqd.remove(e) + elif e in tmpOpt: + tmpOpt.remove(e) + if len(failed) == len(tmpExprs): + keepMatching = False + + if tmpReqd: + missing = ", ".join(_ustr(e) for e in tmpReqd) + raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) + + # add any unmatched Optionals, in case they have default values defined + matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt] + + resultlist = [] + for e in matchOrder: + loc,results = e._parse(instring,loc,doActions) + resultlist.append(results) + + finalResults = ParseResults([]) + for r in resultlist: + dups = {} + for k in r.keys(): + if k in finalResults: + tmp = ParseResults(finalResults[k]) + tmp += ParseResults(r[k]) + dups[k] = tmp + finalResults += ParseResults(r) + for k,v in dups.items(): + finalResults[k] = v + return loc, finalResults + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class ParseElementEnhance(ParserElement): + """Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens.""" + def __init__( self, expr, savelist=False ): + super(ParseElementEnhance,self).__init__(savelist) + if isinstance( expr, basestring ): + expr = Literal(expr) + self.expr = expr + self.strRepr = None + if expr is not None: + self.mayIndexError = expr.mayIndexError + self.mayReturnEmpty = expr.mayReturnEmpty + self.setWhitespaceChars( expr.whiteChars ) + self.skipWhitespace = expr.skipWhitespace + self.saveAsList = expr.saveAsList + self.callPreparse = expr.callPreparse + self.ignoreExprs.extend(expr.ignoreExprs) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr is not None: + return self.expr._parse( instring, loc, doActions, callPreParse=False ) + else: + raise ParseException("",loc,self.errmsg,self) + + def leaveWhitespace( self ): + self.skipWhitespace = False + self.expr = self.expr.copy() + if self.expr is not None: + self.expr.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + else: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + return self + + def streamline( self ): + super(ParseElementEnhance,self).streamline() + if self.expr is not None: + self.expr.streamline() + return self + + def checkRecursion( self, parseElementList ): + if self in parseElementList: + raise RecursiveGrammarException( parseElementList+[self] ) + subRecCheckList = parseElementList[:] + [ self ] + if self.expr is not None: + self.expr.checkRecursion( subRecCheckList ) + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion( [] ) + + def __str__( self ): + try: + return super(ParseElementEnhance,self).__str__() + except: + pass + + if self.strRepr is None and self.expr is not None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) + return self.strRepr + + +class FollowedBy(ParseElementEnhance): + """Lookahead matching of the given parse expression. C{FollowedBy} + does *not* advance the parsing position within the input string, it only + verifies that the specified parse expression matches at the current + position. C{FollowedBy} always returns a null token list.""" + def __init__( self, expr ): + super(FollowedBy,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + self.expr.tryParse( instring, loc ) + return loc, [] + + +class NotAny(ParseElementEnhance): + """Lookahead to disallow matching with the given parse expression. C{NotAny} + does *not* advance the parsing position within the input string, it only + verifies that the specified parse expression does *not* match at the current + position. Also, C{NotAny} does *not* skip over leading whitespace. C{NotAny} + always returns a null token list. May be constructed using the '~' operator.""" + def __init__( self, expr ): + super(NotAny,self).__init__(expr) + #~ self.leaveWhitespace() + self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs + self.mayReturnEmpty = True + self.errmsg = "Found unwanted token, "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + try: + self.expr.tryParse( instring, loc ) + except (ParseException,IndexError): + pass + else: + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "~{" + _ustr(self.expr) + "}" + + return self.strRepr + + +class ZeroOrMore(ParseElementEnhance): + """Optional repetition of zero or more of the given expression.""" + def __init__( self, expr ): + super(ZeroOrMore,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + tokens = [] + try: + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + hasIgnoreExprs = ( len(self.ignoreExprs) > 0 ) + while 1: + if hasIgnoreExprs: + preloc = self._skipIgnorables( instring, loc ) + else: + preloc = loc + loc, tmptokens = self.expr._parse( instring, preloc, doActions ) + if tmptokens or tmptokens.haskeys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]..." + + return self.strRepr + + def setResultsName( self, name, listAllMatches=False ): + ret = super(ZeroOrMore,self).setResultsName(name,listAllMatches) + ret.saveAsList = True + return ret + + +class OneOrMore(ParseElementEnhance): + """Repetition of one or more of the given expression.""" + def parseImpl( self, instring, loc, doActions=True ): + # must be at least one + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + try: + hasIgnoreExprs = ( len(self.ignoreExprs) > 0 ) + while 1: + if hasIgnoreExprs: + preloc = self._skipIgnorables( instring, loc ) + else: + preloc = loc + loc, tmptokens = self.expr._parse( instring, preloc, doActions ) + if tmptokens or tmptokens.haskeys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + _ustr(self.expr) + "}..." + + return self.strRepr + + def setResultsName( self, name, listAllMatches=False ): + ret = super(OneOrMore,self).setResultsName(name,listAllMatches) + ret.saveAsList = True + return ret + +class _NullToken(object): + def __bool__(self): + return False + __nonzero__ = __bool__ + def __str__(self): + return "" + +_optionalNotMatched = _NullToken() +class Optional(ParseElementEnhance): + """Optional matching of the given expression. + A default return string can also be specified, if the optional expression + is not found. + """ + def __init__( self, expr, default=_optionalNotMatched ): + super(Optional,self).__init__( expr, savelist=False ) + self.defaultValue = default + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + except (ParseException,IndexError): + if self.defaultValue is not _optionalNotMatched: + if self.expr.resultsName: + tokens = ParseResults([ self.defaultValue ]) + tokens[self.expr.resultsName] = self.defaultValue + else: + tokens = [ self.defaultValue ] + else: + tokens = [] + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]" + + return self.strRepr + + +class SkipTo(ParseElementEnhance): + """Token for skipping over all undefined text until the matched expression is found. + If C{include} is set to true, the matched expression is also parsed (the skipped text + and matched expression are returned as a 2-element list). The C{ignore} + argument is used to define grammars (typically quoted strings and comments) that + might contain false matches. + """ + def __init__( self, other, include=False, ignore=None, failOn=None ): + super( SkipTo, self ).__init__( other ) + self.ignoreExpr = ignore + self.mayReturnEmpty = True + self.mayIndexError = False + self.includeMatch = include + self.asList = False + if failOn is not None and isinstance(failOn, basestring): + self.failOn = Literal(failOn) + else: + self.failOn = failOn + self.errmsg = "No match found for "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + startLoc = loc + instrlen = len(instring) + expr = self.expr + failParse = False + while loc <= instrlen: + try: + if self.failOn: + try: + self.failOn.tryParse(instring, loc) + except ParseBaseException: + pass + else: + failParse = True + raise ParseException(instring, loc, "Found expression " + str(self.failOn)) + failParse = False + if self.ignoreExpr is not None: + while 1: + try: + loc = self.ignoreExpr.tryParse(instring,loc) + # print("found ignoreExpr, advance to", loc) + except ParseBaseException: + break + expr._parse( instring, loc, doActions=False, callPreParse=False ) + skipText = instring[startLoc:loc] + if self.includeMatch: + loc,mat = expr._parse(instring,loc,doActions,callPreParse=False) + if mat: + skipRes = ParseResults( skipText ) + skipRes += mat + return loc, [ skipRes ] + else: + return loc, [ skipText ] + else: + return loc, [ skipText ] + except (ParseException,IndexError): + if failParse: + raise + else: + loc += 1 + raise ParseException(instring, loc, self.errmsg, self) + +class Forward(ParseElementEnhance): + """Forward declaration of an expression to be defined later - + used for recursive grammars, such as algebraic infix notation. + When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. + + Note: take care when assigning to C{Forward} not to overlook precedence of operators. + Specifically, '|' has a lower precedence than '<<', so that:: + fwdExpr << a | b | c + will actually be evaluated as:: + (fwdExpr << a) | b | c + thereby leaving b and c out as parseable alternatives. It is recommended that you + explicitly group the values inserted into the C{Forward}:: + fwdExpr << (a | b | c) + Converting to use the '<<=' operator instead will avoid this problem. + """ + def __init__( self, other=None ): + super(Forward,self).__init__( other, savelist=False ) + + def __lshift__( self, other ): + if isinstance( other, basestring ): + other = ParserElement.literalStringClass(other) + self.expr = other + self.mayReturnEmpty = other.mayReturnEmpty + self.strRepr = None + self.mayIndexError = self.expr.mayIndexError + self.mayReturnEmpty = self.expr.mayReturnEmpty + self.setWhitespaceChars( self.expr.whiteChars ) + self.skipWhitespace = self.expr.skipWhitespace + self.saveAsList = self.expr.saveAsList + self.ignoreExprs.extend(self.expr.ignoreExprs) + return self + + def __ilshift__(self, other): + return self << other + + def leaveWhitespace( self ): + self.skipWhitespace = False + return self + + def streamline( self ): + if not self.streamlined: + self.streamlined = True + if self.expr is not None: + self.expr.streamline() + return self + + def validate( self, validateTrace=[] ): + if self not in validateTrace: + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion([]) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + self._revertClass = self.__class__ + self.__class__ = _ForwardNoRecurse + try: + if self.expr is not None: + retString = _ustr(self.expr) + else: + retString = "None" + finally: + self.__class__ = self._revertClass + return self.__class__.__name__ + ": " + retString + + def copy(self): + if self.expr is not None: + return super(Forward,self).copy() + else: + ret = Forward() + ret <<= self + return ret + +class _ForwardNoRecurse(Forward): + def __str__( self ): + return "..." + +class TokenConverter(ParseElementEnhance): + """Abstract subclass of C{ParseExpression}, for converting parsed results.""" + def __init__( self, expr, savelist=False ): + super(TokenConverter,self).__init__( expr )#, savelist ) + self.saveAsList = False + +class Upcase(TokenConverter): + """Converter to upper case all matching tokens.""" + def __init__(self, *args): + super(Upcase,self).__init__(*args) + warnings.warn("Upcase class is deprecated, use upcaseTokens parse action instead", + DeprecationWarning,stacklevel=2) + + def postParse( self, instring, loc, tokenlist ): + return list(map( str.upper, tokenlist )) + + +class Combine(TokenConverter): + """Converter to concatenate all matching tokens to a single string. + By default, the matching patterns must also be contiguous in the input string; + this can be disabled by specifying C{'adjacent=False'} in the constructor. + """ + def __init__( self, expr, joinString="", adjacent=True ): + super(Combine,self).__init__( expr ) + # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself + if adjacent: + self.leaveWhitespace() + self.adjacent = adjacent + self.skipWhitespace = True + self.joinString = joinString + self.callPreparse = True + + def ignore( self, other ): + if self.adjacent: + ParserElement.ignore(self, other) + else: + super( Combine, self).ignore( other ) + return self + + def postParse( self, instring, loc, tokenlist ): + retToks = tokenlist.copy() + del retToks[:] + retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) + + if self.resultsName and retToks.haskeys(): + return [ retToks ] + else: + return retToks + +class Group(TokenConverter): + """Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions.""" + def __init__( self, expr ): + super(Group,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + return [ tokenlist ] + +class Dict(TokenConverter): + """Converter to return a repetitive expression as a list, but also as a dictionary. + Each element can also be referenced using the first token in the expression as its key. + Useful for tabular report scraping when the first column can be used as a item key. + """ + def __init__( self, expr ): + super(Dict,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + for i,tok in enumerate(tokenlist): + if len(tok) == 0: + continue + ikey = tok[0] + if isinstance(ikey,int): + ikey = _ustr(tok[0]).strip() + if len(tok)==1: + tokenlist[ikey] = _ParseResultsWithOffset("",i) + elif len(tok)==2 and not isinstance(tok[1],ParseResults): + tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) + else: + dictvalue = tok.copy() #ParseResults(i) + del dictvalue[0] + if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) + else: + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) + + if self.resultsName: + return [ tokenlist ] + else: + return tokenlist + + +class Suppress(TokenConverter): + """Converter for ignoring the results of a parsed expression.""" + def postParse( self, instring, loc, tokenlist ): + return [] + + def suppress( self ): + return self + + +class OnlyOnce(object): + """Wrapper for parse actions, to ensure they are only called once.""" + def __init__(self, methodCall): + self.callable = _trim_arity(methodCall) + self.called = False + def __call__(self,s,l,t): + if not self.called: + results = self.callable(s,l,t) + self.called = True + return results + raise ParseException(s,l,"") + def reset(self): + self.called = False + +def traceParseAction(f): + """Decorator for debugging parse actions.""" + f = _trim_arity(f) + def z(*paArgs): + thisFunc = f.func_name + s,l,t = paArgs[-3:] + if len(paArgs)>3: + thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc + sys.stderr.write( ">>entering %s(line: '%s', %d, %s)\n" % (thisFunc,line(l,s),l,t) ) + try: + ret = f(*paArgs) + except Exception as exc: + sys.stderr.write( "<", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) + try: + if len(symbols)==len("".join(symbols)): + return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ) + else: + return Regex( "|".join(re.escape(sym) for sym in symbols) ) + except: + warnings.warn("Exception creating Regex for oneOf, building MatchFirst", + SyntaxWarning, stacklevel=2) + + + # last resort, just use MatchFirst + return MatchFirst( [ parseElementClass(sym) for sym in symbols ] ) + +def dictOf( key, value ): + """Helper to easily and clearly define a dictionary by specifying the respective patterns + for the key and value. Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens + in the proper order. The key pattern can include delimiting markers or punctuation, + as long as they are suppressed, thereby leaving the significant key text. The value + pattern can include named results, so that the C{Dict} results can include named token + fields. + """ + return Dict( ZeroOrMore( Group ( key + value ) ) ) + +def originalTextFor(expr, asString=True): + """Helper to return the original, untokenized text for a given expression. Useful to + restore the parsed fields of an HTML start tag into the raw tag text itself, or to + revert separate tokens with intervening whitespace back to the original matching + input text. Simpler to use than the parse action C{L{keepOriginalText}}, and does not + require the inspect module to chase up the call stack. By default, returns a + string containing the original parsed text. + + If the optional C{asString} argument is passed as C{False}, then the return value is a + C{L{ParseResults}} containing any results names that were originally matched, and a + single token containing the original matched text from the input string. So if + the expression passed to C{L{originalTextFor}} contains expressions with defined + results names, you must set C{asString} to C{False} if you want to preserve those + results name values.""" + locMarker = Empty().setParseAction(lambda s,loc,t: loc) + endlocMarker = locMarker.copy() + endlocMarker.callPreparse = False + matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") + if asString: + extractText = lambda s,l,t: s[t._original_start:t._original_end] + else: + def extractText(s,l,t): + del t[:] + t.insert(0, s[t._original_start:t._original_end]) + del t["_original_start"] + del t["_original_end"] + matchExpr.setParseAction(extractText) + return matchExpr + +def ungroup(expr): + """Helper to undo pyparsing's default grouping of And expressions, even + if all but one are non-empty.""" + return TokenConverter(expr).setParseAction(lambda t:t[0]) + +def locatedExpr(expr): + """Helper to decorate a returned token with its starting and ending locations in the input string. + This helper adds the following results names: + - locn_start = location where matched expression begins + - locn_end = location where matched expression ends + - value = the actual parsed results + + Be careful if the input text contains C{} characters, you may want to call + C{L{ParserElement.parseWithTabs}} + """ + locator = Empty().setParseAction(lambda s,l,t: l) + return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) + + +# convenience constants for positional expressions +empty = Empty().setName("empty") +lineStart = LineStart().setName("lineStart") +lineEnd = LineEnd().setName("lineEnd") +stringStart = StringStart().setName("stringStart") +stringEnd = StringEnd().setName("stringEnd") + +_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) +_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16))) +_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8))) +_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(printables, excludeChars=r'\]', exact=1) | Regex(r"\w", re.UNICODE) +_charRange = Group(_singleChar + Suppress("-") + _singleChar) +_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" + +def srange(s): + r"""Helper to easily define string ranges for use in Word construction. Borrows + syntax from regexp '[]' string range definitions:: + srange("[0-9]") -> "0123456789" + srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" + srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" + The input string must be enclosed in []'s, and the returned string is the expanded + character set joined into a single string. + The values enclosed in the []'s may be:: + a single character + an escaped character with a leading backslash (such as \- or \]) + an escaped hex character with a leading '\x' (\x21, which is a '!' character) + (\0x## is also supported for backwards compatibility) + an escaped octal character with a leading '\0' (\041, which is a '!' character) + a range of any of the above, separated by a dash ('a-z', etc.) + any combination of the above ('aeiouy', 'a-zA-Z0-9_$', etc.) + """ + _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1)) + try: + return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) + except: + return "" + +def matchOnlyAtCol(n): + """Helper method for defining parse actions that require matching at a specific + column in the input text. + """ + def verifyCol(strg,locn,toks): + if col(locn,strg) != n: + raise ParseException(strg,locn,"matched token not at column %d" % n) + return verifyCol + +def replaceWith(replStr): + """Helper method for common parse actions that simply return a literal value. Especially + useful when used with C{L{transformString}()}. + """ + #def _replFunc(*args): + # return [replStr] + #return _replFunc + return functools.partial(next, itertools.repeat([replStr])) + +def removeQuotes(s,l,t): + """Helper parse action for removing quotation marks from parsed quoted strings. + To use, add this parse action to quoted string using:: + quotedString.setParseAction( removeQuotes ) + """ + return t[0][1:-1] + +def upcaseTokens(s,l,t): + """Helper parse action to convert tokens to upper case.""" + return [ tt.upper() for tt in map(_ustr,t) ] + +def downcaseTokens(s,l,t): + """Helper parse action to convert tokens to lower case.""" + return [ tt.lower() for tt in map(_ustr,t) ] + +def keepOriginalText(s,startLoc,t): + """DEPRECATED - use new helper method C{L{originalTextFor}}. + Helper parse action to preserve original parsed text, + overriding any nested parse actions.""" + try: + endloc = getTokensEndLoc() + except ParseException: + raise ParseFatalException("incorrect usage of keepOriginalText - may only be called as a parse action") + del t[:] + t += ParseResults(s[startLoc:endloc]) + return t + +def getTokensEndLoc(): + """Method to be called from within a parse action to determine the end + location of the parsed tokens.""" + import inspect + fstack = inspect.stack() + try: + # search up the stack (through intervening argument normalizers) for correct calling routine + for f in fstack[2:]: + if f[3] == "_parseNoCache": + endloc = f[0].f_locals["loc"] + return endloc + else: + raise ParseFatalException("incorrect usage of getTokensEndLoc - may only be called from within a parse action") + finally: + del fstack + +def _makeTags(tagStr, xml): + """Internal helper to construct opening and closing tag expressions, given a tag name""" + if isinstance(tagStr,basestring): + resname = tagStr + tagStr = Keyword(tagStr, caseless=not xml) + else: + resname = tagStr.name + + tagAttrName = Word(alphas,alphanums+"_-:") + if (xml): + tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + else: + printablesLessRAbrack = "".join(c for c in printables if c not in ">") + tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ + Optional( Suppress("=") + tagAttrValue ) ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + closeTag = Combine(_L("") + + openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % tagStr) + closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("" % tagStr) + openTag.tag = resname + closeTag.tag = resname + return openTag, closeTag + +def makeHTMLTags(tagStr): + """Helper to construct opening and closing tag expressions for HTML, given a tag name""" + return _makeTags( tagStr, False ) + +def makeXMLTags(tagStr): + """Helper to construct opening and closing tag expressions for XML, given a tag name""" + return _makeTags( tagStr, True ) + +def withAttribute(*args,**attrDict): + """Helper to create a validating parse action to be used with start tags created + with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag + with a required attribute value, to avoid false matches on common tags such as + C{} or C{
}. + + Call C{withAttribute} with a series of attribute names and values. Specify the list + of filter attributes names and values as: + - keyword arguments, as in C{(align="right")}, or + - as an explicit dict with C{**} operator, when an attribute name is also a Python + reserved word, as in C{**{"class":"Customer", "align":"right"}} + - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) + For attribute names with a namespace prefix, you must use the second form. Attribute + names are matched insensitive to upper/lower case. + + If just testing for C{class} (with or without a namespace), use C{L{withClass}}. + + To verify that the attribute exists, but without specifying a value, pass + C{withAttribute.ANY_VALUE} as the value. + """ + if args: + attrs = args[:] + else: + attrs = attrDict.items() + attrs = [(k,v) for k,v in attrs] + def pa(s,l,tokens): + for attrName,attrValue in attrs: + if attrName not in tokens: + raise ParseException(s,l,"no matching attribute " + attrName) + if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: + raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % + (attrName, tokens[attrName], attrValue)) + return pa +withAttribute.ANY_VALUE = object() + +def withClass(classname, namespace=''): + """Simplified version of C{L{withAttribute}} when matching on a div class - made + difficult because C{class} is a reserved word in Python. + """ + classattr = "%s:class" % namespace if namespace else "class" + return withAttribute(**{classattr : classname}) + +opAssoc = _Constants() +opAssoc.LEFT = object() +opAssoc.RIGHT = object() + +def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): + """Helper method for constructing grammars of expressions made up of + operators working in a precedence hierarchy. Operators may be unary or + binary, left- or right-associative. Parse actions can also be attached + to operator expressions. + + Parameters: + - baseExpr - expression representing the most basic element for the nested + - opList - list of tuples, one for each operator precedence level in the + expression grammar; each tuple is of the form + (opExpr, numTerms, rightLeftAssoc, parseAction), where: + - opExpr is the pyparsing expression for the operator; + may also be a string, which will be converted to a Literal; + if numTerms is 3, opExpr is a tuple of two expressions, for the + two operators separating the 3 terms + - numTerms is the number of terms for this operator (must + be 1, 2, or 3) + - rightLeftAssoc is the indicator whether the operator is + right or left associative, using the pyparsing-defined + constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. + - parseAction is the parse action to be associated with + expressions matching this operator expression (the + parse action tuple member may be omitted) + - lpar - expression for matching left-parentheses (default=Suppress('(')) + - rpar - expression for matching right-parentheses (default=Suppress(')')) + """ + ret = Forward() + lastExpr = baseExpr | ( lpar + ret + rpar ) + for i,operDef in enumerate(opList): + opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] + if arity == 3: + if opExpr is None or len(opExpr) != 2: + raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") + opExpr1, opExpr2 = opExpr + thisExpr = Forward()#.setName("expr%d" % i) + if rightLeftAssoc == opAssoc.LEFT: + if arity == 1: + matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) + else: + matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ + Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + elif rightLeftAssoc == opAssoc.RIGHT: + if arity == 1: + # try to avoid LR with this extra test + if not isinstance(opExpr, Optional): + opExpr = Optional(opExpr) + matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) + else: + matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ + Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + else: + raise ValueError("operator must indicate right or left associativity") + if pa: + matchExpr.setParseAction( pa ) + thisExpr <<= ( matchExpr | lastExpr ) + lastExpr = thisExpr + ret <<= lastExpr + return ret +operatorPrecedence = infixNotation + +dblQuotedString = Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\x[0-9a-fA-F]+)|(?:\\.))*"').setName("string enclosed in double quotes") +sglQuotedString = Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\x[0-9a-fA-F]+)|(?:\\.))*'").setName("string enclosed in single quotes") +quotedString = Regex(r'''(?:"(?:[^"\n\r\\]|(?:"")|(?:\\x[0-9a-fA-F]+)|(?:\\.))*")|(?:'(?:[^'\n\r\\]|(?:'')|(?:\\x[0-9a-fA-F]+)|(?:\\.))*')''').setName("quotedString using single or double quotes") +unicodeString = Combine(_L('u') + quotedString.copy()) + +def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): + """Helper method for defining nested lists enclosed in opening and closing + delimiters ("(" and ")" are the default). + + Parameters: + - opener - opening character for a nested list (default="("); can also be a pyparsing expression + - closer - closing character for a nested list (default=")"); can also be a pyparsing expression + - content - expression for items within the nested lists (default=None) + - ignoreExpr - expression for ignoring opening and closing delimiters (default=quotedString) + + If an expression is not provided for the content argument, the nested + expression will capture all whitespace-delimited content between delimiters + as a list of separate values. + + Use the C{ignoreExpr} argument to define expressions that may contain + opening or closing characters that should not be treated as opening + or closing characters for nesting, such as quotedString or a comment + expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. + The default is L{quotedString}, but if no expressions are to be ignored, + then pass C{None} for this argument. + """ + if opener == closer: + raise ValueError("opening and closing strings cannot be the same") + if content is None: + if isinstance(opener,basestring) and isinstance(closer,basestring): + if len(opener) == 1 and len(closer)==1: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS + ).setParseAction(lambda t:t[0].strip())) + else: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + ~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + raise ValueError("opening and closing arguments must be strings if no content expression is given") + ret = Forward() + if ignoreExpr is not None: + ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) + else: + ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) + return ret + +def indentedBlock(blockStatementExpr, indentStack, indent=True): + """Helper method for defining space-delimited indentation blocks, such as + those used to define block statements in Python source code. + + Parameters: + - blockStatementExpr - expression defining syntax of statement that + is repeated within the indented block + - indentStack - list created by caller to manage indentation stack + (multiple statementWithIndentedBlock expressions within a single grammar + should share a common indentStack) + - indent - boolean indicating whether block must be indented beyond the + the current level; set to False for block of left-most statements + (default=True) + + A valid block must contain at least one C{blockStatement}. + """ + def checkPeerIndent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if curCol != indentStack[-1]: + if curCol > indentStack[-1]: + raise ParseFatalException(s,l,"illegal nesting") + raise ParseException(s,l,"not a peer entry") + + def checkSubIndent(s,l,t): + curCol = col(l,s) + if curCol > indentStack[-1]: + indentStack.append( curCol ) + else: + raise ParseException(s,l,"not a subentry") + + def checkUnindent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): + raise ParseException(s,l,"not an unindent") + indentStack.pop() + + NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) + INDENT = Empty() + Empty().setParseAction(checkSubIndent) + PEER = Empty().setParseAction(checkPeerIndent) + UNDENT = Empty().setParseAction(checkUnindent) + if indent: + smExpr = Group( Optional(NL) + + #~ FollowedBy(blockStatementExpr) + + INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) + else: + smExpr = Group( Optional(NL) + + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) + blockStatementExpr.ignore(_bslash + LineEnd()) + return smExpr + +alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") +punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") + +anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:")) +commonHTMLEntity = Combine(_L("&") + oneOf("gt lt amp nbsp quot").setResultsName("entity") +";").streamline() +_htmlEntityMap = dict(zip("gt lt amp nbsp quot".split(),'><& "')) +replaceHTMLEntity = lambda t : t.entity in _htmlEntityMap and _htmlEntityMap[t.entity] or None + +# it's easy to get these comment structures wrong - they're very common, so may as well make them available +cStyleComment = Regex(r"/\*(?:[^*]*\*+)+?/").setName("C style comment") + +htmlComment = Regex(r"") +restOfLine = Regex(r".*").leaveWhitespace() +dblSlashComment = Regex(r"\/\/(\\\n|.)*").setName("// comment") +cppStyleComment = Regex(r"/(?:\*(?:[^*]*\*+)+?/|/[^\n]*(?:\n[^\n]*)*?(?:(?`_. + +------------------------- +Installation Instructions +------------------------- + +The recommended way to bootstrap setuptools on any system is to download +`ez_setup.py`_ and run it using the target Python environment. Different +operating systems have different recommended techniques to accomplish this +basic routine, so below are some examples to get you started. + +Setuptools requires Python 2.6 or later. To install setuptools +on Python 2.4 or Python 2.5, use the `bootstrap script for Setuptools 1.x +`_. + +The link provided to ez_setup.py is a bookmark to bootstrap script for the +latest known stable release. + +.. _ez_setup.py: https://bootstrap.pypa.io/ez_setup.py + +Windows (Powershell 3 or later) +=============================== + +For best results, uninstall previous versions FIRST (see `Uninstalling`_). + +Using Windows 8 (which includes PowerShell 3) or earlier versions of Windows +with PowerShell 3 installed, it's possible to install with one simple +Powershell command. Start up Powershell and paste this command:: + + > (Invoke-WebRequest https://bootstrap.pypa.io/ez_setup.py).Content | python - + +You must start the Powershell with Administrative privileges or you may choose +to install a user-local installation:: + + > (Invoke-WebRequest https://bootstrap.pypa.io/ez_setup.py).Content | python - --user + +If you have Python 3.3 or later, you can use the ``py`` command to install to +different Python versions. For example, to install to Python 3.3 if you have +Python 2.7 installed:: + + > (Invoke-WebRequest https://bootstrap.pypa.io/ez_setup.py).Content | py -3 - + +The recommended way to install setuptools on Windows is to download +`ez_setup.py`_ and run it. The script will download the appropriate +distribution file and install it for you. + +Once installation is complete, you will find an ``easy_install`` program in +your Python ``Scripts`` subdirectory. For simple invocation and best results, +add this directory to your ``PATH`` environment variable, if it is not already +present. If you did a user-local install, the ``Scripts`` subdirectory is +``$env:APPDATA\Python\Scripts``. + + +Windows (simplified) +==================== + +For Windows without PowerShell 3 or for installation without a command-line, +download `ez_setup.py`_ using your preferred web browser or other technique +and "run" that file. + + +Unix (wget) +=========== + +Most Linux distributions come with wget. + +Download `ez_setup.py`_ and run it using the target Python version. The script +will download the appropriate version and install it for you:: + + > wget https://bootstrap.pypa.io/ez_setup.py -O - | python + +Note that you will may need to invoke the command with superuser privileges to +install to the system Python:: + + > wget https://bootstrap.pypa.io/ez_setup.py -O - | sudo python + +Alternatively, Setuptools may be installed to a user-local path:: + + > wget https://bootstrap.pypa.io/ez_setup.py -O - | python - --user + +Note that on some older systems (noted on Debian 6 and CentOS 5 installations), +`wget` may refuse to download `ez_setup.py`, complaining that the certificate common name `*.c.ssl.fastly.net` +does not match the host name `bootstrap.pypa.io`. In addition, the `ez_setup.py` script may then encounter similar problems using +`wget` internally to download `setuptools-x.y.zip`, complaining that the certificate common name of `www.python.org` does not match the +host name `pypi.python.org`. Those are known issues, related to a bug in the older versions of `wget` +(see `Issue 59 `_). If you happen to encounter them, +install Setuptools as follows:: + + > wget --no-check-certificate https://bootstrap.pypa.io/ez_setup.py + > python ez_setup.py --insecure + + +Unix including Mac OS X (curl) +============================== + +If your system has curl installed, follow the ``wget`` instructions but +replace ``wget`` with ``curl`` and ``-O`` with ``-o``. For example:: + + > curl https://bootstrap.pypa.io/ez_setup.py -o - | python + + +Advanced Installation +===================== + +For more advanced installation options, such as installing to custom +locations or prefixes, download and extract the source +tarball from `Setuptools on PyPI `_ +and run setup.py with any supported distutils and Setuptools options. +For example:: + + setuptools-x.x$ python setup.py install --prefix=/opt/setuptools + +Use ``--help`` to get a full options list, but we recommend consulting +the `EasyInstall manual`_ for detailed instructions, especially `the section +on custom installation locations`_. + +.. _EasyInstall manual: https://pythonhosted.org/setuptools/EasyInstall +.. _the section on custom installation locations: https://pythonhosted.org/setuptools/EasyInstall#custom-installation-locations + + +Downloads +========= + +All setuptools downloads can be found at `the project's home page in the Python +Package Index`_. Scroll to the very bottom of the page to find the links. + +.. _the project's home page in the Python Package Index: https://pypi.python.org/pypi/setuptools + +In addition to the PyPI downloads, the development version of ``setuptools`` +is available from the `Bitbucket repo`_, and in-development versions of the +`0.6 branch`_ are available as well. + +.. _Bitbucket repo: https://bitbucket.org/pypa/setuptools/get/default.tar.gz#egg=setuptools-dev +.. _0.6 branch: http://svn.python.org/projects/sandbox/branches/setuptools-0.6/#egg=setuptools-dev06 + +Uninstalling +============ + +On Windows, if Setuptools was installed using an ``.exe`` or ``.msi`` +installer, simply use the uninstall feature of "Add/Remove Programs" in the +Control Panel. + +Otherwise, to uninstall Setuptools or Distribute, regardless of the Python +version, delete all ``setuptools*`` and ``distribute*`` files and +directories from your system's ``site-packages`` directory +(and any other ``sys.path`` directories) FIRST. + +If you are upgrading or otherwise plan to re-install Setuptools or Distribute, +nothing further needs to be done. If you want to completely remove Setuptools, +you may also want to remove the 'easy_install' and 'easy_install-x.x' scripts +and associated executables installed to the Python scripts directory. + +-------------------------------- +Using Setuptools and EasyInstall +-------------------------------- + +Here are some of the available manuals, tutorials, and other resources for +learning about Setuptools, Python Eggs, and EasyInstall: + +* `The EasyInstall user's guide and reference manual`_ +* `The setuptools Developer's Guide`_ +* `The pkg_resources API reference`_ +* `The Internal Structure of Python Eggs`_ + +Questions, comments, and bug reports should be directed to the `distutils-sig +mailing list`_. If you have written (or know of) any tutorials, documentation, +plug-ins, or other resources for setuptools users, please let us know about +them there, so this reference list can be updated. If you have working, +*tested* patches to correct problems or add features, you may submit them to +the `setuptools bug tracker`_. + +.. _setuptools bug tracker: https://bitbucket.org/pypa/setuptools/issues +.. _The Internal Structure of Python Eggs: https://pythonhosted.org/setuptools/formats.html +.. _The setuptools Developer's Guide: https://pythonhosted.org/setuptools/setuptools.html +.. _The pkg_resources API reference: https://pythonhosted.org/setuptools/pkg_resources.html +.. _The EasyInstall user's guide and reference manual: https://pythonhosted.org/setuptools/easy_install.html +.. _distutils-sig mailing list: http://mail.python.org/pipermail/distutils-sig/ + + +------- +Credits +------- + +* The original design for the ``.egg`` format and the ``pkg_resources`` API was + co-created by Phillip Eby and Bob Ippolito. Bob also implemented the first + version of ``pkg_resources``, and supplied the OS X operating system version + compatibility algorithm. + +* Ian Bicking implemented many early "creature comfort" features of + easy_install, including support for downloading via Sourceforge and + Subversion repositories. Ian's comments on the Web-SIG about WSGI + application deployment also inspired the concept of "entry points" in eggs, + and he has given talks at PyCon and elsewhere to inform and educate the + community about eggs and setuptools. + +* Jim Fulton contributed time and effort to build automated tests of various + aspects of ``easy_install``, and supplied the doctests for the command-line + ``.exe`` wrappers on Windows. + +* Phillip J. Eby is the seminal author of setuptools, and + first proposed the idea of an importable binary distribution format for + Python application plug-ins. + +* Significant parts of the implementation of setuptools were funded by the Open + Source Applications Foundation, to provide a plug-in infrastructure for the + Chandler PIM application. In addition, many OSAF staffers (such as Mike + "Code Bear" Taylor) contributed their time and stress as guinea pigs for the + use of eggs and setuptools, even before eggs were "cool". (Thanks, guys!) + +* Tarek Ziadé is the principal author of the Distribute fork, which + re-invigorated the community on the project, encouraged renewed innovation, + and addressed many defects. + +* Since the merge with Distribute, Jason R. Coombs is the + maintainer of setuptools. The project is maintained in coordination with + the Python Packaging Authority (PyPA) and the larger Python community. + +.. _files: + + +--------------- +Code of Conduct +--------------- + +Everyone interacting in the setuptools project's codebases, issue trackers, +chat rooms, and mailing lists is expected to follow the +`PyPA Code of Conduct`_. + +.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + + diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/INSTALLER b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/METADATA b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/METADATA similarity index 99% rename from Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/METADATA rename to Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/METADATA index 6faaab5..e901218 100644 --- a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/METADATA +++ b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.0 Name: setuptools -Version: 20.1.1 +Version: 20.2.2 Summary: Easily download, build, install, upgrade, and uninstall Python packages Home-page: https://bitbucket.org/pypa/setuptools Author: Python Packaging Authority diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/RECORD b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/RECORD similarity index 74% rename from Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/RECORD rename to Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/RECORD index bd156b5..f4a1729 100644 --- a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/RECORD +++ b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/RECORD @@ -1,16 +1,18 @@ easy_install.py,sha256=MDC9vt5AxDsXX5qcKlBz2TnW6Tpuv_AobnfhCJ9X3PM,126 -_markerlib/__init__.py,sha256=GSmhZqvAitLJHhSgtqqusfq2nJ_ClP3oy3Lm0uZLIsU,552 -_markerlib/markers.py,sha256=YuFp0-osufFIoqnzG3L0Z2fDCx4Vln3VUDeXJ2DA_1I,3979 -pkg_resources/__init__.py,sha256=bucu_98c11mzrGldEJeqxArn14F7ZmURsb-8CaNSbVo,108616 +pkg_resources/__init__.py,sha256=bwxm1Fn4zVXphbGYtK6sddFL-iMdlwIX7A2pOlN0tVk,100876 pkg_resources/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pkg_resources/_vendor/pyparsing.py,sha256=ic8qmDPiq8Li-Y0PeZcI56rEyMqevKNBK6hr6FbyVBc,160425 pkg_resources/_vendor/six.py,sha256=A6hdJZVjI3t_geebZ9BzUvwRrIXo0lfwzQlM2LcKyas,30098 -pkg_resources/_vendor/packaging/__about__.py,sha256=YzdrW-1lWmyCBDyrcNkZbJo4tiDWXpoiqPjfyCYMzIE,1073 -pkg_resources/_vendor/packaging/__init__.py,sha256=2V8n-eEpSgBuXlV8hlMmhU7ZklpsrrusWMZNp2gC4Hs,906 -pkg_resources/_vendor/packaging/_compat.py,sha256=wofog8iYo_zudt_10i6JiXKHDs5GhCuXC09hCuSJiv4,1253 -pkg_resources/_vendor/packaging/_structures.py,sha256=93YvgrEE2HgFp8AdXy0pwCRVnZeutRHO_-puJ7T0cPw,1809 -pkg_resources/_vendor/packaging/specifiers.py,sha256=UV9T01_kKloA8PSeMI3HTYBSJ_4KLs00yLvrlciZ3yU,28079 -pkg_resources/_vendor/packaging/version.py,sha256=dEGrWZJZ6sef1xMxSfDCego2hS3Q86by0hUIFVk-AGc,11949 -pkg_resources/extern/__init__.py,sha256=azKvXDutMVFe3c641wdiwndjtku92Bl3_iGVAIMKnsM,2461 +pkg_resources/_vendor/packaging/__about__.py,sha256=AEwkfVSNgMMAAugtYao7b7wah9XryokeoXBuIw4h6d8,720 +pkg_resources/_vendor/packaging/__init__.py,sha256=_vNac5TrzwsrzbOFIbF-5cHqc_Y2aPT2D7zrIR06BOo,513 +pkg_resources/_vendor/packaging/_compat.py,sha256=Vi_A0rAQeHbU-a9X0tt1yQm9RqkgQbDSxzRw8WlU9kA,860 +pkg_resources/_vendor/packaging/_structures.py,sha256=RImECJ4c_wTlaTYYwZYLHEiebDMaAJmK1oPARhw1T5o,1416 +pkg_resources/_vendor/packaging/markers.py,sha256=0Z2in1kNfYn93n9uJj0hNEmu-sJpEQpa_qAbxpYXdS4,7359 +pkg_resources/_vendor/packaging/requirements.py,sha256=SikL2UynbsT0qtY9ltqngndha_sfo0w6XGFhAhoSoaQ,4355 +pkg_resources/_vendor/packaging/specifiers.py,sha256=SAMRerzO3fK2IkFZCaZkuwZaL_EGqHNOz4pni4vhnN0,28025 +pkg_resources/_vendor/packaging/utils.py,sha256=3m6WvPm6NNxE8rkTGmn0r75B_GZSGg7ikafxHsBN1WA,421 +pkg_resources/_vendor/packaging/version.py,sha256=OwGnxYfr2ghNzYx59qWIBkrK3SnB6n-Zfd1XaLpnnM0,11556 +pkg_resources/extern/__init__.py,sha256=rMBTxKimjNg8plSH94cB-y52pKO0zmM-AkFL30lZGfY,2474 setuptools/__init__.py,sha256=WEGb6BRGN2dz3eJTbNRUfInUAhb6_OZJyYAndPGJm6w,5440 setuptools/archive_util.py,sha256=N30WE5ZQjkytzhAodAXw4FkK-9J5AP1ChrClHnZthOA,6609 setuptools/cli-32.exe,sha256=dfEuovMNnA2HLa3jRfMPVi5tk4R7alCbpTvuxtCyw0Y,65536 @@ -38,7 +40,7 @@ setuptools/site-patch.py,sha256=K-0-cAx36mX_PG-qPZwosG9ZLCliRjquKQ4nHiJvvzg,2389 setuptools/ssl_support.py,sha256=tAFeeyFPVle_GgarPkNrdfnCJgP9PyN_QYGXTgypoyc,8119 setuptools/unicode_utils.py,sha256=8zVyrL_MFc6P5AmErs21rr7z-3N1pZ_NkOcDC7BPElU,995 setuptools/utils.py,sha256=08Z7mt-9mvrx-XvmS5EyKoRn2lxNTlgFsUwBU3Eq9JQ,293 -setuptools/version.py,sha256=E3F8rAlTgCNpmTTY2YGy4T_1iQn3gKsePB7TVIcObu0,23 +setuptools/version.py,sha256=vRyfcfc7GHZS-3JCgX02OcTSUwmEyvPJpQQF4XGxTmc,23 setuptools/windows_support.py,sha256=5GrfqSP2-dLGJoZTq2g6dCKkyQxxa2n5IQiXlJCoYEE,714 setuptools/command/__init__.py,sha256=1AM3hv_zCixE7kTXA-onWfK_2KF8GC8fUw3WSxzi5Fg,564 setuptools/command/alias.py,sha256=KjpE0sz_SDIHv3fpZcIQK-sCkJz-SrC6Gmug6b9Nkc8,2426 @@ -48,7 +50,7 @@ setuptools/command/bdist_wininst.py,sha256=_6dz3lpB1tY200LxKPLM7qgwTCceOMgaWFF-j setuptools/command/build_ext.py,sha256=pkQ8xp3YPVGGLkGv-SvfxC_GqFpboph1AFEoMFOgQMo,11964 setuptools/command/build_py.py,sha256=HvJ88JuougDccaowYlfMV12kYtd0GLahg2DR2vQRqL4,7983 setuptools/command/develop.py,sha256=VxSYbpM2jQqtRBn5klIjPVBo3sWKNZMlSbHHiRLUlZo,7383 -setuptools/command/easy_install.py,sha256=w3rYTMOEAxMPNMQ6A3RWgaFNL6y1Ms2TFrgHqAxMrlE,86096 +setuptools/command/easy_install.py,sha256=H2aThxQAtB-WKu52Hsc8ePfJcbILMQPq060CgUtvDtw,86035 setuptools/command/egg_info.py,sha256=0_8eI8hgLAlGt8Xk5kiodY_d9lxG6_RSescJISKBJgA,16890 setuptools/command/install.py,sha256=QwaFiZRU3ytIHoPh8uJ9EqV3Fu9C4ca4B7UGAo95tws,4685 setuptools/command/install_egg_info.py,sha256=8J_cH4VbOJv-9Wey8Ijw5SnNI7YS_CA2IKYX569mP5Q,4035 @@ -64,70 +66,72 @@ setuptools/command/test.py,sha256=N2f5RwxkjwU3YQzFYHtzHr636-pdX9XJDuPg5Y92kSo,68 setuptools/command/upload.py,sha256=OjAryq4ZoARZiaTN_MpuG1X8Pu9CJNCKmmbMg-gab5I,649 setuptools/command/upload_docs.py,sha256=htXpASci5gKP0RIrGZRRmbll7RnTRuwvKWZkYsBlDMM,6815 setuptools/extern/__init__.py,sha256=mTrrj4yLMdFeEwwnqKnSuvZM5RM-HPZ1iXLgaYDlB9o,132 -setuptools-20.1.1.dist-info/DESCRIPTION.rst,sha256=MDsJej8DPV2OKpAKpu74g-2xksRd-uGTeZn4W7D1dnI,9940 -setuptools-20.1.1.dist-info/METADATA,sha256=mXcb68OjP3H_wq0JMNyeX3nYGlTPDi74cndXOowhZps,11173 -setuptools-20.1.1.dist-info/RECORD,, -setuptools-20.1.1.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 -setuptools-20.1.1.dist-info/dependency_links.txt,sha256=oUNXJEArClXFiSSvfFwUKY8TYjeIXhuFfCpXn5K0DCE,226 -setuptools-20.1.1.dist-info/entry_points.txt,sha256=revbaRBbkZ2b1B-hZlAXo_18J9GjdYHgA4DoW8wdTOU,2835 -setuptools-20.1.1.dist-info/metadata.json,sha256=NVNudLLjxdP9rz5vqMErRBQTdpX1tTEbp9EhBRSCQ8U,4636 -setuptools-20.1.1.dist-info/top_level.txt,sha256=7780fzudMJkykiTcIrAQ8m8Lll6kot3EEePye3VJgEE,49 -setuptools-20.1.1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/bin/easy_install,sha256=4bXVXBoSo_A1XK3Ga5UMkOREdCSnh8FZIYqtJVSWCa4,298 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/bin/easy_install-3.4,sha256=4bXVXBoSo_A1XK3Ga5UMkOREdCSnh8FZIYqtJVSWCa4,298 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pkg_resources/_vendor/__pycache__/six.cpython-34.pyc,, -setuptools/command/__pycache__/bdist_wininst.cpython-34.pyc,, -setuptools/__pycache__/__init__.cpython-34.pyc,, -setuptools/command/__pycache__/rotate.cpython-34.pyc,, +setuptools-20.2.2.dist-info/DESCRIPTION.rst,sha256=MDsJej8DPV2OKpAKpu74g-2xksRd-uGTeZn4W7D1dnI,9940 +setuptools-20.2.2.dist-info/METADATA,sha256=iyHIJhxBur1zKQdezmdxh356iMZBDPWC-HnpBxSJkjA,11173 +setuptools-20.2.2.dist-info/RECORD,, +setuptools-20.2.2.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 +setuptools-20.2.2.dist-info/dependency_links.txt,sha256=oUNXJEArClXFiSSvfFwUKY8TYjeIXhuFfCpXn5K0DCE,226 +setuptools-20.2.2.dist-info/entry_points.txt,sha256=revbaRBbkZ2b1B-hZlAXo_18J9GjdYHgA4DoW8wdTOU,2835 +setuptools-20.2.2.dist-info/metadata.json,sha256=NJw3rJiskXQqc4F9J19zjdRFEpI28APWvf149lL509g,4636 +setuptools-20.2.2.dist-info/top_level.txt,sha256=2HUXVVwA4Pff1xgTFr3GsTXXKaPaO6vlG6oNJ_4u4Tg,38 +setuptools-20.2.2.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +../../../bin/easy_install,sha256=4bXVXBoSo_A1XK3Ga5UMkOREdCSnh8FZIYqtJVSWCa4,298 +../../../bin/easy_install-3.4,sha256=4bXVXBoSo_A1XK3Ga5UMkOREdCSnh8FZIYqtJVSWCa4,298 +setuptools-20.2.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +setuptools/__pycache__/py27compat.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-34.pyc,, +setuptools/__pycache__/sandbox.cpython-34.pyc,, +pkg_resources/__pycache__/__init__.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-34.pyc,, setuptools/__pycache__/version.cpython-34.pyc,, -setuptools/command/__pycache__/egg_info.cpython-34.pyc,, -setuptools/__pycache__/lib2to3_ex.cpython-34.pyc,, -setuptools/__pycache__/utils.cpython-34.pyc,, -pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-34.pyc,, -setuptools/__pycache__/unicode_utils.cpython-34.pyc,, -setuptools/__pycache__/msvc9_support.cpython-34.pyc,, -setuptools/command/__pycache__/easy_install.cpython-34.pyc,, -setuptools/command/__pycache__/__init__.cpython-34.pyc,, -setuptools/__pycache__/py31compat.cpython-34.pyc,, -setuptools/command/__pycache__/develop.cpython-34.pyc,, -setuptools/command/__pycache__/register.cpython-34.pyc,, -setuptools/command/__pycache__/setopt.cpython-34.pyc,, -setuptools/__pycache__/py26compat.cpython-34.pyc,, -setuptools/__pycache__/extension.cpython-34.pyc,, -setuptools/command/__pycache__/bdist_rpm.cpython-34.pyc,, -setuptools/command/__pycache__/install_egg_info.cpython-34.pyc,, -pkg_resources/_vendor/packaging/__pycache__/version.cpython-34.pyc,, -setuptools/__pycache__/site-patch.cpython-34.pyc,, -_markerlib/__pycache__/markers.cpython-34.pyc,, -setuptools/command/__pycache__/install_scripts.cpython-34.pyc,, -pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-34.pyc,, -pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-34.pyc,, -setuptools/command/__pycache__/saveopts.cpython-34.pyc,, -setuptools/command/__pycache__/upload_docs.cpython-34.pyc,, -setuptools/command/__pycache__/install.cpython-34.pyc,, setuptools/__pycache__/depends.cpython-34.pyc,, -_markerlib/__pycache__/__init__.cpython-34.pyc,, -pkg_resources/_vendor/__pycache__/__init__.cpython-34.pyc,, -setuptools/command/__pycache__/build_py.cpython-34.pyc,, +setuptools/__pycache__/windows_support.cpython-34.pyc,, +pkg_resources/_vendor/__pycache__/six.cpython-34.pyc,, +setuptools/command/__pycache__/install_egg_info.cpython-34.pyc,, +setuptools/command/__pycache__/egg_info.cpython-34.pyc,, +pkg_resources/extern/__pycache__/__init__.cpython-34.pyc,, +setuptools/__pycache__/py26compat.cpython-34.pyc,, +setuptools/command/__pycache__/rotate.cpython-34.pyc,, +setuptools/command/__pycache__/install_scripts.cpython-34.pyc,, +setuptools/command/__pycache__/alias.cpython-34.pyc,, +setuptools/__pycache__/unicode_utils.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/utils.cpython-34.pyc,, setuptools/command/__pycache__/install_lib.cpython-34.pyc,, setuptools/__pycache__/package_index.cpython-34.pyc,, -setuptools/command/__pycache__/build_ext.cpython-34.pyc,, -setuptools/extern/__pycache__/__init__.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/version.cpython-34.pyc,, +setuptools/__pycache__/lib2to3_ex.cpython-34.pyc,, +pkg_resources/_vendor/__pycache__/__init__.cpython-34.pyc,, +setuptools/command/__pycache__/bdist_rpm.cpython-34.pyc,, +setuptools/command/__pycache__/setopt.cpython-34.pyc,, __pycache__/easy_install.cpython-34.pyc,, -setuptools/command/__pycache__/upload.cpython-34.pyc,, -setuptools/__pycache__/archive_util.cpython-34.pyc,, -setuptools/command/__pycache__/alias.cpython-34.pyc,, -pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-34.pyc,, -pkg_resources/extern/__pycache__/__init__.cpython-34.pyc,, -setuptools/__pycache__/ssl_support.cpython-34.pyc,, -setuptools/__pycache__/launch.cpython-34.pyc,, +setuptools/command/__pycache__/build_py.cpython-34.pyc,, +setuptools/command/__pycache__/bdist_wininst.cpython-34.pyc,, +setuptools/command/__pycache__/upload_docs.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-34.pyc,, setuptools/command/__pycache__/sdist.cpython-34.pyc,, -setuptools/command/__pycache__/test.cpython-34.pyc,, -setuptools/__pycache__/windows_support.cpython-34.pyc,, -pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-34.pyc,, -pkg_resources/__pycache__/__init__.cpython-34.pyc,, -setuptools/__pycache__/py27compat.cpython-34.pyc,, -setuptools/__pycache__/sandbox.cpython-34.pyc,, setuptools/__pycache__/dist.cpython-34.pyc,, +setuptools/__pycache__/archive_util.cpython-34.pyc,, +setuptools/command/__pycache__/register.cpython-34.pyc,, +setuptools/__pycache__/extension.cpython-34.pyc,, +setuptools/command/__pycache__/test.cpython-34.pyc,, +setuptools/command/__pycache__/__init__.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-34.pyc,, +setuptools/command/__pycache__/develop.cpython-34.pyc,, +setuptools/extern/__pycache__/__init__.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-34.pyc,, +setuptools/__pycache__/launch.cpython-34.pyc,, +setuptools/command/__pycache__/build_ext.cpython-34.pyc,, +setuptools/__pycache__/utils.cpython-34.pyc,, +pkg_resources/_vendor/packaging/__pycache__/markers.cpython-34.pyc,, setuptools/command/__pycache__/bdist_egg.cpython-34.pyc,, +setuptools/__pycache__/site-patch.cpython-34.pyc,, +setuptools/command/__pycache__/saveopts.cpython-34.pyc,, +pkg_resources/_vendor/__pycache__/pyparsing.cpython-34.pyc,, +setuptools/command/__pycache__/install.cpython-34.pyc,, +setuptools/command/__pycache__/easy_install.cpython-34.pyc,, +setuptools/__pycache__/msvc9_support.cpython-34.pyc,, +setuptools/__pycache__/__init__.cpython-34.pyc,, +setuptools/__pycache__/ssl_support.cpython-34.pyc,, +setuptools/__pycache__/py31compat.cpython-34.pyc,, +setuptools/command/__pycache__/upload.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/WHEEL b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/WHEEL similarity index 100% rename from Shared/lib/python3.4/site-packages/pip-8.0.2.dist-info/WHEEL rename to Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/WHEEL diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/dependency_links.txt b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/dependency_links.txt new file mode 100644 index 0000000..47d1e81 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/dependency_links.txt @@ -0,0 +1,2 @@ +https://pypi.python.org/packages/source/c/certifi/certifi-2015.11.20.tar.gz#md5=25134646672c695c1ff1593c2dd75d08 +https://pypi.python.org/packages/source/w/wincertstore/wincertstore-0.2.zip#md5=ae728f2f007185648d0c7a8679b361e2 diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/entry_points.txt b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/entry_points.txt similarity index 100% rename from Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/entry_points.txt rename to Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/entry_points.txt diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/metadata.json b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/metadata.json similarity index 98% rename from Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/metadata.json rename to Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/metadata.json index 385a951..9f390ea 100644 --- a/Shared/lib/python3.4/site-packages/setuptools-20.1.1.dist-info/metadata.json +++ b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/metadata.json @@ -1 +1 @@ -{"generator": "bdist_wheel (0.26.0)", "summary": "Easily download, build, install, upgrade, and uninstall Python packages", "classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: System :: Archiving :: Packaging", "Topic :: System :: Systems Administration", "Topic :: Utilities"], "extensions": {"python.details": {"project_urls": {"Home": "https://bitbucket.org/pypa/setuptools"}, "contacts": [{"email": "distutils-sig@python.org", "name": "Python Packaging Authority", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}}, "python.exports": {"console_scripts": {"easy_install": "setuptools.command.easy_install:main", "easy_install-3.5": "setuptools.command.easy_install:main"}, "distutils.commands": {"alias": "setuptools.command.alias:alias", "bdist_egg": "setuptools.command.bdist_egg:bdist_egg", "bdist_rpm": "setuptools.command.bdist_rpm:bdist_rpm", "bdist_wininst": "setuptools.command.bdist_wininst:bdist_wininst", "build_ext": "setuptools.command.build_ext:build_ext", "build_py": "setuptools.command.build_py:build_py", "develop": "setuptools.command.develop:develop", "easy_install": "setuptools.command.easy_install:easy_install", "egg_info": "setuptools.command.egg_info:egg_info", "install": "setuptools.command.install:install", "install_egg_info": "setuptools.command.install_egg_info:install_egg_info", "install_lib": "setuptools.command.install_lib:install_lib", "install_scripts": "setuptools.command.install_scripts:install_scripts", "register": "setuptools.command.register:register", "rotate": "setuptools.command.rotate:rotate", "saveopts": "setuptools.command.saveopts:saveopts", "sdist": "setuptools.command.sdist:sdist", "setopt": "setuptools.command.setopt:setopt", "test": "setuptools.command.test:test", "upload": "setuptools.command.upload:upload", "upload_docs": "setuptools.command.upload_docs:upload_docs"}, "distutils.setup_keywords": {"convert_2to3_doctests": "setuptools.dist:assert_string_list", "dependency_links": "setuptools.dist:assert_string_list", "eager_resources": "setuptools.dist:assert_string_list", "entry_points": "setuptools.dist:check_entry_points", "exclude_package_data": "setuptools.dist:check_package_data", "extras_require": "setuptools.dist:check_extras", "include_package_data": "setuptools.dist:assert_bool", "install_requires": "setuptools.dist:check_requirements", "namespace_packages": "setuptools.dist:check_nsp", "package_data": "setuptools.dist:check_package_data", "packages": "setuptools.dist:check_packages", "setup_requires": "setuptools.dist:check_requirements", "test_loader": "setuptools.dist:check_importable", "test_runner": "setuptools.dist:check_importable", "test_suite": "setuptools.dist:check_test_suite", "tests_require": "setuptools.dist:check_requirements", "use_2to3": "setuptools.dist:assert_bool", "use_2to3_exclude_fixers": "setuptools.dist:assert_string_list", "use_2to3_fixers": "setuptools.dist:assert_string_list", "zip_safe": "setuptools.dist:assert_bool"}, "egg_info.writers": {"PKG-INFO": "setuptools.command.egg_info:write_pkg_info", "dependency_links.txt": "setuptools.command.egg_info:overwrite_arg", "depends.txt": "setuptools.command.egg_info:warn_depends_obsolete", "eager_resources.txt": "setuptools.command.egg_info:overwrite_arg", "entry_points.txt": "setuptools.command.egg_info:write_entries", "namespace_packages.txt": "setuptools.command.egg_info:overwrite_arg", "requires.txt": "setuptools.command.egg_info:write_requirements", "top_level.txt": "setuptools.command.egg_info:write_toplevel_names"}, "setuptools.installation": {"eggsecutable": "setuptools.command.easy_install:bootstrap"}}, "python.commands": {"wrap_console": {"easy_install": "setuptools.command.easy_install:main", "easy_install-3.5": "setuptools.command.easy_install:main"}}}, "keywords": ["CPAN", "PyPI", "distutils", "eggs", "package", "management"], "metadata_version": "2.0", "name": "setuptools", "extras": ["certs", "ssl"], "run_requires": [{"requires": ["certifi (==2015.11.20)"], "extra": "certs"}, {"requires": ["wincertstore (==0.2)"], "extra": "ssl", "environment": "sys_platform=='win32'"}], "version": "20.1.1", "test_requires": [{"requires": ["pytest (>=2.8)", "setuptools[ssl]"]}]} \ No newline at end of file +{"generator": "bdist_wheel (0.26.0)", "summary": "Easily download, build, install, upgrade, and uninstall Python packages", "classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: System :: Archiving :: Packaging", "Topic :: System :: Systems Administration", "Topic :: Utilities"], "extensions": {"python.details": {"project_urls": {"Home": "https://bitbucket.org/pypa/setuptools"}, "contacts": [{"email": "distutils-sig@python.org", "name": "Python Packaging Authority", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}}, "python.exports": {"console_scripts": {"easy_install": "setuptools.command.easy_install:main", "easy_install-3.5": "setuptools.command.easy_install:main"}, "distutils.commands": {"alias": "setuptools.command.alias:alias", "bdist_egg": "setuptools.command.bdist_egg:bdist_egg", "bdist_rpm": "setuptools.command.bdist_rpm:bdist_rpm", "bdist_wininst": "setuptools.command.bdist_wininst:bdist_wininst", "build_ext": "setuptools.command.build_ext:build_ext", "build_py": "setuptools.command.build_py:build_py", "develop": "setuptools.command.develop:develop", "easy_install": "setuptools.command.easy_install:easy_install", "egg_info": "setuptools.command.egg_info:egg_info", "install": "setuptools.command.install:install", "install_egg_info": "setuptools.command.install_egg_info:install_egg_info", "install_lib": "setuptools.command.install_lib:install_lib", "install_scripts": "setuptools.command.install_scripts:install_scripts", "register": "setuptools.command.register:register", "rotate": "setuptools.command.rotate:rotate", "saveopts": "setuptools.command.saveopts:saveopts", "sdist": "setuptools.command.sdist:sdist", "setopt": "setuptools.command.setopt:setopt", "test": "setuptools.command.test:test", "upload": "setuptools.command.upload:upload", "upload_docs": "setuptools.command.upload_docs:upload_docs"}, "distutils.setup_keywords": {"convert_2to3_doctests": "setuptools.dist:assert_string_list", "dependency_links": "setuptools.dist:assert_string_list", "eager_resources": "setuptools.dist:assert_string_list", "entry_points": "setuptools.dist:check_entry_points", "exclude_package_data": "setuptools.dist:check_package_data", "extras_require": "setuptools.dist:check_extras", "include_package_data": "setuptools.dist:assert_bool", "install_requires": "setuptools.dist:check_requirements", "namespace_packages": "setuptools.dist:check_nsp", "package_data": "setuptools.dist:check_package_data", "packages": "setuptools.dist:check_packages", "setup_requires": "setuptools.dist:check_requirements", "test_loader": "setuptools.dist:check_importable", "test_runner": "setuptools.dist:check_importable", "test_suite": "setuptools.dist:check_test_suite", "tests_require": "setuptools.dist:check_requirements", "use_2to3": "setuptools.dist:assert_bool", "use_2to3_exclude_fixers": "setuptools.dist:assert_string_list", "use_2to3_fixers": "setuptools.dist:assert_string_list", "zip_safe": "setuptools.dist:assert_bool"}, "egg_info.writers": {"PKG-INFO": "setuptools.command.egg_info:write_pkg_info", "dependency_links.txt": "setuptools.command.egg_info:overwrite_arg", "depends.txt": "setuptools.command.egg_info:warn_depends_obsolete", "eager_resources.txt": "setuptools.command.egg_info:overwrite_arg", "entry_points.txt": "setuptools.command.egg_info:write_entries", "namespace_packages.txt": "setuptools.command.egg_info:overwrite_arg", "requires.txt": "setuptools.command.egg_info:write_requirements", "top_level.txt": "setuptools.command.egg_info:write_toplevel_names"}, "setuptools.installation": {"eggsecutable": "setuptools.command.easy_install:bootstrap"}}, "python.commands": {"wrap_console": {"easy_install": "setuptools.command.easy_install:main", "easy_install-3.5": "setuptools.command.easy_install:main"}}}, "keywords": ["CPAN", "PyPI", "distutils", "eggs", "package", "management"], "metadata_version": "2.0", "name": "setuptools", "extras": ["certs", "ssl"], "run_requires": [{"requires": ["certifi (==2015.11.20)"], "extra": "certs"}, {"requires": ["wincertstore (==0.2)"], "extra": "ssl", "environment": "sys_platform=='win32'"}], "version": "20.2.2", "test_requires": [{"requires": ["pytest (>=2.8)", "setuptools[ssl]"]}]} \ No newline at end of file diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/top_level.txt b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/top_level.txt new file mode 100644 index 0000000..4577c6a --- /dev/null +++ b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/top_level.txt @@ -0,0 +1,3 @@ +easy_install +pkg_resources +setuptools diff --git a/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/zip-safe b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/setuptools-20.2.2.dist-info/zip-safe @@ -0,0 +1 @@ + diff --git a/Shared/lib/python3.4/site-packages/setuptools/command/easy_install.py b/Shared/lib/python3.4/site-packages/setuptools/command/easy_install.py index 4605617..9fc287e 100644 --- a/Shared/lib/python3.4/site-packages/setuptools/command/easy_install.py +++ b/Shared/lib/python3.4/site-packages/setuptools/command/easy_install.py @@ -136,13 +136,15 @@ class easy_install(Command): ('local-snapshots-ok', 'l', "allow building eggs from local checkouts"), ('version', None, "print version information and exit"), + ('install-layout=', None, "installation layout to choose (known values: deb)"), + ('force-installation-into-system-dir', '0', "force installation into /usr"), ('no-find-links', None, "Don't load find-links defined in packages being installed") ] boolean_options = [ 'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy', 'editable', - 'no-deps', 'local-snapshots-ok', 'version' + 'no-deps', 'local-snapshots-ok', 'version', 'force-installation-into-system-dir' ] if site.ENABLE_USER_SITE: @@ -190,6 +192,11 @@ class easy_install(Command): self.site_dirs = None self.installed_projects = {} self.sitepy_installed = False + # enable custom installation, known values: deb + self.install_layout = None + self.force_installation_into_system_dir = None + self.multiarch = None + # Always read easy_install options, even if we are subclassed, or have # an independent instance created. This ensures that defaults will # always come from the standard configuration file(s)' "easy_install" @@ -258,6 +265,13 @@ class easy_install(Command): self.expand_basedirs() self.expand_dirs() + if self.install_layout: + if not self.install_layout.lower() in ['deb']: + raise DistutilsOptionError("unknown value for --install-layout") + self.install_layout = self.install_layout.lower() + import sysconfig + if sys.version_info[:2] >= (3, 3): + self.multiarch = sysconfig.get_config_var('MULTIARCH') self._expand('install_dir', 'script_dir', 'build_directory', 'site_dirs') # If a non-default installation directory was specified, default the @@ -282,6 +296,15 @@ class easy_install(Command): if self.user and self.install_purelib: self.install_dir = self.install_purelib self.script_dir = self.install_scripts + + if self.prefix == '/usr' and not self.force_installation_into_system_dir: + raise DistutilsOptionError("""installation into /usr + +Trying to install into the system managed parts of the file system. Please +consider to install to another location, or use the option +--force-installation-into-system-dir to overwrite this warning. +""") + # default --record from the install command self.set_undefined_options('install', ('record', 'record')) # Should this be moved to the if statement below? It's not used @@ -1277,11 +1300,28 @@ class easy_install(Command): self.debug_print("os.makedirs('%s', 0o700)" % path) os.makedirs(path, 0o700) + if sys.version[:3] in ('2.3', '2.4', '2.5') or 'real_prefix' in sys.__dict__: + sitedir_name = 'site-packages' + else: + sitedir_name = 'dist-packages' + INSTALL_SCHEMES = dict( posix=dict( install_dir='$base/lib/python$py_version_short/site-packages', script_dir='$base/bin', ), + unix_local = dict( + install_dir = '$base/local/lib/python$py_version_short/%s' % sitedir_name, + script_dir = '$base/local/bin', + ), + posix_local = dict( + install_dir = '$base/local/lib/python$py_version_short/%s' % sitedir_name, + script_dir = '$base/local/bin', + ), + deb_system = dict( + install_dir = '$base/lib/python3/%s' % sitedir_name, + script_dir = '$base/bin', + ), ) DEFAULT_SCHEME = dict( @@ -1292,11 +1332,18 @@ class easy_install(Command): def _expand(self, *attrs): config_vars = self.get_finalized_command('install').config_vars - if self.prefix: + if self.prefix or self.install_layout: + if self.install_layout and self.install_layout in ['deb']: + scheme_name = "deb_system" + self.prefix = '/usr' + elif self.prefix or 'real_prefix' in sys.__dict__: + scheme_name = os.name + else: + scheme_name = "posix_local" # Set default install_dir/scripts from --prefix config_vars = config_vars.copy() config_vars['base'] = self.prefix - scheme = self.INSTALL_SCHEMES.get(os.name, self.DEFAULT_SCHEME) + scheme = self.INSTALL_SCHEMES.get(scheme_name,self.DEFAULT_SCHEME) for attr, val in scheme.items(): if getattr(self, attr, None) is None: setattr(self, attr, val) @@ -1330,9 +1377,14 @@ def get_site_dirs(): "site-packages"), os.path.join(prefix, "lib", "site-python")]) else: + if sys.version[:3] in ('2.3', '2.4', '2.5'): + sdir = "site-packages" + else: + sdir = "dist-packages" sitedirs.extend( - [prefix, os.path.join(prefix, "lib", "site-packages")] - ) + [os.path.join(prefix, "local/lib", "python" + sys.version[:3], sdir), + os.path.join(prefix, "lib", "python" + sys.version[:3], sdir)] + ) if sys.platform == 'darwin': # for framework builds *only* we add the standard Apple # locations. Currently only per-user, but /Library and diff --git a/Shared/lib/python3.4/site-packages/setuptools/command/install_egg_info.py b/Shared/lib/python3.4/site-packages/setuptools/command/install_egg_info.py index 60b615d..ae0325d 100644 --- a/Shared/lib/python3.4/site-packages/setuptools/command/install_egg_info.py +++ b/Shared/lib/python3.4/site-packages/setuptools/command/install_egg_info.py @@ -1,5 +1,5 @@ from distutils import log, dir_util -import os +import os, sys from setuptools.extern.six.moves import map @@ -19,14 +19,31 @@ class install_egg_info(Command): def initialize_options(self): self.install_dir = None + self.install_layout = None + self.prefix_option = None def finalize_options(self): self.set_undefined_options('install_lib', ('install_dir', 'install_dir')) + self.set_undefined_options('install',('install_layout','install_layout')) + if sys.hexversion > 0x2060000: + self.set_undefined_options('install',('prefix_option','prefix_option')) ei_cmd = self.get_finalized_command("egg_info") basename = pkg_resources.Distribution( None, None, ei_cmd.egg_name, ei_cmd.egg_version ).egg_name() + '.egg-info' + + if self.install_layout: + if not self.install_layout.lower() in ['deb']: + raise DistutilsOptionError("unknown value for --install-layout") + self.install_layout = self.install_layout.lower() + basename = basename.replace('-py%s' % pkg_resources.PY_MAJOR, '') + elif self.prefix_option or 'real_prefix' in sys.__dict__: + # don't modify for virtualenv + pass + else: + basename = basename.replace('-py%s' % pkg_resources.PY_MAJOR, '') + self.source = ei_cmd.egg_info self.target = os.path.join(self.install_dir, basename) self.outputs = [] @@ -56,6 +73,9 @@ class install_egg_info(Command): for skip in '.svn/', 'CVS/': if src.startswith(skip) or '/' + skip in src: return None + if self.install_layout and self.install_layout in ['deb'] and src.startswith('SOURCES.txt'): + log.info("Skipping SOURCES.txt") + return None self.outputs.append(dst) log.debug("Copying %s to %s", src, dst) return dst diff --git a/Shared/lib/python3.4/site-packages/setuptools/command/install_lib.py b/Shared/lib/python3.4/site-packages/setuptools/command/install_lib.py index 78fe689..696b776 100644 --- a/Shared/lib/python3.4/site-packages/setuptools/command/install_lib.py +++ b/Shared/lib/python3.4/site-packages/setuptools/command/install_lib.py @@ -1,4 +1,5 @@ import os +import sys import imp from itertools import product, starmap import distutils.command.install_lib as orig @@ -6,6 +7,18 @@ import distutils.command.install_lib as orig class install_lib(orig.install_lib): """Don't add compiled flags to filenames of non-Python files""" + def initialize_options(self): + orig.install_lib.initialize_options(self) + self.multiarch = None + self.install_layout = None + + def finalize_options(self): + orig.install_lib.finalize_options(self) + self.set_undefined_options('install',('install_layout','install_layout')) + if self.install_layout == 'deb' and sys.version_info[:2] >= (3, 3): + import sysconfig + self.multiarch = sysconfig.get_config_var('MULTIARCH') + def run(self): self.build() outfiles = self.install() @@ -90,6 +103,8 @@ class install_lib(orig.install_lib): exclude = self.get_exclusions() if not exclude: + import distutils.dir_util + distutils.dir_util._multiarch = self.multiarch return orig.install_lib.copy_tree(self, infile, outfile) # Exclude namespace package __init__.py* files from the output @@ -99,12 +114,24 @@ class install_lib(orig.install_lib): outfiles = [] + if self.multiarch: + import sysconfig + ext_suffix = sysconfig.get_config_var ('EXT_SUFFIX') + if ext_suffix.endswith(self.multiarch + ext_suffix[-3:]): + new_suffix = None + else: + new_suffix = "%s-%s%s" % (ext_suffix[:-3], self.multiarch, ext_suffix[-3:]) + def pf(src, dst): if dst in exclude: log.warn("Skipping installation of %s (namespace package)", dst) return False + if self.multiarch and new_suffix and dst.endswith(ext_suffix) and not dst.endswith(new_suffix): + dst = dst.replace(ext_suffix, new_suffix) + log.info("renaming extension to %s", os.path.basename(dst)) + log.info("copying %s -> %s", src, os.path.dirname(dst)) outfiles.append(dst) return dst diff --git a/Shared/lib/python3.4/site-packages/six-1.10.0.dist-info/RECORD b/Shared/lib/python3.4/site-packages/six-1.10.0.dist-info/RECORD index 18401a3..f4ec904 100644 --- a/Shared/lib/python3.4/site-packages/six-1.10.0.dist-info/RECORD +++ b/Shared/lib/python3.4/site-packages/six-1.10.0.dist-info/RECORD @@ -5,5 +5,5 @@ six-1.10.0.dist-info/RECORD,, six-1.10.0.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 six-1.10.0.dist-info/metadata.json,sha256=jtOeeTBubYDChl_5Ql5ZPlKoHgg6rdqRIjOz1e5Ek2U,658 six-1.10.0.dist-info/top_level.txt,sha256=_iVH_iYEtEXnD8nYGQYpYFUvkUW9sEO1GYbkeKSAais,4 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/lib/python3.4/site-packages/six-1.10.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +six-1.10.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 __pycache__/six.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/sqlitedict-1.4.0.dist-info/RECORD b/Shared/lib/python3.4/site-packages/sqlitedict-1.4.0.dist-info/RECORD index 953b6c1..bdb8a03 100644 --- a/Shared/lib/python3.4/site-packages/sqlitedict-1.4.0.dist-info/RECORD +++ b/Shared/lib/python3.4/site-packages/sqlitedict-1.4.0.dist-info/RECORD @@ -6,5 +6,5 @@ sqlitedict-1.4.0.dist-info/WHEEL,sha256=lCqt3ViRAf9c8mCs6o7ffkwROUdYSy8_YHn5f_ru sqlitedict-1.4.0.dist-info/metadata.json,sha256=Gu_BazsbomIjBcE4XjoiZV6U7DUJpWklZudlIYduauI,1070 sqlitedict-1.4.0.dist-info/pbr.json,sha256=wraF_0ld56r3l9udmVdBYB-N7W8nh7Ax8-HRVqiGRFE,46 sqlitedict-1.4.0.dist-info/top_level.txt,sha256=gRsHHG_lHd0G92cPsIV8dhQS7yZfJUYW5GY_oqapYik,11 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/lib/python3.4/site-packages/sqlitedict-1.4.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +sqlitedict-1.4.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 __pycache__/sqlitedict.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/stem-1.4.0.dist-info/RECORD b/Shared/lib/python3.4/site-packages/stem-1.4.0.dist-info/RECORD index 936586c..f3756f7 100644 --- a/Shared/lib/python3.4/site-packages/stem-1.4.0.dist-info/RECORD +++ b/Shared/lib/python3.4/site-packages/stem-1.4.0.dist-info/RECORD @@ -52,49 +52,49 @@ stem-1.4.0.dist-info/RECORD,, stem-1.4.0.dist-info/WHEEL,sha256=lCqt3ViRAf9c8mCs6o7ffkwROUdYSy8_YHn5f_rulB4,93 stem-1.4.0.dist-info/metadata.json,sha256=_FibkGOQ6hFO-jAnIVQ-8FasdcMDbn7E5yI_b8QfV84,282 stem-1.4.0.dist-info/top_level.txt,sha256=_Fv_hT3iFjDmFwOMcKq7iIsbarreb2UO1-H2frEcwHU,5 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/lib/python3.4/site-packages/stem-1.4.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -stem/__pycache__/control.cpython-34.pyc,, -stem/interpreter/__pycache__/__init__.cpython-34.pyc,, -stem/response/__pycache__/getinfo.cpython-34.pyc,, -stem/descriptor/__pycache__/reader.cpython-34.pyc,, +stem-1.4.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 stem/__pycache__/socket.cpython-34.pyc,, -stem/util/__pycache__/conf.cpython-34.pyc,, -stem/interpreter/__pycache__/help.cpython-34.pyc,, -stem/interpreter/__pycache__/autocomplete.cpython-34.pyc,, -stem/__pycache__/prereq.cpython-34.pyc,, -stem/util/__pycache__/system.cpython-34.pyc,, -stem/descriptor/__pycache__/extrainfo_descriptor.cpython-34.pyc,, -stem/descriptor/__pycache__/export.cpython-34.pyc,, -stem/response/__pycache__/events.cpython-34.pyc,, -stem/util/__pycache__/tor_tools.cpython-34.pyc,, +stem/descriptor/__pycache__/reader.cpython-34.pyc,, +stem/interpreter/__pycache__/commands.cpython-34.pyc,, +stem/util/__pycache__/test_tools.cpython-34.pyc,, +stem/descriptor/__pycache__/tordnsel.cpython-34.pyc,, +stem/descriptor/__pycache__/networkstatus.cpython-34.pyc,, stem/util/__pycache__/term.cpython-34.pyc,, -stem/util/__pycache__/str_tools.cpython-34.pyc,, -stem/util/__pycache__/__init__.cpython-34.pyc,, -stem/response/__pycache__/protocolinfo.cpython-34.pyc,, -stem/util/__pycache__/enum.cpython-34.pyc,, -stem/util/__pycache__/proc.cpython-34.pyc,, -stem/util/__pycache__/connection.cpython-34.pyc,, +stem/__pycache__/control.cpython-34.pyc,, +stem/response/__pycache__/getinfo.cpython-34.pyc,, +stem/__pycache__/exit_policy.cpython-34.pyc,, +stem/util/__pycache__/conf.cpython-34.pyc,, stem/__pycache__/connection.cpython-34.pyc,, +stem/util/__pycache__/log.cpython-34.pyc,, +stem/descriptor/__pycache__/export.cpython-34.pyc,, +stem/descriptor/__pycache__/remote.cpython-34.pyc,, +stem/util/__pycache__/__init__.cpython-34.pyc,, +stem/__pycache__/prereq.cpython-34.pyc,, +stem/util/__pycache__/enum.cpython-34.pyc,, +stem/interpreter/__pycache__/__init__.cpython-34.pyc,, +stem/interpreter/__pycache__/autocomplete.cpython-34.pyc,, +stem/util/__pycache__/str_tools.cpython-34.pyc,, stem/util/__pycache__/lru_cache.cpython-34.pyc,, stem/descriptor/__pycache__/server_descriptor.cpython-34.pyc,, +stem/response/__pycache__/events.cpython-34.pyc,, stem/__pycache__/process.cpython-34.pyc,, +stem/util/__pycache__/proc.cpython-34.pyc,, stem/response/__pycache__/mapaddress.cpython-34.pyc,, -stem/util/__pycache__/test_tools.cpython-34.pyc,, -stem/response/__pycache__/__init__.cpython-34.pyc,, -stem/descriptor/__pycache__/router_status_entry.cpython-34.pyc,, -stem/descriptor/__pycache__/networkstatus.cpython-34.pyc,, -stem/__pycache__/version.cpython-34.pyc,, -stem/descriptor/__pycache__/hidden_service_descriptor.cpython-34.pyc,, -stem/interpreter/__pycache__/arguments.cpython-34.pyc,, -stem/util/__pycache__/ordereddict.cpython-34.pyc,, -stem/interpreter/__pycache__/commands.cpython-34.pyc,, -stem/descriptor/__pycache__/__init__.cpython-34.pyc,, -stem/__pycache__/exit_policy.cpython-34.pyc,, -stem/__pycache__/__init__.cpython-34.pyc,, -stem/util/__pycache__/log.cpython-34.pyc,, -stem/descriptor/__pycache__/remote.cpython-34.pyc,, stem/response/__pycache__/getconf.cpython-34.pyc,, +stem/response/__pycache__/protocolinfo.cpython-34.pyc,, stem/response/__pycache__/add_onion.cpython-34.pyc,, +stem/util/__pycache__/ordereddict.cpython-34.pyc,, +stem/descriptor/__pycache__/router_status_entry.cpython-34.pyc,, +stem/descriptor/__pycache__/hidden_service_descriptor.cpython-34.pyc,, +stem/__pycache__/version.cpython-34.pyc,, stem/response/__pycache__/authchallenge.cpython-34.pyc,, -stem/descriptor/__pycache__/tordnsel.cpython-34.pyc,, +stem/util/__pycache__/connection.cpython-34.pyc,, +stem/response/__pycache__/__init__.cpython-34.pyc,, +stem/interpreter/__pycache__/arguments.cpython-34.pyc,, +stem/interpreter/__pycache__/help.cpython-34.pyc,, +stem/descriptor/__pycache__/extrainfo_descriptor.cpython-34.pyc,, +stem/descriptor/__pycache__/__init__.cpython-34.pyc,, +stem/util/__pycache__/tor_tools.cpython-34.pyc,, +stem/__pycache__/__init__.cpython-34.pyc,, stem/descriptor/__pycache__/microdescriptor.cpython-34.pyc,, +stem/util/__pycache__/system.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/tornado-4.3.dist-info/RECORD b/Shared/lib/python3.4/site-packages/tornado-4.3.dist-info/RECORD index ae39efd..d17b3a0 100644 --- a/Shared/lib/python3.4/site-packages/tornado-4.3.dist-info/RECORD +++ b/Shared/lib/python3.4/site-packages/tornado-4.3.dist-info/RECORD @@ -96,82 +96,82 @@ tornado-4.3.dist-info/RECORD,, tornado-4.3.dist-info/WHEEL,sha256=HslHw5cSLCuyOLxj8duGAooHNvXnupcmoBU1NzRPr2w,104 tornado-4.3.dist-info/metadata.json,sha256=SdpUqt7g_ebcnkms9OevniGL2L3BKJ1Pu3vf4UF8gOs,1073 tornado-4.3.dist-info/top_level.txt,sha256=5QAK1MeNpWgYdqWoU8iYlDuGB8j6NDPgx-uSUHTe0A4,8 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/lib/python3.4/site-packages/tornado-4.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -tornado/__pycache__/locale.cpython-34.pyc,, -tornado/__pycache__/tcpclient.cpython-34.pyc,, -tornado/__pycache__/httpserver.cpython-34.pyc,, -tornado/__pycache__/websocket.cpython-34.pyc,, -tornado/test/__pycache__/import_test.cpython-34.pyc,, -tornado/platform/__pycache__/common.cpython-34.pyc,, -tornado/test/__pycache__/websocket_test.cpython-34.pyc,, -tornado/test/__pycache__/tcpclient_test.cpython-34.pyc,, -tornado/__pycache__/web.cpython-34.pyc,, -tornado/test/__pycache__/queues_test.cpython-34.pyc,, -tornado/test/__pycache__/options_test.cpython-34.pyc,, -tornado/test/__pycache__/__main__.cpython-34.pyc,, -tornado/__pycache__/tcpserver.cpython-34.pyc,, -tornado/platform/__pycache__/posix.cpython-34.pyc,, -tornado/__pycache__/http1connection.cpython-34.pyc,, -tornado/test/__pycache__/__init__.cpython-34.pyc,, -tornado/test/__pycache__/tcpserver_test.cpython-34.pyc,, -tornado/test/__pycache__/netutil_test.cpython-34.pyc,, -tornado/__pycache__/_locale_data.cpython-34.pyc,, -tornado/test/__pycache__/escape_test.cpython-34.pyc,, +tornado-4.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 tornado/test/__pycache__/twisted_test.cpython-34.pyc,, -tornado/__pycache__/curl_httpclient.cpython-34.pyc,, -tornado/__pycache__/options.cpython-34.pyc,, -tornado/__pycache__/httputil.cpython-34.pyc,, -tornado/test/__pycache__/locks_test.cpython-34.pyc,, -tornado/test/__pycache__/runtests.cpython-34.pyc,, -tornado/test/__pycache__/asyncio_test.cpython-34.pyc,, -tornado/test/__pycache__/resolve_test_helper.cpython-34.pyc,, -tornado/platform/__pycache__/twisted.cpython-34.pyc,, -tornado/platform/__pycache__/interface.cpython-34.pyc,, -tornado/platform/__pycache__/kqueue.cpython-34.pyc,, -tornado/test/__pycache__/httputil_test.cpython-34.pyc,, -tornado/__pycache__/netutil.cpython-34.pyc,, -tornado/platform/__pycache__/select.cpython-34.pyc,, -tornado/test/__pycache__/web_test.cpython-34.pyc,, -tornado/__pycache__/auth.cpython-34.pyc,, -tornado/test/__pycache__/locale_test.cpython-34.pyc,, -tornado/platform/__pycache__/windows.cpython-34.pyc,, -tornado/__pycache__/__init__.cpython-34.pyc,, -tornado/__pycache__/ioloop.cpython-34.pyc,, -tornado/platform/__pycache__/asyncio.cpython-34.pyc,, -tornado/test/__pycache__/testing_test.cpython-34.pyc,, -tornado/__pycache__/iostream.cpython-34.pyc,, -tornado/__pycache__/gen.cpython-34.pyc,, -tornado/__pycache__/concurrent.cpython-34.pyc,, -tornado/test/__pycache__/wsgi_test.cpython-34.pyc,, -tornado/__pycache__/process.cpython-34.pyc,, -tornado/__pycache__/queues.cpython-34.pyc,, -tornado/test/__pycache__/util.cpython-34.pyc,, -tornado/__pycache__/template.cpython-34.pyc,, -tornado/test/__pycache__/log_test.cpython-34.pyc,, tornado/test/__pycache__/stack_context_test.cpython-34.pyc,, -tornado/test/__pycache__/httpserver_test.cpython-34.pyc,, -tornado/platform/__pycache__/caresresolver.cpython-34.pyc,, -tornado/test/__pycache__/process_test.cpython-34.pyc,, tornado/__pycache__/httpclient.cpython-34.pyc,, -tornado/__pycache__/testing.cpython-34.pyc,, -tornado/__pycache__/util.cpython-34.pyc,, -tornado/__pycache__/simple_httpclient.cpython-34.pyc,, -tornado/test/__pycache__/template_test.cpython-34.pyc,, -tornado/__pycache__/stack_context.cpython-34.pyc,, -tornado/__pycache__/wsgi.cpython-34.pyc,, tornado/test/__pycache__/concurrent_test.cpython-34.pyc,, -tornado/test/__pycache__/auth_test.cpython-34.pyc,, -tornado/test/__pycache__/iostream_test.cpython-34.pyc,, -tornado/test/__pycache__/ioloop_test.cpython-34.pyc,, -tornado/test/__pycache__/util_test.cpython-34.pyc,, -tornado/platform/__pycache__/__init__.cpython-34.pyc,, -tornado/__pycache__/autoreload.cpython-34.pyc,, -tornado/__pycache__/locks.cpython-34.pyc,, -tornado/platform/__pycache__/epoll.cpython-34.pyc,, tornado/test/__pycache__/httpclient_test.cpython-34.pyc,, -tornado/test/__pycache__/curl_httpclient_test.cpython-34.pyc,, -tornado/__pycache__/escape.cpython-34.pyc,, -tornado/test/__pycache__/gen_test.cpython-34.pyc,, -tornado/platform/__pycache__/auto.cpython-34.pyc,, -tornado/test/__pycache__/simple_httpclient_test.cpython-34.pyc,, +tornado/test/__pycache__/netutil_test.cpython-34.pyc,, +tornado/platform/__pycache__/posix.cpython-34.pyc,, +tornado/test/__pycache__/testing_test.cpython-34.pyc,, tornado/__pycache__/log.cpython-34.pyc,, +tornado/test/__pycache__/template_test.cpython-34.pyc,, +tornado/platform/__pycache__/kqueue.cpython-34.pyc,, +tornado/__pycache__/escape.cpython-34.pyc,, +tornado/__pycache__/gen.cpython-34.pyc,, +tornado/test/__pycache__/__init__.cpython-34.pyc,, +tornado/platform/__pycache__/__init__.cpython-34.pyc,, +tornado/__pycache__/options.cpython-34.pyc,, +tornado/__pycache__/locale.cpython-34.pyc,, +tornado/__pycache__/simple_httpclient.cpython-34.pyc,, +tornado/__pycache__/util.cpython-34.pyc,, +tornado/test/__pycache__/wsgi_test.cpython-34.pyc,, +tornado/__pycache__/web.cpython-34.pyc,, +tornado/test/__pycache__/tcpserver_test.cpython-34.pyc,, +tornado/test/__pycache__/import_test.cpython-34.pyc,, +tornado/platform/__pycache__/epoll.cpython-34.pyc,, +tornado/__pycache__/_locale_data.cpython-34.pyc,, +tornado/test/__pycache__/httpserver_test.cpython-34.pyc,, +tornado/platform/__pycache__/twisted.cpython-34.pyc,, +tornado/__pycache__/__init__.cpython-34.pyc,, +tornado/__pycache__/tcpserver.cpython-34.pyc,, +tornado/test/__pycache__/gen_test.cpython-34.pyc,, +tornado/test/__pycache__/util_test.cpython-34.pyc,, +tornado/platform/__pycache__/asyncio.cpython-34.pyc,, +tornado/__pycache__/autoreload.cpython-34.pyc,, +tornado/__pycache__/iostream.cpython-34.pyc,, +tornado/__pycache__/queues.cpython-34.pyc,, +tornado/__pycache__/httpserver.cpython-34.pyc,, +tornado/__pycache__/auth.cpython-34.pyc,, +tornado/__pycache__/template.cpython-34.pyc,, +tornado/__pycache__/stack_context.cpython-34.pyc,, +tornado/__pycache__/process.cpython-34.pyc,, +tornado/test/__pycache__/iostream_test.cpython-34.pyc,, +tornado/test/__pycache__/asyncio_test.cpython-34.pyc,, +tornado/__pycache__/tcpclient.cpython-34.pyc,, +tornado/test/__pycache__/tcpclient_test.cpython-34.pyc,, +tornado/test/__pycache__/httputil_test.cpython-34.pyc,, +tornado/test/__pycache__/process_test.cpython-34.pyc,, +tornado/__pycache__/wsgi.cpython-34.pyc,, +tornado/test/__pycache__/web_test.cpython-34.pyc,, +tornado/test/__pycache__/util.cpython-34.pyc,, +tornado/test/__pycache__/runtests.cpython-34.pyc,, +tornado/platform/__pycache__/auto.cpython-34.pyc,, +tornado/test/__pycache__/__main__.cpython-34.pyc,, +tornado/test/__pycache__/simple_httpclient_test.cpython-34.pyc,, +tornado/test/__pycache__/auth_test.cpython-34.pyc,, +tornado/__pycache__/ioloop.cpython-34.pyc,, +tornado/__pycache__/locks.cpython-34.pyc,, +tornado/test/__pycache__/escape_test.cpython-34.pyc,, +tornado/__pycache__/testing.cpython-34.pyc,, +tornado/test/__pycache__/curl_httpclient_test.cpython-34.pyc,, +tornado/__pycache__/curl_httpclient.cpython-34.pyc,, +tornado/test/__pycache__/ioloop_test.cpython-34.pyc,, +tornado/platform/__pycache__/caresresolver.cpython-34.pyc,, +tornado/__pycache__/netutil.cpython-34.pyc,, +tornado/test/__pycache__/options_test.cpython-34.pyc,, +tornado/__pycache__/concurrent.cpython-34.pyc,, +tornado/test/__pycache__/resolve_test_helper.cpython-34.pyc,, +tornado/platform/__pycache__/windows.cpython-34.pyc,, +tornado/test/__pycache__/locks_test.cpython-34.pyc,, +tornado/test/__pycache__/locale_test.cpython-34.pyc,, +tornado/test/__pycache__/websocket_test.cpython-34.pyc,, +tornado/__pycache__/httputil.cpython-34.pyc,, +tornado/test/__pycache__/log_test.cpython-34.pyc,, +tornado/__pycache__/http1connection.cpython-34.pyc,, +tornado/platform/__pycache__/select.cpython-34.pyc,, +tornado/test/__pycache__/queues_test.cpython-34.pyc,, +tornado/platform/__pycache__/interface.cpython-34.pyc,, +tornado/__pycache__/websocket.cpython-34.pyc,, +tornado/platform/__pycache__/common.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/wheel-0.29.0.dist-info/LICENSE.txt b/Shared/lib/python3.4/site-packages/wheel-0.29.0.dist-info/LICENSE.txt deleted file mode 100644 index c3441e6..0000000 --- a/Shared/lib/python3.4/site-packages/wheel-0.29.0.dist-info/LICENSE.txt +++ /dev/null @@ -1,22 +0,0 @@ -"wheel" copyright (c) 2012-2014 Daniel Holth and -contributors. - -The MIT License - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/Shared/lib/python3.4/site-packages/wheel-0.29.0.dist-info/RECORD b/Shared/lib/python3.4/site-packages/wheel-0.29.0.dist-info/RECORD index 15473ef..cbdf946 100644 --- a/Shared/lib/python3.4/site-packages/wheel-0.29.0.dist-info/RECORD +++ b/Shared/lib/python3.4/site-packages/wheel-0.29.0.dist-info/RECORD @@ -18,7 +18,7 @@ wheel/signatures/ed25519py.py,sha256=SeTxiMZ7kmoMdIurBSaKb8Ku-amGnf6ZTRGElLzV8iI wheel/signatures/keys.py,sha256=x3g4sAcs7KbIHM-5V8KWdMc24_VK7VeD-pjCyktNnYo,3320 wheel/test/__init__.py,sha256=M0NZuQ7-112l8K2h1eayVvSmvQrufrOcD5AYKgIf_Is,1 wheel/test/pydist-schema.json,sha256=ynEvNvThC1zRa7FioMsW3k-9nl98ytEoo1_3xbOP2eo,11483 -wheel/test/test-1.0-py2.py3-none-win32.whl,sha256=JC_UXTN5KlLrdu43uH4caZSUyzrtPcUsRe-vTMunplE,5226 +wheel/test/test-1.0-py2.py3-none-win32.whl,sha256=tCbefJJ7RpQJReRQaSRiwnTDM-YDlBpbcX9Rjcv9bf4,5224 wheel/test/test_basic.py,sha256=2DIvjApcshiLpXVsEhXvN3l62ZrwS0jJcWK8SyASoNU,6405 wheel/test/test_install.py,sha256=c0EECXPkVIGhCD9V5ad2qsBPRPYb1ehhaS0k6Gv5JQc,1866 wheel/test/test_keys.py,sha256=5mBc9tf2TwC3TCpx1ySTYsCe5yvd6kMK64AlUUCcKEY,2575 @@ -37,46 +37,45 @@ wheel/test/simple.dist/setup.py,sha256=8zWen71Um-iN_A5thot6VFogrkWs_RGVO-jr_MxkF wheel/test/simple.dist/simpledist/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 wheel/tool/__init__.py,sha256=anweXjmIg4EIHPkH0kOgcTx-gyOmzE4ieRe2yk-aHDA,13229 wheel-0.29.0.dist-info/DESCRIPTION.rst,sha256=JH6mogUIatQVQewIh4GB1ywCxuWbm7G4TjI_63dURp8,9813 -wheel-0.29.0.dist-info/LICENSE.txt,sha256=zKniDGrx_Pv2lAjzd3aShsvuvN7TNhAMm0o_NfvmNeQ,1125 wheel-0.29.0.dist-info/METADATA,sha256=SA310hLnZJJFgp1TRwFLCIiXurVwKpIq2w3KWhMdgdo,11019 wheel-0.29.0.dist-info/RECORD,, wheel-0.29.0.dist-info/WHEEL,sha256=o2k-Qa-RMNIJmUdIc7KU6VWR_ErNRbWNlxDIpl7lm34,110 wheel-0.29.0.dist-info/entry_points.txt,sha256=2LFQDKAUKNMG-2zNtbLscfirPr9BEqBuwc-JALCv-D0,107 -wheel-0.29.0.dist-info/metadata.json,sha256=kNhUbqu0cIQt0fnVbbbNZer4avDz8L4xhg0rPFL6Lqk,1621 +wheel-0.29.0.dist-info/metadata.json,sha256=dxlCIm4231kQk4VlVdiN5ABz3l0nWY3gQ9HPoDammlU,1510 wheel-0.29.0.dist-info/top_level.txt,sha256=HxSBIbgEstMPe4eFawhA66Mq-QYHMopXVoAncfjb_1c,6 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/bin/wheel,sha256=7tQwd7-yYmSKP07JBIwhFWPH68YseSftvBL19P0Ct5Y,277 -/var/lib/lxc/openmedialibrary/rootfs/srv/client/platform/Shared/p34/lib/python3.4/site-packages/wheel-0.29.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -wheel/test/__pycache__/test_wheelfile.cpython-34.pyc,, -wheel/test/__pycache__/test_ranking.cpython-34.pyc,, -wheel/test/__pycache__/__init__.cpython-34.pyc,, -wheel/test/__pycache__/test_basic.cpython-34.pyc,, -wheel/test/complex-dist/complexdist/__pycache__/__init__.cpython-34.pyc,, -wheel/test/headers.dist/__pycache__/setup.cpython-34.pyc,, -wheel/test/simple.dist/simpledist/__pycache__/__init__.cpython-34.pyc,, +../../../bin/wheel,sha256=7tQwd7-yYmSKP07JBIwhFWPH68YseSftvBL19P0Ct5Y,277 +wheel-0.29.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 wheel/test/__pycache__/test_tool.cpython-34.pyc,, wheel/test/headers.dist/__pycache__/headersdist.cpython-34.pyc,, -wheel/test/__pycache__/test_keys.cpython-34.pyc,, +wheel/test/__pycache__/test_signatures.cpython-34.pyc,, +wheel/test/__pycache__/__init__.cpython-34.pyc,, wheel/test/complex-dist/__pycache__/setup.cpython-34.pyc,, -wheel/__pycache__/bdist_wheel.cpython-34.pyc,, -wheel/signatures/__pycache__/djbec.cpython-34.pyc,, -wheel/__pycache__/install.cpython-34.pyc,, -wheel/test/simple.dist/__pycache__/setup.cpython-34.pyc,, -wheel/__pycache__/egg2wheel.cpython-34.pyc,, -wheel/test/__pycache__/test_install.cpython-34.pyc,, -wheel/__pycache__/decorator.cpython-34.pyc,, -wheel/__pycache__/archive.cpython-34.pyc,, wheel/__pycache__/wininst2wheel.cpython-34.pyc,, wheel/test/__pycache__/test_tagopt.cpython-34.pyc,, -wheel/signatures/__pycache__/keys.cpython-34.pyc,, -wheel/__pycache__/paths.cpython-34.pyc,, +wheel/test/__pycache__/test_install.cpython-34.pyc,, wheel/__pycache__/metadata.cpython-34.pyc,, -wheel/tool/__pycache__/__init__.cpython-34.pyc,, -wheel/signatures/__pycache__/ed25519py.cpython-34.pyc,, -wheel/signatures/__pycache__/__init__.cpython-34.pyc,, -wheel/test/__pycache__/test_signatures.cpython-34.pyc,, -wheel/__pycache__/util.cpython-34.pyc,, +wheel/__pycache__/archive.cpython-34.pyc,, +wheel/test/simple.dist/simpledist/__pycache__/__init__.cpython-34.pyc,, wheel/test/__pycache__/test_paths.cpython-34.pyc,, +wheel/test/__pycache__/test_ranking.cpython-34.pyc,, wheel/__pycache__/__main__.cpython-34.pyc,, -wheel/__pycache__/__init__.cpython-34.pyc,, -wheel/__pycache__/pep425tags.cpython-34.pyc,, +wheel/test/__pycache__/test_keys.cpython-34.pyc,, wheel/__pycache__/pkginfo.cpython-34.pyc,, +wheel/signatures/__pycache__/djbec.cpython-34.pyc,, +wheel/signatures/__pycache__/__init__.cpython-34.pyc,, +wheel/test/complex-dist/complexdist/__pycache__/__init__.cpython-34.pyc,, +wheel/signatures/__pycache__/ed25519py.cpython-34.pyc,, +wheel/__pycache__/paths.cpython-34.pyc,, +wheel/__pycache__/__init__.cpython-34.pyc,, +wheel/test/headers.dist/__pycache__/setup.cpython-34.pyc,, +wheel/__pycache__/egg2wheel.cpython-34.pyc,, +wheel/test/__pycache__/test_wheelfile.cpython-34.pyc,, +wheel/tool/__pycache__/__init__.cpython-34.pyc,, +wheel/__pycache__/decorator.cpython-34.pyc,, +wheel/test/__pycache__/test_basic.cpython-34.pyc,, +wheel/__pycache__/util.cpython-34.pyc,, +wheel/__pycache__/bdist_wheel.cpython-34.pyc,, +wheel/signatures/__pycache__/keys.cpython-34.pyc,, +wheel/__pycache__/install.cpython-34.pyc,, +wheel/__pycache__/pep425tags.cpython-34.pyc,, +wheel/test/simple.dist/__pycache__/setup.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/wheel-0.29.0.dist-info/metadata.json b/Shared/lib/python3.4/site-packages/wheel-0.29.0.dist-info/metadata.json index 35244ea..1a42ef9 100644 --- a/Shared/lib/python3.4/site-packages/wheel-0.29.0.dist-info/metadata.json +++ b/Shared/lib/python3.4/site-packages/wheel-0.29.0.dist-info/metadata.json @@ -1 +1 @@ -{"classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: Developers", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4"], "extensions": {"python.commands": {"wrap_console": {"wheel": "wheel.tool:main"}}, "python.details": {"contacts": [{"email": "dholth@fastmail.fm", "name": "Daniel Holth", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "https://bitbucket.org/pypa/wheel/"}}, "python.exports": {"console_scripts": {"wheel": "wheel.tool:main"}, "distutils.commands": {"bdist_wheel": "wheel.bdist_wheel:bdist_wheel"}}}, "extras": ["faster-signatures", "signatures", "tool"], "generator": "bdist_wheel (0.29.0)", "keywords": ["wheel", "packaging"], "license": "MIT", "metadata_version": "2.0", "name": "wheel", "run_requires": [{"extra": "faster-signatures", "requires": ["ed25519ll"]}, {"extra": "signatures", "requires": ["keyring", "keyrings.alt"]}, {"environment": "python_version==\"2.6\"", "requires": ["argparse"]}, {"environment": "python_version==\"2.6\"", "extra": "signatures", "requires": ["importlib"]}, {"environment": "sys_platform!=\"win32\"", "extra": "signatures", "requires": ["pyxdg"]}], "summary": "A built-package format for Python.", "test_requires": [{"requires": ["coverage", "jsonschema", "pytest", "pytest-cov"]}], "version": "0.29.0"} \ No newline at end of file +{"classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: Developers", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4"], "extensions": {"python.commands": {"wrap_console": {"wheel": "wheel.tool:main"}}, "python.details": {"contacts": [{"email": "dholth@fastmail.fm", "name": "Daniel Holth", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://bitbucket.org/pypa/wheel/"}}, "python.exports": {"console_scripts": {"wheel": "wheel.tool:main"}, "distutils.commands": {"bdist_wheel": "wheel.bdist_wheel:bdist_wheel"}}}, "extras": ["faster-signatures", "signatures", "tool"], "generator": "bdist_wheel (0.29.0)", "keywords": ["wheel", "packaging"], "license": "MIT", "metadata_version": "2.0", "name": "wheel", "run_requires": [{"extra": "faster-signatures", "requires": ["ed25519ll"]}, {"extra": "signatures", "requires": ["keyring", "keyrings.alt"]}, {"environment": "python_version==\"2.6\"", "requires": ["argparse"]}, {"environment": "python_version==\"2.6\"", "extra": "signatures", "requires": ["importlib"]}, {"environment": "sys_platform!=\"win32\"", "extra": "signatures", "requires": ["pyxdg"]}], "summary": "A built-package format for Python.", "version": "0.29.0"} \ No newline at end of file diff --git a/Shared/lib/python3.4/site-packages/wheel/test/test-1.0-py2.py3-none-win32.whl b/Shared/lib/python3.4/site-packages/wheel/test/test-1.0-py2.py3-none-win32.whl index dfd307037d1954471a6eab339b103bd6f781ae07..095583e337128a39ae7dfbf093199cb0909d3f0c 100644 GIT binary patch delta 410 zcmaE*@j`rVbZ}9}MfQ*EX9-~2$tP1%r3&p1~P^d N2(y7^J_iLg0|164Ue*8r delta 422 zcmaE%@k)a)z?+#xgn@y9gMn>hh{Hy{V?1me3^(Wc+E3=>4d6VrA;bYF$-p%EK97t5 zGXp~P4WP{ASY8JfFk>OFGs{Mh$P3;Gmc5l4j+3hd^Lbz>qKC8Q=Y zGB8YJVqlP*9LOiO`6~ZRMm|O+5e9@qCVv++ggGQvNQ&{y92n8m$ zH7f8<_7aj;06FM<&crM(pfCpz%b+L<1Lq~!djQz2U0nbG diff --git a/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/DESCRIPTION.rst b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..e200d8e --- /dev/null +++ b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/DESCRIPTION.rst @@ -0,0 +1,277 @@ +python-zeroconf +=============== + +.. image:: https://travis-ci.org/jstasiak/python-zeroconf.svg?branch=master + :target: https://travis-ci.org/jstasiak/python-zeroconf + +.. image:: https://img.shields.io/pypi/v/zeroconf.svg + :target: https://pypi.python.org/pypi/zeroconf + +.. image:: https://img.shields.io/coveralls/jstasiak/python-zeroconf.svg + :target: https://coveralls.io/r/jstasiak/python-zeroconf + + +This is fork of pyzeroconf, Multicast DNS Service Discovery for Python, +originally by Paul Scott-Murphy (https://github.com/paulsm/pyzeroconf), +modified by William McBrine (https://github.com/wmcbrine/pyzeroconf). + +The original William McBrine's fork note:: + + This fork is used in all of my TiVo-related projects: HME for Python + (and therefore HME/VLC), Network Remote, Remote Proxy, and pyTivo. + Before this, I was tracking the changes for zeroconf.py in three + separate repos. I figured I should have an authoritative source. + + Although I make changes based on my experience with TiVos, I expect that + they're generally applicable. This version also includes patches found + on the now-defunct (?) Launchpad repo of pyzeroconf, and elsewhere + around the net -- not always well-documented, sorry. + +Compatible with: + +* Bonjour +* Avahi + +Compared to some other Zeroconf/Bonjour/Avahi Python packages, python-zeroconf: + +* isn't tied to Bonjour or Avahi +* doesn't use D-Bus +* doesn't force you to use particular event loop or Twisted +* is pip-installable +* has PyPI distribution + +Python compatibility +-------------------- + +* CPython 2.6, 2.7, 3.3+ +* PyPy 2.2+ (possibly 1.9-2.1 as well) +* PyPy3 2.4+ + +Versioning +---------- + +This project's versions follow the following pattern: MAJOR.MINOR.PATCH. + +* MAJOR version has been 0 so far +* MINOR version is incremented on backward incompatible changes +* PATCH version is incremented on backward compatible changes + +Status +------ + +There are some people using this package. I don't actively use it and as such +any help I can offer with regard to any issues is very limited. + + +How to get python-zeroconf? +=========================== + +* PyPI page https://pypi.python.org/pypi/zeroconf +* GitHub project https://github.com/jstasiak/python-zeroconf + +The easiest way to install python-zeroconf is using pip:: + + pip install zeroconf + + + +How do I use it? +================ + +Here's an example: + +.. code-block:: python + + from six.moves import input + from zeroconf import ServiceBrowser, Zeroconf + + + class MyListener(object): + + def remove_service(self, zeroconf, type, name): + print("Service %s removed" % (name,)) + + def add_service(self, zeroconf, type, name): + info = zeroconf.get_service_info(type, name) + print("Service %s added, service info: %s" % (name, info)) + + + zeroconf = Zeroconf() + listener = MyListener() + browser = ServiceBrowser(zeroconf, "_http._tcp.local.", listener) + try: + input("Press enter to exit...\n\n") + finally: + zeroconf.close() + +.. note:: + + Discovery and service registration use *all* available network interfaces by default. + If you want to customize that you need to specify ``interfaces`` argument when + constructing ``Zeroconf`` object (see the code for details). + +See examples directory for more. + +Changelog +========= + +0.17.4 +------ + +* Fixed support for Linux kernel versions < 3.9 (thanks to Giovanni Harting + and Luckydonald, GitHub pull request #26) + +0.17.3 +------ + +* Fixed DNSText repr on Python 3 (it'd crash when the text was longer than + 10 bytes), thanks to Paulus Schoutsen for the patch, GitHub pull request #24 + +0.17.2 +------ + +* Fixed installation on Python 3.4.3+ (was failing because of enum34 dependency + which fails to install on 3.4.3+, changed to depend on enum-compat instead; + thanks to Michael Brennan for the original patch, GitHub pull request #22) + +0.17.1 +------ + +* Fixed EADDRNOTAVAIL when attempting to use dummy network interfaces on Windows, + thanks to daid + +0.17.0 +------ + +* Added some Python dependencies so it's not zero-dependencies anymore +* Improved exception handling (it'll be quieter now) +* Messages are listened to and sent using all available network interfaces + by default (configurable); thanks to Marcus Müller +* Started using logging more freely +* Fixed a bug with binary strings as property values being converted to False + (https://github.com/jstasiak/python-zeroconf/pull/10); thanks to Dr. Seuss +* Added new ``ServiceBrowser`` event handler interface (see the examples) +* PyPy3 now officially supported +* Fixed ServiceInfo repr on Python 3, thanks to Yordan Miladinov + +0.16.0 +------ + +* Set up Python logging and started using it +* Cleaned up code style (includes migrating from camel case to snake case) + +0.15.1 +------ + +* Fixed handling closed socket (GitHub #4) + +0.15 +---- + +* Forked by Jakub Stasiak +* Made Python 3 compatible +* Added setup script, made installable by pip and uploaded to PyPI +* Set up Travis build +* Reformatted the code and moved files around +* Stopped catching BaseException in several places, that could hide errors +* Marked threads as daemonic, they won't keep application alive now + +0.14 +---- + +* Fix for SOL_IP undefined on some systems - thanks Mike Erdely. +* Cleaned up examples. +* Lowercased module name. + +0.13 +---- + +* Various minor changes; see git for details. +* No longer compatible with Python 2.2. Only tested with 2.5-2.7. +* Fork by William McBrine. + +0.12 +---- + +* allow selection of binding interface +* typo fix - Thanks A. M. Kuchlingi +* removed all use of word 'Rendezvous' - this is an API change + +0.11 +---- + +* correction to comments for addListener method +* support for new record types seen from OS X + - IPv6 address + - hostinfo + +* ignore unknown DNS record types +* fixes to name decoding +* works alongside other processes using port 5353 (e.g. on Mac OS X) +* tested against Mac OS X 10.3.2's mDNSResponder +* corrections to removal of list entries for service browser + +0.10 +---- + +* Jonathon Paisley contributed these corrections: + - always multicast replies, even when query is unicast + - correct a pointer encoding problem + - can now write records in any order + - traceback shown on failure + - better TXT record parsing + - server is now separate from name + - can cancel a service browser +* modified some unit tests to accommodate these changes + +0.09 +---- + +* remove all records on service unregistration +* fix DOS security problem with readName + +0.08 +---- + +* changed licensing to LGPL + +0.07 +---- + +* faster shutdown on engine +* pointer encoding of outgoing names +* ServiceBrowser now works +* new unit tests + +0.06 +---- +* small improvements with unit tests +* added defined exception types +* new style objects +* fixed hostname/interface problem +* fixed socket timeout problem +* fixed add_service_listener() typo bug +* using select() for socket reads +* tested on Debian unstable with Python 2.2.2 + +0.05 +---- + +* ensure case insensitivty on domain names +* support for unicast DNS queries + +0.04 +---- + +* added some unit tests +* added __ne__ adjuncts where required +* ensure names end in '.local.' +* timeout on receiving socket for clean shutdown + + +License +======= + +LGPL, see COPYING file for details. + + diff --git a/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/INSTALLER b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/METADATA b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/METADATA new file mode 100644 index 0000000..e099b14 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/METADATA @@ -0,0 +1,310 @@ +Metadata-Version: 2.0 +Name: zeroconf +Version: 0.17.4 +Summary: Pure Python Multicast DNS Service Discovery Library (Bonjour/Avahi compatible) +Home-page: https://github.com/jstasiak/python-zeroconf +Author: Paul Scott-Murphy, William McBrine, Jakub Stasiak +Author-email: UNKNOWN +License: LGPL +Keywords: Bonjour,Avahi,Zeroconf,Multicast DNS,Service Discovery,mDNS +Platform: unix +Platform: linux +Platform: osx +Classifier: Development Status :: 3 - Alpha +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2) +Classifier: Operating System :: POSIX +Classifier: Operating System :: POSIX :: Linux +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Topic :: Software Development :: Libraries +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Dist: enum-compat +Requires-Dist: netifaces +Requires-Dist: six + +python-zeroconf +=============== + +.. image:: https://travis-ci.org/jstasiak/python-zeroconf.svg?branch=master + :target: https://travis-ci.org/jstasiak/python-zeroconf + +.. image:: https://img.shields.io/pypi/v/zeroconf.svg + :target: https://pypi.python.org/pypi/zeroconf + +.. image:: https://img.shields.io/coveralls/jstasiak/python-zeroconf.svg + :target: https://coveralls.io/r/jstasiak/python-zeroconf + + +This is fork of pyzeroconf, Multicast DNS Service Discovery for Python, +originally by Paul Scott-Murphy (https://github.com/paulsm/pyzeroconf), +modified by William McBrine (https://github.com/wmcbrine/pyzeroconf). + +The original William McBrine's fork note:: + + This fork is used in all of my TiVo-related projects: HME for Python + (and therefore HME/VLC), Network Remote, Remote Proxy, and pyTivo. + Before this, I was tracking the changes for zeroconf.py in three + separate repos. I figured I should have an authoritative source. + + Although I make changes based on my experience with TiVos, I expect that + they're generally applicable. This version also includes patches found + on the now-defunct (?) Launchpad repo of pyzeroconf, and elsewhere + around the net -- not always well-documented, sorry. + +Compatible with: + +* Bonjour +* Avahi + +Compared to some other Zeroconf/Bonjour/Avahi Python packages, python-zeroconf: + +* isn't tied to Bonjour or Avahi +* doesn't use D-Bus +* doesn't force you to use particular event loop or Twisted +* is pip-installable +* has PyPI distribution + +Python compatibility +-------------------- + +* CPython 2.6, 2.7, 3.3+ +* PyPy 2.2+ (possibly 1.9-2.1 as well) +* PyPy3 2.4+ + +Versioning +---------- + +This project's versions follow the following pattern: MAJOR.MINOR.PATCH. + +* MAJOR version has been 0 so far +* MINOR version is incremented on backward incompatible changes +* PATCH version is incremented on backward compatible changes + +Status +------ + +There are some people using this package. I don't actively use it and as such +any help I can offer with regard to any issues is very limited. + + +How to get python-zeroconf? +=========================== + +* PyPI page https://pypi.python.org/pypi/zeroconf +* GitHub project https://github.com/jstasiak/python-zeroconf + +The easiest way to install python-zeroconf is using pip:: + + pip install zeroconf + + + +How do I use it? +================ + +Here's an example: + +.. code-block:: python + + from six.moves import input + from zeroconf import ServiceBrowser, Zeroconf + + + class MyListener(object): + + def remove_service(self, zeroconf, type, name): + print("Service %s removed" % (name,)) + + def add_service(self, zeroconf, type, name): + info = zeroconf.get_service_info(type, name) + print("Service %s added, service info: %s" % (name, info)) + + + zeroconf = Zeroconf() + listener = MyListener() + browser = ServiceBrowser(zeroconf, "_http._tcp.local.", listener) + try: + input("Press enter to exit...\n\n") + finally: + zeroconf.close() + +.. note:: + + Discovery and service registration use *all* available network interfaces by default. + If you want to customize that you need to specify ``interfaces`` argument when + constructing ``Zeroconf`` object (see the code for details). + +See examples directory for more. + +Changelog +========= + +0.17.4 +------ + +* Fixed support for Linux kernel versions < 3.9 (thanks to Giovanni Harting + and Luckydonald, GitHub pull request #26) + +0.17.3 +------ + +* Fixed DNSText repr on Python 3 (it'd crash when the text was longer than + 10 bytes), thanks to Paulus Schoutsen for the patch, GitHub pull request #24 + +0.17.2 +------ + +* Fixed installation on Python 3.4.3+ (was failing because of enum34 dependency + which fails to install on 3.4.3+, changed to depend on enum-compat instead; + thanks to Michael Brennan for the original patch, GitHub pull request #22) + +0.17.1 +------ + +* Fixed EADDRNOTAVAIL when attempting to use dummy network interfaces on Windows, + thanks to daid + +0.17.0 +------ + +* Added some Python dependencies so it's not zero-dependencies anymore +* Improved exception handling (it'll be quieter now) +* Messages are listened to and sent using all available network interfaces + by default (configurable); thanks to Marcus Müller +* Started using logging more freely +* Fixed a bug with binary strings as property values being converted to False + (https://github.com/jstasiak/python-zeroconf/pull/10); thanks to Dr. Seuss +* Added new ``ServiceBrowser`` event handler interface (see the examples) +* PyPy3 now officially supported +* Fixed ServiceInfo repr on Python 3, thanks to Yordan Miladinov + +0.16.0 +------ + +* Set up Python logging and started using it +* Cleaned up code style (includes migrating from camel case to snake case) + +0.15.1 +------ + +* Fixed handling closed socket (GitHub #4) + +0.15 +---- + +* Forked by Jakub Stasiak +* Made Python 3 compatible +* Added setup script, made installable by pip and uploaded to PyPI +* Set up Travis build +* Reformatted the code and moved files around +* Stopped catching BaseException in several places, that could hide errors +* Marked threads as daemonic, they won't keep application alive now + +0.14 +---- + +* Fix for SOL_IP undefined on some systems - thanks Mike Erdely. +* Cleaned up examples. +* Lowercased module name. + +0.13 +---- + +* Various minor changes; see git for details. +* No longer compatible with Python 2.2. Only tested with 2.5-2.7. +* Fork by William McBrine. + +0.12 +---- + +* allow selection of binding interface +* typo fix - Thanks A. M. Kuchlingi +* removed all use of word 'Rendezvous' - this is an API change + +0.11 +---- + +* correction to comments for addListener method +* support for new record types seen from OS X + - IPv6 address + - hostinfo + +* ignore unknown DNS record types +* fixes to name decoding +* works alongside other processes using port 5353 (e.g. on Mac OS X) +* tested against Mac OS X 10.3.2's mDNSResponder +* corrections to removal of list entries for service browser + +0.10 +---- + +* Jonathon Paisley contributed these corrections: + - always multicast replies, even when query is unicast + - correct a pointer encoding problem + - can now write records in any order + - traceback shown on failure + - better TXT record parsing + - server is now separate from name + - can cancel a service browser +* modified some unit tests to accommodate these changes + +0.09 +---- + +* remove all records on service unregistration +* fix DOS security problem with readName + +0.08 +---- + +* changed licensing to LGPL + +0.07 +---- + +* faster shutdown on engine +* pointer encoding of outgoing names +* ServiceBrowser now works +* new unit tests + +0.06 +---- +* small improvements with unit tests +* added defined exception types +* new style objects +* fixed hostname/interface problem +* fixed socket timeout problem +* fixed add_service_listener() typo bug +* using select() for socket reads +* tested on Debian unstable with Python 2.2.2 + +0.05 +---- + +* ensure case insensitivty on domain names +* support for unicast DNS queries + +0.04 +---- + +* added some unit tests +* added __ne__ adjuncts where required +* ensure names end in '.local.' +* timeout on receiving socket for clean shutdown + + +License +======= + +LGPL, see COPYING file for details. + + diff --git a/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/RECORD b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/RECORD new file mode 100644 index 0000000..96a0421 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/RECORD @@ -0,0 +1,10 @@ +zeroconf.py,sha256=5LFspm7fZaaG6trVMkZY2t-S-ezev9tdoTTmBqabNeE,57139 +zeroconf-0.17.4.dist-info/DESCRIPTION.rst,sha256=8rlcTqe6M6ytbm5pTf1acLqbRdwaxQa7Fg_Sy6kVrSA,7187 +zeroconf-0.17.4.dist-info/METADATA,sha256=qcgqtuJxaOwEyUS38z9eEYxSj30OG2-8dQ94NWipo7k,8561 +zeroconf-0.17.4.dist-info/metadata.json,sha256=fGng8FC3NLfrxojVUFfEtquL8iURakIJZoKP3DQij8Y,1437 +zeroconf-0.17.4.dist-info/pbr.json,sha256=6YIrYDsheNOX2fcy6S_Jw7xMl65fgtWkooyLbEQLGjE,46 +zeroconf-0.17.4.dist-info/RECORD,, +zeroconf-0.17.4.dist-info/top_level.txt,sha256=G_yoNgGm6QMZZpH139yjBdEQpn-jCn0EN5Zvy0kJuII,9 +zeroconf-0.17.4.dist-info/WHEEL,sha256=AvR0WeTpDaxT645bl5FQxUK6NPsTls2ttpcGJg3j1Xg,110 +zeroconf-0.17.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +__pycache__/zeroconf.cpython-34.pyc,, diff --git a/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/WHEEL b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/WHEEL new file mode 100644 index 0000000..9dff69d --- /dev/null +++ b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.24.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/metadata.json b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/metadata.json new file mode 100644 index 0000000..e09e55e --- /dev/null +++ b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/metadata.json @@ -0,0 +1 @@ +{"license": "LGPL", "name": "zeroconf", "metadata_version": "2.0", "generator": "bdist_wheel (0.24.0)", "summary": "Pure Python Multicast DNS Service Discovery Library (Bonjour/Avahi compatible)", "platform": "unix", "run_requires": [{"requires": ["enum-compat", "netifaces", "six"]}], "version": "0.17.4", "extensions": {"python.details": {"project_urls": {"Home": "https://github.com/jstasiak/python-zeroconf"}, "document_names": {"description": "DESCRIPTION.rst"}, "contacts": [{"role": "author", "name": "Paul Scott-Murphy, William McBrine, Jakub Stasiak"}]}}, "keywords": ["Bonjour", "Avahi", "Zeroconf", "Multicast", "DNS", "Service", "Discovery", "mDNS"], "classifiers": ["Development Status :: 3 - Alpha", "Intended Audience :: Developers", "Intended Audience :: System Administrators", "License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)", "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Operating System :: MacOS :: MacOS X", "Topic :: Software Development :: Libraries", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy"], "extras": []} \ No newline at end of file diff --git a/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/pbr.json b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/pbr.json new file mode 100644 index 0000000..f2cc4e2 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/pbr.json @@ -0,0 +1 @@ +{"is_release": true, "git_version": "0b9093d"} \ No newline at end of file diff --git a/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/top_level.txt b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/top_level.txt new file mode 100644 index 0000000..947c9c5 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/zeroconf-0.17.4.dist-info/top_level.txt @@ -0,0 +1 @@ +zeroconf diff --git a/Shared/lib/python3.4/site-packages/zeroconf.py b/Shared/lib/python3.4/site-packages/zeroconf.py new file mode 100644 index 0000000..2d67563 --- /dev/null +++ b/Shared/lib/python3.4/site-packages/zeroconf.py @@ -0,0 +1,1679 @@ +from __future__ import absolute_import, division, print_function, unicode_literals + +""" Multicast DNS Service Discovery for Python, v0.14-wmcbrine + Copyright 2003 Paul Scott-Murphy, 2014 William McBrine + + This module provides a framework for the use of DNS Service Discovery + using IP multicast. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA +""" + +import enum +import errno +import logging +import select +import socket +import struct +import threading +import time +from functools import reduce + +import netifaces +from six import binary_type, indexbytes, int2byte, iteritems, text_type +from six.moves import xrange + +__author__ = 'Paul Scott-Murphy, William McBrine' +__maintainer__ = 'Jakub Stasiak ' +__version__ = '0.17.4' +__license__ = 'LGPL' + + +try: + NullHandler = logging.NullHandler +except AttributeError: + # Python 2.6 fallback + class NullHandler(logging.Handler): + + def emit(self, record): + pass + +__all__ = [ + "__version__", + "Zeroconf", "ServiceInfo", "ServiceBrowser", + "Error", "InterfaceChoice", "ServiceStateChange", +] + + +log = logging.getLogger(__name__) +log.addHandler(NullHandler()) + +if log.level == logging.NOTSET: + log.setLevel(logging.WARN) + +# hook for threads + +_GLOBAL_DONE = False + +# Some timing constants + +_UNREGISTER_TIME = 125 +_CHECK_TIME = 175 +_REGISTER_TIME = 225 +_LISTENER_TIME = 200 +_BROWSER_TIME = 500 + +# Some DNS constants + +_MDNS_ADDR = '224.0.0.251' +_MDNS_PORT = 5353 +_DNS_PORT = 53 +_DNS_TTL = 60 * 60 # one hour default TTL + +_MAX_MSG_TYPICAL = 1460 # unused +_MAX_MSG_ABSOLUTE = 8972 + +_FLAGS_QR_MASK = 0x8000 # query response mask +_FLAGS_QR_QUERY = 0x0000 # query +_FLAGS_QR_RESPONSE = 0x8000 # response + +_FLAGS_AA = 0x0400 # Authorative answer +_FLAGS_TC = 0x0200 # Truncated +_FLAGS_RD = 0x0100 # Recursion desired +_FLAGS_RA = 0x8000 # Recursion available + +_FLAGS_Z = 0x0040 # Zero +_FLAGS_AD = 0x0020 # Authentic data +_FLAGS_CD = 0x0010 # Checking disabled + +_CLASS_IN = 1 +_CLASS_CS = 2 +_CLASS_CH = 3 +_CLASS_HS = 4 +_CLASS_NONE = 254 +_CLASS_ANY = 255 +_CLASS_MASK = 0x7FFF +_CLASS_UNIQUE = 0x8000 + +_TYPE_A = 1 +_TYPE_NS = 2 +_TYPE_MD = 3 +_TYPE_MF = 4 +_TYPE_CNAME = 5 +_TYPE_SOA = 6 +_TYPE_MB = 7 +_TYPE_MG = 8 +_TYPE_MR = 9 +_TYPE_NULL = 10 +_TYPE_WKS = 11 +_TYPE_PTR = 12 +_TYPE_HINFO = 13 +_TYPE_MINFO = 14 +_TYPE_MX = 15 +_TYPE_TXT = 16 +_TYPE_AAAA = 28 +_TYPE_SRV = 33 +_TYPE_ANY = 255 + +# Mapping constants to names + +_CLASSES = {_CLASS_IN: "in", + _CLASS_CS: "cs", + _CLASS_CH: "ch", + _CLASS_HS: "hs", + _CLASS_NONE: "none", + _CLASS_ANY: "any"} + +_TYPES = {_TYPE_A: "a", + _TYPE_NS: "ns", + _TYPE_MD: "md", + _TYPE_MF: "mf", + _TYPE_CNAME: "cname", + _TYPE_SOA: "soa", + _TYPE_MB: "mb", + _TYPE_MG: "mg", + _TYPE_MR: "mr", + _TYPE_NULL: "null", + _TYPE_WKS: "wks", + _TYPE_PTR: "ptr", + _TYPE_HINFO: "hinfo", + _TYPE_MINFO: "minfo", + _TYPE_MX: "mx", + _TYPE_TXT: "txt", + _TYPE_AAAA: "quada", + _TYPE_SRV: "srv", + _TYPE_ANY: "any"} + +# utility functions + + +def current_time_millis(): + """Current system time in milliseconds""" + return time.time() * 1000 + +# Exceptions + + +class Error(Exception): + pass + + +class NonLocalNameException(Exception): + pass + + +class NonUniqueNameException(Exception): + pass + + +class NamePartTooLongException(Exception): + pass + + +class AbstractMethodException(Exception): + pass + + +class BadTypeInNameException(Exception): + pass + +# implementation classes + + +class DNSEntry(object): + + """A DNS entry""" + + def __init__(self, name, type, class_): + self.key = name.lower() + self.name = name + self.type = type + self.class_ = class_ & _CLASS_MASK + self.unique = (class_ & _CLASS_UNIQUE) != 0 + + def __eq__(self, other): + """Equality test on name, type, and class""" + return (isinstance(other, DNSEntry) and + self.name == other.name and + self.type == other.type and + self.class_ == other.class_) + + def __ne__(self, other): + """Non-equality test""" + return not self.__eq__(other) + + def get_class_(self, class_): + """Class accessor""" + return _CLASSES.get(class_, "?(%s)" % class_) + + def get_type(self, t): + """Type accessor""" + return _TYPES.get(t, "?(%s)" % t) + + def to_string(self, hdr, other): + """String representation with additional information""" + result = "%s[%s,%s" % (hdr, self.get_type(self.type), + self.get_class_(self.class_)) + if self.unique: + result += "-unique," + else: + result += "," + result += self.name + if other is not None: + result += ",%s]" % (other) + else: + result += "]" + return result + + +class DNSQuestion(DNSEntry): + + """A DNS question entry""" + + def __init__(self, name, type, class_): + # if not name.endswith(".local."): + # raise NonLocalNameException + DNSEntry.__init__(self, name, type, class_) + + def answered_by(self, rec): + """Returns true if the question is answered by the record""" + return (self.class_ == rec.class_ and + (self.type == rec.type or self.type == _TYPE_ANY) and + self.name == rec.name) + + def __repr__(self): + """String representation""" + return DNSEntry.to_string(self, "question", None) + + +class DNSRecord(DNSEntry): + + """A DNS record - like a DNS entry, but has a TTL""" + + def __init__(self, name, type, class_, ttl): + DNSEntry.__init__(self, name, type, class_) + self.ttl = ttl + self.created = current_time_millis() + + def __eq__(self, other): + """Tests equality as per DNSRecord""" + return isinstance(other, DNSRecord) and DNSEntry.__eq__(self, other) + + def suppressed_by(self, msg): + """Returns true if any answer in a message can suffice for the + information held in this record.""" + for record in msg.answers: + if self.suppressed_by_answer(record): + return True + return False + + def suppressed_by_answer(self, other): + """Returns true if another record has same name, type and class, + and if its TTL is at least half of this record's.""" + return self == other and other.ttl > (self.ttl / 2) + + def get_expiration_time(self, percent): + """Returns the time at which this record will have expired + by a certain percentage.""" + return self.created + (percent * self.ttl * 10) + + def get_remaining_ttl(self, now): + """Returns the remaining TTL in seconds.""" + return max(0, (self.get_expiration_time(100) - now) / 1000) + + def is_expired(self, now): + """Returns true if this record has expired.""" + return self.get_expiration_time(100) <= now + + def is_stale(self, now): + """Returns true if this record is at least half way expired.""" + return self.get_expiration_time(50) <= now + + def reset_ttl(self, other): + """Sets this record's TTL and created time to that of + another record.""" + self.created = other.created + self.ttl = other.ttl + + def write(self, out): + """Abstract method""" + raise AbstractMethodException + + def to_string(self, other): + """String representation with addtional information""" + arg = "%s/%s,%s" % (self.ttl, + self.get_remaining_ttl(current_time_millis()), other) + return DNSEntry.to_string(self, "record", arg) + + +class DNSAddress(DNSRecord): + + """A DNS address record""" + + def __init__(self, name, type, class_, ttl, address): + DNSRecord.__init__(self, name, type, class_, ttl) + self.address = address + + def write(self, out): + """Used in constructing an outgoing packet""" + out.write_string(self.address) + + def __eq__(self, other): + """Tests equality on address""" + return isinstance(other, DNSAddress) and self.address == other.address + + def __repr__(self): + """String representation""" + try: + return socket.inet_ntoa(self.address) + except Exception as e: # TODO stop catching all Exceptions + log.exception('Unknown error, possibly benign: %r', e) + return self.address + + +class DNSHinfo(DNSRecord): + + """A DNS host information record""" + + def __init__(self, name, type, class_, ttl, cpu, os): + DNSRecord.__init__(self, name, type, class_, ttl) + self.cpu = cpu + self.os = os + + def write(self, out): + """Used in constructing an outgoing packet""" + out.write_string(self.cpu) + out.write_string(self.oso) + + def __eq__(self, other): + """Tests equality on cpu and os""" + return (isinstance(other, DNSHinfo) and + self.cpu == other.cpu and self.os == other.os) + + def __repr__(self): + """String representation""" + return self.cpu + " " + self.os + + +class DNSPointer(DNSRecord): + + """A DNS pointer record""" + + def __init__(self, name, type, class_, ttl, alias): + DNSRecord.__init__(self, name, type, class_, ttl) + self.alias = alias + + def write(self, out): + """Used in constructing an outgoing packet""" + out.write_name(self.alias) + + def __eq__(self, other): + """Tests equality on alias""" + return isinstance(other, DNSPointer) and self.alias == other.alias + + def __repr__(self): + """String representation""" + return self.to_string(self.alias) + + +class DNSText(DNSRecord): + + """A DNS text record""" + + def __init__(self, name, type_, class_, ttl, text): + assert isinstance(text, (bytes, type(None))) + DNSRecord.__init__(self, name, type_, class_, ttl) + self.text = text + + def write(self, out): + """Used in constructing an outgoing packet""" + out.write_string(self.text) + + def __eq__(self, other): + """Tests equality on text""" + return isinstance(other, DNSText) and self.text == other.text + + def __repr__(self): + """String representation""" + if len(self.text) > 10: + return self.to_string(self.text[:7]) + "..." + else: + return self.to_string(self.text) + + +class DNSService(DNSRecord): + + """A DNS service record""" + + def __init__(self, name, type, class_, ttl, priority, weight, port, server): + DNSRecord.__init__(self, name, type, class_, ttl) + self.priority = priority + self.weight = weight + self.port = port + self.server = server + + def write(self, out): + """Used in constructing an outgoing packet""" + out.write_short(self.priority) + out.write_short(self.weight) + out.write_short(self.port) + out.write_name(self.server) + + def __eq__(self, other): + """Tests equality on priority, weight, port and server""" + return (isinstance(other, DNSService) and + self.priority == other.priority and + self.weight == other.weight and + self.port == other.port and + self.server == other.server) + + def __repr__(self): + """String representation""" + return self.to_string("%s:%s" % (self.server, self.port)) + + +class DNSIncoming(object): + + """Object representation of an incoming DNS packet""" + + def __init__(self, data): + """Constructor from string holding bytes of packet""" + self.offset = 0 + self.data = data + self.questions = [] + self.answers = [] + self.num_questions = 0 + self.num_answers = 0 + self.num_authorities = 0 + self.num_additionals = 0 + + self.read_header() + self.read_questions() + self.read_others() + + def unpack(self, format): + length = struct.calcsize(format) + info = struct.unpack(format, self.data[self.offset:self.offset + length]) + self.offset += length + return info + + def read_header(self): + """Reads header portion of packet""" + (self.id, self.flags, self.num_questions, self.num_answers, + self.num_quthorities, self.num_additionals) = self.unpack(b'!6H') + + def read_questions(self): + """Reads questions section of packet""" + for i in xrange(self.num_questions): + name = self.read_name() + type, class_ = self.unpack(b'!HH') + + question = DNSQuestion(name, type, class_) + self.questions.append(question) + + def read_int(self): + """Reads an integer from the packet""" + return self.unpack(b'!I')[0] + + def read_character_string(self): + """Reads a character string from the packet""" + length = indexbytes(self.data, self.offset) + self.offset += 1 + return self.read_string(length) + + def read_string(self, length): + """Reads a string of a given length from the packet""" + info = self.data[self.offset:self.offset + length] + self.offset += length + return info + + def read_unsigned_short(self): + """Reads an unsigned short from the packet""" + return self.unpack(b'!H')[0] + + def read_others(self): + """Reads the answers, authorities and additionals section of the + packet""" + n = self.num_answers + self.num_authorities + self.num_additionals + for i in xrange(n): + domain = self.read_name() + type, class_, ttl, length = self.unpack(b'!HHiH') + + rec = None + if type == _TYPE_A: + rec = DNSAddress(domain, type, class_, ttl, self.read_string(4)) + elif type == _TYPE_CNAME or type == _TYPE_PTR: + rec = DNSPointer(domain, type, class_, ttl, self.read_name()) + elif type == _TYPE_TXT: + rec = DNSText(domain, type, class_, ttl, self.read_string(length)) + elif type == _TYPE_SRV: + rec = DNSService(domain, type, class_, ttl, + self.read_unsigned_short(), self.read_unsigned_short(), + self.read_unsigned_short(), self.read_name()) + elif type == _TYPE_HINFO: + rec = DNSHinfo(domain, type, class_, ttl, + self.read_character_string(), self.read_character_string()) + elif type == _TYPE_AAAA: + rec = DNSAddress(domain, type, class_, ttl, self.read_string(16)) + else: + # Try to ignore types we don't know about + # Skip the payload for the resource record so the next + # records can be parsed correctly + self.offset += length + + if rec is not None: + self.answers.append(rec) + + def is_query(self): + """Returns true if this is a query""" + return (self.flags & _FLAGS_QR_MASK) == _FLAGS_QR_QUERY + + def is_response(self): + """Returns true if this is a response""" + return (self.flags & _FLAGS_QR_MASK) == _FLAGS_QR_RESPONSE + + def read_utf(self, offset, length): + """Reads a UTF-8 string of a given length from the packet""" + return text_type(self.data[offset:offset + length], 'utf-8', 'replace') + + def read_name(self): + """Reads a domain name from the packet""" + result = '' + off = self.offset + next = -1 + first = off + + while True: + length = indexbytes(self.data, off) + off += 1 + if length == 0: + break + t = length & 0xC0 + if t == 0x00: + result = ''.join((result, self.read_utf(off, length) + '.')) + off += length + elif t == 0xC0: + if next < 0: + next = off + 1 + off = ((length & 0x3F) << 8) | indexbytes(self.data, off) + if off >= first: + # TODO raise more specific exception + raise Exception("Bad domain name (circular) at %s" % (off,)) + first = off + else: + # TODO raise more specific exception + raise Exception("Bad domain name at %s" % (off,)) + + if next >= 0: + self.offset = next + else: + self.offset = off + + return result + + +class DNSOutgoing(object): + + """Object representation of an outgoing packet""" + + def __init__(self, flags, multicast=True): + self.finished = False + self.id = 0 + self.multicast = multicast + self.flags = flags + self.names = {} + self.data = [] + self.size = 12 + + self.questions = [] + self.answers = [] + self.authorities = [] + self.additionals = [] + + def add_question(self, record): + """Adds a question""" + self.questions.append(record) + + def add_answer(self, inp, record): + """Adds an answer""" + if not record.suppressed_by(inp): + self.add_answer_at_time(record, 0) + + def add_answer_at_time(self, record, now): + """Adds an answer if if does not expire by a certain time""" + if record is not None: + if now == 0 or not record.is_expired(now): + self.answers.append((record, now)) + + def add_authorative_answer(self, record): + """Adds an authoritative answer""" + self.authorities.append(record) + + def add_additional_answer(self, record): + """Adds an additional answer""" + self.additionals.append(record) + + def pack(self, format, value): + self.data.append(struct.pack(format, value)) + self.size += struct.calcsize(format) + + def write_byte(self, value): + """Writes a single byte to the packet""" + self.pack(b'!c', int2byte(value)) + + def insert_short(self, index, value): + """Inserts an unsigned short in a certain position in the packet""" + self.data.insert(index, struct.pack(b'!H', value)) + self.size += 2 + + def write_short(self, value): + """Writes an unsigned short to the packet""" + self.pack(b'!H', value) + + def write_int(self, value): + """Writes an unsigned integer to the packet""" + self.pack(b'!I', int(value)) + + def write_string(self, value): + """Writes a string to the packet""" + assert isinstance(value, bytes) + self.data.append(value) + self.size += len(value) + + def write_utf(self, s): + """Writes a UTF-8 string of a given length to the packet""" + utfstr = s.encode('utf-8') + length = len(utfstr) + if length > 64: + raise NamePartTooLongException + self.write_byte(length) + self.write_string(utfstr) + + def write_name(self, name): + """Writes a domain name to the packet""" + + if name in self.names: + # Find existing instance of this name in packet + # + index = self.names[name] + + # An index was found, so write a pointer to it + # + self.write_byte((index >> 8) | 0xC0) + self.write_byte(index & 0xFF) + else: + # No record of this name already, so write it + # out as normal, recording the location of the name + # for future pointers to it. + # + self.names[name] = self.size + parts = name.split('.') + if parts[-1] == '': + parts = parts[:-1] + for part in parts: + self.write_utf(part) + self.write_byte(0) + + def write_question(self, question): + """Writes a question to the packet""" + self.write_name(question.name) + self.write_short(question.type) + self.write_short(question.class_) + + def write_record(self, record, now): + """Writes a record (answer, authoritative answer, additional) to + the packet""" + self.write_name(record.name) + self.write_short(record.type) + if record.unique and self.multicast: + self.write_short(record.class_ | _CLASS_UNIQUE) + else: + self.write_short(record.class_) + if now == 0: + self.write_int(record.ttl) + else: + self.write_int(record.get_remaining_ttl(now)) + index = len(self.data) + # Adjust size for the short we will write before this record + # + self.size += 2 + record.write(self) + self.size -= 2 + + length = len(b''.join(self.data[index:])) + self.insert_short(index, length) # Here is the short we adjusted for + + def packet(self): + """Returns a string containing the packet's bytes + + No further parts should be added to the packet once this + is done.""" + if not self.finished: + self.finished = True + for question in self.questions: + self.write_question(question) + for answer, time_ in self.answers: + self.write_record(answer, time_) + for authority in self.authorities: + self.write_record(authority, 0) + for additional in self.additionals: + self.write_record(additional, 0) + + self.insert_short(0, len(self.additionals)) + self.insert_short(0, len(self.authorities)) + self.insert_short(0, len(self.answers)) + self.insert_short(0, len(self.questions)) + self.insert_short(0, self.flags) + if self.multicast: + self.insert_short(0, 0) + else: + self.insert_short(0, self.id) + return b''.join(self.data) + + +class DNSCache(object): + + """A cache of DNS entries""" + + def __init__(self): + self.cache = {} + + def add(self, entry): + """Adds an entry""" + self.cache.setdefault(entry.key, []).append(entry) + + def remove(self, entry): + """Removes an entry""" + try: + list_ = self.cache[entry.key] + list_.remove(entry) + except (KeyError, ValueError): + pass + + def get(self, entry): + """Gets an entry by key. Will return None if there is no + matching entry.""" + try: + list_ = self.cache[entry.key] + return list_[list_.index(entry)] + except (KeyError, ValueError): + return None + + def get_by_details(self, name, type, class_): + """Gets an entry by details. Will return None if there is + no matching entry.""" + entry = DNSEntry(name, type, class_) + return self.get(entry) + + def entries_with_name(self, name): + """Returns a list of entries whose key matches the name.""" + try: + return self.cache[name] + except KeyError: + return [] + + def entries(self): + """Returns a list of all entries""" + if not self.cache: + return [] + else: + return reduce(lambda a, b: a + b, self.cache.values()) + + +class Engine(threading.Thread): + + """An engine wraps read access to sockets, allowing objects that + need to receive data from sockets to be called back when the + sockets are ready. + + A reader needs a handle_read() method, which is called when the socket + it is interested in is ready for reading. + + Writers are not implemented here, because we only send short + packets. + """ + + def __init__(self, zc): + threading.Thread.__init__(self) + self.daemon = True + self.zc = zc + self.readers = {} # maps socket to reader + self.timeout = 5 + self.condition = threading.Condition() + self.start() + + def run(self): + while not _GLOBAL_DONE: + rs = self.get_readers() + if len(rs) == 0: + # No sockets to manage, but we wait for the timeout + # or addition of a socket + # + with self.condition: + self.condition.wait(self.timeout) + else: + try: + rr, wr, er = select.select(rs, [], [], self.timeout) + for socket_ in rr: + try: + self.readers[socket_].handle_read(socket_) + except Exception as e: # TODO stop catching all Exceptions + log.exception('Unknown error, possibly benign: %r', e) + except Exception as e: # TODO stop catching all Exceptions + log.exception('Unknown error, possibly benign: %r', e) + + def get_readers(self): + result = [] + with self.condition: + result = self.readers.keys() + return result + + def add_reader(self, reader, socket): + with self.condition: + self.readers[socket] = reader + self.condition.notify() + + def del_reader(self, socket): + with self.condition: + del self.readers[socket] + self.condition.notify() + + def notify(self): + with self.condition: + self.condition.notify() + + +class Listener(object): + + """A Listener is used by this module to listen on the multicast + group to which DNS messages are sent, allowing the implementation + to cache information as it arrives. + + It requires registration with an Engine object in order to have + the read() method called when a socket is availble for reading.""" + + def __init__(self, zc): + self.zc = zc + + def handle_read(self, socket_): + try: + data, (addr, port) = socket_.recvfrom(_MAX_MSG_ABSOLUTE) + except socket.error as e: + # If the socket was closed by another thread -- which happens + # regularly on shutdown -- an EBADF exception is thrown here. + # Ignore it. + if e.errno == socket.EBADF: + return + else: + raise e + else: + log.debug('Received %r from %r:%r', data, addr, port) + + self.data = data + msg = DNSIncoming(data) + if msg.is_query(): + # Always multicast responses + # + if port == _MDNS_PORT: + self.zc.handle_query(msg, _MDNS_ADDR, _MDNS_PORT) + # If it's not a multicast query, reply via unicast + # and multicast + # + elif port == _DNS_PORT: + self.zc.handle_query(msg, addr, port) + self.zc.handle_query(msg, _MDNS_ADDR, _MDNS_PORT) + else: + self.zc.handle_response(msg) + + +class Reaper(threading.Thread): + + """A Reaper is used by this module to remove cache entries that + have expired.""" + + def __init__(self, zc): + threading.Thread.__init__(self) + self.daemon = True + self.zc = zc + self.start() + + def run(self): + while True: + self.zc.wait(10 * 1000) + if _GLOBAL_DONE: + return + now = current_time_millis() + for record in self.zc.cache.entries(): + if record.is_expired(now): + self.zc.update_record(now, record) + self.zc.cache.remove(record) + + +class Signal(object): + def __init__(self): + self._handlers = [] + + def fire(self, **kwargs): + for h in list(self._handlers): + h(**kwargs) + + @property + def registration_interface(self): + return SignalRegistrationInterface(self._handlers) + + +class SignalRegistrationInterface(object): + + def __init__(self, handlers): + self._handlers = handlers + + def register_handler(self, handler): + self._handlers.append(handler) + return self + + def unregister_handler(self, handler): + self._handlers.remove(handler) + return self + + +class ServiceBrowser(threading.Thread): + + """Used to browse for a service of a specific type. + + The listener object will have its add_service() and + remove_service() methods called when this browser + discovers changes in the services availability.""" + + def __init__(self, zc, type_, handlers=None, listener=None): + """Creates a browser for a specific type""" + assert handlers or listener, 'You need to specify at least one handler' + threading.Thread.__init__(self) + self.daemon = True + self.zc = zc + self.type = type_ + self.services = {} + self.next_time = current_time_millis() + self.delay = _BROWSER_TIME + self._handlers_to_call = [] + + self.done = False + + self.zc.add_listener(self, DNSQuestion(self.type, _TYPE_PTR, _CLASS_IN)) + self.start() + + self._service_state_changed = Signal() + + if hasattr(handlers, 'add_service'): + listener = handlers + handlers = None + + handlers = handlers or [] + + if listener: + def on_change(zeroconf, service_type, name, state_change): + args = (zeroconf, service_type, name) + if state_change is ServiceStateChange.Added: + listener.add_service(*args) + elif state_change is ServiceStateChange.Removed: + listener.remove_service(*args) + else: + raise NotImplementedError(state_change) + handlers.append(on_change) + + for h in handlers: + self.service_state_changed.register_handler(h) + + @property + def service_state_changed(self): + return self._service_state_changed.registration_interface + + def update_record(self, zc, now, record): + """Callback invoked by Zeroconf when new information arrives. + + Updates information required by browser in the Zeroconf cache.""" + + def enqueue_callback(state_change, name): + self._handlers_to_call.append( + lambda zeroconf: self._service_state_changed.fire( + zeroconf=zeroconf, + service_type=self.type, + name=name, + state_change=state_change, + )) + + if record.type == _TYPE_PTR and record.name == self.type: + expired = record.is_expired(now) + service_key = record.alias.lower() + try: + old_record = self.services[service_key] + except KeyError: + if not expired: + self.services[service_key] = record + enqueue_callback(ServiceStateChange.Added, record.alias) + else: + if not expired: + old_record.reset_ttl(record) + else: + del self.services[service_key] + enqueue_callback(ServiceStateChange.Removed, record.alias) + return + + expires = record.get_expiration_time(75) + if expires < self.next_time: + self.next_time = expires + + def cancel(self): + self.done = True + self.zc.notify_all() + + def run(self): + while True: + now = current_time_millis() + if len(self._handlers_to_call) == 0 and self.next_time > now: + self.zc.wait(self.next_time - now) + if _GLOBAL_DONE or self.done: + return + now = current_time_millis() + + if self.next_time <= now: + out = DNSOutgoing(_FLAGS_QR_QUERY) + out.add_question(DNSQuestion(self.type, _TYPE_PTR, _CLASS_IN)) + for record in self.services.values(): + if not record.is_expired(now): + out.add_answer_at_time(record, now) + self.zc.send(out) + self.next_time = now + self.delay + self.delay = min(20 * 1000, self.delay * 2) + + if len(self._handlers_to_call) > 0: + handler = self._handlers_to_call.pop(0) + handler(self.zc) + + +class ServiceInfo(object): + + """Service information""" + + def __init__(self, type, name, address=None, port=None, weight=0, + priority=0, properties=None, server=None): + """Create a service description. + + type: fully qualified service type name + name: fully qualified service name + address: IP address as unsigned short, network byte order + port: port that the service runs on + weight: weight of the service + priority: priority of the service + properties: dictionary of properties (or a string holding the + bytes for the text field) + server: fully qualified name for service host (defaults to name)""" + + if not name.endswith(type): + raise BadTypeInNameException + self.type = type + self.name = name + self.address = address + self.port = port + self.weight = weight + self.priority = priority + if server: + self.server = server + else: + self.server = name + self._set_properties(properties) + + @property + def properties(self): + return self._properties + + def _set_properties(self, properties): + """Sets properties and text of this info from a dictionary""" + if isinstance(properties, dict): + self._properties = properties + list = [] + result = b'' + for key, value in iteritems(properties): + if isinstance(key, text_type): + key = key.encode('utf-8') + + if value is None: + suffix = b'' + elif isinstance(value, text_type): + suffix = value.encode('utf-8') + elif isinstance(value, binary_type): + suffix = value + elif isinstance(value, int): + if value: + suffix = b'true' + else: + suffix = b'false' + else: + suffix = b'' + list.append(b'='.join((key, suffix))) + for item in list: + result = b''.join((result, int2byte(len(item)), item)) + self.text = result + else: + self.text = properties + + def _set_text(self, text): + """Sets properties and text given a text field""" + self.text = text + result = {} + end = len(text) + index = 0 + strs = [] + while index < end: + length = indexbytes(text, index) + index += 1 + strs.append(text[index:index + length]) + index += length + + for s in strs: + parts = s.split(b'=', 1) + try: + key, value = parts + except ValueError: + # No equals sign at all + key = s + value = False + else: + if value == b'true': + value = True + elif value == b'false' or not value: + value = False + + # Only update non-existent properties + if key and result.get(key) is None: + result[key] = value + + self._properties = result + + def get_name(self): + """Name accessor""" + if self.type is not None and self.name.endswith("." + self.type): + return self.name[:len(self.name) - len(self.type) - 1] + return self.name + + def update_record(self, zc, now, record): + """Updates service information from a DNS record""" + if record is not None and not record.is_expired(now): + if record.type == _TYPE_A: + # if record.name == self.name: + if record.name == self.server: + self.address = record.address + elif record.type == _TYPE_SRV: + if record.name == self.name: + self.server = record.server + self.port = record.port + self.weight = record.weight + self.priority = record.priority + # self.address = None + self.update_record(zc, now, + zc.cache.get_by_details(self.server, _TYPE_A, _CLASS_IN)) + elif record.type == _TYPE_TXT: + if record.name == self.name: + self._set_text(record.text) + + def request(self, zc, timeout): + """Returns true if the service could be discovered on the + network, and updates this object with details discovered. + """ + now = current_time_millis() + delay = _LISTENER_TIME + next = now + delay + last = now + timeout + result = False + try: + zc.add_listener(self, DNSQuestion(self.name, _TYPE_ANY, _CLASS_IN)) + while (self.server is None or self.address is None or + self.text is None): + if last <= now: + return False + if next <= now: + out = DNSOutgoing(_FLAGS_QR_QUERY) + out.add_question(DNSQuestion(self.name, _TYPE_SRV, + _CLASS_IN)) + out.add_answer_at_time(zc.cache.get_by_details(self.name, + _TYPE_SRV, _CLASS_IN), now) + out.add_question(DNSQuestion(self.name, _TYPE_TXT, + _CLASS_IN)) + out.add_answer_at_time(zc.cache.get_by_details(self.name, + _TYPE_TXT, _CLASS_IN), now) + if self.server is not None: + out.add_question(DNSQuestion(self.server, + _TYPE_A, _CLASS_IN)) + out.add_answer_at_time(zc.cache.get_by_details(self.server, + _TYPE_A, _CLASS_IN), now) + zc.send(out) + next = now + delay + delay = delay * 2 + + zc.wait(min(next, last) - now) + now = current_time_millis() + result = True + finally: + zc.remove_listener(self) + + return result + + def __eq__(self, other): + """Tests equality of service name""" + if isinstance(other, ServiceInfo): + return other.name == self.name + return False + + def __ne__(self, other): + """Non-equality test""" + return not self.__eq__(other) + + def __repr__(self): + """String representation""" + return '%s(%s)' % ( + type(self).__name__, + ', '.join( + '%s=%r' % (name, getattr(self, name)) + for name in ( + 'type', 'name', 'address', 'port', 'weight', 'priority', + 'server', 'properties', + ) + ) + ) + + +@enum.unique +class InterfaceChoice(enum.Enum): + Default = 1 + All = 2 + + +@enum.unique +class ServiceStateChange(enum.Enum): + Added = 1 + Removed = 2 + + +HOST_ONLY_NETWORK_MASK = '255.255.255.255' + + +def get_all_addresses(address_family): + return list(set( + addr['addr'] + for iface in netifaces.interfaces() + for addr in netifaces.ifaddresses(iface).get(address_family, []) + if addr.get('netmask') != HOST_ONLY_NETWORK_MASK + )) + + +def normalize_interface_choice(choice, address_family): + if choice is InterfaceChoice.Default: + choice = ['0.0.0.0'] + elif choice is InterfaceChoice.All: + choice = get_all_addresses(address_family) + return choice + + +def new_socket(): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + # SO_REUSEADDR should be equivalent to SO_REUSEPORT for + # multicast UDP sockets (p 731, "TCP/IP Illustrated, + # Volume 2"), but some BSD-derived systems require + # SO_REUSEPORT to be specified explicity. Also, not all + # versions of Python have SO_REUSEPORT available. + # Catch OSError and socket.error for kernel versions <3.9 because lacking + # SO_REUSEPORT support. + try: + reuseport = socket.SO_REUSEPORT + except AttributeError: + pass + else: + try: + s.setsockopt(socket.SOL_SOCKET, reuseport, 1) + except (OSError, socket.error) as err: # OSError on python 3, socket.error on python 2 + if not err.errno == errno.ENOPROTOOPT: + raise + + s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255) + s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1) + + s.bind(('', _MDNS_PORT)) + return s + + +def get_errno(e): + assert isinstance(e, socket.error) + return e.args[0] + + +class Zeroconf(object): + + """Implementation of Zeroconf Multicast DNS Service Discovery + + Supports registration, unregistration, queries and browsing. + """ + + def __init__( + self, + interfaces=InterfaceChoice.All, + ): + """Creates an instance of the Zeroconf class, establishing + multicast communications, listening and reaping threads. + + :type interfaces: :class:`InterfaceChoice` or sequence of ip addresses + """ + global _GLOBAL_DONE + _GLOBAL_DONE = False + + self._listen_socket = new_socket() + interfaces = normalize_interface_choice(interfaces, socket.AF_INET) + + self._respond_sockets = [] + + for i in interfaces: + log.debug('Adding %r to multicast group', i) + try: + self._listen_socket.setsockopt( + socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, + socket.inet_aton(_MDNS_ADDR) + socket.inet_aton(i)) + except socket.error as e: + if get_errno(e) == errno.EADDRINUSE: + log.info( + 'Address in use when adding %s to multicast group, ' + 'it is expected to happen on some systems', i, + ) + elif get_errno(e) == errno.EADDRNOTAVAIL: + log.info( + 'Address not available when adding %s to multicast group, ' + 'it is expected to happen on some systems', i, + ) + continue + else: + raise + + respond_socket = new_socket() + respond_socket.setsockopt( + socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(i)) + + self._respond_sockets.append(respond_socket) + + self.listeners = [] + self.browsers = [] + self.services = {} + self.servicetypes = {} + + self.cache = DNSCache() + + self.condition = threading.Condition() + + self.engine = Engine(self) + self.listener = Listener(self) + self.engine.add_reader(self.listener, self._listen_socket) + self.reaper = Reaper(self) + + def wait(self, timeout): + """Calling thread waits for a given number of milliseconds or + until notified.""" + with self.condition: + self.condition.wait(timeout / 1000) + + def notify_all(self): + """Notifies all waiting threads""" + with self.condition: + self.condition.notify_all() + + def get_service_info(self, type, name, timeout=3000): + """Returns network's service information for a particular + name and type, or None if no service matches by the timeout, + which defaults to 3 seconds.""" + info = ServiceInfo(type, name) + if info.request(self, timeout): + return info + return None + + def add_service_listener(self, type, listener): + """Adds a listener for a particular service type. This object + will then have its update_record method called when information + arrives for that type.""" + self.remove_service_listener(listener) + self.browsers.append(ServiceBrowser(self, type, listener)) + + def remove_service_listener(self, listener): + """Removes a listener from the set that is currently listening.""" + for browser in self.browsers: + if browser.listener == listener: + browser.cancel() + del browser + + def register_service(self, info, ttl=_DNS_TTL): + """Registers service information to the network with a default TTL + of 60 seconds. Zeroconf will then respond to requests for + information for that service. The name of the service may be + changed if needed to make it unique on the network.""" + self.check_service(info) + self.services[info.name.lower()] = info + if info.type in self.servicetypes: + self.servicetypes[info.type] += 1 + else: + self.servicetypes[info.type] = 1 + now = current_time_millis() + next_time = now + i = 0 + while i < 3: + if now < next_time: + self.wait(next_time - now) + now = current_time_millis() + continue + out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA) + out.add_answer_at_time(DNSPointer(info.type, _TYPE_PTR, + _CLASS_IN, ttl, info.name), 0) + out.add_answer_at_time(DNSService(info.name, _TYPE_SRV, + _CLASS_IN, ttl, info.priority, info.weight, info.port, + info.server), 0) + out.add_answer_at_time(DNSText(info.name, _TYPE_TXT, _CLASS_IN, + ttl, info.text), 0) + if info.address: + out.add_answer_at_time(DNSAddress(info.server, _TYPE_A, + _CLASS_IN, ttl, info.address), 0) + self.send(out) + i += 1 + next_time += _REGISTER_TIME + + def unregister_service(self, info): + """Unregister a service.""" + try: + del self.services[info.name.lower()] + if self.servicetypes[info.type] > 1: + self.servicetypes[info.type] -= 1 + else: + del self.servicetypes[info.type] + except Exception as e: # TODO stop catching all Exceptions + log.exception('Unknown error, possibly benign: %r', e) + now = current_time_millis() + next_time = now + i = 0 + while i < 3: + if now < next_time: + self.wait(next_time - now) + now = current_time_millis() + continue + out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA) + out.add_answer_at_time(DNSPointer(info.type, _TYPE_PTR, + _CLASS_IN, 0, info.name), 0) + out.add_answer_at_time(DNSService(info.name, _TYPE_SRV, + _CLASS_IN, 0, info.priority, info.weight, info.port, + info.name), 0) + out.add_answer_at_time(DNSText(info.name, _TYPE_TXT, _CLASS_IN, + 0, info.text), 0) + if info.address: + out.add_answer_at_time(DNSAddress(info.server, _TYPE_A, + _CLASS_IN, 0, info.address), 0) + self.send(out) + i += 1 + next_time += _UNREGISTER_TIME + + def unregister_all_services(self): + """Unregister all registered services.""" + if len(self.services) > 0: + now = current_time_millis() + next_time = now + i = 0 + while i < 3: + if now < next_time: + self.wait(next_time - now) + now = current_time_millis() + continue + out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA) + for info in self.services.values(): + out.add_answer_at_time(DNSPointer(info.type, _TYPE_PTR, + _CLASS_IN, 0, info.name), 0) + out.add_answer_at_time(DNSService(info.name, _TYPE_SRV, + _CLASS_IN, 0, info.priority, info.weight, + info.port, info.server), 0) + out.add_answer_at_time(DNSText(info.name, _TYPE_TXT, + _CLASS_IN, 0, info.text), 0) + if info.address: + out.add_answer_at_time(DNSAddress(info.server, + _TYPE_A, _CLASS_IN, 0, info.address), 0) + self.send(out) + i += 1 + next_time += _UNREGISTER_TIME + + def check_service(self, info): + """Checks the network for a unique service name, modifying the + ServiceInfo passed in if it is not unique.""" + now = current_time_millis() + next_time = now + i = 0 + while i < 3: + for record in self.cache.entries_with_name(info.type): + if (record.type == _TYPE_PTR and + not record.is_expired(now) and + record.alias == info.name): + if info.name.find('.') < 0: + info.name = '%s.[%s:%s].%s' % (info.name, + info.address, info.port, info.type) + + self.check_service(info) + return + raise NonUniqueNameException + if now < next_time: + self.wait(next_time - now) + now = current_time_millis() + continue + out = DNSOutgoing(_FLAGS_QR_QUERY | _FLAGS_AA) + self.debug = out + out.add_question(DNSQuestion(info.type, _TYPE_PTR, _CLASS_IN)) + out.add_authorative_answer(DNSPointer(info.type, _TYPE_PTR, + _CLASS_IN, _DNS_TTL, info.name)) + self.send(out) + i += 1 + next_time += _CHECK_TIME + + def add_listener(self, listener, question): + """Adds a listener for a given question. The listener will have + its update_record method called when information is available to + answer the question.""" + now = current_time_millis() + self.listeners.append(listener) + if question is not None: + for record in self.cache.entries_with_name(question.name): + if question.answered_by(record) and not record.is_expired(now): + listener.update_record(self, now, record) + self.notify_all() + + def remove_listener(self, listener): + """Removes a listener.""" + try: + self.listeners.remove(listener) + self.notify_all() + except Exception as e: # TODO stop catching all Exceptions + log.exception('Unknown error, possibly benign: %r', e) + + def update_record(self, now, rec): + """Used to notify listeners of new information that has updated + a record.""" + for listener in self.listeners: + listener.update_record(self, now, rec) + self.notify_all() + + def handle_response(self, msg): + """Deal with incoming response packets. All answers + are held in the cache, and listeners are notified.""" + now = current_time_millis() + for record in msg.answers: + expired = record.is_expired(now) + if record in self.cache.entries(): + if expired: + self.cache.remove(record) + else: + entry = self.cache.get(record) + if entry is not None: + entry.reset_ttl(record) + record = entry + else: + self.cache.add(record) + + self.update_record(now, record) + + def handle_query(self, msg, addr, port): + """Deal with incoming query packets. Provides a response if + possible.""" + out = None + + # Support unicast client responses + # + if port != _MDNS_PORT: + out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA, False) + for question in msg.questions: + out.add_question(question) + + for question in msg.questions: + if question.type == _TYPE_PTR: + if question.name == "_services._dns-sd._udp.local.": + for stype in self.servicetypes.keys(): + if out is None: + out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA) + out.add_answer(msg, + DNSPointer("_services._dns-sd._udp.local.", + _TYPE_PTR, _CLASS_IN, _DNS_TTL, stype)) + for service in self.services.values(): + if question.name == service.type: + if out is None: + out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA) + out.add_answer(msg, + DNSPointer(service.type, _TYPE_PTR, + _CLASS_IN, _DNS_TTL, service.name)) + else: + try: + if out is None: + out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA) + + # Answer A record queries for any service addresses we know + if question.type in (_TYPE_A, _TYPE_ANY): + for service in self.services.values(): + if service.server == question.name.lower(): + out.add_answer(msg, DNSAddress(question.name, + _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, + _DNS_TTL, service.address)) + + service = self.services.get(question.name.lower(), None) + if not service: + continue + + if question.type in (_TYPE_SRV, _TYPE_ANY): + out.add_answer(msg, DNSService(question.name, + _TYPE_SRV, _CLASS_IN | _CLASS_UNIQUE, + _DNS_TTL, service.priority, service.weight, + service.port, service.server)) + if question.type in (_TYPE_TXT, _TYPE_ANY): + out.add_answer(msg, DNSText(question.name, + _TYPE_TXT, _CLASS_IN | _CLASS_UNIQUE, + _DNS_TTL, service.text)) + if question.type == _TYPE_SRV: + out.add_additional_answer(DNSAddress(service.server, + _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, + _DNS_TTL, service.address)) + except Exception as e: # TODO stop catching all Exceptions + log.exception('Unknown error, possibly benign: %r', e) + + if out is not None and out.answers: + out.id = msg.id + self.send(out, addr, port) + + def send(self, out, addr=_MDNS_ADDR, port=_MDNS_PORT): + """Sends an outgoing packet.""" + packet = out.packet() + log.debug('Sending %r as %r...', out, packet) + for s in self._respond_sockets: + bytes_sent = s.sendto(packet, 0, (addr, port)) + if bytes_sent != len(packet): + raise Error( + 'Should not happen, sent %d out of %d bytes' % ( + bytes_sent, len(packet))) + + def close(self): + """Ends the background threads, and prevent this instance from + servicing further queries.""" + global _GLOBAL_DONE + if not _GLOBAL_DONE: + _GLOBAL_DONE = True + self.notify_all() + self.engine.notify() + self.unregister_all_services() + for s in [self._listen_socket] + self._respond_sockets: + s.close()