diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..96c89ce
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,3 @@
+# Ignore all Git auto CR/LF line endings conversions
+* -text
+pyproject.toml export-subst
diff --git a/.gitignore b/.gitignore
index 898133b..43de283 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+# Python compiled files
*.py[cod]
# virtualenv and other misc bits
@@ -16,12 +17,15 @@
/Include
/local
*/local/*
+/local/
+/share/
+/tcl/
+/.eggs/
# Installer logs
pip-log.txt
# Unit test / coverage reports
-.tox
.cache
.coverage
.coverage.*
@@ -36,10 +40,19 @@ htmlcov
.pydevproject
.idea
org.eclipse.core.resources.prefs
+.vscode
+.vs
# Sphinx
docs/_build
+docs/bin
+docs/build
+docs/include
+docs/Lib
+doc/pyvenv.cfg
+pyvenv.cfg
+# Various junk and temp files
.DS_Store
*~
.*.sw[po]
@@ -48,6 +61,13 @@ docs/_build
*.bak
/.cache/
-/share/
-/local/
+# pyenv
+/.python-version
+/man/
/.pytest_cache/
+lib64
+tcl
+
+# Ignore Jupyter Notebook related temp files
+.ipynb_checkpoints/
+/.tox/
diff --git a/.readthedocs.yml b/.readthedocs.yml
new file mode 100644
index 0000000..1b71cd9
--- /dev/null
+++ b/.readthedocs.yml
@@ -0,0 +1,18 @@
+# .readthedocs.yml
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+
+# Required
+version: 2
+
+# Where the Sphinx conf.py file is located
+sphinx:
+ configuration: docs/source/conf.py
+
+# Setting the python version and doc build requirements
+python:
+ install:
+ - method: pip
+ path: .
+ extra_requirements:
+ - docs
diff --git a/.travis.yml b/.travis.yml
index 7785f04..1a90a38 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,75 +1,22 @@
-matrix:
- include:
- - os: osx
- env:
- - PYTHON="3.6.8"
- - TEST_SUITE="bin/py.test -vvs"
- language: generic
- python:
+# This is a skeleton Travis CI config file that provides a starting point for adding CI
+# to a Python project. Since we primarily develop in python3, this skeleton config file
+# will be specific to that language.
+#
+# See https://config.travis-ci.com/ for a full list of configuration options.
- - os: osx
- env:
- - PYTHON="2.7.15"
- - TEST_SUITE="bin/py.test -vvs"
- language: generic
- python:
+os: linux
- - os: linux
- sudo: required
- env: TEST_SUITE="bin/py.test -vvs"
- language: python
- python: "2.7"
- dist: xenial
-
- - os: linux
- sudo: required
- env: TEST_SUITE="bin/py.test -vvs"
- language: python
- python: "2.7"
- dist: bionic
-
- - os: linux
- sudo: required
- env: TEST_SUITE="bin/py.test -vvs"
- language: python
- python: "3.6"
- dist: xenial
-
- - os: linux
- sudo: required
- env: TEST_SUITE="bin/py.test -vvs"
- language: python
- python: "3.6"
- dist: bionic
+dist: xenial
-addons:
- homebrew:
- packages:
- - openssl
- - readline
- - sqlite3
- - xz
- - zlib
- - pyenv
- update: true
+language: python
+python:
+ - "3.6"
+ - "3.7"
+ - "3.8"
+ - "3.9"
-install:
- - ./configure
+# Scripts to run at install stage
+install: ./configure --dev
-script:
- # If debugging, use a subset of tests to wait less:
- # - ./bin/py.test -n 2 -vvs --cov=src tests/scancode
- # - echo $TEST_SUITE
- - bin/about check --verbose .
- - $TEST_SUITE
-
-notifications:
- irc:
- channels:
- - "chat.freenode.net#aboutcode"
- on_success: change
- on_failure: always
- use_notice: true
- skip_join: true
- template:
- - "%{repository_slug}#%{build_number} (%{branch}-%{commit}:%{author})-%{message}- %{build_url}"
+# Scripts to run at script stage
+script: tmp/bin/pytest
diff --git a/AUTHORS.rst b/AUTHORS.rst
index 997e20d..df7d6db 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -4,3 +4,8 @@ The following organizations or individuals have contributed to this code:
- Philippe Ombredanne @pombredanne
- Thomas Druez @tdruez
- Carmen Bianca Bakker @carmenbianca
+- Chin-Yeung Li @chinyeungli
+- Steven Esser @majurg
+- Sebastian Schuberth @sschuberth
+- Max Mehl @mxmehl
+- Peter Kolbus @pkolbus
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index e1fef5d..246afc4 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,13 +1,25 @@
Changelog
=========
-All notable changes to this project will be documented in this file.
-
-The format is based on `Keep a
-Changelog `__
[Unreleased]
------------
+
+
+[2.0] - 2021-06-04
+------------------
+
+Added
+~~~~~
+- Add ability to simplify license expressions without over simplifying by not
+ using using boolean logic.
+
+Changed
+~~~~~~~
+- Drop support for python27
+- Adopt the skeleton from https://github.com/nexB/skeleton
+
+
[1.2] - 2019-11-14
------------------
Added
@@ -22,6 +34,7 @@ Changed
~~~~~~~
- Update the thirdparty directory structure.
+
[1.0] - 2019-10-16
------------------
Added
@@ -33,6 +46,7 @@ Changed
~~~~~~~
- updated travis CI settings
+
[0.999] - 2019-04-29
--------------------
- Initial release
diff --git a/MANIFEST.in b/MANIFEST.in
index 5fdc938..ef3721e 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,19 +1,15 @@
graft src
-graft etc
-graft tests
-prune src/license_expression.egg-info
-
-include README.rst
-include apache-2.0.LICENSE
+include *.LICENSE
include NOTICE
-include MANIFEST.in
-include setup.py
-include setup.cfg
-include .gitignore
-include configure
-include configure.bat
-
-include .travis.yml appveyor.yml
+include *.ABOUT
+include *.toml
+include *.yml
+include *.rst
+include setup.*
+include configure*
+include requirements*
+include .git*
global-exclude *.py[co] __pycache__ *.*~
+
diff --git a/NOTICE b/NOTICE
index 186fbbe..82ebf8b 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,26 +1,19 @@
-Software license
-================
-
-license-expression is a free software tool from nexB Inc. and others.
-Visit https://github.com/nexB/license-expression for support and download.
-
-Copyright (c) 2016 nexB Inc. and others. All rights reserved.
-http://nexb.com and http://aboutcode.org
-
-This software is licensed under the Apache License version 2.0.
-
-You may not use this software except in compliance with the License.
-You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing, software distributed
-under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-CONDITIONS OF ANY KIND, either express or implied. See the License for the
-specific language governing permissions and limitations under the License.
-
-
-Third-party software licenses
-=============================
-
-license-expression embeds third-party free and open source software packages under
-various licenses. The origin and license of these packages is documented by .ABOUT
-files. The corresponding source code for pre-compiled third-party software is
-available in the thirdparty directory.
+#
+# Copyright (c) nexB Inc. and others.
+# SPDX-License-Identifier: Apache-2.0
+#
+# Visit https://aboutcode.org and https://github.com/nexB/license-expression
+# for support and download.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
diff --git a/README.rst b/README.rst
index 125ced9..1cd3eca 100644
--- a/README.rst
+++ b/README.rst
@@ -2,16 +2,16 @@
license-expression
==================
-license-expression is a small utility library to parse, compare, simplify and normalize
-license expressions (e.g. SPDX license expressions) using boolean logic such as:
-`GPL-2.0 or later WITH Classpath Exception AND MIT`.
+license-expression is a comprehensive utility library to parse, compare,
+simplify and normalize license expressions (such as SPDX license expressions)
+using boolean logic like in: `GPL-2.0 or later WITH Classpath Exception AND MIT`.
See also for details:
https://spdx.org/sites/cpstandard/files/pages/files/spdxversion2.1.pdf#page=95&zoom=auto
license: apache-2.0
-Python: 2.7 and 3.5+
+Python: 3.6+
Build and tests status
======================
@@ -135,6 +135,7 @@ Development
===========
* Checkout a clone from https://github.com/nexB/license-expression.git
-* Then run ``./configure`` (or ``configure.bat``) and then ``source bin/activate``. This will
- install all vendored dependencies in a local virtualenv, including development deps.
+* Then run ``./configure`` (or ``configure.bat``) and then ``source bin/activate``.
+ This will install all vendored dependencies in a local virtualenv, including
+ development deps.
* To run the tests, run ``py.test -vvs``
diff --git a/apache-2.0.LICENSE b/apache-2.0.LICENSE
index d9a10c0..d193db1 100644
--- a/apache-2.0.LICENSE
+++ b/apache-2.0.LICENSE
@@ -174,3 +174,31 @@
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
+<<<<<<< HEAD
+=======
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+>>>>>>> refs/remotes/skeleton/main
diff --git a/appveyor.yml b/appveyor.yml
index f6026af..a176708 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -2,20 +2,18 @@ version: '{build}'
environment:
matrix:
- - PYTHON_EXE: "C:\\Python27\\python.exe"
- - PYTHON_EXE: "C:\\Python27-x64\\python.exe"
- - PYTHON_EXE: "C:\\Python36\\python.exe"
- PYTHON_EXE: "C:\\Python36-x64\\python.exe"
+ - PYTHON_EXE: "C:\\Python37-x64\\python.exe"
+ - PYTHON_EXE: "C:\\Python38-x64\\python.exe"
+ - PYTHON_EXE: "C:\\Python39-x64\\python.exe"
install:
- - configure
+ - configure --dev
build: off
test_script:
- - 'bin\activate'
- - 'bin\python -c "from __future__ import print_function;import sys;print(sys.getdefaultencoding())"'
- - 'bin\py.test -vvs'
+ - 'tmp\Scripts\activate'
+ - 'tmp\Scripts\python -c "from __future__ import print_function;import sys;print(sys.getdefaultencoding())"'
+ - 'tmp\Scripts\pytest -vvs'
-on_failure:
- - "python etc/scripts/irc-notify.py aboutcode [{project_name}:{branch}] {short_commit}: \"{message}\" ({author}) {color_red}Failed,Details: {build_url},Commit: {commit_url}"
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 2625b5d..31ef36f 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -1,232 +1,64 @@
-trigger:
- branches:
- include: ['*']
- tags:
- include: ['*']
-
-pr:
- branches:
- include: ['*']
-
-jobs:
################################################################################
-# These jobs are using VMs and Azure-provided Pythons
+# We use Azure to run the full tests suites on multiple Python 3.x
+# on multiple Windows, macOS and Linux versions all on 64 bits
+# These jobs are using VMs with Azure-provided Python builds
################################################################################
+jobs:
+
- template: etc/ci/azure-posix.yml
parameters:
- name: Ubuntu_16
+ job_name: ubuntu16_cpython
image_name: ubuntu-16.04
- matrix:
- py27:
- python_version: '2.7'
- py36:
- python_version: '3.6'
- py37:
- python_version: '3.7'
+ python_versions: ['3.6', '3.7', '3.8', '3.9']
+ test_suites:
+ all: tmp/bin/pytest -vvs
+
+ - template: etc/ci/azure-posix.yml
+ parameters:
+ job_name: ubuntu18_cpython
+ image_name: ubuntu-18.04
+ python_versions: ['3.6', '3.7', '3.8', '3.9']
+ test_suites:
+ all: tmp/bin/pytest -n 2 -vvs
- template: etc/ci/azure-posix.yml
parameters:
- name: macOS_1013
- image_name: macos-10.13
- matrix:
- py27:
- python_version: '2.7'
- py36:
- python_version: '3.6'
- py37:
- python_version: '3.7'
+ job_name: ubuntu20_cpython
+ image_name: ubuntu-20.04
+ python_versions: ['3.6', '3.7', '3.8', '3.9']
+ test_suites:
+ all: tmp/bin/pytest -n 2 -vvs
- template: etc/ci/azure-posix.yml
parameters:
- name: macOS_1014
+ job_name: macos1014_cpython
image_name: macos-10.14
- matrix:
- py27:
- python_version: '2.7'
- py36:
- python_version: '3.6'
- py37:
- python_version: '3.7'
+ python_versions: ['3.6', '3.7', '3.8', '3.9']
+ test_suites:
+ all: tmp/bin/pytest -n 2 -vvs
- - template: etc/ci/azure-win.yml
+ - template: etc/ci/azure-posix.yml
parameters:
- name: Win_2016_32
- image_name: vs2017-win2016
- matrix:
- py27:
- python_version: '2.7'
- python_architecture: 'x86'
- py36:
- python_version: '3.6'
- python_architecture: 'x86'
- py37:
- python_version: '3.7'
- python_architecture: 'x86'
+ job_name: macos1015_cpython
+ image_name: macos-10.15
+ python_versions: ['3.6', '3.7', '3.8', '3.9']
+ test_suites:
+ all: tmp/bin/pytest -n 2 -vvs
- template: etc/ci/azure-win.yml
parameters:
- name: Win_2016_64
+ job_name: win2016_cpython
image_name: vs2017-win2016
- matrix:
- py27:
- python_version: '2.7'
- python_architecture: 'x64'
- py36:
- python_version: '3.6'
- python_architecture: 'x64'
- py37:
- python_version: '3.7'
- python_architecture: 'x64'
-
-
-################################################################################
-# These jobs are using containers and their own Python
-################################################################################
-
- - template: etc/ci/azure-container-deb.yml
- parameters:
- name: Ubuntu_16_xenial_py27
- container: 'ubuntu:xenial'
- python_path: 'python2.7'
- install_python: sudo apt-get install -y python python-dev
-
- - template: etc/ci/azure-container-deb.yml
- parameters:
- name: Ubuntu_16_xenial_py36
- container: 'ubuntu:xenial'
- python_path: 'python3.6'
- install_python: |
- sudo apt-get -y install software-properties-common
- sudo add-apt-repository -y ppa:deadsnakes
- sudo apt-get -y update
- sudo apt-get install -y python3.6 python3.6-venv python3.6-dev
-
- - template: etc/ci/azure-container-deb.yml
- parameters:
- name: Ubuntu_18_Bionic_py27
- container: 'ubuntu:bionic'
- python_path: 'python2.7'
- install_python: sudo apt-get install -y python python-dev
-
- - template: etc/ci/azure-container-deb.yml
- parameters:
- name: Ubuntu_18_Bionic_py36
- container: 'ubuntu:bionic'
- python_path: 'python3.6'
- install_python: sudo apt-get install -y python3.6 python3.6-venv python3.6-dev
-
+ python_versions: ['3.6', '3.7', '3.8', '3.9']
+ test_suites:
+ all: tmp\Scripts\pytest -n 2 -vvs
- - template: etc/ci/azure-container-rpm.yml
- parameters:
- name: CentOS7_py27
- container: 'centos:7'
- python_path: 'python2.7'
- install_python: sudo yum install -y python python27-devel
-
- - template: etc/ci/azure-container-rpm.yml
- parameters:
- name: CentOS7_py36
- container: 'centos:7'
- python_path: 'python3.6'
- install_python: |
- set -e -x
- sudo yum install -y epel-release
- sudo yum install -y python36 python36-devel python36-virtualenv
-
-
- - template: etc/ci/azure-container-rpm.yml
- parameters:
- name: Manylinux1_64_py27
- container: 'quay.io/pypa/manylinux1_x86_64:latest'
- python_path: '/opt/python/cp27-cp27mu/bin/python'
- install_packages: echo "No extra packages for now"
- install_python: echo "Python is pre-installed"
-
- - template: etc/ci/azure-container-rpm.yml
- parameters:
- name: Manylinux1_64_py36
- container: 'quay.io/pypa/manylinux1_x86_64:latest'
- python_path: '/opt/python/cp36-cp36m/bin/python'
- install_packages: echo "No extra packages for now"
- install_python: echo "Python is pre-installed"
-
- - template: etc/ci/azure-container-rpm.yml
- parameters:
- name: Manylinux2010_64_py27
- container: 'quay.io/pypa/manylinux2010_x86_64:latest'
- python_path: '/opt/python/cp27-cp27mu/bin/python'
- install_packages: echo "No extra packages for now"
- install_python: echo "Python is pre-installed"
-
- - template: etc/ci/azure-container-rpm.yml
- parameters:
- name: Manylinux2010_64_py36
- container: 'quay.io/pypa/manylinux2010_x86_64:latest'
- python_path: '/opt/python/cp36-cp36m/bin/python'
- install_packages: echo "No extra packages for now"
- install_python: echo "Python is pre-installed"
-
- - template: etc/ci/azure-container-rpm.yml
- parameters:
- name: Manylinux2010_64_py37
- container: 'quay.io/pypa/manylinux2010_x86_64:latest'
- python_path: '/opt/python/cp37-cp37m/bin/python'
- install_packages: echo "No extra packages for now"
- install_python: echo "Python is pre-installed"
-
-
- - template: etc/ci/azure-container-deb.yml
- parameters:
- name: Debian_9_Stretch_py27
- container: 'debian:stretch'
- python_path: 'python2.7'
- install_python: sudo apt-get install -y python python-dev
-
-
-################################################################################
-# These jobs are using containers and their own Python: FAILING FOR NOW
-################################################################################
-
-# - template: etc/ci/azure-container-deb.yml
-# parameters:
-# name: Debian_9_Stretch_py36
-# container: 'debian:stretch'
-# python_path: 'python3.6'
-# install_python: |
-# set -e -x
-# sudo apt-get install -y \
-# libncurses5-dev libncursesw5-dev libreadline6-dev \
-# libdb-dev libgdbm-dev libsqlite3-dev libssl-dev \
-# libbz2-dev libexpat1-dev liblzma-dev zlib1g-dev \
-# libcurl4-openssl-dev libpam0g-dev \
-# libsqlite3-dev tk-dev libffi-dev \
-# curl
-# export PYVER=3.6.8
-# curl -o Python-$PYVER.tgz https://www.python.org/ftp/python/$PYVER/Python-$PYVER.tgz
-# tar -xvf Python-$PYVER.tgz
-# cd Python-$PYVER
-# ./configure --enable-optimizations
-# make -j8
-# sudo make altinstall
-#
- - template: etc/ci/azure-container-rpm.yml
- parameters:
- name: Fedora_30_py27
- container: 'fedora:30'
- package_manager: dnf
- python_path: 'python2.7'
- install_python: |
- set -e -x
- sudo dnf install -y python2 python2-devel
-
- - template: etc/ci/azure-container-rpm.yml
+ - template: etc/ci/azure-win.yml
parameters:
- name: Fedora_30_py37
- container: 'fedora:30'
- package_manager: dnf
- python_path: 'python3.7'
- install_python: |
- set -e -x
- sudo dnf install -y python3 python3-devel python3-virtualenv
+ job_name: win2019_cpython
+ image_name: windows-2019
+ python_versions: ['3.6', '3.7', '3.8', '3.9']
+ test_suites:
+ all: tmp\Scripts\pytest -n 2 -vvs
diff --git a/configure b/configure
index 28a24ed..25ab0ce 100755
--- a/configure
+++ b/configure
@@ -1,28 +1,169 @@
-#!/bin/bash
+#!/usr/bin/env bash
#
-# Copyright (c) 2016 nexB Inc. http://www.nexb.com/ - All rights reserved.
+# Copyright (c) nexB Inc. and others. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0
+# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
+# See https://github.com/nexB/ for support or download.
+# See https://aboutcode.org for more information about nexB OSS projects.
#
+
+set -e
+#set -x
+
################################
-# change these variables to customize this script locally
+# A configuration script to set things up:
+# create a virtualenv and install or update thirdparty packages.
+# Source this script for initial configuration
+# Use configure --help for details
+#
+# This script will search for a virtualenv.pyz app in etc/thirdparty/virtualenv.pyz
+# Otherwise it will download the latest from the VIRTUALENV_PYZ_URL default
+################################
+CLI_ARGS=$1
+
+################################
+# Defaults. Change these variables to customize this script
+################################
+
+# Requirement arguments passed to pip and used by default or with --dev.
+REQUIREMENTS="--editable ."
+DEV_REQUIREMENTS="--editable .[testing]"
+
+# where we create a virtualenv
+VIRTUALENV_DIR=tmp
+
+# Cleanable files and directories with the --clean option
+CLEANABLE="
+ build
+ tmp"
+
+# extra arguments passed to pip
+PIP_EXTRA_ARGS=" "
+
+# the URL to download virtualenv.pyz if needed
+VIRTUALENV_PYZ_URL=https://bootstrap.pypa.io/virtualenv.pyz
################################
-# you can define one or more thirdparty dirs, each prefixed with TPP_DIR
-export TPP_DIR_BASE="thirdparty"
-# default configurations for dev
-CONF_DEFAULT="etc/conf/dev"
-#################################
-CFG_CMD_LINE_ARGS="$@"
+################################
+# Current directory where this script lives
+CFG_ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+CFG_BIN_DIR=$CFG_ROOT_DIR/$VIRTUALENV_DIR/bin
+
-if [[ "$1" == "" ]]; then
- # default for dev conf if not argument is provided
- CFG_CMD_LINE_ARGS=$CONF_DEFAULT
+################################
+# Set the quiet flag to empty if not defined
+if [[ "$CFG_QUIET" == "" ]]; then
+ CFG_QUIET=" "
fi
-CONFIGURE_ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-if [[ "$PYTHON_EXE" == "" ]]; then
- PYTHON_EXE=python
+################################
+# find a proper Python to run
+# Use environment variables or a file if available.
+# Otherwise the latest Python by default.
+if [[ "$PYTHON_EXECUTABLE" == "" ]]; then
+ # check for a file named PYTHON_EXECUTABLE
+ if [ -f "$CFG_ROOT_DIR/PYTHON_EXECUTABLE" ]; then
+ PYTHON_EXECUTABLE=$(cat "$CFG_ROOT_DIR/PYTHON_EXECUTABLE")
+ else
+ PYTHON_EXECUTABLE=python3
+ fi
fi
-$PYTHON_EXE "$CONFIGURE_ROOT_DIR/etc/configure.py" $CFG_CMD_LINE_ARGS
+
+################################
+cli_help() {
+ echo An initial configuration script
+ echo " usage: ./configure [options]"
+ echo
+ echo The default is to configure for regular use. Use --dev for development.
+ echo
+ echo The options are:
+ echo " --clean: clean built and installed files and exit."
+ echo " --dev: configure the environment for development."
+ echo " --help: display this help message and exit."
+ echo
+ echo By default, the python interpreter version found in the path is used.
+ echo Alternatively, the PYTHON_EXECUTABLE environment variable can be set to
+ echo configure another Python executable interpreter to use. If this is not
+ echo set, a file named PYTHON_EXECUTABLE containing a single line with the
+ echo path of the Python executable to use will be checked last.
+ set +e
+ exit
+}
+
+
+clean() {
+ # Remove cleanable file and directories and files from the root dir.
+ echo "* Cleaning ..."
+ for cln in $CLEANABLE;
+ do rm -rf "${CFG_ROOT_DIR:?}/${cln:?}";
+ done
+ set +e
+ exit
+}
+
+
+create_virtualenv() {
+ # create a virtualenv for Python
+ # Note: we do not use the bundled Python 3 "venv" because its behavior and
+ # presence is not consistent across Linux distro and sometimes pip is not
+ # included either by default. The virtualenv.pyz app cures all these issues.
+
+ VENV_DIR="$1"
+ if [ ! -f "$CFG_BIN_DIR/python" ]; then
+
+ mkdir -p "$CFG_ROOT_DIR/$VENV_DIR"
+
+ if [ -f "$CFG_ROOT_DIR/etc/thirdparty/virtualenv.pyz" ]; then
+ VIRTUALENV_PYZ="$CFG_ROOT_DIR/etc/thirdparty/virtualenv.pyz"
+ else
+ VIRTUALENV_PYZ="$CFG_ROOT_DIR/$VENV_DIR/virtualenv.pyz"
+ wget -O "$VIRTUALENV_PYZ" "$VIRTUALENV_PYZ_URL"
+ fi
+
+ $PYTHON_EXECUTABLE "$VIRTUALENV_PYZ" \
+ --wheel embed --pip embed --setuptools embed \
+ --seeder pip \
+ --never-download \
+ --no-periodic-update \
+ --no-vcs-ignore \
+ $CFG_QUIET \
+ "$CFG_ROOT_DIR/$VENV_DIR"
+ fi
+}
+
+
+install_packages() {
+ # install requirements in virtualenv
+ # note: --no-build-isolation means that pip/wheel/setuptools will not
+ # be reinstalled a second time and reused from the virtualenv and this
+ # speeds up the installation.
+ # We always have the PEP517 build dependencies installed already.
+
+ "$CFG_BIN_DIR/pip" install \
+ --upgrade \
+ --no-build-isolation \
+ $CFG_QUIET \
+ $PIP_EXTRA_ARGS \
+ $1
+}
+
+
+################################
+# Main command line entry point
+CFG_DEV_MODE=0
+CFG_REQUIREMENTS=$REQUIREMENTS
+
+case "$CLI_ARGS" in
+ --help) cli_help;;
+ --clean) clean;;
+ --dev) CFG_REQUIREMENTS="$DEV_REQUIREMENTS" && CFG_DEV_MODE=1;;
+esac
+
+create_virtualenv "$VIRTUALENV_DIR"
+install_packages "$CFG_REQUIREMENTS"
+. "$CFG_BIN_DIR/activate"
+
+set +e
diff --git a/configure.bat b/configure.bat
index 5d216df..c12f937 100755
--- a/configure.bat
+++ b/configure.bat
@@ -1,54 +1,180 @@
@echo OFF
-setlocal
-@rem Copyright (c) nexB Inc. http://www.nexb.com/ - All rights reserved.
+@setlocal
+
+@rem Copyright (c) nexB Inc. and others. All rights reserved.
+@rem SPDX-License-Identifier: Apache-2.0
+@rem See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
+@rem See https://github.com/nexB/ for support or download.
+@rem See https://aboutcode.org for more information about nexB OSS projects.
+
@rem ################################
-@rem # Defaults. change these variables to customize this script locally
+@rem # A configuration script to set things up:
+@rem # create a virtualenv and install or update thirdparty packages.
+@rem # Source this script for initial configuration
+@rem # Use configure --help for details
+
+@rem # This script will search for a virtualenv.pyz app in etc\thirdparty\virtualenv.pyz
+@rem # Otherwise it will download the latest from the VIRTUALENV_PYZ_URL default
@rem ################################
-@rem # you can define one or more thirdparty dirs, each prefixed with TPP_DIR
-set TPP_DIR=thirdparty
-set DEFAULT_PYTHON=python
-@rem # default configurations for dev
-set CONF_DEFAULT="etc/conf/dev"
-@rem #################################
+@rem ################################
+@rem # Defaults. Change these variables to customize this script
+@rem ################################
-set CFG_ROOT_DIR=%~dp0
+@rem # Requirement arguments passed to pip and used by default or with --dev.
+set "REQUIREMENTS=--editable ."
+set "DEV_REQUIREMENTS=--editable .[testing]"
+
+@rem # where we create a virtualenv
+set "VIRTUALENV_DIR=tmp"
-@rem Collect all command line arguments in a variable
-set CFG_CMD_LINE_ARGS=
+@rem # Cleanable files and directories to delete with the --clean option
+set "CLEANABLE=build tmp"
-@rem a possible alternative way and simpler way to slurp args
-@rem set CFG_CMD_LINE_ARGS=%*
+@rem # extra arguments passed to pip
+set "PIP_EXTRA_ARGS= "
+
+@rem # the URL to download virtualenv.pyz if needed
+set VIRTUALENV_PYZ_URL=https://bootstrap.pypa.io/virtualenv.pyz
+@rem ################################
-:collectarg
- if ""%1""=="""" goto continue
- call set CFG_CMD_LINE_ARGS=%CFG_CMD_LINE_ARGS% %1
- shift
- goto collectarg
+@rem ################################
+@rem # Current directory where this script lives
+set CFG_ROOT_DIR=%~dp0
+set "CFG_BIN_DIR=%CFG_ROOT_DIR%\%VIRTUALENV_DIR%\Scripts"
+
+
+@rem ################################
+@rem # Set the quiet flag to empty if not defined
+if not defined CFG_QUIET (
+ set "CFG_QUIET= "
+)
-:continue
-@rem Set defaults when no args are passed
-if "%CFG_CMD_LINE_ARGS%"=="" set CFG_CMD_LINE_ARGS="%CONF_DEFAULT%"
-if "%PYTHON_EXE%"=="" set PYTHON_EXE=%DEFAULT_PYTHON%
+@rem ################################
+@rem # Main command line entry point
+set CFG_DEV_MODE=0
+set "CFG_REQUIREMENTS=%REQUIREMENTS%"
+
+if "%1" EQU "--help" (goto cli_help)
+if "%1" EQU "--clean" (goto clean)
+if "%1" EQU "--dev" (
+ set "CFG_REQUIREMENTS=%DEV_REQUIREMENTS%"
+ set CFG_DEV_MODE=1
+)
+if "%1" EQU "--python" (
+ echo "The --python option is now DEPRECATED. Use the PYTHON_EXECUTABLE environment"
+ echo "variable instead. Run configure --help for details."
+ exit /b 0
+)
+@rem ################################
+@rem # find a proper Python to run
+@rem # Use environment variables or a file if available.
+@rem # Otherwise the latest Python by default.
+if not defined PYTHON_EXECUTABLE (
+ @rem # check for a file named PYTHON_EXECUTABLE
+ if exist ""%CFG_ROOT_DIR%\PYTHON_EXECUTABLE"" (
+ set /p PYTHON_EXECUTABLE=<""%CFG_ROOT_DIR%\PYTHON_EXECUTABLE""
+ ) else (
+ set "PYTHON_EXECUTABLE=py"
+ )
+)
-call "%PYTHON_EXE%" "%CFG_ROOT_DIR%etc\configure.py" %CFG_CMD_LINE_ARGS%
-@rem Return a proper return code on failure
+:create_virtualenv
+@rem # create a virtualenv for Python
+@rem # Note: we do not use the bundled Python 3 "venv" because its behavior and
+@rem # presence is not consistent across Linux distro and sometimes pip is not
+@rem # included either by default. The virtualenv.pyz app cures all these issues.
+
+if not exist ""%CFG_BIN_DIR%\python.exe"" (
+ if not exist "%CFG_BIN_DIR%" (
+ mkdir %CFG_BIN_DIR%
+ )
+
+ if exist ""%CFG_ROOT_DIR%\etc\thirdparty\virtualenv.pyz"" (
+ %PYTHON_EXECUTABLE% "%CFG_ROOT_DIR%\etc\thirdparty\virtualenv.pyz" ^
+ --wheel embed --pip embed --setuptools embed ^
+ --seeder pip ^
+ --never-download ^
+ --no-periodic-update ^
+ --no-vcs-ignore ^
+ %CFG_QUIET% ^
+ %CFG_ROOT_DIR%\%VIRTUALENV_DIR%
+ ) else (
+ if not exist ""%CFG_ROOT_DIR%\%VIRTUALENV_DIR%\virtualenv.pyz"" (
+ curl -o "%CFG_ROOT_DIR%\%VIRTUALENV_DIR%\virtualenv.pyz" %VIRTUALENV_PYZ_URL%
+
+ if %ERRORLEVEL% neq 0 (
+ exit /b %ERRORLEVEL%
+ )
+ )
+ %PYTHON_EXECUTABLE% "%CFG_ROOT_DIR%\%VIRTUALENV_DIR%\virtualenv.pyz" ^
+ --wheel embed --pip embed --setuptools embed ^
+ --seeder pip ^
+ --never-download ^
+ --no-periodic-update ^
+ --no-vcs-ignore ^
+ %CFG_QUIET% ^
+ %CFG_ROOT_DIR%\%VIRTUALENV_DIR%
+ )
+)
-if %errorlevel% neq 0 (
- exit /b %errorlevel%
+if %ERRORLEVEL% neq 0 (
+ exit /b %ERRORLEVEL%
)
-@rem Activate the virtualenv
-endlocal
-if exist "%CFG_ROOT_DIR%bin\activate" (
- "%CFG_ROOT_DIR%bin\activate"
+:install_packages
+@rem # install requirements in virtualenv
+@rem # note: --no-build-isolation means that pip/wheel/setuptools will not
+@rem # be reinstalled a second time and reused from the virtualenv and this
+@rem # speeds up the installation.
+@rem # We always have the PEP517 build dependencies installed already.
+
+%CFG_BIN_DIR%\pip install ^
+ --upgrade ^
+ --no-build-isolation ^
+ %CFG_QUIET% ^
+ %PIP_EXTRA_ARGS% ^
+ %CFG_REQUIREMENTS%
+
+if %ERRORLEVEL% neq 0 (
+ exit /b %ERRORLEVEL%
)
-goto EOS
-:EOS
+exit /b 0
+
+
+@rem ################################
+
+:cli_help
+ echo An initial configuration script
+ echo " usage: configure [options]"
+ echo " "
+ echo The default is to configure for regular use. Use --dev for development.
+ echo " "
+ echo The options are:
+ echo " --clean: clean built and installed files and exit."
+ echo " --dev: configure the environment for development."
+ echo " --help: display this help message and exit."
+ echo " "
+ echo By default, the python interpreter version found in the path is used.
+ echo Alternatively, the PYTHON_EXECUTABLE environment variable can be set to
+ echo configure another Python executable interpreter to use. If this is not
+ echo set, a file named PYTHON_EXECUTABLE containing a single line with the
+ echo path of the Python executable to use will be checked last.
+ exit /b 0
+
+
+:clean
+@rem # Remove cleanable file and directories and files from the root dir.
+echo "* Cleaning ..."
+for %%F in (%CLEANABLE%) do (
+ rmdir /s /q "%CFG_ROOT_DIR%\%%F" >nul 2>&1
+ del /f /q "%CFG_ROOT_DIR%\%%F" >nul 2>&1
+)
+exit /b 0
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..d0c3cbf
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+SOURCEDIR = source
+BUILDDIR = build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 0000000..6247f7e
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=source
+set BUILDDIR=build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd
diff --git a/docs/scripts/doc8_style_check.sh b/docs/scripts/doc8_style_check.sh
new file mode 100644
index 0000000..9416323
--- /dev/null
+++ b/docs/scripts/doc8_style_check.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# halt script on error
+set -e
+# Check for Style Code Violations
+doc8 --max-line-length 100 source --ignore D000 --quiet
\ No newline at end of file
diff --git a/docs/scripts/sphinx_build_link_check.sh b/docs/scripts/sphinx_build_link_check.sh
new file mode 100644
index 0000000..c542686
--- /dev/null
+++ b/docs/scripts/sphinx_build_link_check.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+# halt script on error
+set -e
+# Build locally, and then check links
+sphinx-build -E -W -b linkcheck source build
\ No newline at end of file
diff --git a/docs/source/conf.py b/docs/source/conf.py
new file mode 100644
index 0000000..529cae3
--- /dev/null
+++ b/docs/source/conf.py
@@ -0,0 +1,63 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+
+# -- Project information -----------------------------------------------------
+
+project = 'nexb-skeleton'
+copyright = 'nexb Inc.'
+author = 'nexb Inc.'
+
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = []
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'sphinx_rtd_theme'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+html_context = {
+ 'css_files': [
+ '_static/theme_overrides.css', # override wide tables in RTD theme
+ ],
+ "display_github": True,
+ "github_user": "nexB",
+ "github_repo": "nexb-skeleton",
+ "github_version": "develop", # branch
+ "conf_py_path": "/docs/source/", # path in the checkout to the docs root
+ }
\ No newline at end of file
diff --git a/docs/source/index.rst b/docs/source/index.rst
new file mode 100644
index 0000000..67fcf21
--- /dev/null
+++ b/docs/source/index.rst
@@ -0,0 +1,15 @@
+Welcome to nexb-skeleton's documentation!
+=========================================
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Contents:
+
+ skeleton/index
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
diff --git a/docs/source/skeleton/index.rst b/docs/source/skeleton/index.rst
new file mode 100644
index 0000000..7dfc6cb
--- /dev/null
+++ b/docs/source/skeleton/index.rst
@@ -0,0 +1,15 @@
+# Docs Structure Guide
+# Rst docs - https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html
+#
+# 1. Place docs in folders under source for different sections
+# 2. Link them by adding individual index files in each section
+# to the main index, and then files for each section to their
+# respective index files.
+# 3. Use `.. include` statements to include other .rst files
+# or part of them, or use hyperlinks to a section of the docs,
+# to get rid of repetition.
+# https://docutils.sourceforge.io/docs/ref/rst/directives.html#including-an-external-document-fragment
+#
+# Note: Replace these guide/placeholder docs
+
+.. include:: ../../../README.rst
diff --git a/etc/ci/azure-container-deb.yml b/etc/ci/azure-container-deb.yml
deleted file mode 100644
index 425f5b8..0000000
--- a/etc/ci/azure-container-deb.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-parameters:
- name: ''
- container: ''
- python_path: ''
- package_manager: apt-get
- install_python: ''
- install_packages: |
- set -e -x
- sudo apt-get -y update
- sudo apt-get -y install \
- build-essential \
- xz-utils zlib1g bzip2 libbz2-1.0 tar \
- sqlite3 libxml2-dev libxslt1-dev \
- software-properties-common openssl
-
-jobs:
-- job: ${{ parameters.name }}
-
- pool:
- vmImage: 'ubuntu-16.04'
-
- container:
- image: ${{ parameters.container }}
- options: '--name ${{ parameters.name }} -v /usr/bin/docker:/tmp/docker:ro'
-
- steps:
- - script: /tmp/docker exec -t -u 0 ${{ parameters.name }} $(Build.SourcesDirectory)/etc/ci/install_sudo.sh ${{ parameters.package_manager }}
- displayName: Install sudo
-
- - script: ${{ parameters.install_packages }}
- displayName: Install required packages
-
- - script: ${{ parameters.install_python }}
- displayName: Install Python
-
- - script: PYTHON_EXE=${{ parameters.python_path }} ./configure
- displayName: 'Configure'
-
- - script: bin/py.test -vvs
- displayName: 'Run tests'
diff --git a/etc/ci/azure-container-rpm.yml b/etc/ci/azure-container-rpm.yml
deleted file mode 100644
index 3e8b7e8..0000000
--- a/etc/ci/azure-container-rpm.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-parameters:
- name: ''
- container: ''
- python_path: ''
- package_manager: yum
- install_python: ''
- install_packages: |
- set -e -x
- sudo yum groupinstall -y "Development Tools"
- sudo yum install -y \
- openssl openssl-devel \
- sqlite-devel zlib-devel xz-devel bzip2-devel \
- bzip2 tar unzip zip \
- libxml2-devel libxslt-devel
-
-jobs:
-- job: ${{ parameters.name }}
-
- pool:
- vmImage: 'ubuntu-16.04'
-
- container:
- image: ${{ parameters.container }}
- options: '--name ${{ parameters.name }} -v /usr/bin/docker:/tmp/docker:ro'
-
- steps:
- - script: /tmp/docker exec -t -u 0 ${{ parameters.name }} $(Build.SourcesDirectory)/etc/ci/install_sudo.sh ${{ parameters.package_manager }}
- displayName: Install sudo
-
- - script: ${{ parameters.install_packages }}
- displayName: Install required packages
-
- - script: ${{ parameters.install_python }}
- displayName: Install Python
-
- - script: PYTHON_EXE=${{ parameters.python_path }} ./configure
- displayName: 'Configure'
-
- - script: bin/py.test -vvs
- displayName: 'Run tests'
diff --git a/etc/ci/azure-posix.yml b/etc/ci/azure-posix.yml
index 679d155..0921d9b 100644
--- a/etc/ci/azure-posix.yml
+++ b/etc/ci/azure-posix.yml
@@ -1,28 +1,41 @@
parameters:
- name: ''
- image_name: ''
- matrix: []
+ job_name: ''
+ image_name: ''
+ python_versions: []
+ test_suites: {}
+ python_architecture: x64
jobs:
-- job: ${{ parameters.name }}
+ - job: ${{ parameters.job_name }}
- pool:
- vmImage: ${{ parameters.image_name }}
+ pool:
+ vmImage: ${{ parameters.image_name }}
- strategy:
- matrix:
- ${{ insert }}: ${{ parameters.matrix }}
+ strategy:
+ matrix:
+ ${{ each pyver in parameters.python_versions }}:
+ ${{ each tsuite in parameters.test_suites }}:
+ ${{ format('py{0} {1}', pyver, tsuite.key) }}:
+ python_version: ${{ pyver }}
+ test_suite_label: ${{ tsuite.key }}
+ test_suite: ${{ tsuite.value }}
- steps:
- - task: UsePythonVersion@0
- inputs:
- versionSpec: '$(python_version)'
+ steps:
+ - checkout: self
+ fetchDepth: 10
- - script: ./configure
- displayName: 'Configure'
+ - task: UsePythonVersion@0
+ inputs:
+ versionSpec: '$(python_version)'
+ architecture: '${{ parameters.python_architecture }}'
+ displayName: 'Install Python $(python_version)'
- - script: bin/about check --verbose .
- displayName: 'Check ABOUT files'
+ - script: |
+ python3 --version
+ python$(python_version) --version
+ echo "python$(python_version)" > PYTHON_EXECUTABLE
+ ./configure --dev
+ displayName: 'Run Configure'
- - script: bin/py.test -vvs
- displayName: 'Run tests'
+ - script: $(test_suite)
+ displayName: 'Run $(test_suite_label) tests with py$(python_version) on ${{ parameters.job_name }}'
diff --git a/etc/ci/azure-win.yml b/etc/ci/azure-win.yml
index ffed900..03d8927 100644
--- a/etc/ci/azure-win.yml
+++ b/etc/ci/azure-win.yml
@@ -1,29 +1,39 @@
parameters:
- name: ''
- image_name: ''
- matrix: []
+ job_name: ''
+ image_name: ''
+ python_versions: []
+ test_suites: {}
+ python_architecture: x64
jobs:
-- job: ${{ parameters.name }}
+ - job: ${{ parameters.job_name }}
- pool:
- vmImage: ${{ parameters.image_name }}
+ pool:
+ vmImage: ${{ parameters.image_name }}
- strategy:
- matrix:
- ${{ insert }}: ${{ parameters.matrix }}
+ strategy:
+ matrix:
+ ${{ each pyver in parameters.python_versions }}:
+ ${{ each tsuite in parameters.test_suites }}:
+ ${{ format('py{0} {1}', pyver, tsuite.key) }}:
+ python_version: ${{ pyver }}
+ test_suite_label: ${{ tsuite.key }}
+ test_suite: ${{ tsuite.value }}
+ steps:
+ - checkout: self
+ fetchDepth: 10
- steps:
- - task: UsePythonVersion@0
- inputs:
- versionSpec: '$(python_version)'
- architecture: '$(python_architecture)'
+ - task: UsePythonVersion@0
+ inputs:
+ versionSpec: '$(python_version)'
+ architecture: '${{ parameters.python_architecture }}'
+ displayName: 'Install Python $(python_version)'
- - script: configure
- displayName: 'Configure'
+ - script: |
+ python --version
+ echo | set /p=python> PYTHON_EXECUTABLE
+ configure --dev
+ displayName: 'Run Configure'
- - script: bin\about check --verbose .
- displayName: 'Check ABOUT files'
-
- - script: bin\py.test -vvs
- displayName: 'Run tests'
+ - script: $(test_suite)
+ displayName: 'Run $(test_suite_label) tests with py$(python_version) on ${{ parameters.job_name }}'
diff --git a/etc/ci/install_sudo.sh b/etc/ci/install_sudo.sh
deleted file mode 100755
index 77f4210..0000000
--- a/etc/ci/install_sudo.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-set -e
-
-
-if [[ "$1" == "apt-get" ]]; then
- apt-get update -y
- apt-get -o DPkg::Options::="--force-confold" install -y sudo
-
-elif [[ "$1" == "yum" ]]; then
- yum install -y sudo
-
-elif [[ "$1" == "dnf" ]]; then
- dnf install -y sudo
-
-fi
diff --git a/etc/conf/base.txt b/etc/conf/base.txt
deleted file mode 100644
index 267ac4a..0000000
--- a/etc/conf/base.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-# Base configuration tools
-certifi
-setuptools
-wheel
-pip
-wincertstore
-
-# Self
--e .
\ No newline at end of file
diff --git a/etc/conf/dev/base.txt b/etc/conf/dev/base.txt
deleted file mode 100644
index a32ceb9..0000000
--- a/etc/conf/dev/base.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# Testing
-py
-colorama
-pytest
-pluggy
-aboutcode-toolkit
\ No newline at end of file
diff --git a/etc/conf/win.txt b/etc/conf/win.txt
deleted file mode 100644
index f6ee7e9..0000000
--- a/etc/conf/win.txt
+++ /dev/null
@@ -1 +0,0 @@
-wincertstore
diff --git a/etc/configure.py b/etc/configure.py
deleted file mode 100644
index 8f42f20..0000000
--- a/etc/configure.py
+++ /dev/null
@@ -1,410 +0,0 @@
-#!/usr/bin/python
-
-# Copyright (c) 2017 nexB Inc. and others. All rights reserved.
-# http://nexb.com and http://aboutcode.org
-#
-# This software is licensed under the Apache License version 2.0.
-#
-# You may not use this software except in compliance with the License.
-# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software distributed
-# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-# CONDITIONS OF ANY KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations under the License.
-
-"""
-This script a configuration helper to select pip requirement files to install
-and python and shell configuration scripts to execute based on provided config
-directories paths arguments and the operating system platform. To use, create
-a configuration directory tree that contains any of these:
-
- * Requirements files named with this convention:
- - base.txt contains common requirements installed on all platforms.
- - win.txt, linux.txt, mac.txt, posix.txt are os-specific requirements.
-
- * Python scripts files named with this convention:
- - base.py is a common script executed on all os before os-specific scripts.
- - win.py, linux.py, mac.py, posix.py are os-specific scripts to execute.
-
- * Shell or Windows CMD scripts files named with this convention:
- - win.bat is a windows bat file to execute
- - posix.sh, linux.sh, mac.sh are os-specific scripts to execute.
-
-The config directory structure contains one or more directories paths. This
-way you can have a main configuration and additional sub-configurations of a
-product such as for prod, test, ci, dev, or anything else.
-
-All scripts and requirements are optional and only used if presents. Scripts
-are executed in sequence, one after the other after all requirements are
-installed, so they may import from any installed requirement.
-
-The execution order is:
- - requirements installation
- - python scripts execution
- - shell scripts execution
-
-On posix, posix Python and shell scripts are executed before mac or linux
-scripts.
-
-The base scripts or packages are always installed first before platform-
-specific ones.
-
-For example a tree could be looking like this::
- etc/conf
- base.txt : base pip requirements for all platforms
- linux.txt : linux-only pip requirements
- base.py : base config script for all platforms
- win.py : windows-only config script
- posix.sh: posix-only shell script
-
- etc/conf/prod
- base.txt : base pip requirements for all platforms
- linux.txt : linux-only pip requirements
- linux.sh : linux-only script
- base.py : base config script for all platforms
- mac.py : mac-only config script
-"""
-
-from __future__ import print_function
-
-import os
-import stat
-import sys
-import shutil
-import subprocess
-
-# platform-specific file base names
-sys_platform = str(sys.platform).lower()
-on_win = False
-if 'linux' in sys_platform:
- platform_names = ('posix', 'linux',)
-elif'win32' in sys_platform:
- platform_names = ('win',)
- on_win = True
-elif 'darwin' in sys_platform:
- platform_names = ('posix', 'mac',)
-else:
- raise Exception('Unsupported OS/platform')
- platform_names = tuple()
-
-# common file basenames for requirements and scripts
-base = ('base',)
-
-# known full file names with txt extension for requirements
-# base is always last
-requirements = tuple(p + '.txt' for p in platform_names + base)
-
-# known full file names with py extensions for scripts
-# base is always last
-python_scripts = tuple(p + '.py' for p in platform_names + base)
-
-# known full file names of shell scripts
-# there is no base for scripts: they cannot work cross OS (cmd vs. sh)
-shell_scripts = tuple(p + '.sh' for p in platform_names)
-if on_win:
- shell_scripts = ('win.bat',)
-
-
-def call(cmd, root_dir, quiet=True):
- """ Run a `cmd` command (as a list of args) with all env vars."""
- cmd = ' '.join(cmd)
- # if not quiet:
- # print(' Running command:', repr(cmd))
-
- if subprocess.Popen(cmd, shell=True, env=dict(os.environ), cwd=root_dir).wait() != 0:
- print()
- print('Failed to execute command:\n%(cmd)s. Aborting...' % locals())
- sys.exit(1)
-
-
-def find_pycache(root_dir):
- """
- Yield __pycache__ directory paths found in root_dir as paths relative to
- root_dir.
- """
- for top, dirs, _files in os.walk(root_dir):
- for d in dirs:
- if d == '__pycache__':
- dir_path = os.path.join(top, d)
- dir_path = dir_path.replace(root_dir, '', 1)
- dir_path = dir_path.strip(os.path.sep)
- yield dir_path
-
-
-def clean(root_dir):
- """
- Remove cleanable directories and files in root_dir.
- """
- print('* Cleaning ...')
- cleanable = '''build bin lib Lib include Include Scripts local
- django_background_task.log
- develop-eggs eggs parts .installed.cfg
- .Python
- .cache
- pip-selfcheck.json
- '''.split()
-
- # also clean __pycache__ if any
- cleanable.extend(find_pycache(root_dir))
-
- for d in cleanable:
- try:
- loc = os.path.join(root_dir, d)
- if os.path.exists(loc):
- if os.path.isdir(loc):
- shutil.rmtree(loc)
- else:
- os.remove(loc)
- except:
- pass
-
-
-def build_pip_dirs_args(paths, root_dir, option='--extra-search-dir='):
- """
- Return an iterable of pip command line options for `option` of pip using a
- list of `paths` to directories.
- """
- for path in paths:
- if not os.path.isabs(path):
- path = os.path.join(root_dir, path)
- if os.path.exists(path):
- yield option + '"' + path + '"'
-
-
-def create_virtualenv(std_python, root_dir, tpp_dirs, quiet=False):
- """
- Create a virtualenv in `root_dir` using the `std_python` Python
- executable. One of the `tpp_dirs` must contain a vendored virtualenv.py and
- virtualenv dependencies such as setuptools and pip packages.
-
- @std_python: Path or name of the Python executable to use.
-
- @root_dir: directory in which the virtualenv will be created. This is also
- the root directory for the project and the base directory for vendored
- components directory paths.
-
- @tpp_dirs: list of directory paths relative to `root_dir` containing
- vendored Python distributions that pip will use to find required
- components.
- """
- if not quiet:
- print('* Configuring Python ...')
- # search virtualenv.py in the tpp_dirs. keep the first found
- venv_py = None
- for tpd in tpp_dirs:
- venv = os.path.join(root_dir, tpd, 'virtualenv.py')
- if os.path.exists(venv):
- venv_py = '"' + venv + '"'
- break
-
- # error out if venv_py not found
- if not venv_py:
- print('Configuration Error ... aborting.')
- exit(1)
-
- vcmd = [std_python, venv_py, '--never-download']
- if quiet:
- vcmd += ['--quiet']
- # third parties may be in more than one directory
- vcmd.extend(build_pip_dirs_args(tpp_dirs, root_dir))
- # we create the virtualenv in the root_dir
- vcmd.append('"' + root_dir + '"')
- call(vcmd, root_dir, quiet)
-
-
-def activate(root_dir):
- """ Activate a virtualenv in the current process."""
- print('* Activating ...')
- bin_dir = os.path.join(root_dir, 'bin')
- activate_this = os.path.join(bin_dir, 'activate_this.py')
- with open(activate_this) as f:
- code = compile(f.read(), activate_this, 'exec')
- exec(code, dict(__file__=activate_this))
-
-
-def install_3pp(configs, root_dir, tpp_dirs, quiet=False):
- """
- Install requirements from requirement files found in `configs` with pip,
- using the vendored components in `tpp_dirs`.
- """
- if not quiet:
- print('* Installing components ...')
- requirement_files = get_conf_files(configs, root_dir, requirements)
- for req_file in requirement_files:
- if on_win:
- pcmd = ['python', '-m']
- else:
- pcmd = []
- pcmd += ['pip', 'install', '--no-index', '--no-cache-dir']
- if quiet:
- pcmd += ['--quiet']
-
- pip_dir_args = list(build_pip_dirs_args(tpp_dirs, root_dir, '--find-links='))
- pcmd.extend(pip_dir_args)
- req_loc = os.path.join(root_dir, req_file)
- pcmd.extend(['-r' , '"' + req_loc + '"'])
- call(pcmd, root_dir, quiet)
-
-
-def run_scripts(configs, root_dir, configured_python, quiet=False):
- """
- Run Python scripts and shell scripts found in `configs`.
- """
- if not quiet:
- print('* Configuring ...')
- # Run Python scripts for each configurations
- for py_script in get_conf_files(configs, root_dir, python_scripts):
- cmd = [configured_python, '"' + os.path.join(root_dir, py_script) + '"']
- call(cmd, root_dir, quiet)
-
- # Run sh_script scripts for each configurations
- for sh_script in get_conf_files(configs, root_dir, shell_scripts):
- # we source the scripts on posix
- cmd = ['.']
- if on_win:
- cmd = []
- cmd = cmd + [os.path.join(root_dir, sh_script)]
- call(cmd, root_dir, quiet)
-
-
-def chmod_bin(directory):
- """
- Makes the directory and its children executable recursively.
- """
- rwx = (stat.S_IXUSR | stat.S_IRUSR | stat.S_IWUSR
- | stat.S_IXGRP | stat.S_IXOTH)
- for path, _, files in os.walk(directory):
- for f in files:
- os.chmod(os.path.join(path, f), rwx)
-
-
-def get_conf_files(config_dir_paths, root_dir, file_names=requirements):
- """
- Return a list of collected path-prefixed file paths matching names in a
- file_names tuple, based on config_dir_paths, root_dir and the types of
- file_names requested. Returned paths are posix paths.
-
- @config_dir_paths: Each config_dir_path is a relative from the project
- root to a config dir. This script should always be called from the project
- root dir.
-
- @root_dir: The project absolute root dir.
-
- @file_names: get requirements, python or shell files based on list of
- supported file names provided as a tuple of supported file_names.
-
- Scripts or requirements are optional and only used if presents. Unknown
- scripts or requirements file_names are ignored (but they could be used
- indirectly by known requirements with -r requirements inclusion, or
- scripts with python imports.)
-
- Since Python scripts are executed after requirements are installed they
- can import from any requirement-installed component such as Fabric.
- """
- # collect files for each requested dir path
- collected = []
- for config_dir_path in config_dir_paths:
- abs_config_dir_path = os.path.join(root_dir, config_dir_path)
- if not os.path.exists(abs_config_dir_path):
- print('Configuration directory %(config_dir_path)s '
- 'does not exists. Skipping.' % locals())
- continue
- # Support args like enterprise or enterprise/dev
- paths = config_dir_path.strip('/').replace('\\', '/').split('/')
- # a tuple of (relative path, location,)
- current = None
- for path in paths:
- if not current:
- current = (path, os.path.join(root_dir, path),)
- else:
- base_path, base_loc = current
- current = (os.path.join(base_path, path),
- os.path.join(base_loc, path),)
- path, loc = current
- # we iterate on known filenames to ensure the defined precedence
- # is respected (posix over mac, linux), etc
- for n in file_names:
- for f in os.listdir(loc):
- if f == n:
- f_loc = os.path.join(loc, f)
- if f_loc not in collected:
- collected.append(f_loc)
-
- return collected
-
-
-if __name__ == '__main__':
- # define/setup common directories
- etc_dir = os.path.abspath(os.path.dirname(__file__))
- root_dir = os.path.dirname(etc_dir)
-
- args = sys.argv[1:]
- if args[0] == '--clean':
- clean(root_dir)
- sys.exit(0)
-
- sys.path.insert(0, root_dir)
- bin_dir = os.path.join(root_dir, 'bin')
- standard_python = sys.executable
-
- # you must create a CONFIGURE_QUIET env var if you want to run quietly
- run_quiet = 'CONFIGURE_QUIET' in os.environ
-
- if on_win:
- configured_python = os.path.join(bin_dir, 'python.exe')
- scripts_dir = os.path.join(root_dir, 'Scripts')
- bin_dir = os.path.join(root_dir, 'bin')
- if not os.path.exists(scripts_dir):
- os.makedirs(scripts_dir)
- if not os.path.exists(bin_dir):
- cmd = [
- 'mklink', '/J',
- '"%(bin_dir)s"' % locals(),
- '"%(scripts_dir)s"' % locals()]
- call(cmd, root_dir, run_quiet)
- else:
- configured_python = os.path.join(bin_dir, 'python')
- scripts_dir = bin_dir
-
- # Get requested configuration paths to collect components and scripts later
- configs = []
- for path in args[:]:
- if not os.path.isabs(path):
- abs_path = os.path.join(root_dir, path)
- if os.path.exists(abs_path):
- configs.append(path)
- else:
- print()
- print('WARNING: Skipping missing Configuration directory:\n'
- ' %(path)s does not exist.' % locals())
- print()
-
- # Collect vendor directories from environment variables: one or more third-
- # party directories may exist as environment variables prefixed with TPP_DIR
- thirdparty_dirs = []
- for envvar, path in os.environ.items():
- if not envvar.startswith('TPP_DIR'):
- continue
- if not os.path.isabs(path):
- abs_path = os.path.join(root_dir, path)
- if os.path.exists(abs_path):
- thirdparty_dirs.append(path)
- else:
- print()
- print('WARNING: Skipping missing Python thirdparty directory:\n'
- ' %(path)s does not exist.\n'
- ' Provided by environment variable:\n'
- ' set %(envvar)s=%(path)s' % locals())
- print()
-
- # Finally execute our three steps: venv, install and scripts
- if not os.path.exists(configured_python):
- create_virtualenv(standard_python, root_dir, thirdparty_dirs, quiet=run_quiet)
- activate(root_dir)
-
- install_3pp(configs, root_dir, thirdparty_dirs, quiet=run_quiet)
- run_scripts(configs, root_dir, configured_python, quiet=run_quiet)
- chmod_bin(bin_dir)
- if not run_quiet:
- print('* Configuration completed.')
- print()
diff --git a/etc/scripts/gpl-2.0.LICENSE b/etc/scripts/gpl-2.0.LICENSE
deleted file mode 100644
index d159169..0000000
--- a/etc/scripts/gpl-2.0.LICENSE
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- , 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/etc/scripts/irc-notify.py b/etc/scripts/irc-notify.py
deleted file mode 100644
index 8b8376f..0000000
--- a/etc/scripts/irc-notify.py
+++ /dev/null
@@ -1,154 +0,0 @@
-"""
-From: https://raw.githubusercontent.com/gridsync/gridsync/def54f8166089b733d166665fdabcad4cdc526d8/misc/irc-notify.py
-and: https://github.com/gridsync/gridsync
-
-Copyright (C) 2015-2016 Christopher R. Wood
-
-This program is free software; you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the Free Software Foundation;
-either version 2 of the License, or (at your option) any later version.
-
-This program 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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this
-program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
-Fifth Floor, Boston, MA 02110-1301 USA.
-
-Simple AppVeyor IRC notification script.
-
-Modified by nexB on October 2016:
- - rework the handling of environment variables.
- - made the script use functions
- - support only Appveyor loading its environment variable to craft IRC notices.
-
-
-The first argument is a Frenode channel. Other arguments passed to the script will be
-sent as notice messages content and any {var}-formatted environment variables will be
-expanded automatically, replaced with a corresponding Appveyor environment variable
-value. se commas to delineate multiple messages.
-
-
-Example:
-export APPVEYOR_URL=https://ci.appveyor.com
-export APPVEYOR_PROJECT_NAME=attributecode
-export APPVEYOR_REPO_COMMIT_AUTHOR=pombredanne
-export APPVEYOR_REPO_COMMIT_TIMESTAMP=2016-10-31
-export APPVEYOR_REPO_PROVIDER=gihub
-export APPVEYOR_REPO_BRANCH=repo_branch
-export APPVEYOR_PULL_REQUEST_TITLE=pull_request_title
-export APPVEYOR_BUILD_VERSION=1
-export APPVEYOR_REPO_COMMIT=22c95b72e29248dc4de9b85e590ee18f6f587de8
-export APPVEYOR_REPO_COMMIT_MESSAGE="some IRC test"
-export APPVEYOR_ACCOUNT_NAME=nexB
-export APPVEYOR_PULL_REQUEST_NUMBER=pull_request_number
-export APPVEYOR_REPO_NAME=nexB/attributecode
-python etc/scripts/irc-notify.py aboutcode '[{project_name}:{branch}] {short_commit}: "{message}" ({author}) {color_red}Succeeded','Details: {build_url} | Commit: {commit_url}'
-
-See also https://github.com/gridsync/gridsync/blob/master/appveyor.yml for examples
-in Appveyor's YAML:
-
- on_success:
- - "python etc/scripts/irc-notify.py channel [{project_name}:{branch}] {short_commit}: \"{message}\" ({author}) {color_green}Succeeded,Details: {build_url},Commit: {commit_url}"
- on_failure:
- - "python etc/scripts/irc-notify.py channel [{project_name}:{branch}] {short_commit}: \"{message}\" ({author}) {color_red}Failed,Details: {build_url},Commit: {commit_url}"
-
-"""
-
-import os, random, socket, ssl, sys, time
-
-
-def appveyor_vars():
- """
- Return a dict of key value carfted from appveyor environment variables.
- """
- from os import environ
-
- appveyor_url = environ.get('APPVEYOR_URL')
- message_extended = environ.get('APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED')
- branch = environ.get('APPVEYOR_REPO_BRANCH')
- author = environ.get('APPVEYOR_REPO_COMMIT_AUTHOR')
- author_email = environ.get('APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL')
- timestamp = environ.get('APPVEYOR_REPO_COMMIT_TIMESTAMP')
- repo_provider = environ.get('APPVEYOR_REPO_PROVIDER')
- project_name = environ.get('APPVEYOR_PROJECT_NAME')
- pull_request_title = environ.get('APPVEYOR_PULL_REQUEST_TITLE')
- build_version = environ.get('APPVEYOR_BUILD_VERSION')
- commit = environ.get('APPVEYOR_REPO_COMMIT')
- message = environ.get('APPVEYOR_REPO_COMMIT_MESSAGE')
- account_name = environ.get('APPVEYOR_ACCOUNT_NAME')
- pull_request_number = environ.get('APPVEYOR_PULL_REQUEST_NUMBER')
- repo_name = environ.get('APPVEYOR_REPO_NAME')
-
- short_commit = commit[:7]
- build_url = '{appveyor_url}/project/{account_name}/{project_name}/build/{build_version}'.format(**locals())
- commit_url = 'https://{repo_provider}.com/{repo_name}/commit/{commit}'.format(**locals())
-
- vars = dict(
- appveyor_url=appveyor_url,
- account_name=account_name,
- project_name=project_name,
- build_version=build_version,
-
- build_url=build_url,
-
- repo_provider=repo_provider,
- repo_name=repo_name,
- branch=branch,
- author=author,
- author_email=author_email,
- timestamp=timestamp,
- commit=commit,
- short_commit=short_commit,
- message=message,
- message_extended=message_extended,
-
- pull_request_title=pull_request_title,
- pull_request_number=pull_request_number,
-
- commit_url=commit_url,
-
- color_green='\x033',
- color_red='\x034',
- )
- return vars
-
-
-if __name__ == '__main__':
- apvy_vars = appveyor_vars()
-
- channel = sys.argv[1]
- messages = sys.argv[2:]
- messages = ' '.join(messages)
- messages = messages.split(',')
- messages = [msg.format(**apvy_vars).strip() for msg in messages]
-
- irc_username = 'Appveyor'
- irc_nick = irc_username + str(random.randint(1, 9999))
-
- # establish connection
- irc_sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
- irc_sock.connect((socket.gethostbyname('chat.freenode.net'), 6697))
- irc_sock.send('NICK {0}\r\nUSER {0} * 0 :{0}\r\n'.format(irc_username).encode())
- irc_file = irc_sock.makefile()
-
- while irc_file:
- line = irc_file.readline()
- print(line.rstrip())
- response = line.split()
-
- if response[0] == 'PING':
- irc_file.send('PONG {}\r\n'.format(reponse[1]).encode())
-
- elif response[1] == '433':
- irc_sock.send('NICK {}\r\n'.format(irc_nick).encode())
-
- elif response[1] == '001':
- time.sleep(5)
- # send notification
- for msg in messages:
- print('NOTICE #{} :{}'.format(channel, msg))
- irc_sock.send('NOTICE #{} :{}\r\n'.format(channel, msg).encode())
- time.sleep(5)
- sys.exit()
diff --git a/etc/scripts/irc-notify.py.ABOUT b/etc/scripts/irc-notify.py.ABOUT
deleted file mode 100644
index cca515e..0000000
--- a/etc/scripts/irc-notify.py.ABOUT
+++ /dev/null
@@ -1,11 +0,0 @@
-about_resource: irc-notify.py
-name: irc-notify.py
-version: def54f8166089b733d166665fdabcad4cdc526d8
-download_url: https://raw.githubusercontent.com/gridsync/gridsync/def54f8166089b733d166665fdabcad4cdc526d8/misc/irc-notify.py
-description: Quick and dirty IRC notification script.
-homepage_url: https://github.com/gridsync/gridsync
-owner: Christopher R. Wood
-copyright: Copyright (C) 2015-2016 Christopher R. Wood
-license_expression: gpl-2.0-plus
-license_file: gpl-2.0.LICENSE
-notice_file: irc-notify.py.NOTICE
\ No newline at end of file
diff --git a/etc/scripts/irc-notify.py.NOTICE b/etc/scripts/irc-notify.py.NOTICE
deleted file mode 100644
index 7c28423..0000000
--- a/etc/scripts/irc-notify.py.NOTICE
+++ /dev/null
@@ -1,12 +0,0 @@
-This program is free software; you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the Free Software
-Foundation; either version 2 of the License, or (at your option) any later
-version.
-
-This program 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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License along with this
-program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
-Fifth Floor, Boston, MA 02110-1301 USA.
diff --git a/license-expression.ABOUT b/license-expression.ABOUT
index ac3771a..07ab9f1 100644
--- a/license-expression.ABOUT
+++ b/license-expression.ABOUT
@@ -1,7 +1,7 @@
about_resource: .
name: license-expression
-copyright: Copyright (c) 2017 nexB Inc. and others.
+copyright: Copyright (c) nexB Inc. and others.
license_expression: apache-2.0
license_file: apache-2.0.LICENSE
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..852f0fc
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,49 @@
+[build-system]
+requires = ["setuptools >= 50", "wheel", "setuptools_scm[toml] >= 6"]
+build-backend = "setuptools.build_meta"
+
+[tool.setuptools_scm]
+# this is used populated when creating a git archive
+# and when there is .git dir and/or there is no git installed
+fallback_version = "9999.$Format:%h-%cs$"
+
+[tool.pytest.ini_options]
+norecursedirs = [
+ ".git",
+ "bin",
+ "dist",
+ "build",
+ "_build",
+ "dist",
+ "etc",
+ "local",
+ "ci",
+ "docs",
+ "man",
+ "share",
+ "samples",
+ ".cache",
+ ".settings",
+ "Include",
+ "include",
+ "Lib",
+ "lib",
+ "lib64",
+ "Lib64",
+ "Scripts",
+ "thirdparty",
+ "tmp",
+ "tests/data",
+ ".eggs"
+]
+
+python_files = "*.py"
+
+python_classes = "Test"
+python_functions = "test"
+
+addopts = [
+ "-rfExXw",
+ "--strict-markers",
+ "--doctest-modules"
+]
diff --git a/setup.cfg b/setup.cfg
index 388f0f8..c0cc516 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,43 +1,55 @@
-[bdist_wheel]
-universal = 1
-
[metadata]
-license_file = NOTICE
-
-[aliases]
-release = clean --all sdist --formats=gztar bdist_wheel register upload
+license_files =
+ apache-2.0.LICENSE
+ NOTICE
+ AUTHORS.rst
+ CHANGELOG.rst
+name = license-expression
+author = nexB. Inc. and others
+author_email = info@aboutcode.org
+license = Apache-2.0
-[tool:pytest]
-norecursedirs =
- .git
- bin
- build
- _build
- dist
- local
- ci
- docs
- etc
- Include
- include
- Lib
- lib
- lib64
- Scripts
- thirdparty
- tmp
- src/*/data
- tests/*/data
+# description must be on ONE line https://github.com/pypa/setuptools/issues/1390
+description = license-expression is a comprehensive utility library to parse, compare, simplify and normalize license expressions (such as SPDX license expressions) using boolean logic.
+long_description = file:README.rst
+url = https://github.com/nexB/license-expression
+classifiers =
+ Development Status :: 5 - Production/Stable
+ Intended Audience :: Developers
+ Programming Language :: Python :: 3
+ Programming Language :: Python :: 3 :: Only
+ Topic :: Software Development
+ Topic :: Utilities
+keywords =
+ open source
+ license expression
+ license
+ spdx
+ boolean
+ parse expression
+ normalize expression
+ compare expression
+ licence
-python_files = *.py
+[options]
+package_dir=
+ =src
+packages=find:
+include_package_data = true
+zip_safe = false
+install_requires =
+ boolean.py >= 3.6, < 4.0.0
+setup_requires = setuptools_scm[toml] >= 4
-python_classes=Test
-python_functions=test
+[options.packages.find]
+where=src
-addopts =
- -rfEsxXw
- --strict
- --ignore docs/conf.py
- --ignore setup.py
- --doctest-modules
- --doctest-glob=README.rst
\ No newline at end of file
+[options.extras_require]
+testing =
+ # upstream
+ pytest >= 6
+ pytest-xdist >= 2
+docs=
+ Sphinx>=3.3.1
+ sphinx-rtd-theme>=0.5.0
+ doc8>=0.8.1
diff --git a/setup.py b/setup.py
index 2dd7867..bac24a4 100644
--- a/setup.py
+++ b/setup.py
@@ -1,53 +1,6 @@
#!/usr/bin/env python
-# -*- encoding: utf-8 -*-
-from __future__ import absolute_import
-from __future__ import print_function
+import setuptools
-from glob import glob
-from os.path import basename
-from os.path import splitext
-from setuptools import find_packages
-from setuptools import setup
-
-
-desc = ('license-expression is small utility library to parse, compare, '
- 'simplify and normalize license expressions (such as SPDX license '
- 'expressions) using boolean logic.')
-
-setup(
- name='license-expression',
- version='1.2',
- license='apache-2.0',
- description=desc,
- long_description=desc,
- author='nexB Inc.',
- author_email='info@nexb.com',
- url='https://github.com/nexB/license-expression',
- packages=find_packages('src'),
- package_dir={'': 'src'},
- py_modules=[splitext(basename(path))[0] for path in glob('src/*.py')],
- include_package_data=True,
- zip_safe=False,
- classifiers=[
- 'Development Status :: 5 - Production/Stable',
- 'License :: OSI Approved :: Apache Software License',
- 'Intended Audience :: Developers',
- 'Operating System :: OS Independent',
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.4',
- 'Programming Language :: Python :: 3.5',
- 'Topic :: Utilities',
- ],
- keywords=[
- 'license', 'spdx', 'license expression', 'open source', 'boolean',
- 'parse expression', 'normalize expression', 'compare expression',
- 'licence'
- ],
- install_requires=[
- 'boolean.py >= 3.6, < 4.0.0',
- ]
-)
+if __name__ == "__main__":
+ setuptools.setup()
diff --git a/src/license_expression/__init__.py b/src/license_expression/__init__.py
index e16cb67..800d316 100644
--- a/src/license_expression/__init__.py
+++ b/src/license_expression/__init__.py
@@ -1,19 +1,10 @@
#
-# license-expression is a free software tool from nexB Inc. and others.
-# Visit https://github.com/nexB/license-expression for support and download.
+# Copyright (c) nexB Inc. and others. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0
+# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
+# See https://github.com/nexB/license-expression for support or download.
+# See https://aboutcode.org for more information about nexB OSS projects.
#
-# Copyright (c) 2017 nexB Inc. and others. All rights reserved.
-# http://nexb.com and http://aboutcode.org
-#
-# This software is licensed under the Apache License version 2.0.
-#
-# You may not use this software except in compliance with the License.
-# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software distributed
-# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-# CONDITIONS OF ANY KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations under the License.
-
"""
This module defines a mini language to parse, validate, simplify, normalize and
compare license expressions using a boolean logic engine.
@@ -27,20 +18,15 @@
The main entry point is the Licensing object.
"""
-from __future__ import absolute_import
-from __future__ import unicode_literals
-from __future__ import print_function
-
+import itertools
+import re
+import string
from collections import defaultdict
from collections import deque
from collections import namedtuple
-from collections import OrderedDict
from copy import copy
from copy import deepcopy
from functools import total_ordering
-import itertools
-import re
-import string
import boolean
from boolean import Expression as LicenseExpression
@@ -65,17 +51,6 @@
from license_expression._pyahocorasick import Trie as AdvancedTokenizer
from license_expression._pyahocorasick import Token
-
-# Python 2 and 3 support
-try:
- # Python 2
- unicode
- str = unicode # NOQA
-except NameError:
- # Python 3
- unicode = str # NOQA
-
-
# append new error codes to PARSE_ERRORS by monkey patching
PARSE_EXPRESSION_NOT_UNICODE = 100
if PARSE_EXPRESSION_NOT_UNICODE not in PARSE_ERRORS:
@@ -599,6 +574,49 @@ def simple_tokenizer(self, expression):
sym = LicenseSymbol(key=sym_or_op)
yield Token(start, end, sym_or_op, sym)
+ def dedup(self, expression):
+ """
+ Return a deduplicated LicenseExpression given a license expression
+ string or LicenseExpression object.
+
+ The deduplication process is similar to simplification but is specialized
+ for working with license expressions. Simplification on the other hand
+ is a generic boolean operation not aware of the specifis of license expressions.
+
+ The deduplication:
+
+ - Does not sort the licenses of sub-expression in an expression. They
+ stay in the same order as in the original.
+
+ - Choices (as in MIT or GPL) are kept as-is and not treated as
+ simplifiable. This way this avoid droping important choice options in
+ complex expressions which is never desirable.
+
+ """
+ exp = self.parse(expression)
+ expressions = []
+ for arg in exp.args:
+ if isinstance(arg, (self.AND, self.OR,)):
+ # Run this recursive function if there is another AND/OR
+ # expression and add the expression to the expressions list.
+ expressions.append(self.dedup(arg))
+ else:
+ expressions.append(arg)
+
+ if isinstance(exp, BaseSymbol):
+ deduped = exp
+ elif isinstance(exp, (self.AND, self.OR,)):
+ relation = exp.__class__.__name__
+ deduped = combine_expressions(
+ expressions,
+ relation=relation,
+ unique=True,
+ licensing=self,
+ )
+ else:
+ raise Exception(f'Unknown expression type: {expression!r}')
+ return deduped
+
def build_symbols_from_unknown_tokens(tokens):
"""
@@ -713,8 +731,8 @@ def replace_with_subexpression_by_license_symbol(tokens, strict=False):
Check validity of with subexpessions and raise ParseError as needed.
If `strict` is True also raise ParseError if the left hand side
- LicenseSymbol has is_exception True or if the right hand side
- LicenseSymbol has is_exception False.
+ LicenseSymbol has is_exception True or if the right hand side LicenseSymbol
+ has is_exception False.
"""
token_groups = build_token_groups_for_with_subexpression(tokens)
@@ -747,7 +765,7 @@ def replace_with_subexpression_by_license_symbol(tokens, strict=False):
else:
# this should not be possible by design
- raise Exception('Licensing.tokenize is internally confused...:' + repr(tval))
+ raise Exception(f'Licensing.tokenize is internally confused...: {tval!r}')
yield token
continue
@@ -759,8 +777,8 @@ def replace_with_subexpression_by_license_symbol(tokens, strict=False):
raise ParseError(
TOKEN_SYMBOL, string, start, PARSE_INVALID_EXPRESSION)
- # from now on we have a tripple of tokens: a WITH sub-expression such as "A with
- # B" seq of three tokens
+ # from now on we have a tripple of tokens: a WITH sub-expression such as
+ # "A with B" seq of three tokens
lic_token, WITH , exc_token = token_group
token_string = ' '.join([
@@ -814,13 +832,14 @@ class Renderable(object):
def render(self, template='{symbol.key}', *args, **kwargs):
"""
- Return a formatted string rendering for this expression using the `template`
- format string to render each symbol. The variable available are `symbol.key`
- and any other attribute that was attached to a license symbol instance and a
- custom template can be provided to handle custom HTML rendering or similar.
+ Return a formatted string rendering for this expression using the
+ `template` format string to render each symbol. The variable available
+ are `symbol.key` and any other attribute that was attached to a license
+ symbol instance and a custom template can be provided to handle custom
+ HTML rendering or similar.
- For symbols that hold multiple licenses (e.g. a WITH statement) the template
- is applied to each symbol individually.
+ For symbols that hold multiple licenses (e.g. a WITH statement) the
+ template is applied to each symbol individually.
Note that when render() is called the *args and **kwargs are propagated
recursively to any Renderable object render() method.
@@ -836,9 +855,18 @@ def render_as_readable(self, template='{symbol.key}', *args, **kwargs):
"""
if isinstance(self, LicenseWithExceptionSymbol):
return self.render(
- template=template, wrap_with_in_parens=False, *args, **kwargs)
- else:
- return self.render(template=template, wrap_with_in_parens=True, *args, **kwargs)
+ template=template,
+ wrap_with_in_parens=False,
+ *args,
+ **kwargs,
+ )
+
+ return self.render(
+ template=template,
+ wrap_with_in_parens=True,
+ *args,
+ **kwargs,
+ )
class BaseSymbol(Renderable, boolean.Symbol):
@@ -858,6 +886,7 @@ def __contains__(self, other):
"""
if not isinstance(other, BaseSymbol):
return False
+
if self == other:
return True
@@ -901,7 +930,8 @@ def __init__(self, key, aliases=tuple(), is_exception=False, *args, **kwargs):
if not is_valid_license_key(key):
raise ExpressionError(
'Invalid license key: the valid characters are: letters and numbers, '
- 'underscore, dot, colon or hyphen signs and spaces: "%(key)s"' % locals())
+ f'underscore, dot, colon or hyphen signs and spaces: {key!r}'
+ )
# normalize for spaces
key = ' '.join(key.split())
@@ -1045,10 +1075,11 @@ def __lt__(self, other):
@total_ordering
class LicenseWithExceptionSymbol(BaseSymbol):
"""
- A LicenseWithExceptionSymbol represents a license "with" an exception as used in
- a license expression. It holds two LicenseSymbols objects: one for the left-hand
- license proper and one for the right-hand exception to this license and deals
- with the specifics of resolution, validation and representation.
+ A LicenseWithExceptionSymbol represents a license "with" an exception as
+ used in a license expression. It holds two LicenseSymbols objects: one for
+ the left-hand license proper and one for the right-hand exception to this
+ license and deals with the specifics of resolution, validation and
+ representation.
"""
def __init__(self, license_symbol, exception_symbol, strict=False, *args, **kwargs):
@@ -1176,8 +1207,11 @@ def render(self, template='{symbol.key}', *args, **kwargs):
rendered = arg.render(template, *args, **kwargs)
else:
- print('WARNING: object in expression is not renderable: falling back to plain string representation: %(arg)r.')
# FIXME: CAN THIS REALLY HAPPEN since we only have symbols, or and AND?
+ print(
+ 'WARNING: object in expression is not renderable: '
+ f'falling back to plain string representation: {arg!r}.'
+ )
rendered = str(arg)
if arg.isliteral:
@@ -1195,7 +1229,8 @@ class AND(RenderableFunction, boolean.AND):
def __init__(self, *args):
if len(args) < 2:
- raise ExpressionError('AND requires two or more licenses as in: MIT AND BSD')
+ raise ExpressionError(
+ 'AND requires two or more licenses as in: MIT AND BSD')
super(AND, self).__init__(*args)
self.operator = ' AND '
@@ -1207,7 +1242,8 @@ class OR(RenderableFunction, boolean.OR):
def __init__(self, *args):
if len(args) < 2:
- raise ExpressionError('OR requires two or more licenses as in: MIT OR BSD')
+ raise ExpressionError(
+ 'OR requires two or more licenses as in: MIT OR BSD')
super(OR, self).__init__(*args)
self.operator = ' OR '
@@ -1255,8 +1291,9 @@ def as_symbols(symbols):
yield LicenseSymbolLike(symbol)
else:
- raise TypeError('%(symbol)r is not a unicode string '
- 'or a LicenseSymbol-like instance.' % locals())
+ raise TypeError(
+ '%(symbol)r is not a unicode string '
+ 'or a LicenseSymbol-like instance.' % locals())
def validate_symbols(symbols, validate_keys=False):
@@ -1371,7 +1408,54 @@ def validate_symbols(symbols, validate_keys=False):
errors.append('Invalid key: a key cannot be an expression keyword: %(ikw)s.' % locals())
warnings = []
- for dupeal in sorted(dupe_aliases):
- errors.append('Duplicated or empty aliases ignored for license key: %(dupeal)r.' % locals())
+ for dupe_alias in sorted(dupe_aliases):
+ errors.append('Duplicated or empty aliases ignored for license key: %(dupe_alias)r.' % locals())
return warnings, errors
+
+
+def combine_expressions(
+ expressions,
+ relation='AND',
+ unique=True,
+ licensing=Licensing(),
+):
+ """
+ Return a combined LicenseExpression object with the `relation`, given a list
+ of license `expressions` strings or LicenseExpression. If unique is True
+ remove duplicates before combining expressions.
+
+ For example::
+
+ >>> a = 'mit'
+ >>> b = 'gpl'
+ >>> str(combine_expressions([a, b]))
+ 'mit AND gpl'
+ >>> assert 'mit' == str(combine_expressions([a]))
+ >>> combine_expressions([])
+ >>> combine_expressions(None)
+ >>> str(combine_expressions(('gpl', 'mit', 'apache',)))
+ 'gpl AND mit AND apache'
+ >>> str(combine_expressions(('gpl', 'mit', 'apache',), relation='OR'))
+ 'gpl OR mit OR apache'
+ """
+ if not expressions:
+ return
+
+ if not isinstance(expressions, (list, tuple)):
+ raise TypeError(
+ 'expressions should be a list or tuple and not: {}'.format(
+ type(expressions)))
+
+ # only del with LicenseExpression objects
+ expressions = [licensing.parse(le, simple=True) for le in expressions]
+
+ # Remove duplicate expressions
+ if unique:
+ expressions = list({str(x): x for x in expressions}.values())
+
+ if len(expressions) == 1:
+ return expressions[0]
+
+ relation = {'AND': licensing.AND, 'OR': licensing.OR}[relation]
+ return relation(*expressions)
diff --git a/src/license_expression/_pyahocorasick.py b/src/license_expression/_pyahocorasick.py
index 655de94..ddf4f88 100644
--- a/src/license_expression/_pyahocorasick.py
+++ b/src/license_expression/_pyahocorasick.py
@@ -1,36 +1,29 @@
# -*- coding: utf-8 -*-
+#
+# SPDX-License-Identifier: LicenseRef-scancode-public-domain
+# See https://github.com/nexB/license-expression for support or download.
+# See https://aboutcode.org for more information about nexB OSS projects.
+#
"""
-Aho-Corasick string search algorithm.
+Aho-Corasick string search algorithm in pure Python
Original Author: Wojciech Muła, wojciech_mula@poczta.onet.pl
WWW : http://0x80.pl
License : public domain
-Modified for use in the license_expression library:
+This is the pure Python Aho-Corasick automaton from pyahocorasick modified for
+use in the license_expression library for advanced tokenization:
+
- add support for unicode strings.
- case insensitive search using sequence of words and not characters
- improve returned results with the actual start,end and matched string.
- support returning non-matched parts of a string
"""
-
-from __future__ import absolute_import
-from __future__ import print_function
-from __future__ import unicode_literals
-
from collections import deque
from collections import OrderedDict
import logging
import re
-# Python 2 and 3 support
-try:
- # Python 2
- unicode
- str = unicode # NOQA
-except NameError:
- # Python 3
- unicode = str # NOQA
-
TRACE = False
logger = logging.getLogger(__name__)
@@ -109,7 +102,7 @@ def add(self, tokens_string, value=None):
provided value, typically a Token object. If a value is not provided,
the tokens_string is used as value.
- A tokens_string is any unicode string. It will be tokenized when added
+ A tokens_string is any string. It will be tokenized when added
to the Trie.
"""
if self._converted:
@@ -326,7 +319,12 @@ def iter(self, tokens_string, include_unmatched=False, include_space=False):
if include_unmatched:
n = len(token_string)
start_pos = end_pos - n + 1
- tok = Token(start_pos, end_pos, tokens_string[start_pos: end_pos + 1], None)
+ tok = Token(
+ start=start_pos,
+ end=end_pos,
+ string=tokens_string[start_pos: end_pos + 1],
+ value=None
+ )
if TRACE:
logger_debug(' unmatched tok:', tok)
yield tok
diff --git a/tests/test__pyahocorasick.py b/tests/test__pyahocorasick.py
index e7ad883..a18c21b 100644
--- a/tests/test__pyahocorasick.py
+++ b/tests/test__pyahocorasick.py
@@ -1,4 +1,8 @@
# -*- coding: utf-8 -*-
+#
+# SPDX-License-Identifier: LicenseRef-scancode-public-domain
+# See https://github.com/nexB/license-expression for support or download.
+# See https://aboutcode.org for more information about nexB OSS projects.
"""
Tests for Aho-Corasick string search algorithm.
@@ -9,10 +13,6 @@
Modified for use in the license_expression library.
"""
-from __future__ import unicode_literals
-from __future__ import absolute_import
-from __future__ import print_function
-
import unittest
from license_expression._pyahocorasick import Trie
diff --git a/tests/test_license_expression.py b/tests/test_license_expression.py
index e349b0c..62cc2fb 100644
--- a/tests/test_license_expression.py
+++ b/tests/test_license_expression.py
@@ -1,27 +1,15 @@
-# license-expression is a free software tool from nexB Inc. and others.
-# Visit https://github.com/nexB/license-expression for support and download.
#
-# Copyright (c) 2017 nexB Inc. and others. All rights reserved.
-# http://nexb.com and http://aboutcode.org
+# Copyright (c) nexB Inc. and others. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0
+# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
+# See https://github.com/nexB/license-expression for support or download.
+# See https://aboutcode.org for more information about nexB OSS projects.
#
-# This software is licensed under the Apache License version 2.0.
-#
-# You may not use this software except in compliance with the License.
-# You may obtain a copy of the License at: http://apache.org/licenses/LICENSE-2.0
-# Unless required by applicable law or agreed to in writing, software distributed
-# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-# CONDITIONS OF ANY KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations under the License.
-
-from __future__ import absolute_import
-from __future__ import print_function
-from __future__ import unicode_literals
+import sys
from collections import namedtuple
-from collections import OrderedDict
from unittest import TestCase
from unittest.case import expectedFailure
-import sys
from boolean.boolean import PARSE_UNBALANCED_CLOSING_PARENS
from boolean.boolean import PARSE_INVALID_SYMBOL_SEQUENCE
@@ -645,6 +633,76 @@ def test_simplify_and_contains(self):
expr3 = l.parse('mit and LGPL2.1')
assert expr3 in expr2
+ def test_dedup_expressions_can_be_simplified_1(self):
+ l = Licensing()
+ exp = 'mit OR mit AND apache-2.0 AND bsd-new OR mit'
+ result = l.dedup(exp)
+ expected = l.parse('mit OR (mit AND apache-2.0 AND bsd-new)')
+ assert result == expected
+
+ def test_dedup_expressions_can_be_simplified_2(self):
+ l = Licensing()
+ exp = 'mit AND (mit OR bsd-new) AND mit OR mit'
+ result = l.dedup(exp)
+ expected = l.parse('(mit AND (mit OR bsd-new)) OR mit')
+ assert result == expected
+
+ def test_dedup_expressions_multiple_occurrences(self):
+ l = Licensing()
+ exp = ' GPL-2.0 or (mit and LGPL-2.1) or bsd Or GPL-2.0 or (mit and LGPL-2.1)'
+ result = l.dedup(exp)
+ expected = l.parse('GPL-2.0 OR (mit AND LGPL-2.1) OR bsd')
+ assert result == expected
+
+ def test_dedup_expressions_cannot_be_simplified(self):
+ l = Licensing()
+ exp = l.parse('mit AND (mit OR bsd-new)')
+ result = l.dedup(exp)
+ expected = l.parse('mit AND (mit OR bsd-new)')
+ assert result == expected
+
+ def test_dedup_expressions_single_license(self):
+ l = Licensing()
+ exp = l.parse('mit')
+ result = l.dedup(exp)
+ expected = l.parse('mit')
+ assert result == expected
+
+ def test_dedup_expressions_WITH(self):
+ l = Licensing()
+ exp = l.parse('gpl-2.0 with autoconf-exception-2.0')
+ result = l.dedup(exp)
+ expected = l.parse('gpl-2.0 with autoconf-exception-2.0')
+ assert result == expected
+
+ def test_dedup_expressions_WITH_OR(self):
+ l = Licensing()
+ exp = l.parse('gpl-2.0 with autoconf-exception-2.0 OR gpl-2.0')
+ result = l.dedup(exp)
+ expected = l.parse('gpl-2.0 with autoconf-exception-2.0 OR gpl-2.0')
+ assert result == expected
+
+ def test_dedup_expressions_WITH_AND(self):
+ l = Licensing()
+ exp = l.parse('gpl-2.0 AND gpl-2.0 with autoconf-exception-2.0 AND gpl-2.0')
+ result = l.dedup(exp)
+ expected = l.parse('gpl-2.0 AND gpl-2.0 with autoconf-exception-2.0')
+ assert result == expected
+
+ def test_dedup_licensexpressions_can_be_simplified_3(self):
+ l = Licensing()
+ exp = l.parse('mit AND mit')
+ result = l.dedup(exp)
+ expected = l.parse('mit')
+ assert result == expected
+
+ def test_dedup_licensexpressions_works_with_subexpressions(self):
+ l = Licensing()
+ exp = l.parse('(mit OR gpl-2.0) AND mit AND bsd-new AND (mit OR gpl-2.0)')
+ result = l.dedup(exp)
+ expected = l.parse('(mit OR gpl-2.0) AND mit AND bsd-new')
+ assert result == expected
+
def test_simplify_and_equivalent_and_contains(self):
l = Licensing()
expr2 = l.parse(' GPL-2.0 or (mit and LGPL-2.1) or bsd Or GPL-2.0 or (mit and LGPL-2.1)')
@@ -889,21 +947,17 @@ def test_parse_invalid_expression_with_repeated_trailing_or_raise_exception(self
}
assert expected == _parse_error_as_dict(pe)
- @expectedFailure
- def test_parse_invalid_expression_with_single_trailing_or_raise_exception(self):
+ def test_parse_invalid_expression_drops_single_trailing_or(self):
licensing = Licensing()
expression = 'mit or mit or'
- try:
- licensing.parse(expression, simple=False)
- self.fail('Exception not raised')
- except ParseError as pe:
- expected = {
- 'error_code': PARSE_INVALID_OPERATOR_SEQUENCE,
- 'position': 14,
- 'token_string': 'or',
- 'token_type': TOKEN_OR
- }
- assert expected == _parse_error_as_dict(pe)
+ e = licensing.parse(expression, simple=False)
+ assert str(e) == 'mit OR mit'
+
+ def test_parse_invalid_expression_drops_single_trailing_or2(self):
+ licensing = Licensing()
+ expression = 'mit or mit or'
+ e = licensing.parse(expression, simple=True)
+ assert str(e) == 'mit OR mit'
def test_parse_invalid_expression_with_single_trailing_and_raise_exception(self):
licensing = Licensing()
@@ -1220,7 +1274,7 @@ def test_multiple_substitutions(self):
source3 = gpl2
target3 = gpl2plus
- subs = OrderedDict([
+ subs = dict([
(source1, target1),
(source2, target2),
(source3, target3),
@@ -1244,7 +1298,7 @@ def test_multiple_substitutions_complex(self):
source3 = gpl2
target3 = gpl2plus
- subs = OrderedDict([
+ subs = dict([
(source1, target1),
(source2, target2),
(source3, target3),
diff --git a/thirdparty/Jinja2-2.10-py2.py3-none-any.whl b/thirdparty/Jinja2-2.10-py2.py3-none-any.whl
deleted file mode 100644
index 7bc4e35..0000000
Binary files a/thirdparty/Jinja2-2.10-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/Jinja2-2.10-py2.py3-none-any.whl.ABOUT b/thirdparty/Jinja2-2.10-py2.py3-none-any.whl.ABOUT
deleted file mode 100644
index f98c06d..0000000
--- a/thirdparty/Jinja2-2.10-py2.py3-none-any.whl.ABOUT
+++ /dev/null
@@ -1,15 +0,0 @@
-about_resource: Jinja2-2.10-py2.py3-none-any.whl
-checksum_md5: cb679acd14423aef56dfff61d6a988f8
-checksum_sha1: f14bb3e5021b2b0605dcd4865ac539cde04fe856
-contact: armin.ronacher@active-4.com
-copyright: Copyright (c) 2009 by the Jinja Team
-description: Jinja2 is a full featured template engine for Python. It has full unicode
- support, an optional integrated sandboxed execution environment, widely used and
- BSD licensed.
-download_url: https://pypi.python.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl#md5=cb679acd14423aef56dfff61d6a988f8
-homepage_url: http://jinja.pocoo.org/
-license_expression: bsd-new
-name: Jinja2
-owner: Armin Ronacher
-owner_url: http://lucumr.pocoo.org/about/
-version: '2.10'
diff --git a/thirdparty/Jinja2.LICENSE b/thirdparty/Jinja2.LICENSE
deleted file mode 100644
index 5a0acde..0000000
--- a/thirdparty/Jinja2.LICENSE
+++ /dev/null
@@ -1,31 +0,0 @@
-Copyright (c) 2009 by the Jinja Team, see AUTHORS for more details.
-
-Some rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
-
- * The names of the contributors may not be used to endorse or
- promote products derived from this software without specific
- prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/thirdparty/MarkupSafe-1.0.tar.gz b/thirdparty/MarkupSafe-1.0.tar.gz
deleted file mode 100644
index 606021a..0000000
Binary files a/thirdparty/MarkupSafe-1.0.tar.gz and /dev/null differ
diff --git a/thirdparty/MarkupSafe.ABOUT b/thirdparty/MarkupSafe.ABOUT
deleted file mode 100644
index d872e56..0000000
--- a/thirdparty/MarkupSafe.ABOUT
+++ /dev/null
@@ -1,9 +0,0 @@
-about_resource: MarkupSafe-1.0.tar.gz
-version: 1.0
-download_url: https://pypi.python.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz#md5=2fcedc9284d50e577b5192e8e3578355
-
-name: MarkupSafe
-license_expression: bsd-new
-copyright: Copyright (c) 2010 by Armin Ronacher and contributors
-license_file: MarkupSafe.LICENSE
-homepage_url: https://github.com/pallets/markupsafe
diff --git a/thirdparty/MarkupSafe.LICENSE b/thirdparty/MarkupSafe.LICENSE
deleted file mode 100644
index 0a486d6..0000000
--- a/thirdparty/MarkupSafe.LICENSE
+++ /dev/null
@@ -1,33 +0,0 @@
-Copyright (c) 2010 by Armin Ronacher and contributors. See AUTHORS
-for more details.
-
-Some rights reserved.
-
-Redistribution and use in source and binary forms of the software as well
-as documentation, with or without modification, are permitted provided
-that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
-
-* The names of the contributors may not be used to endorse or
- promote products derived from this software without specific
- prior written permission.
-
-THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
-CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
-NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGE.
\ No newline at end of file
diff --git a/thirdparty/PSF.LICENSE b/thirdparty/PSF.LICENSE
deleted file mode 100644
index 4e9d7f2..0000000
--- a/thirdparty/PSF.LICENSE
+++ /dev/null
@@ -1,635 +0,0 @@
-A. HISTORY OF THE SOFTWARE
-==========================
-
-Python was created in the early 1990s by Guido van Rossum at Stichting
-Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
-as a successor of a language called ABC. Guido remains Python's
-principal author, although it includes many contributions from others.
-
-In 1995, Guido continued his work on Python at the Corporation for
-National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
-in Reston, Virginia where he released several versions of the
-software.
-
-In May 2000, Guido and the Python core development team moved to
-BeOpen.com to form the BeOpen PythonLabs team. In October of the same
-year, the PythonLabs team moved to Digital Creations (now Zope
-Corporation, see http://www.zope.com). In 2001, the Python Software
-Foundation (PSF, see http://www.python.org/psf/) was formed, a
-non-profit organization created specifically to own Python-related
-Intellectual Property. Zope Corporation is a sponsoring member of
-the PSF.
-
-All Python releases are Open Source (see http://www.opensource.org for
-the Open Source Definition). Historically, most, but not all, Python
-releases have also been GPL-compatible; the table below summarizes
-the various releases.
-
- Release Derived Year Owner GPL-
- from compatible? (1)
-
- 0.9.0 thru 1.2 1991-1995 CWI yes
- 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
- 1.6 1.5.2 2000 CNRI no
- 2.0 1.6 2000 BeOpen.com no
- 1.6.1 1.6 2001 CNRI yes (2)
- 2.1 2.0+1.6.1 2001 PSF no
- 2.0.1 2.0+1.6.1 2001 PSF yes
- 2.1.1 2.1+2.0.1 2001 PSF yes
- 2.2 2.1.1 2001 PSF yes
- 2.1.2 2.1.1 2002 PSF yes
- 2.1.3 2.1.2 2002 PSF yes
- 2.2.1 2.2 2002 PSF yes
- 2.2.2 2.2.1 2002 PSF yes
- 2.2.3 2.2.2 2003 PSF yes
- 2.3 2.2.2 2002-2003 PSF yes
- 2.3.1 2.3 2002-2003 PSF yes
- 2.3.2 2.3.1 2002-2003 PSF yes
- 2.3.3 2.3.2 2002-2003 PSF yes
- 2.3.4 2.3.3 2004 PSF yes
- 2.3.5 2.3.4 2005 PSF yes
- 2.4 2.3 2004 PSF yes
- 2.4.1 2.4 2005 PSF yes
- 2.4.2 2.4.1 2005 PSF yes
- 2.4.3 2.4.2 2006 PSF yes
- 2.4.4 2.4.3 2006 PSF yes
- 2.5 2.4 2006 PSF yes
- 2.5.1 2.5 2007 PSF yes
- 2.5.2 2.5.2 2008 PSF yes
-
-Footnotes:
-
-(1) GPL-compatible doesn't mean that we're distributing Python under
- the GPL. All Python licenses, unlike the GPL, let you distribute
- a modified version without making your changes open source. The
- GPL-compatible licenses make it possible to combine Python with
- other software that is released under the GPL; the others don't.
-
-(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
- because its license has a choice of law clause. According to
- CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
- is "not incompatible" with the GPL.
-
-Thanks to the many outside volunteers who have worked under Guido's
-direction to make these releases possible.
-
-
-B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
-===============================================================
-
-PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
---------------------------------------------
-
-1. This LICENSE AGREEMENT is between the Python Software Foundation
-("PSF"), and the Individual or Organization ("Licensee") accessing and
-otherwise using this software ("Python") in source or binary form and
-its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, PSF
-hereby grants Licensee a nonexclusive, royalty-free, world-wide
-license to reproduce, analyze, test, perform and/or display publicly,
-prepare derivative works, distribute, and otherwise use Python
-alone or in any derivative version, provided, however, that PSF's
-License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Python Software Foundation;
-All Rights Reserved" are retained in Python alone or in any derivative
-version prepared by Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python.
-
-4. PSF is making Python available to Licensee on an "AS IS"
-basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between PSF and
-Licensee. This License Agreement does not grant permission to use PSF
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using Python, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
-
-
-BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
--------------------------------------------
-
-BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
-
-1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
-office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
-Individual or Organization ("Licensee") accessing and otherwise using
-this software in source or binary form and its associated
-documentation ("the Software").
-
-2. Subject to the terms and conditions of this BeOpen Python License
-Agreement, BeOpen hereby grants Licensee a non-exclusive,
-royalty-free, world-wide license to reproduce, analyze, test, perform
-and/or display publicly, prepare derivative works, distribute, and
-otherwise use the Software alone or in any derivative version,
-provided, however, that the BeOpen Python License is retained in the
-Software, alone or in any derivative version prepared by Licensee.
-
-3. BeOpen is making the Software available to Licensee on an "AS IS"
-basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
-SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
-AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
-DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-5. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-6. This License Agreement shall be governed by and interpreted in all
-respects by the law of the State of California, excluding conflict of
-law provisions. Nothing in this License Agreement shall be deemed to
-create any relationship of agency, partnership, or joint venture
-between BeOpen and Licensee. This License Agreement does not grant
-permission to use BeOpen trademarks or trade names in a trademark
-sense to endorse or promote products or services of Licensee, or any
-third party. As an exception, the "BeOpen Python" logos available at
-http://www.pythonlabs.com/logos.html may be used according to the
-permissions granted on that web page.
-
-7. By copying, installing or otherwise using the software, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
-
-
-CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
----------------------------------------
-
-1. This LICENSE AGREEMENT is between the Corporation for National
-Research Initiatives, having an office at 1895 Preston White Drive,
-Reston, VA 20191 ("CNRI"), and the Individual or Organization
-("Licensee") accessing and otherwise using Python 1.6.1 software in
-source or binary form and its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, CNRI
-hereby grants Licensee a nonexclusive, royalty-free, world-wide
-license to reproduce, analyze, test, perform and/or display publicly,
-prepare derivative works, distribute, and otherwise use Python 1.6.1
-alone or in any derivative version, provided, however, that CNRI's
-License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
-1995-2001 Corporation for National Research Initiatives; All Rights
-Reserved" are retained in Python 1.6.1 alone or in any derivative
-version prepared by Licensee. Alternately, in lieu of CNRI's License
-Agreement, Licensee may substitute the following text (omitting the
-quotes): "Python 1.6.1 is made available subject to the terms and
-conditions in CNRI's License Agreement. This Agreement together with
-Python 1.6.1 may be located on the Internet using the following
-unique, persistent identifier (known as a handle): 1895.22/1013. This
-Agreement may also be obtained from a proxy server on the Internet
-using the following URL: http://hdl.handle.net/1895.22/1013".
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python 1.6.1 or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python 1.6.1.
-
-4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
-basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. This License Agreement shall be governed by the federal
-intellectual property law of the United States, including without
-limitation the federal copyright law, and, to the extent such
-U.S. federal law does not apply, by the law of the Commonwealth of
-Virginia, excluding Virginia's conflict of law provisions.
-Notwithstanding the foregoing, with regard to derivative works based
-on Python 1.6.1 that incorporate non-separable material that was
-previously distributed under the GNU General Public License (GPL), the
-law of the Commonwealth of Virginia shall govern this License
-Agreement only as to issues arising under or with respect to
-Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
-License Agreement shall be deemed to create any relationship of
-agency, partnership, or joint venture between CNRI and Licensee. This
-License Agreement does not grant permission to use CNRI trademarks or
-trade name in a trademark sense to endorse or promote products or
-services of Licensee, or any third party.
-
-8. By clicking on the "ACCEPT" button where indicated, or by copying,
-installing or otherwise using Python 1.6.1, Licensee agrees to be
-bound by the terms and conditions of this License Agreement.
-
- ACCEPT
-
-
-CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
---------------------------------------------------
-
-Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
-The Netherlands. All rights reserved.
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Stichting Mathematisch
-Centrum or CWI not be used in advertising or publicity pertaining to
-distribution of the software without specific, written prior
-permission.
-
-STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
-THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
-FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-This copy of Python includes a copy of bzip2, which is licensed under the following terms:
-
-
-This program, "bzip2", the associated library "libbzip2", and all
-documentation, are copyright (C) 1996-2005 Julian R Seward. All
-rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
-3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
-4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
-OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Julian Seward, Cambridge, UK.
-jseward@acm.org
-bzip2/libbzip2 version 1.0.3 of 15 February 2005
-
-
-This copy of Python includes a copy of db, which is licensed under the following terms:
-
-/*-
- * $Id: LICENSE,v 12.1 2005/06/16 20:20:10 bostic Exp $
- */
-
-The following is the license that applies to this copy of the Berkeley DB
-software. For a license to use the Berkeley DB software under conditions
-other than those described here, or to purchase support for this software,
-please contact Sleepycat Software by email at info@sleepycat.com, or on
-the Web at http://www.sleepycat.com.
-
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-/*
- * Copyright (c) 1990-2005
- * Sleepycat Software. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Redistributions in any form must be accompanied by information on
- * how to obtain complete source code for the DB software and any
- * accompanying software that uses the DB software. The source code
- * must either be included in the distribution or be available for no
- * more than the cost of distribution plus a nominal fee, and must be
- * freely redistributable under reasonable conditions. For an
- * executable file, complete source code means the source code for all
- * modules it contains. It does not include source code for modules or
- * files that typically accompany the major components of the operating
- * system on which the executable file runs.
- *
- * THIS SOFTWARE IS PROVIDED BY SLEEPYCAT SOFTWARE ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
- * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL SLEEPYCAT SOFTWARE
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-/*
- * Copyright (c) 1990, 1993, 1994, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/*
- * Copyright (c) 1995, 1996
- * The President and Fellows of Harvard University. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-This copy of Python includes a copy of openssl, which is licensed under the following terms:
-
-
- LICENSE ISSUES
- ==============
-
- The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
- the OpenSSL License and the original SSLeay license apply to the toolkit.
- See below for the actual license texts. Actually both licenses are BSD-style
- Open Source licenses. In case of any license issues related to OpenSSL
- please contact openssl-core@openssl.org.
-
- OpenSSL License
- ---------------
-
-/* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
- Original SSLeay License
- -----------------------
-
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-
-This copy of Python includes a copy of tcl, which is licensed under the following terms:
-
-This software is copyrighted by the Regents of the University of
-California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState
-Corporation and other parties. The following terms apply to all files
-associated with the software unless explicitly disclaimed in
-individual files.
-
-The authors hereby grant permission to use, copy, modify, distribute,
-and license this software and its documentation for any purpose, provided
-that existing copyright notices are retained in all copies and that this
-notice is included verbatim in any distributions. No written agreement,
-license, or royalty fee is required for any of the authorized uses.
-Modifications to this software may be copyrighted by their authors
-and need not follow the licensing terms described here, provided that
-the new terms are clearly indicated on the first page of each file where
-they apply.
-
-IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
-FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
-ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
-DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
-IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
-NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
-MODIFICATIONS.
-
-GOVERNMENT USE: If you are acquiring this software on behalf of the
-U.S. government, the Government shall have only "Restricted Rights"
-in the software and related documentation as defined in the Federal
-Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
-are acquiring the software on behalf of the Department of Defense, the
-software shall be classified as "Commercial Computer Software" and the
-Government shall have only "Restricted Rights" as defined in Clause
-252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
-authors grant the U.S. Government and others acting in its behalf
-permission to use and distribute the software in accordance with the
-terms specified in this license.
-
-This copy of Python includes a copy of tk, which is licensed under the following terms:
-
-This software is copyrighted by the Regents of the University of
-California, Sun Microsystems, Inc., and other parties. The following
-terms apply to all files associated with the software unless explicitly
-disclaimed in individual files.
-
-The authors hereby grant permission to use, copy, modify, distribute,
-and license this software and its documentation for any purpose, provided
-that existing copyright notices are retained in all copies and that this
-notice is included verbatim in any distributions. No written agreement,
-license, or royalty fee is required for any of the authorized uses.
-Modifications to this software may be copyrighted by their authors
-and need not follow the licensing terms described here, provided that
-the new terms are clearly indicated on the first page of each file where
-they apply.
-
-IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
-FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
-ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
-DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
-IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
-NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
-MODIFICATIONS.
-
-GOVERNMENT USE: If you are acquiring this software on behalf of the
-U.S. government, the Government shall have only "Restricted Rights"
-in the software and related documentation as defined in the Federal
-Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
-are acquiring the software on behalf of the Department of Defense, the
-software shall be classified as "Commercial Computer Software" and the
-Government shall have only "Restricted Rights" as defined in Clause
-252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the
-authors grant the U.S. Government and others acting in its behalf
-permission to use and distribute the software in accordance with the
-terms specified in this license.
diff --git a/thirdparty/PyYAML-3.12-py2-none-any.whl b/thirdparty/PyYAML-3.12-py2-none-any.whl
deleted file mode 100644
index c301d13..0000000
Binary files a/thirdparty/PyYAML-3.12-py2-none-any.whl and /dev/null differ
diff --git a/thirdparty/PyYAML-3.12-py3-none-any.whl b/thirdparty/PyYAML-3.12-py3-none-any.whl
deleted file mode 100644
index 4c971df..0000000
Binary files a/thirdparty/PyYAML-3.12-py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/PyYAML-3.12.tar.gz b/thirdparty/PyYAML-3.12.tar.gz
deleted file mode 100644
index aabee39..0000000
Binary files a/thirdparty/PyYAML-3.12.tar.gz and /dev/null differ
diff --git a/thirdparty/README.md b/thirdparty/README.md
deleted file mode 100644
index ecc1ba2..0000000
--- a/thirdparty/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Thirdparty dependencies repository
-
-See .ABOUT files for provenance details
-
diff --git a/thirdparty/aboutcode_toolkit-4.0.1-py2.py3-none-any.whl b/thirdparty/aboutcode_toolkit-4.0.1-py2.py3-none-any.whl
deleted file mode 100644
index 56af5e1..0000000
Binary files a/thirdparty/aboutcode_toolkit-4.0.1-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/aboutcode_toolkit-4.0.1-py2.py3-none-any.whl.ABOUT b/thirdparty/aboutcode_toolkit-4.0.1-py2.py3-none-any.whl.ABOUT
deleted file mode 100644
index 3f499b1..0000000
--- a/thirdparty/aboutcode_toolkit-4.0.1-py2.py3-none-any.whl.ABOUT
+++ /dev/null
@@ -1,16 +0,0 @@
-about_resource: aboutcode_toolkit-4.0.1-py2.py3-none-any.whl
-checksum_md5: 03479c18061c592e726a8e8acabbd6b0
-checksum_sha1: 1324a179851952569b98da5189755579905e64ab
-contact: http://www.nexb.com/contactus.html
-copyright: Copyright (c) 2013-2017 nexB Inc.
-description: AboutCode Toolkit is a tool to process ABOUT files. An ABOUT file provides
- a simple way to document the provenance (origin and license) 'about' a software
- component. This is a small text file stored in the codebase side-by-side with the
- documented software component.
-download_url: https://files.pythonhosted.org/packages/df/d6/d982675e00c9e7f94cf641ea7eeeacbe5adbf6bac928e660673bb844261d/aboutcode_toolkit-4.0.1-py2.py3-none-any.whl
-homepage_url: https://aboutcode.org
-license_expression: apache-2.0
-name: AboutCode toolkit
-owner: nexB
-owner_url: http://www.nexb.com/
-version: 4.0.1
diff --git a/thirdparty/apache-2.0.LICENSE b/thirdparty/apache-2.0.LICENSE
deleted file mode 100644
index f433b1a..0000000
--- a/thirdparty/apache-2.0.LICENSE
+++ /dev/null
@@ -1,177 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
diff --git a/thirdparty/atomicwrites-1.1.5-py2.py3-none-any.whl b/thirdparty/atomicwrites-1.1.5-py2.py3-none-any.whl
deleted file mode 100644
index 5d3cbf0..0000000
Binary files a/thirdparty/atomicwrites-1.1.5-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/atomicwrites-1.1.5-py2.py3-none-any.whl.ABOUT b/thirdparty/atomicwrites-1.1.5-py2.py3-none-any.whl.ABOUT
deleted file mode 100644
index 16d700e..0000000
--- a/thirdparty/atomicwrites-1.1.5-py2.py3-none-any.whl.ABOUT
+++ /dev/null
@@ -1,8 +0,0 @@
-about_resource: atomicwrites-1.1.5-py2.py3-none-any.whl
-version: 1.1.5
-name: atomicwrites
-homepage_url: https://github.com/untitaker/python-atomicwrites
-download_url: https://files.pythonhosted.org/packages/0a/e8/cd6375e7a59664eeea9e1c77a766eeac0fc3083bb958c2b41ec46b95f29c/atomicwrites-1.1.5-py2.py3-none-any.whl
-license_file: attrs.LICENSE
-license_expression: mit
-copyright: Copyright (c) 2015-2016 Markus Unterwaditzer
\ No newline at end of file
diff --git a/thirdparty/atomicwrites.LICENSE b/thirdparty/atomicwrites.LICENSE
deleted file mode 100644
index 3bbadc3..0000000
--- a/thirdparty/atomicwrites.LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2015-2016 Markus Unterwaditzer
-
-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/thirdparty/attrs-18.1.0-py2.py3-none-any.whl b/thirdparty/attrs-18.1.0-py2.py3-none-any.whl
deleted file mode 100644
index b0e33a1..0000000
Binary files a/thirdparty/attrs-18.1.0-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/attrs.ABOUT b/thirdparty/attrs.ABOUT
deleted file mode 100644
index b823d6b..0000000
--- a/thirdparty/attrs.ABOUT
+++ /dev/null
@@ -1,8 +0,0 @@
-about_resource: attrs-18.1.0-py2.py3-none-any.whl
-version: 18.1.0
-name: attrs
-homepage_url: http://attrs.org
-download_url: https://files.pythonhosted.org/packages/41/59/cedf87e91ed541be7957c501a92102f9cc6363c623a7666d69d51c78ac5b/attrs-18.1.0-py2.py3-none-any.whl
-license_file: attrs.LICENSE
-license_expression: mit
-copyright: Copyright (c) Hynek Schlawack
\ No newline at end of file
diff --git a/thirdparty/attrs.LICENSE b/thirdparty/attrs.LICENSE
deleted file mode 100644
index e7ca4f7..0000000
--- a/thirdparty/attrs.LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015 Hynek Schlawack
-
-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.
\ No newline at end of file
diff --git a/thirdparty/backports.csv-1.0.6-py2.py3-none-any.whl b/thirdparty/backports.csv-1.0.6-py2.py3-none-any.whl
deleted file mode 100644
index 5d2dc9b..0000000
Binary files a/thirdparty/backports.csv-1.0.6-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/backports.csv.ABOUT b/thirdparty/backports.csv.ABOUT
deleted file mode 100644
index 752ba38..0000000
--- a/thirdparty/backports.csv.ABOUT
+++ /dev/null
@@ -1,16 +0,0 @@
-about_resource: backports.csv-1.0.6-py2.py3-none-any.whl
-version: 1.0.6
-download_url: https://files.pythonhosted.org/packages/71/f7/5db9136de67021a6dce4eefbe50d46aa043e59ebb11c83d4ecfeb47b686e/backports.csv-1.0.6-py2.py3-none-any.whl
-
-name: backports.csv
-homepage_url: https://github.com/ryanhiebert/backports.csv
-owner: Ryan Hiebert
-
-notes: backports.csv is a backport of the csv module from Python 3.
- Because of this fact, it is released under the same license as Python.
-
-license: python
-license_file: PSF.LICENSE
-
-vcs_tool: git
-vcs_repository: https://github.com/ryanhiebert/backports.csv.git
diff --git a/thirdparty/backports.csv.NOTICE b/thirdparty/backports.csv.NOTICE
deleted file mode 100644
index e69de29..0000000
diff --git a/thirdparty/boolean.py-3.7-py2.py3-none-any.whl b/thirdparty/boolean.py-3.7-py2.py3-none-any.whl
deleted file mode 100644
index 6f153e9..0000000
Binary files a/thirdparty/boolean.py-3.7-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/boolean.py-3.7-py2.py3-none-any.whl.ABOUT b/thirdparty/boolean.py-3.7-py2.py3-none-any.whl.ABOUT
deleted file mode 100644
index 2380120..0000000
--- a/thirdparty/boolean.py-3.7-py2.py3-none-any.whl.ABOUT
+++ /dev/null
@@ -1,8 +0,0 @@
-about_resource: boolean.py-3.7-py2.py3-none-any.whl
-download_url: https://files.pythonhosted.org/packages/dc/53/b9c4f026bac231cbf7ddc214d879c3bdb5cda9a57adbe10520deeae4f154/boolean.py-3.7-py2.py3-none-any.whl
-attribute: yes
-checksum_md5: 97af5906f5eaa22539a034a99c24c824
-checksum_sha1: 514c2b60f10521988063a9e6b56e3fae24b393c7
-license_expression: bsd-simplified
-name: boolean.py
-version: '3.7'
diff --git a/thirdparty/boolean.py-3.7-py2.py3-none-any.whl.NOTICE b/thirdparty/boolean.py-3.7-py2.py3-none-any.whl.NOTICE
deleted file mode 100644
index 8819ea1..0000000
--- a/thirdparty/boolean.py-3.7-py2.py3-none-any.whl.NOTICE
+++ /dev/null
@@ -1,23 +0,0 @@
-Copyright (c) 2009-2017 Sebastian Kraemer, basti.kr@gmail.com
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
-list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
-this list of conditions and the following disclaimer in the documentation and/or
-other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/thirdparty/bsd-simplified.LICENSE b/thirdparty/bsd-simplified.LICENSE
deleted file mode 100644
index d99a0b1..0000000
--- a/thirdparty/bsd-simplified.LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this list
-of conditions and the following disclaimer.
-
-Redistributions in binary form must reproduce the above copyright notice, this
-list of conditions and the following disclaimer in the documentation and/or
-other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/thirdparty/certifi-2018.4.16-py2.py3-none-any.whl b/thirdparty/certifi-2018.4.16-py2.py3-none-any.whl
deleted file mode 100644
index 37d13a3..0000000
Binary files a/thirdparty/certifi-2018.4.16-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/certifi-2018.4.16-py2.py3-none-any.whl.ABOUT b/thirdparty/certifi-2018.4.16-py2.py3-none-any.whl.ABOUT
deleted file mode 100644
index ac0ed23..0000000
--- a/thirdparty/certifi-2018.4.16-py2.py3-none-any.whl.ABOUT
+++ /dev/null
@@ -1,18 +0,0 @@
-about_resource: certifi-2018.4.16-py2.py3-none-any.whl
-checksum_md5: 8280b65d50546025140b542904e86c3b
-checksum_sha1: 760c62185c36483f7f7b9db7788c699e9c735990
-contact: me@kennethreitz.com
-copyright: Kenneth Reitz
-description: Certifi is a carefully curated collection of Root Certificates for validating
- the trustworthiness of SSL certificates while verifying the identity of TLS hosts.
- It has been extracted from the Requests project.
-download_url: https://files.pythonhosted.org/packages/7c/e6/92ad559b7192d846975fc916b65f667c7b8c3a32bea7372340bfe9a15fa5/certifi-2018.4.16-py2.py3-none-any.whl#sha256=9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0
-homepage_url: https://certifi.io/en/latest/
-license_expression: mpl-2.0
-name: certifi
-notice_url: https://certifi.io/en/latest/
-notice_file: certifi.NOTICE
-license_file: mpl-2.0.LICENSE
-owner: Kenneth Reitz
-owner_url: https://github.com/kennethreitz
-version: 2018.4.16
diff --git a/thirdparty/certifi.NOTICE b/thirdparty/certifi.NOTICE
deleted file mode 100644
index c2fda9a..0000000
--- a/thirdparty/certifi.NOTICE
+++ /dev/null
@@ -1,21 +0,0 @@
-This package contains a modified version of ca-bundle.crt:
-
-ca-bundle.crt -- Bundle of CA Root Certificates
-
-Certificate data from Mozilla as of: Thu Nov 3 19:04:19 2011#
-This is a bundle of X.509 certificates of public Certificate Authorities
-(CA). These were automatically extracted from Mozilla's root certificates
-file (certdata.txt). This file can be found in the mozilla source tree:
-http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1#
-It contains the certificates in PEM format and therefore
-can be directly used with curl / libcurl / php_curl, or with
-an Apache+mod_ssl webserver for SSL client authentication.
-Just configure this file as the SSLCACertificateFile.#
-
-***** BEGIN LICENSE BLOCK *****
-This Source Code Form is subject to the terms of the Mozilla Public License,
-v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain
-one at http://mozilla.org/MPL/2.0/.
-
-***** END LICENSE BLOCK *****
-@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $
diff --git a/thirdparty/click-6.7-py2.py3-none-any.whl b/thirdparty/click-6.7-py2.py3-none-any.whl
deleted file mode 100644
index 56c7ff3..0000000
Binary files a/thirdparty/click-6.7-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/click-6.7-py2.py3-none-any.whl.ABOUT b/thirdparty/click-6.7-py2.py3-none-any.whl.ABOUT
deleted file mode 100644
index 00da06e..0000000
--- a/thirdparty/click-6.7-py2.py3-none-any.whl.ABOUT
+++ /dev/null
@@ -1,14 +0,0 @@
-about_resource: click-6.7-py2.py3-none-any.whl
-checksum_md5: 5e7a4e296b3212da2ff11017675d7a4d
-checksum_sha1: 9490775172e63ba94233d4b201f0e8d78b0cd939
-contact: armin.ronacher@active-4.com
-copyright: Copyright (c) 2014 by Armin Ronacher.
-description: A simple wrapper around optparse for powerful command line utilities.
-download_url: https://pypi.python.org/packages/34/c1/8806f99713ddb993c5366c362b2f908f18269f8d792aff1abfd700775a77/click-6.7-py2.py3-none-any.whl#md5=5e7a4e296b3212da2ff11017675d7a4d
-homepage_url: http://click.pocoo.org/
-license_expression: bsd-new
-name: click
-notes: "contact: armin.ronacher@active-4.com\r\nvcs_tool: git\r\nvcs_repository: https://github.com/pallets/click.git"
-owner: Armin Ronacher
-owner_url: http://lucumr.pocoo.org/about/
-version: 6.7
diff --git a/thirdparty/click.LICENSE b/thirdparty/click.LICENSE
deleted file mode 100644
index 012b628..0000000
--- a/thirdparty/click.LICENSE
+++ /dev/null
@@ -1,38 +0,0 @@
-Copyright (c) 2014 by Armin Ronacher.
-
-Click uses parts of optparse written by Gregory P. Ward and maintained by the
-Python software foundation. This is limited to code in the parser.py
-module:
-
-Copyright (c) 2001-2006 Gregory P. Ward. All rights reserved.
-Copyright (c) 2002-2006 Python Software Foundation. All rights reserved.
-
-Some rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
-
- * The names of the contributors may not be used to endorse or
- promote products derived from this software without specific
- prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/thirdparty/colorama-0.3.9-py2.py3-none-any.whl b/thirdparty/colorama-0.3.9-py2.py3-none-any.whl
deleted file mode 100644
index 29b83f0..0000000
Binary files a/thirdparty/colorama-0.3.9-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/colorama.ABOUT b/thirdparty/colorama.ABOUT
deleted file mode 100644
index 4e2ddc3..0000000
--- a/thirdparty/colorama.ABOUT
+++ /dev/null
@@ -1,11 +0,0 @@
-about_resource: colorama-0.3.9-py2.py3-none-any.whl
-download_url: https://pypi.python.org/packages/db/c8/7dcf9dbcb22429512708fe3a547f8b6101c0d02137acbd892505aee57adf/colorama-0.3.9-py2.py3-none-any.whl#md5=cc0c01c7b3b34d0354d813e9ab26aca3
-version: 0.3.9
-
-name: colorama
-description: Cross-platform colored terminal text
-homepage_url: https://pypi.python.org/pypi/colorama
-owner: Jonathan Hartley
-license_expression: bds-new
-license_file: colorama.LICENSE
-copyright: Copyright (c) 2010 Jonathan Hartley
\ No newline at end of file
diff --git a/thirdparty/colorama.LICENSE b/thirdparty/colorama.LICENSE
deleted file mode 100644
index 5f56779..0000000
--- a/thirdparty/colorama.LICENSE
+++ /dev/null
@@ -1,28 +0,0 @@
-Copyright (c) 2010 Jonathan Hartley
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-* Neither the name of the copyright holders, nor those of its contributors
- may be used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/thirdparty/funcsigs-1.0.2-py2.py3-none-any.whl b/thirdparty/funcsigs-1.0.2-py2.py3-none-any.whl
deleted file mode 100644
index ec5973f..0000000
Binary files a/thirdparty/funcsigs-1.0.2-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/funcsigs.ABOUT b/thirdparty/funcsigs.ABOUT
deleted file mode 100644
index d533283..0000000
--- a/thirdparty/funcsigs.ABOUT
+++ /dev/null
@@ -1,12 +0,0 @@
-about_resource: funcsigs-1.0.2-py2.py3-none-any.whl
-version: 1.0.2
-download_url: https://pypi.python.org/packages/94/4a/db842e7a0545de1cdb0439bb80e6e42dfe82aaeaadd4072f2263a4fbed23/funcsigs-1.0.2.tar.gz#md5=7e583285b1fb8a76305d6d68f4ccc14e
-
-name: funcsigs
-description: funcsigs is a backport of the PEP 362 function signature features from Python 3.3’s inspect module. The backport is compatible with Python 2.6, 2.7 as well as 3.2 and up.
-
-homepage_url: http://funcsigs.readthedocs.org/
-owner: Testing Cabal
-license: apache-2.0
-license_file: funcsigs.LICENSE
-copyright: Copyright (c) Testing Cabal
\ No newline at end of file
diff --git a/thirdparty/funcsigs.LICENSE b/thirdparty/funcsigs.LICENSE
deleted file mode 100644
index d9a10c0..0000000
--- a/thirdparty/funcsigs.LICENSE
+++ /dev/null
@@ -1,176 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
diff --git a/thirdparty/more-itertools-py2.ABOUT b/thirdparty/more-itertools-py2.ABOUT
deleted file mode 100644
index 6317114..0000000
--- a/thirdparty/more-itertools-py2.ABOUT
+++ /dev/null
@@ -1,12 +0,0 @@
-about_resource: more_itertools-4.2.0-py2-none-any.whl
-download_url: https://files.pythonhosted.org/packages/82/05/43e3947125a2137cba4746135c75934ceed1863f27e050fc560052104a71/pluggy-0.6.0-py2-none-any.whl
-version: 4.2.0
-
-name: more_itertools
-description: More routines for operating on iterables, beyond itertools
-
-homepage_url: https://github.com/erikrose/more-itertools
-owner: Erik Rose
-license_expression: mit
-notice_file: more-itertools.NOTICE
-copyright: Copyright (c) 2012 Erik Rose
diff --git a/thirdparty/more-itertools-py3.ABOUT b/thirdparty/more-itertools-py3.ABOUT
deleted file mode 100644
index 304fc26..0000000
--- a/thirdparty/more-itertools-py3.ABOUT
+++ /dev/null
@@ -1,12 +0,0 @@
-about_resource: more_itertools-4.2.0-py3-none-any.whl
-download_url: https://files.pythonhosted.org/packages/85/40/90c3b0393e12b9827381004224de8814686e3d7182f9d4182477f600826d/more_itertools-4.2.0-py3-none-any.whl
-version: 4.2.0
-
-name: more_itertools
-description: More routines for operating on iterables, beyond itertools
-
-homepage_url: https://github.com/erikrose/more-itertools
-owner: Erik Rose
-license_expression: mit
-notice_file: more-itertools.NOTICE
-copyright: Copyright (c) 2012 Erik Rose
diff --git a/thirdparty/more-itertools.NOTICE b/thirdparty/more-itertools.NOTICE
deleted file mode 100644
index 0a523be..0000000
--- a/thirdparty/more-itertools.NOTICE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2012 Erik Rose
-
-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/thirdparty/more_itertools-4.2.0-py2-none-any.whl b/thirdparty/more_itertools-4.2.0-py2-none-any.whl
deleted file mode 100644
index 5a31af7..0000000
Binary files a/thirdparty/more_itertools-4.2.0-py2-none-any.whl and /dev/null differ
diff --git a/thirdparty/more_itertools-4.2.0-py3-none-any.whl b/thirdparty/more_itertools-4.2.0-py3-none-any.whl
deleted file mode 100644
index 0ac0745..0000000
Binary files a/thirdparty/more_itertools-4.2.0-py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/mpl-2.0.LICENSE b/thirdparty/mpl-2.0.LICENSE
deleted file mode 100644
index 14e2f77..0000000
--- a/thirdparty/mpl-2.0.LICENSE
+++ /dev/null
@@ -1,373 +0,0 @@
-Mozilla Public License Version 2.0
-==================================
-
-1. Definitions
---------------
-
-1.1. "Contributor"
- means each individual or legal entity that creates, contributes to
- the creation of, or owns Covered Software.
-
-1.2. "Contributor Version"
- means the combination of the Contributions of others (if any) used
- by a Contributor and that particular Contributor's Contribution.
-
-1.3. "Contribution"
- means Covered Software of a particular Contributor.
-
-1.4. "Covered Software"
- means Source Code Form to which the initial Contributor has attached
- the notice in Exhibit A, the Executable Form of such Source Code
- Form, and Modifications of such Source Code Form, in each case
- including portions thereof.
-
-1.5. "Incompatible With Secondary Licenses"
- means
-
- (a) that the initial Contributor has attached the notice described
- in Exhibit B to the Covered Software; or
-
- (b) that the Covered Software was made available under the terms of
- version 1.1 or earlier of the License, but not also under the
- terms of a Secondary License.
-
-1.6. "Executable Form"
- means any form of the work other than Source Code Form.
-
-1.7. "Larger Work"
- means a work that combines Covered Software with other material, in
- a separate file or files, that is not Covered Software.
-
-1.8. "License"
- means this document.
-
-1.9. "Licensable"
- means having the right to grant, to the maximum extent possible,
- whether at the time of the initial grant or subsequently, any and
- all of the rights conveyed by this License.
-
-1.10. "Modifications"
- means any of the following:
-
- (a) any file in Source Code Form that results from an addition to,
- deletion from, or modification of the contents of Covered
- Software; or
-
- (b) any new file in Source Code Form that contains any Covered
- Software.
-
-1.11. "Patent Claims" of a Contributor
- means any patent claim(s), including without limitation, method,
- process, and apparatus claims, in any patent Licensable by such
- Contributor that would be infringed, but for the grant of the
- License, by the making, using, selling, offering for sale, having
- made, import, or transfer of either its Contributions or its
- Contributor Version.
-
-1.12. "Secondary License"
- means either the GNU General Public License, Version 2.0, the GNU
- Lesser General Public License, Version 2.1, the GNU Affero General
- Public License, Version 3.0, or any later versions of those
- licenses.
-
-1.13. "Source Code Form"
- means the form of the work preferred for making modifications.
-
-1.14. "You" (or "Your")
- means an individual or a legal entity exercising rights under this
- License. For legal entities, "You" includes any entity that
- controls, is controlled by, or is under common control with You. For
- purposes of this definition, "control" means (a) the power, direct
- or indirect, to cause the direction or management of such entity,
- whether by contract or otherwise, or (b) ownership of more than
- fifty percent (50%) of the outstanding shares or beneficial
- ownership of such entity.
-
-2. License Grants and Conditions
---------------------------------
-
-2.1. Grants
-
-Each Contributor hereby grants You a world-wide, royalty-free,
-non-exclusive license:
-
-(a) under intellectual property rights (other than patent or trademark)
- Licensable by such Contributor to use, reproduce, make available,
- modify, display, perform, distribute, and otherwise exploit its
- Contributions, either on an unmodified basis, with Modifications, or
- as part of a Larger Work; and
-
-(b) under Patent Claims of such Contributor to make, use, sell, offer
- for sale, have made, import, and otherwise transfer either its
- Contributions or its Contributor Version.
-
-2.2. Effective Date
-
-The licenses granted in Section 2.1 with respect to any Contribution
-become effective for each Contribution on the date the Contributor first
-distributes such Contribution.
-
-2.3. Limitations on Grant Scope
-
-The licenses granted in this Section 2 are the only rights granted under
-this License. No additional rights or licenses will be implied from the
-distribution or licensing of Covered Software under this License.
-Notwithstanding Section 2.1(b) above, no patent license is granted by a
-Contributor:
-
-(a) for any code that a Contributor has removed from Covered Software;
- or
-
-(b) for infringements caused by: (i) Your and any other third party's
- modifications of Covered Software, or (ii) the combination of its
- Contributions with other software (except as part of its Contributor
- Version); or
-
-(c) under Patent Claims infringed by Covered Software in the absence of
- its Contributions.
-
-This License does not grant any rights in the trademarks, service marks,
-or logos of any Contributor (except as may be necessary to comply with
-the notice requirements in Section 3.4).
-
-2.4. Subsequent Licenses
-
-No Contributor makes additional grants as a result of Your choice to
-distribute the Covered Software under a subsequent version of this
-License (see Section 10.2) or under the terms of a Secondary License (if
-permitted under the terms of Section 3.3).
-
-2.5. Representation
-
-Each Contributor represents that the Contributor believes its
-Contributions are its original creation(s) or it has sufficient rights
-to grant the rights to its Contributions conveyed by this License.
-
-2.6. Fair Use
-
-This License is not intended to limit any rights You have under
-applicable copyright doctrines of fair use, fair dealing, or other
-equivalents.
-
-2.7. Conditions
-
-Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
-in Section 2.1.
-
-3. Responsibilities
--------------------
-
-3.1. Distribution of Source Form
-
-All distribution of Covered Software in Source Code Form, including any
-Modifications that You create or to which You contribute, must be under
-the terms of this License. You must inform recipients that the Source
-Code Form of the Covered Software is governed by the terms of this
-License, and how they can obtain a copy of this License. You may not
-attempt to alter or restrict the recipients' rights in the Source Code
-Form.
-
-3.2. Distribution of Executable Form
-
-If You distribute Covered Software in Executable Form then:
-
-(a) such Covered Software must also be made available in Source Code
- Form, as described in Section 3.1, and You must inform recipients of
- the Executable Form how they can obtain a copy of such Source Code
- Form by reasonable means in a timely manner, at a charge no more
- than the cost of distribution to the recipient; and
-
-(b) You may distribute such Executable Form under the terms of this
- License, or sublicense it under different terms, provided that the
- license for the Executable Form does not attempt to limit or alter
- the recipients' rights in the Source Code Form under this License.
-
-3.3. Distribution of a Larger Work
-
-You may create and distribute a Larger Work under terms of Your choice,
-provided that You also comply with the requirements of this License for
-the Covered Software. If the Larger Work is a combination of Covered
-Software with a work governed by one or more Secondary Licenses, and the
-Covered Software is not Incompatible With Secondary Licenses, this
-License permits You to additionally distribute such Covered Software
-under the terms of such Secondary License(s), so that the recipient of
-the Larger Work may, at their option, further distribute the Covered
-Software under the terms of either this License or such Secondary
-License(s).
-
-3.4. Notices
-
-You may not remove or alter the substance of any license notices
-(including copyright notices, patent notices, disclaimers of warranty,
-or limitations of liability) contained within the Source Code Form of
-the Covered Software, except that You may alter any license notices to
-the extent required to remedy known factual inaccuracies.
-
-3.5. Application of Additional Terms
-
-You may choose to offer, and to charge a fee for, warranty, support,
-indemnity or liability obligations to one or more recipients of Covered
-Software. However, You may do so only on Your own behalf, and not on
-behalf of any Contributor. You must make it absolutely clear that any
-such warranty, support, indemnity, or liability obligation is offered by
-You alone, and You hereby agree to indemnify every Contributor for any
-liability incurred by such Contributor as a result of warranty, support,
-indemnity or liability terms You offer. You may include additional
-disclaimers of warranty and limitations of liability specific to any
-jurisdiction.
-
-4. Inability to Comply Due to Statute or Regulation
----------------------------------------------------
-
-If it is impossible for You to comply with any of the terms of this
-License with respect to some or all of the Covered Software due to
-statute, judicial order, or regulation then You must: (a) comply with
-the terms of this License to the maximum extent possible; and (b)
-describe the limitations and the code they affect. Such description must
-be placed in a text file included with all distributions of the Covered
-Software under this License. Except to the extent prohibited by statute
-or regulation, such description must be sufficiently detailed for a
-recipient of ordinary skill to be able to understand it.
-
-5. Termination
---------------
-
-5.1. The rights granted under this License will terminate automatically
-if You fail to comply with any of its terms. However, if You become
-compliant, then the rights granted under this License from a particular
-Contributor are reinstated (a) provisionally, unless and until such
-Contributor explicitly and finally terminates Your grants, and (b) on an
-ongoing basis, if such Contributor fails to notify You of the
-non-compliance by some reasonable means prior to 60 days after You have
-come back into compliance. Moreover, Your grants from a particular
-Contributor are reinstated on an ongoing basis if such Contributor
-notifies You of the non-compliance by some reasonable means, this is the
-first time You have received notice of non-compliance with this License
-from such Contributor, and You become compliant prior to 30 days after
-Your receipt of the notice.
-
-5.2. If You initiate litigation against any entity by asserting a patent
-infringement claim (excluding declaratory judgment actions,
-counter-claims, and cross-claims) alleging that a Contributor Version
-directly or indirectly infringes any patent, then the rights granted to
-You by any and all Contributors for the Covered Software under Section
-2.1 of this License shall terminate.
-
-5.3. In the event of termination under Sections 5.1 or 5.2 above, all
-end user license agreements (excluding distributors and resellers) which
-have been validly granted by You or Your distributors under this License
-prior to termination shall survive termination.
-
-************************************************************************
-* *
-* 6. Disclaimer of Warranty *
-* ------------------------- *
-* *
-* Covered Software is provided under this License on an "as is" *
-* basis, without warranty of any kind, either expressed, implied, or *
-* statutory, including, without limitation, warranties that the *
-* Covered Software is free of defects, merchantable, fit for a *
-* particular purpose or non-infringing. The entire risk as to the *
-* quality and performance of the Covered Software is with You. *
-* Should any Covered Software prove defective in any respect, You *
-* (not any Contributor) assume the cost of any necessary servicing, *
-* repair, or correction. This disclaimer of warranty constitutes an *
-* essential part of this License. No use of any Covered Software is *
-* authorized under this License except under this disclaimer. *
-* *
-************************************************************************
-
-************************************************************************
-* *
-* 7. Limitation of Liability *
-* -------------------------- *
-* *
-* Under no circumstances and under no legal theory, whether tort *
-* (including negligence), contract, or otherwise, shall any *
-* Contributor, or anyone who distributes Covered Software as *
-* permitted above, be liable to You for any direct, indirect, *
-* special, incidental, or consequential damages of any character *
-* including, without limitation, damages for lost profits, loss of *
-* goodwill, work stoppage, computer failure or malfunction, or any *
-* and all other commercial damages or losses, even if such party *
-* shall have been informed of the possibility of such damages. This *
-* limitation of liability shall not apply to liability for death or *
-* personal injury resulting from such party's negligence to the *
-* extent applicable law prohibits such limitation. Some *
-* jurisdictions do not allow the exclusion or limitation of *
-* incidental or consequential damages, so this exclusion and *
-* limitation may not apply to You. *
-* *
-************************************************************************
-
-8. Litigation
--------------
-
-Any litigation relating to this License may be brought only in the
-courts of a jurisdiction where the defendant maintains its principal
-place of business and such litigation shall be governed by laws of that
-jurisdiction, without reference to its conflict-of-law provisions.
-Nothing in this Section shall prevent a party's ability to bring
-cross-claims or counter-claims.
-
-9. Miscellaneous
-----------------
-
-This License represents the complete agreement concerning the subject
-matter hereof. If any provision of this License is held to be
-unenforceable, such provision shall be reformed only to the extent
-necessary to make it enforceable. Any law or regulation which provides
-that the language of a contract shall be construed against the drafter
-shall not be used to construe this License against a Contributor.
-
-10. Versions of the License
----------------------------
-
-10.1. New Versions
-
-Mozilla Foundation is the license steward. Except as provided in Section
-10.3, no one other than the license steward has the right to modify or
-publish new versions of this License. Each version will be given a
-distinguishing version number.
-
-10.2. Effect of New Versions
-
-You may distribute the Covered Software under the terms of the version
-of the License under which You originally received the Covered Software,
-or under the terms of any subsequent version published by the license
-steward.
-
-10.3. Modified Versions
-
-If you create software not governed by this License, and you want to
-create a new license for such software, you may create and use a
-modified version of this License if you rename the license and remove
-any references to the name of the license steward (except to note that
-such modified license differs from this License).
-
-10.4. Distributing Source Code Form that is Incompatible With Secondary
-Licenses
-
-If You choose to distribute Source Code Form that is Incompatible With
-Secondary Licenses under the terms of this version of the License, the
-notice described in Exhibit B of this License must be attached.
-
-Exhibit A - Source Code Form License Notice
--------------------------------------------
-
- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-If it is not possible or desirable to put the notice in a particular
-file, then You may include the notice in a location (such as a LICENSE
-file in a relevant directory) where a recipient would be likely to look
-for such a notice.
-
-You may add additional accurate notices of copyright ownership.
-
-Exhibit B - "Incompatible With Secondary Licenses" Notice
----------------------------------------------------------
-
- This Source Code Form is "Incompatible With Secondary Licenses", as
- defined by the Mozilla Public License, v. 2.0.
diff --git a/thirdparty/pip-10.0.1-py2.py3-none-any.whl b/thirdparty/pip-10.0.1-py2.py3-none-any.whl
deleted file mode 100644
index 9837092..0000000
Binary files a/thirdparty/pip-10.0.1-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/pip-10.0.1-py2.py3-none-any.whl.ABOUT b/thirdparty/pip-10.0.1-py2.py3-none-any.whl.ABOUT
deleted file mode 100644
index 942f78d..0000000
--- a/thirdparty/pip-10.0.1-py2.py3-none-any.whl.ABOUT
+++ /dev/null
@@ -1,14 +0,0 @@
-about_resource: pip-10.0.1-py2.py3-none-any.whl
-checksum_md5: eb92c86bfda9cde5e082a1fd76f1e627
-checksum_sha1: bed4d1300f778a636fc7d2733ee451daff1b6405
-copyright: Copyright (c) 2008-2016 The pip developers (see AUTHORS.txt file)
-description: A tool for installing and managing Python packages.
-download_url: https://files.pythonhosted.org/packages/0f/74/ecd13431bcc456ed390b44c8a6e917c1820365cbebcb6a8974d1cd045ab4/pip-10.0.1-py2.py3-none-any.whl#sha256=717cdffb2833be8409433a93746744b59505f42146e8d37de6c62b430e25d6d7
-homepage_url: http://www.pip-installer.org
-license_expression: mit AND bsd-new AND lgpl-2.1
-name: pip
-notice_file: pip.LICENSE
-notice_url: https://github.com/pypa/pip/blob/master/LICENSE.txt
-owner: The pip developers
-owner_url: http://www.pip-installer.org/en/latest/
-version: 10.0.1
diff --git a/thirdparty/pip.LICENSE b/thirdparty/pip.LICENSE
deleted file mode 100644
index d3379fa..0000000
--- a/thirdparty/pip.LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-Copyright (c) 2008-2018 The pip developers (see AUTHORS.txt file)
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/thirdparty/pluggy-0.6.0-py2-none-any.whl b/thirdparty/pluggy-0.6.0-py2-none-any.whl
deleted file mode 100644
index adb7ef9..0000000
Binary files a/thirdparty/pluggy-0.6.0-py2-none-any.whl and /dev/null differ
diff --git a/thirdparty/pluggy-0.6.0-py3-none-any.whl b/thirdparty/pluggy-0.6.0-py3-none-any.whl
deleted file mode 100644
index abf0c58..0000000
Binary files a/thirdparty/pluggy-0.6.0-py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/pluggy-py2.ABOUT b/thirdparty/pluggy-py2.ABOUT
deleted file mode 100644
index fbc3107..0000000
--- a/thirdparty/pluggy-py2.ABOUT
+++ /dev/null
@@ -1,11 +0,0 @@
-about_resource: pluggy-0.6.0-py2-none-any.whl
-download_url: https://files.pythonhosted.org/packages/82/05/43e3947125a2137cba4746135c75934ceed1863f27e050fc560052104a71/pluggy-0.6.0-py2-none-any.whl
-version: 0.6.0
-
-name: pluggy
-description: plugin and hook calling mechanisms for python
-homepage_url: https://github.com/pytest-dev/pluggy
-owner: Holger Krekel
-contact: holger at merlinux.eu
-license_expression: mit
-license_file: pluggy.LICENSE
\ No newline at end of file
diff --git a/thirdparty/pluggy-py3.ABOUT b/thirdparty/pluggy-py3.ABOUT
deleted file mode 100644
index 3cd8c3c..0000000
--- a/thirdparty/pluggy-py3.ABOUT
+++ /dev/null
@@ -1,11 +0,0 @@
-about_resource: pluggy-0.6.0-py3-none-any.whl
-download_url: https://files.pythonhosted.org/packages/ba/65/ded3bc40bbf8d887f262f150fbe1ae6637765b5c9534bd55690ed2c0b0f7/pluggy-0.6.0-py3-none-any.whl
-version: 0.6.0
-
-name: pluggy
-description: plugin and hook calling mechanisms for python
-homepage_url: https://github.com/pytest-dev/pluggy
-owner: Holger Krekel
-contact: holger at merlinux.eu
-license_expression: mit
-license_file: pluggy.LICENSE
\ No newline at end of file
diff --git a/thirdparty/pluggy.LICENSE b/thirdparty/pluggy.LICENSE
deleted file mode 100644
index 121017d..0000000
--- a/thirdparty/pluggy.LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015 holger krekel (rather uses bitbucket/hpk42)
-
-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/thirdparty/py-1.5.3-py2.py3-none-any.whl b/thirdparty/py-1.5.3-py2.py3-none-any.whl
deleted file mode 100644
index 127d886..0000000
Binary files a/thirdparty/py-1.5.3-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/py.ABOUT b/thirdparty/py.ABOUT
deleted file mode 100644
index 6a5831f..0000000
--- a/thirdparty/py.ABOUT
+++ /dev/null
@@ -1,12 +0,0 @@
-about_resource: py-1.5.3-py2.py3-none-any.whl
-version: 1.5.3
-download_url: https://files.pythonhosted.org/packages/67/a5/f77982214dd4c8fd104b066f249adea2c49e25e8703d284382eb5e9ab35a/py-1.5.3-py2.py3-none-any.whl
-
-name: py
-description: library with cross-python path, ini-parsing, io, code, log facilities
-homepage_url: http://py.readthedocs.org/
-owner: holger krekel, Ronny Pfannschmidt, Benjamin Peterson and others
-contact: pytest-dev@python.org
-license_expression: mit
-license_file: py.LICENSE
-copyright: copyright (c) 2004-2014 Holger Krekel and others
diff --git a/thirdparty/py.LICENSE b/thirdparty/py.LICENSE
deleted file mode 100644
index 31ecdfb..0000000
--- a/thirdparty/py.LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-
- 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/thirdparty/pytest-3.5.1-py2.py3-none-any.whl b/thirdparty/pytest-3.5.1-py2.py3-none-any.whl
deleted file mode 100644
index 5baaf73..0000000
Binary files a/thirdparty/pytest-3.5.1-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/pytest.ABOUT b/thirdparty/pytest.ABOUT
deleted file mode 100644
index 2809f77..0000000
--- a/thirdparty/pytest.ABOUT
+++ /dev/null
@@ -1,12 +0,0 @@
-about_resource: pytest-3.5.1-py2.py3-none-any.whl
-download_url: https://files.pythonhosted.org/packages/76/52/fc48d02492d9e6070cb672d9133382e83084f567f88eff1c27bd2c6c27a8/pytest-3.5.1-py2.py3-none-any.whl
-version: 3.5.1
-
-name: pytest
-description: simple powerful testing with Python
-homepage_url: http://pytest.org
-owner: Holger Krekel, Benjamin Peterson, Ronny Pfannschmidt, Floris Bruynooghe and others
-contact: holger at merlinux.eu
-license_expression: mit
-license_file: pytest.LICENSE
-copyright: Copyright Holger Krekel and others, 2004-2014
diff --git a/thirdparty/pytest.LICENSE b/thirdparty/pytest.LICENSE
deleted file mode 100644
index 31ecdfb..0000000
--- a/thirdparty/pytest.LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-
- 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/thirdparty/pyyaml.LICENSE b/thirdparty/pyyaml.LICENSE
deleted file mode 100644
index 050ced2..0000000
--- a/thirdparty/pyyaml.LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2006 Kirill Simonov
-
-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/thirdparty/pyyaml.py2.ABOUT b/thirdparty/pyyaml.py2.ABOUT
deleted file mode 100644
index 46d4227..0000000
--- a/thirdparty/pyyaml.py2.ABOUT
+++ /dev/null
@@ -1,15 +0,0 @@
-about_resource: PyYAML-3.12-py2-none-any.whl
-download_url: https://pypi.python.org/packages/4a/85/db5a2df477072b2902b0eb892feb37d88ac635d36245a72a6a69b23b383a/PyYAML-3.12.tar.gz#md5=4c129761b661d181ebf7ff4eb2d79950
-version: 3.12
-
-name: PyYAML
-
-homepage_url: http://pyyaml.org/wiki/PyYAML
-copyright: Copyright (c) 2006 Kirill Simonov
-owner: Kirill Simonov
-contact: xi@resolvent.net
-
-license_expression: mit
-license_file: pyyaml.LICENSE
-
-description: YAML parser and emitter for Python
diff --git a/thirdparty/pyyaml.py3.ABOUT b/thirdparty/pyyaml.py3.ABOUT
deleted file mode 100644
index 10e99b5..0000000
--- a/thirdparty/pyyaml.py3.ABOUT
+++ /dev/null
@@ -1,15 +0,0 @@
-about_resource: PyYAML-3.12-py3-none-any.whl
-download_url: https://pypi.python.org/packages/4a/85/db5a2df477072b2902b0eb892feb37d88ac635d36245a72a6a69b23b383a/PyYAML-3.12.tar.gz#md5=4c129761b661d181ebf7ff4eb2d79950
-version: 3.12
-
-name: PyYAML
-
-homepage_url: http://pyyaml.org/wiki/PyYAML
-copyright: Copyright (c) 2006 Kirill Simonov
-owner: Kirill Simonov
-contact: xi@resolvent.net
-
-license_expression: mit
-license_file: pyyaml.LICENSE
-
-description: YAML parser and emitter for Python
diff --git a/thirdparty/pyyaml.tar.ABOUT b/thirdparty/pyyaml.tar.ABOUT
deleted file mode 100644
index a23f42d..0000000
--- a/thirdparty/pyyaml.tar.ABOUT
+++ /dev/null
@@ -1,15 +0,0 @@
-about_resource: PyYAML-3.12.tar.gz
-download_url: https://pypi.python.org/packages/4a/85/db5a2df477072b2902b0eb892feb37d88ac635d36245a72a6a69b23b383a/PyYAML-3.12.tar.gz#md5=4c129761b661d181ebf7ff4eb2d79950
-version: 3.12
-
-name: PyYAML
-
-homepage_url: http://pyyaml.org/wiki/PyYAML
-copyright: Copyright (c) 2006 Kirill Simonov
-owner: Kirill Simonov
-contact: xi@resolvent.net
-
-license_expression: mit
-license_file: pyyaml.LICENSE
-
-description: YAML parser and emitter for Python
diff --git a/thirdparty/saneyaml-0.1-py2.py3-none-any.whl b/thirdparty/saneyaml-0.1-py2.py3-none-any.whl
deleted file mode 100644
index c8aa66f..0000000
Binary files a/thirdparty/saneyaml-0.1-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/saneyaml-0.1-py2.py3-none-any.whl.ABOUT b/thirdparty/saneyaml-0.1-py2.py3-none-any.whl.ABOUT
deleted file mode 100644
index ae857b3..0000000
--- a/thirdparty/saneyaml-0.1-py2.py3-none-any.whl.ABOUT
+++ /dev/null
@@ -1,20 +0,0 @@
-about_resource: saneyaml-0.1-py2.py3-none-any.whl
-attribute: true
-checksum_md5: 53509e4f1ee9f6565158163a56513b7c
-checksum_sha1: a66920309794ead47711473a21f1c7d003acd005
-contact: http://www.nexb.com/contactus.html
-copyright: Copyright (c) nexB Inc. and others.
-download_url: https://files.pythonhosted.org/packages/21/13/3d639adcd97fc22cfc4acfd23330cc26f96a85a5b992d93086684e24ac14/saneyaml-0.1-py2.py3-none-any.whl
-homepage_url: https://github.com/nexB/saneyaml
-license_expression: apache-2.0
-licenses:
-- file: apache-2.0.LICENSE
- key: apache-2.0
- name: Apache License 2.0
-name: saneyaml
-owner: nexB
-owner_url: http://www.nexb.com/
-package_url: pkg:pypi/saneyaml@0.1
-track_changes: true
-vcs_repository: https://github.com/nexB/saneyaml
-version: '0.1'
diff --git a/thirdparty/setuptools-39.2.0-py2.py3-none-any.whl b/thirdparty/setuptools-39.2.0-py2.py3-none-any.whl
deleted file mode 100644
index 712352e..0000000
Binary files a/thirdparty/setuptools-39.2.0-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/setuptools-39.2.0-py2.py3-none-any.whl.ABOUT b/thirdparty/setuptools-39.2.0-py2.py3-none-any.whl.ABOUT
deleted file mode 100644
index 2988c80..0000000
--- a/thirdparty/setuptools-39.2.0-py2.py3-none-any.whl.ABOUT
+++ /dev/null
@@ -1,14 +0,0 @@
-about_resource: setuptools-39.2.0-py2.py3-none-any.whl
-checksum_md5: 8d066d2201311ed30be535b473e32fed
-checksum_sha1: 31cc9b16ed22e1a0bc95b57428a7b6efbf7b7295
-contact: distutils-sig@python.org
-copyright: Copyright (c) Python Packaging Authority
-description: Easily download, build, install, upgrade, and uninstall Python packages
-download_url: https://files.pythonhosted.org/packages/7f/e1/820d941153923aac1d49d7fc37e17b6e73bfbd2904959fffbad77900cf92/setuptools-39.2.0-py2.py3-none-any.whl#sha256=8fca9275c89964f13da985c3656cb00ba029d7f3916b37990927ffdf264e7926
-homepage_url: https://pypi.python.org/pypi/setuptools
-license_expression: python AND mit
-notice_file: setuptools.NOTICE
-name: setuptools
-owner: Python Packaging Authority
-owner_url: https://www.pypa.io/en/latest/
-version: 39.2.0
diff --git a/thirdparty/setuptools.NOTICE b/thirdparty/setuptools.NOTICE
deleted file mode 100644
index 6e0693b..0000000
--- a/thirdparty/setuptools.NOTICE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (C) 2016 Jason R Coombs
-
-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/thirdparty/six-1.11.0-py2.py3-none-any.whl b/thirdparty/six-1.11.0-py2.py3-none-any.whl
deleted file mode 100644
index 5996023..0000000
Binary files a/thirdparty/six-1.11.0-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/six-1.11.0-py2.py3-none-any.whl.ABOUT b/thirdparty/six-1.11.0-py2.py3-none-any.whl.ABOUT
deleted file mode 100644
index c8e71ff..0000000
--- a/thirdparty/six-1.11.0-py2.py3-none-any.whl.ABOUT
+++ /dev/null
@@ -1,18 +0,0 @@
-about_resource: six-1.11.0-py2.py3-none-any.whl
-checksum_md5: 866ab722be6bdfed6830f3179af65468
-checksum_sha1: fa2683a24d4a7422add33400048fc375b2afe57b
-contact: benjamin@python.org
-copyright: Copyright (c) 2010-2011 Benjamin Peterson
-description: Six is a Python 2 and 3 compatibility library. It provides utility functions
- for smoothing over the differences between the Python versions with the goal of
- writing Python code that is compatible on both Python versions.
-download_url: https://pypi.python.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl#md5=866ab722be6bdfed6830f3179af65468
-homepage_url: http://bitbucket.org/gutworth/six
-license_expression: mit
-name: six
-notice_file: six.LICENSE
-notice_url: https://github.com/benjaminp/six/blob/master/LICENSE
-owner: Benjamin Peterson
-owner_url: http://www.benjamin-peterson.org/
-vcs_repository: https://bitbucket.org/gutworth/six
-version: 1.11.0
diff --git a/thirdparty/six.LICENSE b/thirdparty/six.LICENSE
deleted file mode 100644
index 8e2cd30..0000000
--- a/thirdparty/six.LICENSE
+++ /dev/null
@@ -1,18 +0,0 @@
-Copyright (c) 2010-2011 Benjamin Peterson
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/thirdparty/virtualenv-16.0.0-py2.py3-none-any.whl b/thirdparty/virtualenv-16.0.0-py2.py3-none-any.whl
deleted file mode 100644
index 1a90656..0000000
Binary files a/thirdparty/virtualenv-16.0.0-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/virtualenv.ABOUT b/thirdparty/virtualenv.ABOUT
deleted file mode 100644
index c9ec369..0000000
--- a/thirdparty/virtualenv.ABOUT
+++ /dev/null
@@ -1,17 +0,0 @@
-about_resource: virtualenv-16.0-py2.py3-none-any.whl
-version: 16.0
-download_url: https://files.pythonhosted.org/packages/b6/30/96a02b2287098b23b875bc8c2f58071c35d2efe84f747b64d523721dc2b5/virtualenv-16.0.0-py2.py3-none-any.whl
-
-vcs_tool: git
-vcs_repository: https://github.com/pypa/virtualenv.git
-
-name: virtualenv
-homepage_url: http://virtualenv.org/
-owner: The virtualenv developers
-
-license_url: https://raw.github.com/pypa/virtualenv/develop/LICENSE.txt
-license_file: virtualenv.LICENSE
-license_expression: mit
-copyright: Copyright (c) 2007 Ian Bicking and Contributors
- Copyright (c) 2009 Ian Bicking, The Open Planning Project
- Copyright (c) The virtualenv developers
diff --git a/thirdparty/virtualenv.LICENSE b/thirdparty/virtualenv.LICENSE
deleted file mode 100644
index 7e00d5d..0000000
--- a/thirdparty/virtualenv.LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2007 Ian Bicking and Contributors
-Copyright (c) 2009 Ian Bicking, The Open Planning Project
-Copyright (c) 2011-2014 The virtualenv developers
-
-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/thirdparty/virtualenv.py b/thirdparty/virtualenv.py
deleted file mode 100644
index cbf41de..0000000
--- a/thirdparty/virtualenv.py
+++ /dev/null
@@ -1,2347 +0,0 @@
-#!/usr/bin/env python
-"""Create a "virtual" Python installation"""
-
-import os
-import sys
-
-# If we are running in a new interpreter to create a virtualenv,
-# we do NOT want paths from our existing location interfering with anything,
-# So we remove this file's directory from sys.path - most likely to be
-# the previous interpreter's site-packages. Solves #705, #763, #779
-if os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
- for path in sys.path[:]:
- if os.path.realpath(os.path.dirname(__file__)) == os.path.realpath(path):
- sys.path.remove(path)
-
-import base64
-import codecs
-import optparse
-import re
-import shutil
-import logging
-import zlib
-import errno
-import glob
-import distutils.spawn
-import distutils.sysconfig
-import struct
-import subprocess
-import pkgutil
-import tempfile
-import textwrap
-from distutils.util import strtobool
-from os.path import join
-
-try:
- import ConfigParser
-except ImportError:
- import configparser as ConfigParser
-
-__version__ = "16.0.0"
-virtualenv_version = __version__ # legacy
-
-if sys.version_info < (2, 7):
- print('ERROR: %s' % sys.exc_info()[1])
- print('ERROR: this script requires Python 2.7 or greater.')
- sys.exit(101)
-
-try:
- basestring
-except NameError:
- basestring = str
-
-py_version = 'python%s.%s' % (sys.version_info[0], sys.version_info[1])
-
-is_jython = sys.platform.startswith('java')
-is_pypy = hasattr(sys, 'pypy_version_info')
-is_win = (sys.platform == 'win32')
-is_cygwin = (sys.platform == 'cygwin')
-is_darwin = (sys.platform == 'darwin')
-abiflags = getattr(sys, 'abiflags', '')
-
-user_dir = os.path.expanduser('~')
-if is_win:
- default_storage_dir = os.path.join(user_dir, 'virtualenv')
-else:
- default_storage_dir = os.path.join(user_dir, '.virtualenv')
-default_config_file = os.path.join(default_storage_dir, 'virtualenv.ini')
-
-if is_pypy:
- expected_exe = 'pypy'
-elif is_jython:
- expected_exe = 'jython'
-else:
- expected_exe = 'python'
-
-# Return a mapping of version -> Python executable
-# Only provided for Windows, where the information in the registry is used
-if not is_win:
- def get_installed_pythons():
- return {}
-else:
- try:
- import winreg
- except ImportError:
- import _winreg as winreg
-
- def get_installed_pythons():
- try:
- python_core = winreg.CreateKey(winreg.HKEY_LOCAL_MACHINE,
- "Software\\Python\\PythonCore")
- except WindowsError:
- # No registered Python installations
- return {}
- i = 0
- versions = []
- while True:
- try:
- versions.append(winreg.EnumKey(python_core, i))
- i = i + 1
- except WindowsError:
- break
- exes = dict()
- for ver in versions:
- try:
- path = winreg.QueryValue(python_core, "%s\\InstallPath" % ver)
- except WindowsError:
- continue
- exes[ver] = join(path, "python.exe")
-
- winreg.CloseKey(python_core)
-
- # Add the major versions
- # Sort the keys, then repeatedly update the major version entry
- # Last executable (i.e., highest version) wins with this approach
- for ver in sorted(exes):
- exes[ver[0]] = exes[ver]
-
- return exes
-
-REQUIRED_MODULES = ['os', 'posix', 'posixpath', 'nt', 'ntpath', 'genericpath',
- 'fnmatch', 'locale', 'encodings', 'codecs',
- 'stat', 'UserDict', 'readline', 'copy_reg', 'types',
- 're', 'sre', 'sre_parse', 'sre_constants', 'sre_compile',
- 'zlib']
-
-REQUIRED_FILES = ['lib-dynload', 'config']
-
-majver, minver = sys.version_info[:2]
-if majver == 2:
- if minver >= 6:
- REQUIRED_MODULES.extend(['warnings', 'linecache', '_abcoll', 'abc'])
- if minver >= 7:
- REQUIRED_MODULES.extend(['_weakrefset'])
-elif majver == 3:
- # Some extra modules are needed for Python 3, but different ones
- # for different versions.
- REQUIRED_MODULES.extend([
- '_abcoll', 'warnings', 'linecache', 'abc', 'io', '_weakrefset',
- 'copyreg', 'tempfile', 'random', '__future__', 'collections',
- 'keyword', 'tarfile', 'shutil', 'struct', 'copy', 'tokenize',
- 'token', 'functools', 'heapq', 'bisect', 'weakref', 'reprlib'
- ])
- if minver >= 2:
- REQUIRED_FILES[-1] = 'config-%s' % majver
- if minver >= 3:
- import sysconfig
- platdir = sysconfig.get_config_var('PLATDIR')
- REQUIRED_FILES.append(platdir)
- REQUIRED_MODULES.extend([
- 'base64', '_dummy_thread', 'hashlib', 'hmac',
- 'imp', 'importlib', 'rlcompleter'
- ])
- if minver >= 4:
- REQUIRED_MODULES.extend([
- 'operator',
- '_collections_abc',
- '_bootlocale',
- ])
- if minver >= 6:
- REQUIRED_MODULES.extend(['enum'])
-
-if is_pypy:
- # these are needed to correctly display the exceptions that may happen
- # during the bootstrap
- REQUIRED_MODULES.extend(['traceback', 'linecache'])
-
- if majver == 3:
- # _functools is needed to import locale during stdio initialization and
- # needs to be copied on PyPy because it's not built in
- REQUIRED_MODULES.append('_functools')
-
-
-class Logger(object):
-
- """
- Logging object for use in command-line script. Allows ranges of
- levels, to avoid some redundancy of displayed information.
- """
-
- DEBUG = logging.DEBUG
- INFO = logging.INFO
- NOTIFY = (logging.INFO+logging.WARN)/2
- WARN = WARNING = logging.WARN
- ERROR = logging.ERROR
- FATAL = logging.FATAL
-
- LEVELS = [DEBUG, INFO, NOTIFY, WARN, ERROR, FATAL]
-
- def __init__(self, consumers):
- self.consumers = consumers
- self.indent = 0
- self.in_progress = None
- self.in_progress_hanging = False
-
- def debug(self, msg, *args, **kw):
- self.log(self.DEBUG, msg, *args, **kw)
-
- def info(self, msg, *args, **kw):
- self.log(self.INFO, msg, *args, **kw)
-
- def notify(self, msg, *args, **kw):
- self.log(self.NOTIFY, msg, *args, **kw)
-
- def warn(self, msg, *args, **kw):
- self.log(self.WARN, msg, *args, **kw)
-
- def error(self, msg, *args, **kw):
- self.log(self.ERROR, msg, *args, **kw)
-
- def fatal(self, msg, *args, **kw):
- self.log(self.FATAL, msg, *args, **kw)
-
- def log(self, level, msg, *args, **kw):
- if args:
- if kw:
- raise TypeError(
- "You may give positional or keyword arguments, not both")
- args = args or kw
- rendered = None
- for consumer_level, consumer in self.consumers:
- if self.level_matches(level, consumer_level):
- if (self.in_progress_hanging
- and consumer in (sys.stdout, sys.stderr)):
- self.in_progress_hanging = False
- sys.stdout.write('\n')
- sys.stdout.flush()
- if rendered is None:
- if args:
- rendered = msg % args
- else:
- rendered = msg
- rendered = ' '*self.indent + rendered
- if hasattr(consumer, 'write'):
- consumer.write(rendered+'\n')
- else:
- consumer(rendered)
-
- def start_progress(self, msg):
- assert not self.in_progress, (
- "Tried to start_progress(%r) while in_progress %r"
- % (msg, self.in_progress))
- if self.level_matches(self.NOTIFY, self._stdout_level()):
- sys.stdout.write(msg)
- sys.stdout.flush()
- self.in_progress_hanging = True
- else:
- self.in_progress_hanging = False
- self.in_progress = msg
-
- def end_progress(self, msg='done.'):
- assert self.in_progress, (
- "Tried to end_progress without start_progress")
- if self.stdout_level_matches(self.NOTIFY):
- if not self.in_progress_hanging:
- # Some message has been printed out since start_progress
- sys.stdout.write('...' + self.in_progress + msg + '\n')
- sys.stdout.flush()
- else:
- sys.stdout.write(msg + '\n')
- sys.stdout.flush()
- self.in_progress = None
- self.in_progress_hanging = False
-
- def show_progress(self):
- """If we are in a progress scope, and no log messages have been
- shown, write out another '.'"""
- if self.in_progress_hanging:
- sys.stdout.write('.')
- sys.stdout.flush()
-
- def stdout_level_matches(self, level):
- """Returns true if a message at this level will go to stdout"""
- return self.level_matches(level, self._stdout_level())
-
- def _stdout_level(self):
- """Returns the level that stdout runs at"""
- for level, consumer in self.consumers:
- if consumer is sys.stdout:
- return level
- return self.FATAL
-
- def level_matches(self, level, consumer_level):
- """
- >>> l = Logger([])
- >>> l.level_matches(3, 4)
- False
- >>> l.level_matches(3, 2)
- True
- >>> l.level_matches(slice(None, 3), 3)
- False
- >>> l.level_matches(slice(None, 3), 2)
- True
- >>> l.level_matches(slice(1, 3), 1)
- True
- >>> l.level_matches(slice(2, 3), 1)
- False
- """
- if isinstance(level, slice):
- start, stop = level.start, level.stop
- if start is not None and start > consumer_level:
- return False
- if stop is not None and stop <= consumer_level:
- return False
- return True
- else:
- return level >= consumer_level
-
- @classmethod
- def level_for_integer(cls, level):
- levels = cls.LEVELS
- if level < 0:
- return levels[0]
- if level >= len(levels):
- return levels[-1]
- return levels[level]
-
-# create a silent logger just to prevent this from being undefined
-# will be overridden with requested verbosity main() is called.
-logger = Logger([(Logger.LEVELS[-1], sys.stdout)])
-
-def mkdir(path):
- if not os.path.exists(path):
- logger.info('Creating %s', path)
- os.makedirs(path)
- else:
- logger.info('Directory %s already exists', path)
-
-def copyfileordir(src, dest, symlink=True):
- if os.path.isdir(src):
- shutil.copytree(src, dest, symlink)
- else:
- shutil.copy2(src, dest)
-
-def copyfile(src, dest, symlink=True):
- if not os.path.exists(src):
- # Some bad symlink in the src
- logger.warn('Cannot find file %s (bad symlink)', src)
- return
- if os.path.exists(dest):
- logger.debug('File %s already exists', dest)
- return
- if not os.path.exists(os.path.dirname(dest)):
- logger.info('Creating parent directories for %s', os.path.dirname(dest))
- os.makedirs(os.path.dirname(dest))
- if not os.path.islink(src):
- srcpath = os.path.abspath(src)
- else:
- srcpath = os.readlink(src)
- if symlink and hasattr(os, 'symlink') and not is_win:
- logger.info('Symlinking %s', dest)
- try:
- os.symlink(srcpath, dest)
- except (OSError, NotImplementedError):
- logger.info('Symlinking failed, copying to %s', dest)
- copyfileordir(src, dest, symlink)
- else:
- logger.info('Copying to %s', dest)
- copyfileordir(src, dest, symlink)
-
-def writefile(dest, content, overwrite=True):
- if not os.path.exists(dest):
- logger.info('Writing %s', dest)
- with open(dest, 'wb') as f:
- f.write(content.encode('utf-8'))
- return
- else:
- with open(dest, 'rb') as f:
- c = f.read()
- if c != content.encode("utf-8"):
- if not overwrite:
- logger.notify('File %s exists with different content; not overwriting', dest)
- return
- logger.notify('Overwriting %s with new content', dest)
- with open(dest, 'wb') as f:
- f.write(content.encode('utf-8'))
- else:
- logger.info('Content %s already in place', dest)
-
-def rmtree(dir):
- if os.path.exists(dir):
- logger.notify('Deleting tree %s', dir)
- shutil.rmtree(dir)
- else:
- logger.info('Do not need to delete %s; already gone', dir)
-
-def make_exe(fn):
- if hasattr(os, 'chmod'):
- oldmode = os.stat(fn).st_mode & 0xFFF # 0o7777
- newmode = (oldmode | 0x16D) & 0xFFF # 0o555, 0o7777
- os.chmod(fn, newmode)
- logger.info('Changed mode of %s to %s', fn, oct(newmode))
-
-def _find_file(filename, dirs):
- for dir in reversed(dirs):
- files = glob.glob(os.path.join(dir, filename))
- if files and os.path.isfile(files[0]):
- return True, files[0]
- return False, filename
-
-def file_search_dirs():
- here = os.path.dirname(os.path.abspath(__file__))
- dirs = [here, join(here, 'virtualenv_support')]
- if os.path.splitext(os.path.dirname(__file__))[0] != 'virtualenv':
- # Probably some boot script; just in case virtualenv is installed...
- try:
- import virtualenv
- except ImportError:
- pass
- else:
- dirs.append(os.path.join(
- os.path.dirname(virtualenv.__file__), 'virtualenv_support'))
- return [d for d in dirs if os.path.isdir(d)]
-
-
-class UpdatingDefaultsHelpFormatter(optparse.IndentedHelpFormatter):
- """
- Custom help formatter for use in ConfigOptionParser that updates
- the defaults before expanding them, allowing them to show up correctly
- in the help listing
- """
- def expand_default(self, option):
- if self.parser is not None:
- self.parser.update_defaults(self.parser.defaults)
- return optparse.IndentedHelpFormatter.expand_default(self, option)
-
-
-class ConfigOptionParser(optparse.OptionParser):
- """
- Custom option parser which updates its defaults by checking the
- configuration files and environmental variables
- """
- def __init__(self, *args, **kwargs):
- self.config = ConfigParser.RawConfigParser()
- self.files = self.get_config_files()
- self.config.read(self.files)
- optparse.OptionParser.__init__(self, *args, **kwargs)
-
- def get_config_files(self):
- config_file = os.environ.get('VIRTUALENV_CONFIG_FILE', False)
- if config_file and os.path.exists(config_file):
- return [config_file]
- return [default_config_file]
-
- def update_defaults(self, defaults):
- """
- Updates the given defaults with values from the config files and
- the environ. Does a little special handling for certain types of
- options (lists).
- """
- # Then go and look for the other sources of configuration:
- config = {}
- # 1. config files
- config.update(dict(self.get_config_section('virtualenv')))
- # 2. environmental variables
- config.update(dict(self.get_environ_vars()))
- # Then set the options with those values
- for key, val in config.items():
- key = key.replace('_', '-')
- if not key.startswith('--'):
- key = '--%s' % key # only prefer long opts
- option = self.get_option(key)
- if option is not None:
- # ignore empty values
- if not val:
- continue
- # handle multiline configs
- if option.action == 'append':
- val = val.split()
- else:
- option.nargs = 1
- if option.action == 'store_false':
- val = not strtobool(val)
- elif option.action in ('store_true', 'count'):
- val = strtobool(val)
- try:
- val = option.convert_value(key, val)
- except optparse.OptionValueError:
- e = sys.exc_info()[1]
- print("An error occurred during configuration: %s" % e)
- sys.exit(3)
- defaults[option.dest] = val
- return defaults
-
- def get_config_section(self, name):
- """
- Get a section of a configuration
- """
- if self.config.has_section(name):
- return self.config.items(name)
- return []
-
- def get_environ_vars(self, prefix='VIRTUALENV_'):
- """
- Returns a generator with all environmental vars with prefix VIRTUALENV
- """
- for key, val in os.environ.items():
- if key.startswith(prefix):
- yield (key.replace(prefix, '').lower(), val)
-
- def get_default_values(self):
- """
- Overridding to make updating the defaults after instantiation of
- the option parser possible, update_defaults() does the dirty work.
- """
- if not self.process_default_values:
- # Old, pre-Optik 1.5 behaviour.
- return optparse.Values(self.defaults)
-
- defaults = self.update_defaults(self.defaults.copy()) # ours
- for option in self._get_all_options():
- default = defaults.get(option.dest)
- if isinstance(default, basestring):
- opt_str = option.get_opt_string()
- defaults[option.dest] = option.check_value(opt_str, default)
- return optparse.Values(defaults)
-
-
-def main():
- parser = ConfigOptionParser(
- version=virtualenv_version,
- usage="%prog [OPTIONS] DEST_DIR",
- formatter=UpdatingDefaultsHelpFormatter())
-
- parser.add_option(
- '-v', '--verbose',
- action='count',
- dest='verbose',
- default=0,
- help="Increase verbosity.")
-
- parser.add_option(
- '-q', '--quiet',
- action='count',
- dest='quiet',
- default=0,
- help='Decrease verbosity.')
-
- parser.add_option(
- '-p', '--python',
- dest='python',
- metavar='PYTHON_EXE',
- help='The Python interpreter to use, e.g., --python=python3.5 will use the python3.5 '
- 'interpreter to create the new environment. The default is the interpreter that '
- 'virtualenv was installed with (%s)' % sys.executable)
-
- parser.add_option(
- '--clear',
- dest='clear',
- action='store_true',
- help="Clear out the non-root install and start from scratch.")
-
- parser.set_defaults(system_site_packages=False)
- parser.add_option(
- '--no-site-packages',
- dest='system_site_packages',
- action='store_false',
- help="DEPRECATED. Retained only for backward compatibility. "
- "Not having access to global site-packages is now the default behavior.")
-
- parser.add_option(
- '--system-site-packages',
- dest='system_site_packages',
- action='store_true',
- help="Give the virtual environment access to the global site-packages.")
-
- parser.add_option(
- '--always-copy',
- dest='symlink',
- action='store_false',
- default=True,
- help="Always copy files rather than symlinking.")
-
- parser.add_option(
- '--relocatable',
- dest='relocatable',
- action='store_true',
- help='Make an EXISTING virtualenv environment relocatable. '
- 'This fixes up scripts and makes all .pth files relative.')
-
- parser.add_option(
- '--no-setuptools',
- dest='no_setuptools',
- action='store_true',
- help='Do not install setuptools in the new virtualenv.')
-
- parser.add_option(
- '--no-pip',
- dest='no_pip',
- action='store_true',
- help='Do not install pip in the new virtualenv.')
-
- parser.add_option(
- '--no-wheel',
- dest='no_wheel',
- action='store_true',
- help='Do not install wheel in the new virtualenv.')
-
- default_search_dirs = file_search_dirs()
- parser.add_option(
- '--extra-search-dir',
- dest="search_dirs",
- action="append",
- metavar='DIR',
- default=default_search_dirs,
- help="Directory to look for setuptools/pip distributions in. "
- "This option can be used multiple times.")
-
- parser.add_option(
- "--download",
- dest="download",
- default=True,
- action="store_true",
- help="Download preinstalled packages from PyPI.",
- )
-
- parser.add_option(
- "--no-download",
- '--never-download',
- dest="download",
- action="store_false",
- help="Do not download preinstalled packages from PyPI.",
- )
-
- parser.add_option(
- '--prompt',
- dest='prompt',
- help='Provides an alternative prompt prefix for this environment.')
-
- parser.add_option(
- '--setuptools',
- dest='setuptools',
- action='store_true',
- help="DEPRECATED. Retained only for backward compatibility. This option has no effect.")
-
- parser.add_option(
- '--distribute',
- dest='distribute',
- action='store_true',
- help="DEPRECATED. Retained only for backward compatibility. This option has no effect.")
-
- parser.add_option(
- '--unzip-setuptools',
- action='store_true',
- help="DEPRECATED. Retained only for backward compatibility. This option has no effect.")
-
- if 'extend_parser' in globals():
- extend_parser(parser)
-
- options, args = parser.parse_args()
-
- global logger
-
- if 'adjust_options' in globals():
- adjust_options(options, args)
-
- verbosity = options.verbose - options.quiet
- logger = Logger([(Logger.level_for_integer(2 - verbosity), sys.stdout)])
-
- if options.python and not os.environ.get('VIRTUALENV_INTERPRETER_RUNNING'):
- env = os.environ.copy()
- interpreter = resolve_interpreter(options.python)
- if interpreter == sys.executable:
- logger.warn('Already using interpreter %s' % interpreter)
- else:
- logger.notify('Running virtualenv with interpreter %s' % interpreter)
- env['VIRTUALENV_INTERPRETER_RUNNING'] = 'true'
- file = __file__
- if file.endswith('.pyc'):
- file = file[:-1]
- popen = subprocess.Popen([interpreter, file] + sys.argv[1:], env=env)
- raise SystemExit(popen.wait())
-
- if not args:
- print('You must provide a DEST_DIR')
- parser.print_help()
- sys.exit(2)
- if len(args) > 1:
- print('There must be only one argument: DEST_DIR (you gave %s)' % (
- ' '.join(args)))
- parser.print_help()
- sys.exit(2)
-
- home_dir = args[0]
-
- if os.path.exists(home_dir) and os.path.isfile(home_dir):
- logger.fatal('ERROR: File already exists and is not a directory.')
- logger.fatal('Please provide a different path or delete the file.')
- sys.exit(3)
-
- if os.environ.get('WORKING_ENV'):
- logger.fatal('ERROR: you cannot run virtualenv while in a workingenv')
- logger.fatal('Please deactivate your workingenv, then re-run this script')
- sys.exit(3)
-
- if 'PYTHONHOME' in os.environ:
- logger.warn('PYTHONHOME is set. You *must* activate the virtualenv before using it')
- del os.environ['PYTHONHOME']
-
- if options.relocatable:
- make_environment_relocatable(home_dir)
- return
-
- create_environment(home_dir,
- site_packages=options.system_site_packages,
- clear=options.clear,
- prompt=options.prompt,
- search_dirs=options.search_dirs,
- download=options.download,
- no_setuptools=options.no_setuptools,
- no_pip=options.no_pip,
- no_wheel=options.no_wheel,
- symlink=options.symlink)
- if 'after_install' in globals():
- after_install(options, home_dir)
-
-def call_subprocess(cmd, show_stdout=True,
- filter_stdout=None, cwd=None,
- raise_on_returncode=True, extra_env=None,
- remove_from_env=None, stdin=None):
- cmd_parts = []
- for part in cmd:
- if len(part) > 45:
- part = part[:20]+"..."+part[-20:]
- if ' ' in part or '\n' in part or '"' in part or "'" in part:
- part = '"%s"' % part.replace('"', '\\"')
- if hasattr(part, 'decode'):
- try:
- part = part.decode(sys.getdefaultencoding())
- except UnicodeDecodeError:
- part = part.decode(sys.getfilesystemencoding())
- cmd_parts.append(part)
- cmd_desc = ' '.join(cmd_parts)
- if show_stdout:
- stdout = None
- else:
- stdout = subprocess.PIPE
- logger.debug("Running command %s" % cmd_desc)
- if extra_env or remove_from_env:
- env = os.environ.copy()
- if extra_env:
- env.update(extra_env)
- if remove_from_env:
- for varname in remove_from_env:
- env.pop(varname, None)
- else:
- env = None
- try:
- proc = subprocess.Popen(
- cmd, stderr=subprocess.STDOUT,
- stdin=None if stdin is None else subprocess.PIPE,
- stdout=stdout,
- cwd=cwd, env=env)
- except Exception:
- e = sys.exc_info()[1]
- logger.fatal(
- "Error %s while executing command %s" % (e, cmd_desc))
- raise
- all_output = []
- if stdout is not None:
- if stdin is not None:
- proc.stdin.write(stdin)
- proc.stdin.close()
-
- stdout = proc.stdout
- encoding = sys.getdefaultencoding()
- fs_encoding = sys.getfilesystemencoding()
- while 1:
- line = stdout.readline()
- try:
- line = line.decode(encoding)
- except UnicodeDecodeError:
- line = line.decode(fs_encoding)
- if not line:
- break
- line = line.rstrip()
- all_output.append(line)
- if filter_stdout:
- level = filter_stdout(line)
- if isinstance(level, tuple):
- level, line = level
- logger.log(level, line)
- if not logger.stdout_level_matches(level):
- logger.show_progress()
- else:
- logger.info(line)
- else:
- proc.communicate(stdin)
- proc.wait()
- if proc.returncode:
- if raise_on_returncode:
- if all_output:
- logger.notify('Complete output from command %s:' % cmd_desc)
- logger.notify('\n'.join(all_output) + '\n----------------------------------------')
- raise OSError(
- "Command %s failed with error code %s"
- % (cmd_desc, proc.returncode))
- else:
- logger.warn(
- "Command %s had error code %s"
- % (cmd_desc, proc.returncode))
-
-def filter_install_output(line):
- if line.strip().startswith('running'):
- return Logger.INFO
- return Logger.DEBUG
-
-def find_wheels(projects, search_dirs):
- """Find wheels from which we can import PROJECTS.
-
- Scan through SEARCH_DIRS for a wheel for each PROJECT in turn. Return
- a list of the first wheel found for each PROJECT
- """
-
- wheels = []
-
- # Look through SEARCH_DIRS for the first suitable wheel. Don't bother
- # about version checking here, as this is simply to get something we can
- # then use to install the correct version.
- for project in projects:
- for dirname in search_dirs:
- # This relies on only having "universal" wheels available.
- # The pattern could be tightened to require -py2.py3-none-any.whl.
- files = glob.glob(os.path.join(dirname, project + '-*.whl'))
- if files:
- wheels.append(os.path.abspath(files[0]))
- break
- else:
- # We're out of luck, so quit with a suitable error
- logger.fatal('Cannot find a wheel for %s' % (project,))
-
- return wheels
-
-def install_wheel(project_names, py_executable, search_dirs=None,
- download=False):
- if search_dirs is None:
- search_dirs = file_search_dirs()
-
- wheels = find_wheels(['setuptools', 'pip'], search_dirs)
- pythonpath = os.pathsep.join(wheels)
-
- # PIP_FIND_LINKS uses space as the path separator and thus cannot have paths
- # with spaces in them. Convert any of those to local file:// URL form.
- try:
- from urlparse import urljoin
- from urllib import pathname2url
- except ImportError:
- from urllib.parse import urljoin
- from urllib.request import pathname2url
- def space_path2url(p):
- if ' ' not in p:
- return p
- return urljoin('file:', pathname2url(os.path.abspath(p)))
- findlinks = ' '.join(space_path2url(d) for d in search_dirs)
-
- SCRIPT = textwrap.dedent("""
- import sys
- import pkgutil
- import tempfile
- import os
-
- try:
- from pip._internal import main as _main
- cert_data = pkgutil.get_data("pip._vendor.certifi", "cacert.pem")
- except ImportError:
- from pip import main as _main
- cert_data = pkgutil.get_data("pip._vendor.requests", "cacert.pem")
-
- if cert_data is not None:
- cert_file = tempfile.NamedTemporaryFile(delete=False)
- cert_file.write(cert_data)
- cert_file.close()
- else:
- cert_file = None
-
- try:
- args = ["install", "--ignore-installed"]
- if cert_file is not None:
- args += ["--cert", cert_file.name]
- args += sys.argv[1:]
-
- sys.exit(_main(args))
- finally:
- if cert_file is not None:
- os.remove(cert_file.name)
- """).encode("utf8")
-
- cmd = [py_executable, '-'] + project_names
- logger.start_progress('Installing %s...' % (', '.join(project_names)))
- logger.indent += 2
-
- env = {
- "PYTHONPATH": pythonpath,
- "JYTHONPATH": pythonpath, # for Jython < 3.x
- "PIP_FIND_LINKS": findlinks,
- "PIP_USE_WHEEL": "1",
- "PIP_ONLY_BINARY": ":all:",
- "PIP_USER": "0",
- }
-
- if not download:
- env["PIP_NO_INDEX"] = "1"
-
- try:
- call_subprocess(cmd, show_stdout=False, extra_env=env, stdin=SCRIPT)
- finally:
- logger.indent -= 2
- logger.end_progress()
-
-
-def create_environment(home_dir, site_packages=False, clear=False,
- prompt=None, search_dirs=None, download=False,
- no_setuptools=False, no_pip=False, no_wheel=False,
- symlink=True):
- """
- Creates a new environment in ``home_dir``.
-
- If ``site_packages`` is true, then the global ``site-packages/``
- directory will be on the path.
-
- If ``clear`` is true (default False) then the environment will
- first be cleared.
- """
- home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
-
- py_executable = os.path.abspath(install_python(
- home_dir, lib_dir, inc_dir, bin_dir,
- site_packages=site_packages, clear=clear, symlink=symlink))
-
- install_distutils(home_dir)
-
- to_install = []
-
- if not no_setuptools:
- to_install.append('setuptools')
-
- if not no_pip:
- to_install.append('pip')
-
- if not no_wheel:
- to_install.append('wheel')
-
- if to_install:
- install_wheel(
- to_install,
- py_executable,
- search_dirs,
- download=download,
- )
-
- install_activate(home_dir, bin_dir, prompt)
-
- install_python_config(home_dir, bin_dir, prompt)
-
-def is_executable_file(fpath):
- return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
-
-def path_locations(home_dir):
- """Return the path locations for the environment (where libraries are,
- where scripts go, etc)"""
- home_dir = os.path.abspath(home_dir)
- # XXX: We'd use distutils.sysconfig.get_python_inc/lib but its
- # prefix arg is broken: http://bugs.python.org/issue3386
- if is_win:
- # Windows has lots of problems with executables with spaces in
- # the name; this function will remove them (using the ~1
- # format):
- mkdir(home_dir)
- if ' ' in home_dir:
- import ctypes
- GetShortPathName = ctypes.windll.kernel32.GetShortPathNameW
- size = max(len(home_dir)+1, 256)
- buf = ctypes.create_unicode_buffer(size)
- try:
- u = unicode
- except NameError:
- u = str
- ret = GetShortPathName(u(home_dir), buf, size)
- if not ret:
- print('Error: the path "%s" has a space in it' % home_dir)
- print('We could not determine the short pathname for it.')
- print('Exiting.')
- sys.exit(3)
- home_dir = str(buf.value)
- lib_dir = join(home_dir, 'Lib')
- inc_dir = join(home_dir, 'Include')
- bin_dir = join(home_dir, 'Scripts')
- if is_jython:
- lib_dir = join(home_dir, 'Lib')
- inc_dir = join(home_dir, 'Include')
- bin_dir = join(home_dir, 'bin')
- elif is_pypy:
- lib_dir = home_dir
- inc_dir = join(home_dir, 'include')
- bin_dir = join(home_dir, 'bin')
- elif not is_win:
- lib_dir = join(home_dir, 'lib', py_version)
- inc_dir = join(home_dir, 'include', py_version + abiflags)
- bin_dir = join(home_dir, 'bin')
- return home_dir, lib_dir, inc_dir, bin_dir
-
-
-def change_prefix(filename, dst_prefix):
- prefixes = [sys.prefix]
-
- if is_darwin:
- prefixes.extend((
- os.path.join("/Library/Python", sys.version[:3], "site-packages"),
- os.path.join(sys.prefix, "Extras", "lib", "python"),
- os.path.join("~", "Library", "Python", sys.version[:3], "site-packages"),
- # Python 2.6 no-frameworks
- os.path.join("~", ".local", "lib","python", sys.version[:3], "site-packages"),
- # System Python 2.7 on OSX Mountain Lion
- os.path.join("~", "Library", "Python", sys.version[:3], "lib", "python", "site-packages")))
-
- if hasattr(sys, 'real_prefix'):
- prefixes.append(sys.real_prefix)
- if hasattr(sys, 'base_prefix'):
- prefixes.append(sys.base_prefix)
- prefixes = list(map(os.path.expanduser, prefixes))
- prefixes = list(map(os.path.abspath, prefixes))
- # Check longer prefixes first so we don't split in the middle of a filename
- prefixes = sorted(prefixes, key=len, reverse=True)
- filename = os.path.abspath(filename)
- # On Windows, make sure drive letter is uppercase
- if is_win and filename[0] in 'abcdefghijklmnopqrstuvwxyz':
- filename = filename[0].upper() + filename[1:]
- for i, prefix in enumerate(prefixes):
- if is_win and prefix[0] in 'abcdefghijklmnopqrstuvwxyz':
- prefixes[i] = prefix[0].upper() + prefix[1:]
- for src_prefix in prefixes:
- if filename.startswith(src_prefix):
- _, relpath = filename.split(src_prefix, 1)
- if src_prefix != os.sep: # sys.prefix == "/"
- assert relpath[0] == os.sep
- relpath = relpath[1:]
- return join(dst_prefix, relpath)
- assert False, "Filename %s does not start with any of these prefixes: %s" % \
- (filename, prefixes)
-
-def copy_required_modules(dst_prefix, symlink):
- import imp
-
- for modname in REQUIRED_MODULES:
- if modname in sys.builtin_module_names:
- logger.info("Ignoring built-in bootstrap module: %s" % modname)
- continue
- try:
- f, filename, _ = imp.find_module(modname)
- except ImportError:
- logger.info("Cannot import bootstrap module: %s" % modname)
- else:
- if f is not None:
- f.close()
- # special-case custom readline.so on OS X, but not for pypy:
- if modname == 'readline' and sys.platform == 'darwin' and not (
- is_pypy or filename.endswith(join('lib-dynload', 'readline.so'))):
- dst_filename = join(dst_prefix, 'lib', 'python%s' % sys.version[:3], 'readline.so')
- elif modname == 'readline' and sys.platform == 'win32':
- # special-case for Windows, where readline is not a
- # standard module, though it may have been installed in
- # site-packages by a third-party package
- pass
- else:
- dst_filename = change_prefix(filename, dst_prefix)
- copyfile(filename, dst_filename, symlink)
- if filename.endswith('.pyc'):
- pyfile = filename[:-1]
- if os.path.exists(pyfile):
- copyfile(pyfile, dst_filename[:-1], symlink)
-
-def copy_tcltk(src, dest, symlink):
- """ copy tcl/tk libraries on Windows (issue #93) """
- for libversion in '8.5', '8.6':
- for libname in 'tcl', 'tk':
- srcdir = join(src, 'tcl', libname + libversion)
- destdir = join(dest, 'tcl', libname + libversion)
- # Only copy the dirs from the above combinations that exist
- if os.path.exists(srcdir) and not os.path.exists(destdir):
- copyfileordir(srcdir, destdir, symlink)
-
-
-def subst_path(prefix_path, prefix, home_dir):
- prefix_path = os.path.normpath(prefix_path)
- prefix = os.path.normpath(prefix)
- home_dir = os.path.normpath(home_dir)
- if not prefix_path.startswith(prefix):
- logger.warn('Path not in prefix %r %r', prefix_path, prefix)
- return
- return prefix_path.replace(prefix, home_dir, 1)
-
-
-def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear, symlink=True):
- """Install just the base environment, no distutils patches etc"""
- if sys.executable.startswith(bin_dir):
- print('Please use the *system* python to run this script')
- return
-
- if clear:
- rmtree(lib_dir)
- ## FIXME: why not delete it?
- ## Maybe it should delete everything with #!/path/to/venv/python in it
- logger.notify('Not deleting %s', bin_dir)
-
- if hasattr(sys, 'real_prefix'):
- logger.notify('Using real prefix %r' % sys.real_prefix)
- prefix = sys.real_prefix
- elif hasattr(sys, 'base_prefix'):
- logger.notify('Using base prefix %r' % sys.base_prefix)
- prefix = sys.base_prefix
- else:
- prefix = sys.prefix
- mkdir(lib_dir)
- fix_lib64(lib_dir, symlink)
- stdlib_dirs = [os.path.dirname(os.__file__)]
- if is_win:
- stdlib_dirs.append(join(os.path.dirname(stdlib_dirs[0]), 'DLLs'))
- elif is_darwin:
- stdlib_dirs.append(join(stdlib_dirs[0], 'site-packages'))
- if hasattr(os, 'symlink'):
- logger.info('Symlinking Python bootstrap modules')
- else:
- logger.info('Copying Python bootstrap modules')
- logger.indent += 2
- try:
- # copy required files...
- for stdlib_dir in stdlib_dirs:
- if not os.path.isdir(stdlib_dir):
- continue
- for fn in os.listdir(stdlib_dir):
- bn = os.path.splitext(fn)[0]
- if fn != 'site-packages' and bn in REQUIRED_FILES:
- copyfile(join(stdlib_dir, fn), join(lib_dir, fn), symlink)
- # ...and modules
- copy_required_modules(home_dir, symlink)
- finally:
- logger.indent -= 2
- # ...copy tcl/tk
- if is_win:
- copy_tcltk(prefix, home_dir, symlink)
- mkdir(join(lib_dir, 'site-packages'))
- import site
- site_filename = site.__file__
- if site_filename.endswith('.pyc') or site_filename.endswith('.pyo'):
- site_filename = site_filename[:-1]
- elif site_filename.endswith('$py.class'):
- site_filename = site_filename.replace('$py.class', '.py')
- site_filename_dst = change_prefix(site_filename, home_dir)
- site_dir = os.path.dirname(site_filename_dst)
- writefile(site_filename_dst, SITE_PY)
- writefile(join(site_dir, 'orig-prefix.txt'), prefix)
- site_packages_filename = join(site_dir, 'no-global-site-packages.txt')
- if not site_packages:
- writefile(site_packages_filename, '')
-
- if is_pypy or is_win:
- stdinc_dir = join(prefix, 'include')
- else:
- stdinc_dir = join(prefix, 'include', py_version + abiflags)
- if os.path.exists(stdinc_dir):
- copyfile(stdinc_dir, inc_dir, symlink)
- else:
- logger.debug('No include dir %s' % stdinc_dir)
-
- platinc_dir = distutils.sysconfig.get_python_inc(plat_specific=1)
- if platinc_dir != stdinc_dir:
- platinc_dest = distutils.sysconfig.get_python_inc(
- plat_specific=1, prefix=home_dir)
- if platinc_dir == platinc_dest:
- # Do platinc_dest manually due to a CPython bug;
- # not http://bugs.python.org/issue3386 but a close cousin
- platinc_dest = subst_path(platinc_dir, prefix, home_dir)
- if platinc_dest:
- # PyPy's stdinc_dir and prefix are relative to the original binary
- # (traversing virtualenvs), whereas the platinc_dir is relative to
- # the inner virtualenv and ignores the prefix argument.
- # This seems more evolved than designed.
- copyfile(platinc_dir, platinc_dest, symlink)
-
- # pypy never uses exec_prefix, just ignore it
- if sys.exec_prefix != prefix and not is_pypy:
- if is_win:
- exec_dir = join(sys.exec_prefix, 'lib')
- elif is_jython:
- exec_dir = join(sys.exec_prefix, 'Lib')
- else:
- exec_dir = join(sys.exec_prefix, 'lib', py_version)
- for fn in os.listdir(exec_dir):
- copyfile(join(exec_dir, fn), join(lib_dir, fn), symlink)
-
- if is_jython:
- # Jython has either jython-dev.jar and javalib/ dir, or just
- # jython.jar
- for name in 'jython-dev.jar', 'javalib', 'jython.jar':
- src = join(prefix, name)
- if os.path.exists(src):
- copyfile(src, join(home_dir, name), symlink)
- # XXX: registry should always exist after Jython 2.5rc1
- src = join(prefix, 'registry')
- if os.path.exists(src):
- copyfile(src, join(home_dir, 'registry'), symlink=False)
- copyfile(join(prefix, 'cachedir'), join(home_dir, 'cachedir'),
- symlink=False)
-
- mkdir(bin_dir)
- py_executable = join(bin_dir, os.path.basename(sys.executable))
- if 'Python.framework' in prefix:
- # OS X framework builds cause validation to break
- # https://github.com/pypa/virtualenv/issues/322
- if os.environ.get('__PYVENV_LAUNCHER__'):
- del os.environ["__PYVENV_LAUNCHER__"]
- if re.search(r'/Python(?:-32|-64)*$', py_executable):
- # The name of the python executable is not quite what
- # we want, rename it.
- py_executable = os.path.join(
- os.path.dirname(py_executable), 'python')
-
- logger.notify('New %s executable in %s', expected_exe, py_executable)
- pcbuild_dir = os.path.dirname(sys.executable)
- pyd_pth = os.path.join(lib_dir, 'site-packages', 'virtualenv_builddir_pyd.pth')
- if is_win and os.path.exists(os.path.join(pcbuild_dir, 'build.bat')):
- logger.notify('Detected python running from build directory %s', pcbuild_dir)
- logger.notify('Writing .pth file linking to build directory for *.pyd files')
- writefile(pyd_pth, pcbuild_dir)
- else:
- pcbuild_dir = None
- if os.path.exists(pyd_pth):
- logger.info('Deleting %s (not Windows env or not build directory python)' % pyd_pth)
- os.unlink(pyd_pth)
-
- if sys.executable != py_executable:
- ## FIXME: could I just hard link?
- executable = sys.executable
- shutil.copyfile(executable, py_executable)
- make_exe(py_executable)
- if is_win or is_cygwin:
- pythonw = os.path.join(os.path.dirname(sys.executable), 'pythonw.exe')
- if os.path.exists(pythonw):
- logger.info('Also created pythonw.exe')
- shutil.copyfile(pythonw, os.path.join(os.path.dirname(py_executable), 'pythonw.exe'))
- python_d = os.path.join(os.path.dirname(sys.executable), 'python_d.exe')
- python_d_dest = os.path.join(os.path.dirname(py_executable), 'python_d.exe')
- if os.path.exists(python_d):
- logger.info('Also created python_d.exe')
- shutil.copyfile(python_d, python_d_dest)
- elif os.path.exists(python_d_dest):
- logger.info('Removed python_d.exe as it is no longer at the source')
- os.unlink(python_d_dest)
-
- # we need to copy the DLL to enforce that windows will load the correct one.
- # may not exist if we are cygwin.
- if is_pypy:
- py_executable_dlls = [
- (
- 'libpypy-c.dll',
- 'libpypy_d-c.dll',
- ),
- ]
- else:
- py_executable_dlls = [
- (
- 'python%s.dll' % (sys.version_info[0]),
- 'python%s_d.dll' % (sys.version_info[0])
- ),
- (
- 'python%s%s.dll' % (sys.version_info[0], sys.version_info[1]),
- 'python%s%s_d.dll' % (sys.version_info[0], sys.version_info[1])
- )
- ]
-
- for py_executable_dll, py_executable_dll_d in py_executable_dlls:
- pythondll = os.path.join(os.path.dirname(sys.executable), py_executable_dll)
- pythondll_d = os.path.join(os.path.dirname(sys.executable), py_executable_dll_d)
- pythondll_d_dest = os.path.join(os.path.dirname(py_executable), py_executable_dll_d)
- if os.path.exists(pythondll):
- logger.info('Also created %s' % py_executable_dll)
- shutil.copyfile(pythondll, os.path.join(os.path.dirname(py_executable), py_executable_dll))
- if os.path.exists(pythondll_d):
- logger.info('Also created %s' % py_executable_dll_d)
- shutil.copyfile(pythondll_d, pythondll_d_dest)
- elif os.path.exists(pythondll_d_dest):
- logger.info('Removed %s as the source does not exist' % pythondll_d_dest)
- os.unlink(pythondll_d_dest)
- if is_pypy:
- # make a symlink python --> pypy-c
- python_executable = os.path.join(os.path.dirname(py_executable), 'python')
- if sys.platform in ('win32', 'cygwin'):
- python_executable += '.exe'
- logger.info('Also created executable %s' % python_executable)
- copyfile(py_executable, python_executable, symlink)
-
- if is_win:
- for name in ['libexpat.dll',
- 'libeay32.dll', 'ssleay32.dll', 'sqlite3.dll',
- 'tcl85.dll', 'tk85.dll']:
- src = join(prefix, name)
- if os.path.exists(src):
- copyfile(src, join(bin_dir, name), symlink)
-
- for d in sys.path:
- if d.endswith('lib_pypy'):
- break
- else:
- logger.fatal('Could not find lib_pypy in sys.path')
- raise SystemExit(3)
- logger.info('Copying lib_pypy')
- copyfile(d, os.path.join(home_dir, 'lib_pypy'), symlink)
-
- if os.path.splitext(os.path.basename(py_executable))[0] != expected_exe:
- secondary_exe = os.path.join(os.path.dirname(py_executable),
- expected_exe)
- py_executable_ext = os.path.splitext(py_executable)[1]
- if py_executable_ext.lower() == '.exe':
- # python2.4 gives an extension of '.4' :P
- secondary_exe += py_executable_ext
- if os.path.exists(secondary_exe):
- logger.warn('Not overwriting existing %s script %s (you must use %s)'
- % (expected_exe, secondary_exe, py_executable))
- else:
- logger.notify('Also creating executable in %s' % secondary_exe)
- shutil.copyfile(sys.executable, secondary_exe)
- make_exe(secondary_exe)
-
- if '.framework' in prefix:
- if 'Python.framework' in prefix:
- logger.debug('MacOSX Python framework detected')
- # Make sure we use the embedded interpreter inside
- # the framework, even if sys.executable points to
- # the stub executable in ${sys.prefix}/bin
- # See http://groups.google.com/group/python-virtualenv/
- # browse_thread/thread/17cab2f85da75951
- original_python = os.path.join(
- prefix, 'Resources/Python.app/Contents/MacOS/Python')
- if 'EPD' in prefix:
- logger.debug('EPD framework detected')
- original_python = os.path.join(prefix, 'bin/python')
- shutil.copy(original_python, py_executable)
-
- # Copy the framework's dylib into the virtual
- # environment
- virtual_lib = os.path.join(home_dir, '.Python')
-
- if os.path.exists(virtual_lib):
- os.unlink(virtual_lib)
- copyfile(
- os.path.join(prefix, 'Python'),
- virtual_lib,
- symlink)
-
- # And then change the install_name of the copied python executable
- try:
- mach_o_change(py_executable,
- os.path.join(prefix, 'Python'),
- '@executable_path/../.Python')
- except:
- e = sys.exc_info()[1]
- logger.warn("Could not call mach_o_change: %s. "
- "Trying to call install_name_tool instead." % e)
- try:
- call_subprocess(
- ["install_name_tool", "-change",
- os.path.join(prefix, 'Python'),
- '@executable_path/../.Python',
- py_executable])
- except:
- logger.fatal("Could not call install_name_tool -- you must "
- "have Apple's development tools installed")
- raise
-
- if not is_win:
- # Ensure that 'python', 'pythonX' and 'pythonX.Y' all exist
- py_exe_version_major = 'python%s' % sys.version_info[0]
- py_exe_version_major_minor = 'python%s.%s' % (
- sys.version_info[0], sys.version_info[1])
- py_exe_no_version = 'python'
- required_symlinks = [ py_exe_no_version, py_exe_version_major,
- py_exe_version_major_minor ]
-
- py_executable_base = os.path.basename(py_executable)
-
- if py_executable_base in required_symlinks:
- # Don't try to symlink to yourself.
- required_symlinks.remove(py_executable_base)
-
- for pth in required_symlinks:
- full_pth = join(bin_dir, pth)
- if os.path.exists(full_pth):
- os.unlink(full_pth)
- if symlink:
- os.symlink(py_executable_base, full_pth)
- else:
- copyfile(py_executable, full_pth, symlink)
-
- cmd = [py_executable, '-c', 'import sys;out=sys.stdout;'
- 'getattr(out, "buffer", out).write(sys.prefix.encode("utf-8"))']
- logger.info('Testing executable with %s %s "%s"' % tuple(cmd))
- try:
- proc = subprocess.Popen(cmd,
- stdout=subprocess.PIPE)
- proc_stdout, proc_stderr = proc.communicate()
- except OSError:
- e = sys.exc_info()[1]
- if e.errno == errno.EACCES:
- logger.fatal('ERROR: The executable %s could not be run: %s' % (py_executable, e))
- sys.exit(100)
- else:
- raise e
-
- proc_stdout = proc_stdout.strip().decode("utf-8")
- proc_stdout = os.path.normcase(os.path.abspath(proc_stdout))
- norm_home_dir = os.path.normcase(os.path.abspath(home_dir))
- if hasattr(norm_home_dir, 'decode'):
- norm_home_dir = norm_home_dir.decode(sys.getfilesystemencoding())
- if proc_stdout != norm_home_dir:
- logger.fatal(
- 'ERROR: The executable %s is not functioning' % py_executable)
- logger.fatal(
- 'ERROR: It thinks sys.prefix is %r (should be %r)'
- % (proc_stdout, norm_home_dir))
- logger.fatal(
- 'ERROR: virtualenv is not compatible with this system or executable')
- if is_win:
- logger.fatal(
- 'Note: some Windows users have reported this error when they '
- 'installed Python for "Only this user" or have multiple '
- 'versions of Python installed. Copying the appropriate '
- 'PythonXX.dll to the virtualenv Scripts/ directory may fix '
- 'this problem.')
- sys.exit(100)
- else:
- logger.info('Got sys.prefix result: %r' % proc_stdout)
-
- pydistutils = os.path.expanduser('~/.pydistutils.cfg')
- if os.path.exists(pydistutils):
- logger.notify('Please make sure you remove any previous custom paths from '
- 'your %s file.' % pydistutils)
- ## FIXME: really this should be calculated earlier
-
- fix_local_scheme(home_dir, symlink)
-
- if site_packages:
- if os.path.exists(site_packages_filename):
- logger.info('Deleting %s' % site_packages_filename)
- os.unlink(site_packages_filename)
-
- return py_executable
-
-
-def install_activate(home_dir, bin_dir, prompt=None):
- if is_win or is_jython and os._name == 'nt':
- files = {
- 'activate.bat': ACTIVATE_BAT,
- 'deactivate.bat': DEACTIVATE_BAT,
- 'activate.ps1': ACTIVATE_PS,
- }
-
- # MSYS needs paths of the form /c/path/to/file
- drive, tail = os.path.splitdrive(home_dir.replace(os.sep, '/'))
- home_dir_msys = (drive and "/%s%s" or "%s%s") % (drive[:1], tail)
-
- # Run-time conditional enables (basic) Cygwin compatibility
- home_dir_sh = ("""$(if [ "$OSTYPE" "==" "cygwin" ]; then cygpath -u '%s'; else echo '%s'; fi;)""" %
- (home_dir, home_dir_msys))
- files['activate'] = ACTIVATE_SH.replace('__VIRTUAL_ENV__', home_dir_sh)
-
- else:
- files = {'activate': ACTIVATE_SH}
-
- # suppling activate.fish in addition to, not instead of, the
- # bash script support.
- files['activate.fish'] = ACTIVATE_FISH
-
- # same for csh/tcsh support...
- files['activate.csh'] = ACTIVATE_CSH
-
- files['activate_this.py'] = ACTIVATE_THIS
-
- install_files(home_dir, bin_dir, prompt, files)
-
-def install_files(home_dir, bin_dir, prompt, files):
- if hasattr(home_dir, 'decode'):
- home_dir = home_dir.decode(sys.getfilesystemencoding())
- vname = os.path.basename(home_dir)
- for name, content in files.items():
- content = content.replace('__VIRTUAL_PROMPT__', prompt or '')
- content = content.replace('__VIRTUAL_WINPROMPT__', prompt or '(%s)' % vname)
- content = content.replace('__VIRTUAL_ENV__', home_dir)
- content = content.replace('__VIRTUAL_NAME__', vname)
- content = content.replace('__BIN_NAME__', os.path.basename(bin_dir))
- writefile(os.path.join(bin_dir, name), content)
-
-def install_python_config(home_dir, bin_dir, prompt=None):
- if sys.platform == 'win32' or is_jython and os._name == 'nt':
- files = {}
- else:
- files = {'python-config': PYTHON_CONFIG}
- install_files(home_dir, bin_dir, prompt, files)
- for name, content in files.items():
- make_exe(os.path.join(bin_dir, name))
-
-def install_distutils(home_dir):
- distutils_path = change_prefix(distutils.__path__[0], home_dir)
- mkdir(distutils_path)
- ## FIXME: maybe this prefix setting should only be put in place if
- ## there's a local distutils.cfg with a prefix setting?
- home_dir = os.path.abspath(home_dir)
- ## FIXME: this is breaking things, removing for now:
- #distutils_cfg = DISTUTILS_CFG + "\n[install]\nprefix=%s\n" % home_dir
- writefile(os.path.join(distutils_path, '__init__.py'), DISTUTILS_INIT)
- writefile(os.path.join(distutils_path, 'distutils.cfg'), DISTUTILS_CFG, overwrite=False)
-
-def fix_local_scheme(home_dir, symlink=True):
- """
- Platforms that use the "posix_local" install scheme (like Ubuntu with
- Python 2.7) need to be given an additional "local" location, sigh.
- """
- try:
- import sysconfig
- except ImportError:
- pass
- else:
- if sysconfig._get_default_scheme() == 'posix_local':
- local_path = os.path.join(home_dir, 'local')
- if not os.path.exists(local_path):
- os.mkdir(local_path)
- for subdir_name in os.listdir(home_dir):
- if subdir_name == 'local':
- continue
- copyfile(os.path.abspath(os.path.join(home_dir, subdir_name)), \
- os.path.join(local_path, subdir_name), symlink)
-
-def fix_lib64(lib_dir, symlink=True):
- """
- Some platforms (particularly Gentoo on x64) put things in lib64/pythonX.Y
- instead of lib/pythonX.Y. If this is such a platform we'll just create a
- symlink so lib64 points to lib
- """
- # PyPy's library path scheme is not affected by this.
- # Return early or we will die on the following assert.
- if is_pypy:
- logger.debug('PyPy detected, skipping lib64 symlinking')
- return
- # Check we have a lib64 library path
- if not [p for p in distutils.sysconfig.get_config_vars().values()
- if isinstance(p, basestring) and 'lib64' in p]:
- return
-
- logger.debug('This system uses lib64; symlinking lib64 to lib')
-
- assert os.path.basename(lib_dir) == 'python%s' % sys.version[:3], (
- "Unexpected python lib dir: %r" % lib_dir)
- lib_parent = os.path.dirname(lib_dir)
- top_level = os.path.dirname(lib_parent)
- lib_dir = os.path.join(top_level, 'lib')
- lib64_link = os.path.join(top_level, 'lib64')
- assert os.path.basename(lib_parent) == 'lib', (
- "Unexpected parent dir: %r" % lib_parent)
- if os.path.lexists(lib64_link):
- return
- if symlink:
- os.symlink('lib', lib64_link)
- else:
- copyfile('lib', lib64_link)
-
-def resolve_interpreter(exe):
- """
- If the executable given isn't an absolute path, search $PATH for the interpreter
- """
- # If the "executable" is a version number, get the installed executable for
- # that version
- orig_exe = exe
- python_versions = get_installed_pythons()
- if exe in python_versions:
- exe = python_versions[exe]
-
- if os.path.abspath(exe) != exe:
- exe = distutils.spawn.find_executable(exe) or exe
- if not os.path.exists(exe):
- logger.fatal('The path %s (from --python=%s) does not exist' % (exe, orig_exe))
- raise SystemExit(3)
- if not is_executable(exe):
- logger.fatal('The path %s (from --python=%s) is not an executable file' % (exe, orig_exe))
- raise SystemExit(3)
- return exe
-
-def is_executable(exe):
- """Checks a file is executable"""
- return os.path.isfile(exe) and os.access(exe, os.X_OK)
-
-############################################################
-## Relocating the environment:
-
-def make_environment_relocatable(home_dir):
- """
- Makes the already-existing environment use relative paths, and takes out
- the #!-based environment selection in scripts.
- """
- home_dir, lib_dir, inc_dir, bin_dir = path_locations(home_dir)
- activate_this = os.path.join(bin_dir, 'activate_this.py')
- if not os.path.exists(activate_this):
- logger.fatal(
- 'The environment doesn\'t have a file %s -- please re-run virtualenv '
- 'on this environment to update it' % activate_this)
- fixup_scripts(home_dir, bin_dir)
- fixup_pth_and_egg_link(home_dir)
- ## FIXME: need to fix up distutils.cfg
-
-OK_ABS_SCRIPTS = ['python', 'python%s' % sys.version[:3],
- 'activate', 'activate.bat', 'activate_this.py',
- 'activate.fish', 'activate.csh']
-
-def fixup_scripts(home_dir, bin_dir):
- if is_win:
- new_shebang_args = (
- '%s /c' % os.path.normcase(os.environ.get('COMSPEC', 'cmd.exe')),
- '', '.exe')
- else:
- new_shebang_args = ('/usr/bin/env', sys.version[:3], '')
-
- # This is what we expect at the top of scripts:
- shebang = '#!%s' % os.path.normcase(os.path.join(
- os.path.abspath(bin_dir), 'python%s' % new_shebang_args[2]))
- # This is what we'll put:
- new_shebang = '#!%s python%s%s' % new_shebang_args
-
- for filename in os.listdir(bin_dir):
- filename = os.path.join(bin_dir, filename)
- if not os.path.isfile(filename):
- # ignore subdirs, e.g. .svn ones.
- continue
- lines = None
- with open(filename, 'rb') as f:
- try:
- lines = f.read().decode('utf-8').splitlines()
- except UnicodeDecodeError:
- # This is probably a binary program instead
- # of a script, so just ignore it.
- continue
- if not lines:
- logger.warn('Script %s is an empty file' % filename)
- continue
-
- old_shebang = lines[0].strip()
- old_shebang = old_shebang[0:2] + os.path.normcase(old_shebang[2:])
-
- if not old_shebang.startswith(shebang):
- if os.path.basename(filename) in OK_ABS_SCRIPTS:
- logger.debug('Cannot make script %s relative' % filename)
- elif lines[0].strip() == new_shebang:
- logger.info('Script %s has already been made relative' % filename)
- else:
- logger.warn('Script %s cannot be made relative (it\'s not a normal script that starts with %s)'
- % (filename, shebang))
- continue
- logger.notify('Making script %s relative' % filename)
- script = relative_script([new_shebang] + lines[1:])
- with open(filename, 'wb') as f:
- f.write('\n'.join(script).encode('utf-8'))
-
-
-def relative_script(lines):
- "Return a script that'll work in a relocatable environment."
- activate = "import os; activate_this=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'activate_this.py'); exec(compile(open(activate_this).read(), activate_this, 'exec'), dict(__file__=activate_this)); del os, activate_this"
- # Find the last future statement in the script. If we insert the activation
- # line before a future statement, Python will raise a SyntaxError.
- activate_at = None
- for idx, line in reversed(list(enumerate(lines))):
- if line.split()[:3] == ['from', '__future__', 'import']:
- activate_at = idx + 1
- break
- if activate_at is None:
- # Activate after the shebang.
- activate_at = 1
- return lines[:activate_at] + ['', activate, ''] + lines[activate_at:]
-
-def fixup_pth_and_egg_link(home_dir, sys_path=None):
- """Makes .pth and .egg-link files use relative paths"""
- home_dir = os.path.normcase(os.path.abspath(home_dir))
- if sys_path is None:
- sys_path = sys.path
- for path in sys_path:
- if not path:
- path = '.'
- if not os.path.isdir(path):
- continue
- path = os.path.normcase(os.path.abspath(path))
- if not path.startswith(home_dir):
- logger.debug('Skipping system (non-environment) directory %s' % path)
- continue
- for filename in os.listdir(path):
- filename = os.path.join(path, filename)
- if filename.endswith('.pth'):
- if not os.access(filename, os.W_OK):
- logger.warn('Cannot write .pth file %s, skipping' % filename)
- else:
- fixup_pth_file(filename)
- if filename.endswith('.egg-link'):
- if not os.access(filename, os.W_OK):
- logger.warn('Cannot write .egg-link file %s, skipping' % filename)
- else:
- fixup_egg_link(filename)
-
-def fixup_pth_file(filename):
- lines = []
- prev_lines = []
- with open(filename) as f:
- prev_lines = f.readlines()
- for line in prev_lines:
- line = line.strip()
- if (not line or line.startswith('#') or line.startswith('import ')
- or os.path.abspath(line) != line):
- lines.append(line)
- else:
- new_value = make_relative_path(filename, line)
- if line != new_value:
- logger.debug('Rewriting path %s as %s (in %s)' % (line, new_value, filename))
- lines.append(new_value)
- if lines == prev_lines:
- logger.info('No changes to .pth file %s' % filename)
- return
- logger.notify('Making paths in .pth file %s relative' % filename)
- with open(filename, 'w') as f:
- f.write('\n'.join(lines) + '\n')
-
-def fixup_egg_link(filename):
- with open(filename) as f:
- link = f.readline().strip()
- if os.path.abspath(link) != link:
- logger.debug('Link in %s already relative' % filename)
- return
- new_link = make_relative_path(filename, link)
- logger.notify('Rewriting link %s in %s as %s' % (link, filename, new_link))
- with open(filename, 'w') as f:
- f.write(new_link)
-
-def make_relative_path(source, dest, dest_is_directory=True):
- """
- Make a filename relative, where the filename is dest, and it is
- being referred to from the filename source.
-
- >>> make_relative_path('/usr/share/something/a-file.pth',
- ... '/usr/share/another-place/src/Directory')
- '../another-place/src/Directory'
- >>> make_relative_path('/usr/share/something/a-file.pth',
- ... '/home/user/src/Directory')
- '../../../home/user/src/Directory'
- >>> make_relative_path('/usr/share/a-file.pth', '/usr/share/')
- './'
- """
- source = os.path.dirname(source)
- if not dest_is_directory:
- dest_filename = os.path.basename(dest)
- dest = os.path.dirname(dest)
- dest = os.path.normpath(os.path.abspath(dest))
- source = os.path.normpath(os.path.abspath(source))
- dest_parts = dest.strip(os.path.sep).split(os.path.sep)
- source_parts = source.strip(os.path.sep).split(os.path.sep)
- while dest_parts and source_parts and dest_parts[0] == source_parts[0]:
- dest_parts.pop(0)
- source_parts.pop(0)
- full_parts = ['..']*len(source_parts) + dest_parts
- if not dest_is_directory:
- full_parts.append(dest_filename)
- if not full_parts:
- # Special case for the current directory (otherwise it'd be '')
- return './'
- return os.path.sep.join(full_parts)
-
-
-
-############################################################
-## Bootstrap script creation:
-
-def create_bootstrap_script(extra_text, python_version=''):
- """
- Creates a bootstrap script, which is like this script but with
- extend_parser, adjust_options, and after_install hooks.
-
- This returns a string that (written to disk of course) can be used
- as a bootstrap script with your own customizations. The script
- will be the standard virtualenv.py script, with your extra text
- added (your extra text should be Python code).
-
- If you include these functions, they will be called:
-
- ``extend_parser(optparse_parser)``:
- You can add or remove options from the parser here.
-
- ``adjust_options(options, args)``:
- You can change options here, or change the args (if you accept
- different kinds of arguments, be sure you modify ``args`` so it is
- only ``[DEST_DIR]``).
-
- ``after_install(options, home_dir)``:
-
- After everything is installed, this function is called. This
- is probably the function you are most likely to use. An
- example would be::
-
- def after_install(options, home_dir):
- subprocess.call([join(home_dir, 'bin', 'easy_install'),
- 'MyPackage'])
- subprocess.call([join(home_dir, 'bin', 'my-package-script'),
- 'setup', home_dir])
-
- This example immediately installs a package, and runs a setup
- script from that package.
-
- If you provide something like ``python_version='2.5'`` then the
- script will start with ``#!/usr/bin/env python2.5`` instead of
- ``#!/usr/bin/env python``. You can use this when the script must
- be run with a particular Python version.
- """
- filename = __file__
- if filename.endswith('.pyc'):
- filename = filename[:-1]
- with codecs.open(filename, 'r', encoding='utf-8') as f:
- content = f.read()
- py_exe = 'python%s' % python_version
- content = (('#!/usr/bin/env %s\n' % py_exe)
- + '## WARNING: This file is generated\n'
- + content)
- return content.replace('##EXT' 'END##', extra_text)
-
-##EXTEND##
-
-def convert(s):
- b = base64.b64decode(s.encode('ascii'))
- return zlib.decompress(b).decode('utf-8')
-
-##file site.py
-SITE_PY = convert("""
-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
-AVijEPwfucjncQ==
-""")
-
-##file activate.sh
-ACTIVATE_SH = convert("""
-eJytVd9v2kAMfs9fYQLq2m4MscdNVKMqEkgtVIQxbeuUHolpTgsXdHehpT/+9/mSEBJS2MOaB0ji
-z77P9menDpOAK5jzEGERKw0zhFihD/dcB2CrKJYewoyLFvM0XzGNNpzOZbSAGVPBqVWHdRSDx4SI
-NMhYANfgc4meDteW5ePGC45P4MkCumKhUENzDsu1H3lw1vJx1RJxGMKns6O2lWDqINGgotAHFCsu
-I7FAoWHFJGezEFWGqsEvaD5C42naHb93X+A3+elYCgVaxgh8DmQAys9HL2SS0mIaWBgm7mTN/O3G
-kzu6vHCng/HkW/fSve5O+hTOpnhfQAcoEry5jKVjNypoO0fgwzKSOgHm79KUK06Jfc7/RebHpD8a
-9kdXvT2UcnuFWG6p0stNB0mWUUQ1q3uiGRVEMfXHR03dTuQATPjwqIIPcB9wL4CArRAY/ZHJixYL
-Y9YBtcAoLQtFevOoI9QaHcEdMSAB0d08kuZhyUiSmav6CPCdVBnFOjNrLu6yMCWgKRA0TInBC5i4
-QwX3JG/mm581GKnSsSSxJTFHf9MAKr8w5T/vOv1mUurn5/zlT6fvTntjZzAaNl9rQ5JkU5KIc0GX
-inagwU57T2eddqWlTrvaS6d9sImZeUMkhWysveF0m37NcGub9Dpgi0j4qGiOzATjDr06OBjOYQOo
-7RBoGtNm9Denv1i0LVI7lxJDXLHSSBeWRflsyyqw7diuW3h0XdvK6lBMyaoMG1UyHdTsoYBuue75
-YOgOu1c91/2cwYpznPPeDoQpGL2xSm09NKp7BsvQ2hnT3aMs07lUnskpxewvBk73/LLnXo9HV9eT
-ijB3hWBO2ygoiWg/bKuZxqCCQq0DD3vkWIVvI2KosIw+vqW1gIItEG5KJb+xb09g65ktwYKgTc51
-uGJ/EFQs0ayEWLCQM5V9N4g+1+8UbXOJzF8bqhKtIqIwicWvzNFROZJlpfD8A7Vc044R0FxkcezG
-VzsV75usvTdYef+57v5n1b225qhXfwEmxHEs
-""")
-
-##file activate.fish
-ACTIVATE_FISH = convert("""
-eJyFVVFv2zYQftevuMoOnBS1gr0WGIZ08RADSRw4boBhGGhGOsUcKFIjKbUu9uN7lC2JsrXWDzZM
-fnf38e6+uwlsdsJCLiRCUVkHrwiVxYy+hHqDbQKvQl3z1ImaO0xyYXdbeP9FuJ1QwMFUSnmcP4dL
-2DlXfry+9v/sDqVMUl3AFVi0Vmj1PokmcKtBaecNQTjIhMHUyX0SRXmlKIpWkGEbDuYZzBZfCVcL
-4youUdVQ6AyBqwwMusoocBrcDsmpKbgEQgijVYHKJbMI6DMhoEUHWmbhLdTcCP4q0TYokYNDev5c
-QTxlq/tb9rJcbz7f3LOnm81d3GD8x3uav30FfwrnwCEOYRyAKot+FvXPzd3q8W71sBiJ3d2dMugu
-fsxjCPsBmz+Wz3fsab16eNqw1ctivV7eBnwm8EzeuQIsSrcHqVMqwHbqq8/aarKSO+oYKhKXUn9p
-SmWw0DVBdQ7bBlwaTR62bc+1tpaYb5PhUyScu48CRgvDLQbtMrMnMQ6dY5022JDRRrwJxWUfJwwP
-ge0YIAVGfcUC1M8s8MxitFZjmR9W64hui7p4fBlWMZ5y81b/9cvfMbz7FWZKq4yOTeW1hbNBEWU+
-b+/ejXMu95lOx696uXb8Go4T+Kw8R2EMSqx5KLkkCkQ+ZBZFbZsHL4OYseAvY3EPO5MYTBuhDZQa
-TwPza8Y+LR/Z483Dgjwd4R3f7bTXx9Znkw6T6PAL83/hRD3jNAKFjuEx9NJkq5t+fabLvdvRwbw4
-nEFTzwO6U+q34cvY7fL55tP94tg58XEA/q7LfdPsaUXFoEIMJdHF5iSW0+48CnDQ82G7n3XzAD6q
-Bmo5XuOA0NQ67ir7AXJtQhtLKO7XhC0l39PGOBsHPvzBuHUSjoOnA0ldozGC9gZ5rek3+y3ALHO/
-kT7AP379lQZLSnFDLtwWihfYxw4nZd+ZR7myfkI2ZTRCuRxmF/bCzkbhcElvYamW9PbDGrvqPKC0
-+D/uLi/sFcxGjOHylYagZzzsjjhw206RQwrWIwOxS2dnk+40xOjX8bTPegz/gdWVSXuaowNuOLda
-wYyNuRPSTcd/B48Ppeg=
-""")
-
-##file activate.csh
-ACTIVATE_CSH = convert("""
-eJx1U2FP2zAQ/e5f8TAV3Soo+0zXbYUiDQkKQgVp2ibjJNfFUuIg22nVf885SVFLO3+I7Lt3fr6X
-d8eY58ZjYQpCWfuAhFB7yrAyIYf0Ve1SQmLsuU6DWepAw9TnEoOFq0rwdjAUx/hV1Ui1tVWAqy1M
-QGYcpaFYx+yVI67LkKwx1UuTEaYGl4X2Bl+zJpAlP/6V2hTDtCq/DYXQhdEeGW040Q/Eb+t9V/e3
-U/V88zh/mtyqh8n8J47G+IKTE3gKZJdoYrK3h5MRU1tGYS83gqNc+3yEgyyP93cP820evHLvr2H8
-kaYB/peoyY7aVHzpJnE9e+6I5Z+ji4GMTNJWNuOQq6MA1N25p8pW9HWdVWlfsNpPDbdxjgpaahuw
-1M7opCA/FFu1uwxC7L8KUqmto1KyQe3rx0I0Eovdf7BVe67U5c1MzSZ310pddGheZoFPWyytRkzU
-aCA/I+RkBXhFXr5aWV0SxjhUI6jwdAj8kmhPzX7nTfJFkM3MImp2VdVFFq1vLHSU5szYQK4Ri+Jd
-xlW2JBtOGcyYVW7SnB3v6RS91g3gKapZ0oWxbHVteYIIq3iv7QeuSrUj6KSqQ+yqsxDj1ivNQxKF
-YON10Q+NH/ARS95i5Tuqq2Vxfvc23f/FO6zrtXXmJr+ZtMY9/A15ZXFWtmch2rEQ4g1ryVHH
-""")
-
-##file activate.bat
-ACTIVATE_BAT = convert("""
-eJx9Ul9LhEAQfxf8DoOclI/dYyFkaCmcq4gZQTBUrincuZFbff12T133TM+nnd35/Zvxlr7XDFhV
-mUZHOVhFlOWP3g4DUriIWoVomYZpNBWUtGpaWgImO191pFkSpzlcmgaI70jVX7n2Qp8tuByg+46O
-CMHbMq64T+nmlJt082D1T44muCDk2prgEHF4mdI9RaS/QwSt3zSyIAaftRccvqVTBziD1x/WlPD5
-xd729NDBb8Nr4DU9QNMKsJeH9pkhPedhQsIkDuCDCa6A+NF9IevVFAohkqizdHetg/tkWvPoftWJ
-MCqnOxv7/x7Np6yv9P2Ker5dmX8yNyCkkWnbZy3N5LarczlqL8htx2EM9rQ/2H5BvIsIEi8OEG8U
-+g8CsNTr
-""")
-
-##file deactivate.bat
-DEACTIVATE_BAT = convert("""
-eJyFkN0KgkAUhO8F32EQpHqFQEjQUPAPMaErqVxzId3IrV6/XST/UDx3c86c4WMO5FYysKJQFVVp
-CEfqxsnJ9DI7SA25i20fFqs3HO+GYLsDZ7h8GM3xfLHrg1QNvpSX4CWpQGvokZk4uqrQAjXjyElB
-a5IjCz0r+2dHcehHCe5MZNmB5R7TdqMqECMptHZh6DN/utb7Zs6Cej8OXYE5J04YOKFvD4GkHuJ0
-pilSd1jG6n87tDZ+BUwUOepI6CGSkFMYWf0ihvT33Qj1A+tCkSI=
-""")
-
-##file activate.ps1
-ACTIVATE_PS = convert("""
-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
-rKQDxR6N/rffXv+lROXet/9Q+l9I4D1U
-""")
-
-##file distutils-init.py
-DISTUTILS_INIT = convert("""
-eJytV1uL4zYUfvevOE0ottuMW9q3gVDa3aUMXXbLMlDKMBiNrSTqOJKRlMxkf33PkXyRbGe7Dw2E
-UXTu37lpxLFV2oIyifAncxmOL0xLIfcG+gv80x9VW6maw7o/CANSWWBwFtqeWMPlGY6qPjV8A0bB
-C4eKSTgZ5LRgFeyErMEeOBhbN+Ipgeizhjtnhkn7DdyjuNLPoCS0l/ayQTG0djwZC08cLXozeMss
-aG5EzQ0IScpnWtHSTXuxByV/QCmxE7y+eS0uxWeoheaVVfqSJHiU7Mhhi6gULbOHorshkrEnKxpT
-0n3A8Y8SMpuwZx6aoix3ouFlmW8gHRSkeSJ2g7hU+kiHLDaQw3bmRDaTGfTnty7gPm0FHbIBg9U9
-oh1kZzAFLaue2R6htPCtAda2nGlDSUJ4PZBgCJBGVcwKTAMz/vJiLD+Oin5Z5QlvDPdulC6EsiyE
-NFzb7McNTKJzbJqzphx92VKRFY1idenzmq3K0emRcbWBD0ryqc4NZGmKOOOX9Pz5x+/l27tP797c
-f/z0d+4NruGNai8uAM0bfsYaw8itFk8ny41jsfpyO+BWlpqfhcG4yxLdi/0tQqoT4a8Vby382mt8
-p7XSo7aWGdPBc+b6utaBmCQ7rQKQoWtAuthQCiold2KfJIPTT8xwg9blPumc+YDZC/wYGdAyHpJk
-vUbHbHWAp5No6pK/WhhLEWrFjUwtPEv1Agf8YmnsuXUQYkeZoHm8ogP16gt2uHoxcEMdf2C6pmbw
-hUMsWGhanboh4IzzmsIpWs134jVPqD/c74bZHdY69UKKSn/+KfVhxLgUlToemayLMYQOqfEC61bh
-cbhwaqoGUzIyZRFHPmau5juaWqwRn3mpWmoEA5nhzS5gog/5jbcFQqOZvmBasZtwYlG93k5GEiyw
-buHhMWLjDarEGpMGB2LFs5nIJkhp/nUmZneFaRth++lieJtHepIvKgx6PJqIlD9X2j6pG1i9x3pZ
-5bHuCPFiirGHeO7McvoXkz786GaKVzC9DSpnOxJdc4xm6NSVq7lNEnKdVlnpu9BNYoKX2Iq3wvgh
-gGEUM66kK6j4NiyoneuPLSwaCWDxczgaolEWpiMyDVDb7dNuLAbriL8ig8mmeju31oNvQdpnvEPC
-1vAXbWacGRVrGt/uXN/gU0CDDwgooKRrHfTBb1/s9lYZ8ZqOBU0yLvpuP6+K9hLFsvIjeNhBi0KL
-MlOuWRn3FRwx5oHXjl0YImUx0+gLzjGchrgzca026ETmYJzPD+IpuKzNi8AFn048Thd63OdD86M6
-84zE8yQm0VqXdbbgvub2pKVnS76icBGdeTHHXTKspUmr4NYo/furFLKiMdQzFjHJNcdAnMhltBJK
-0/IKX3DVFqvPJ2dLE7bDBkH0l/PJ29074+F0CsGYOxsb7U3myTUncYfXqnLLfa6sJybX4g+hmcjO
-kMRBfA1JellfRRKJcyRpxdS4rIl6FdmQCWjo/o9Qz7yKffoP4JHjOvABcRn4CZIT2RH4jnxmfpVG
-qgLaAvQBNfuO6X0/Ux02nb4FKx3vgP+XnkX0QW9pLy/NsXgdN24dD3LxO2Nwil7Zlc1dqtP3d7/h
-kzp1/+7hGBuY4pk0XD/0Ao/oTe/XGrfyM773aB7iUhgkpy+dwAMalxMP0DrBcsVw/6p25+/hobP9
-GBknrWExDhLJ1bwt1NcCNblaFbMKCyvmX0PeRaQ=
-""")
-
-##file distutils.cfg
-DISTUTILS_CFG = convert("""
-eJxNj00KwkAMhfc9xYNuxe4Ft57AjYiUtDO1wXSmNJnK3N5pdSEEAu8nH6lxHVlRhtDHMPATA4uH
-xJ4EFmGbvfJiicSHFRzUSISMY6hq3GLCRLnIvSTnEefN0FIjw5tF0Hkk9Q5dRunBsVoyFi24aaLg
-9FDOlL0FPGluf4QjcInLlxd6f6rqkgPu/5nHLg0cXCscXoozRrP51DRT3j9QNl99AP53T2Q=
-""")
-
-##file activate_this.py
-ACTIVATE_THIS = convert("""
-eJyNU01v2zAMvetXEB4K21jnDOstQA4dMGCHbeihlyEIDMWmE62yJEiKE//7kXKdpEWLzYBt8evx
-kRSzLPs6wiEoswM8YdMpjUXcq1Dz6RZa1cSiTkJdr86GsoTRHuCotBayiWqQEYGtMCgfD1KjGYBe
-5a3p0cRKiEe2NtLAFikftnDco0ko/SFEVgEZ8aRCZDIPY9xbA8pE9M4jfW/B2CjiHq9zbJVZuOQq
-siwTIvpxKYCembPAU4Muwi/Z4zfvrZ/MXipKeB8C+qisSZYiWfjJfs+0/MFMdWn1hJcO5U7G/SLa
-xVx8zU6VG/PXLXvfsyyzUqjeWR8hjGE+2iCE1W1tQ82hsCJN9dzKaoexyB/uH79TnjwvxcW0ntSb
-yZ8jq1Z5Q1UXsyy3gf9nbjTEj7NzQMfCJa/YSmrQ+2D/BqfiOi6sclrGzvoeVivIj8rcfcmnIQRF
-7XCyeZI7DFe5/lhlCs5PRf5QW66VXT/NrlQ46oD/D6InkOmi3IQcbhKxAX2g4a+Xd5s3UtCtG2py
-m8eg6WYWqR6SL5OjKMGfSrYt/6kxxQtOpeAgj1LXBNmpE2ElmCSIy5H0zFd8gJ924HWijWhb2hRC
-6wNEm1QdDZtuSZcEprIUBo/XRNcbQe1OUbQ/r3hPTaPJJDNtFLu8KHV5XoNr3Eo6h6YtOKw8e8yw
-VF5PnJ+ts3a9/Mz38RpG/AUSzYUW
-""")
-
-##file python-config
-PYTHON_CONFIG = convert("""
-eJyNVV1P2zAUfc+v8ODBiSABxlulTipbO6p1LWqBgVhlhcZpPYUkctzSivHfd6+dpGloGH2Ja/ue
-e+65Hz78xNhtf3x90xmw7vCWsRPGLvpDNuz87MKfdKMWSWxZ4ilNpCLZJiuWc66SVFUOZkkcirll
-rfxIBAzOMtImDzSVPBRrekwoX/OZu/0r4lm0DHiG60g86u8sjPw5rCyy86NRkB8QuuBRSqfAKESn
-3orLTCQxE3GYkC9tYp8fk89OSwNsmXgizrhUtnumeSgeo5GbLUMk49Rv+2nK48Cm/qMwfp333J2/
-dVcAGE0CIQHBsgIeEr4Wij0LtWDLzJ9ze5YEvH2WI6CHTAVcSu9ZCsXtgxu81CIvp6/k4eXsdfo7
-PvDCRD75yi41QitfzlcPp1OI7i/1/iQitqnr0iMgQ+A6wa+IKwwdxyk9IiXNAzgquTFU8NIxAVjM
-osm1Zz526e+shQ4hKRVci69nPC3Kw4NQEmkQ65E7OodxorSvxjvpBjQHDmWFIQ1mlmzlS5vedseT
-/mgIEsMJ7Lxz2bLAF9M5xeLEhdbHxpWOw0GdkJApMVBRF1y+a0z3c9WZPAXGFcFrJgCIB+024uad
-0CrzmEoRa3Ub4swNIHPGf7QDV+2uj2OiFWsChgCwjKqN6rp5izpbH6Wc1O1TclQTP/XVwi6anTr1
-1sbubjZLI1+VptPSdCfwnFBrB1jvebrTA9uUhU2/9gad7xPqeFkaQcnnLbCViZK8d7R1kxzFrIJV
-8EaLYmKYpvGVkig+3C5HCXbM1jGCGekiM2pRCVPyRyXYdPf6kcbWEQ36F5V4Gq9N7icNNw+JHwRE
-LTgxRXACpvnQv/PuT0xCCAywY/K4hE6Now2qDwaSE5FB+1agsoUveYDepS83qFcF1NufvULD3fTl
-g6Hgf7WBt6lzMeiyyWVn3P1WVbwaczHmTzE9A5SyItTVgFYyvs/L/fXlaNgbw8v3azT+0eikVlWD
-/vBHbzQumP23uBCjsYdrL9OWARwxs/nuLOzeXbPJTa/Xv6sUmQir5pC1YRLz3eA+CD8Z0XpcW8v9
-MZWF36ryyXXf3yBIz6nzqz8Muyz0m5Qj7OexfYo/Ph3LqvkHUg7AuA==
-""")
-
-MH_MAGIC = 0xfeedface
-MH_CIGAM = 0xcefaedfe
-MH_MAGIC_64 = 0xfeedfacf
-MH_CIGAM_64 = 0xcffaedfe
-FAT_MAGIC = 0xcafebabe
-BIG_ENDIAN = '>'
-LITTLE_ENDIAN = '<'
-LC_LOAD_DYLIB = 0xc
-maxint = majver == 3 and getattr(sys, 'maxsize') or getattr(sys, 'maxint')
-
-
-class fileview(object):
- """
- A proxy for file-like objects that exposes a given view of a file.
- Modified from macholib.
- """
-
- def __init__(self, fileobj, start=0, size=maxint):
- if isinstance(fileobj, fileview):
- self._fileobj = fileobj._fileobj
- else:
- self._fileobj = fileobj
- self._start = start
- self._end = start + size
- self._pos = 0
-
- def __repr__(self):
- return '' % (
- self._start, self._end, self._fileobj)
-
- def tell(self):
- return self._pos
-
- def _checkwindow(self, seekto, op):
- if not (self._start <= seekto <= self._end):
- raise IOError("%s to offset %d is outside window [%d, %d]" % (
- op, seekto, self._start, self._end))
-
- def seek(self, offset, whence=0):
- seekto = offset
- if whence == os.SEEK_SET:
- seekto += self._start
- elif whence == os.SEEK_CUR:
- seekto += self._start + self._pos
- elif whence == os.SEEK_END:
- seekto += self._end
- else:
- raise IOError("Invalid whence argument to seek: %r" % (whence,))
- self._checkwindow(seekto, 'seek')
- self._fileobj.seek(seekto)
- self._pos = seekto - self._start
-
- def write(self, bytes):
- here = self._start + self._pos
- self._checkwindow(here, 'write')
- self._checkwindow(here + len(bytes), 'write')
- self._fileobj.seek(here, os.SEEK_SET)
- self._fileobj.write(bytes)
- self._pos += len(bytes)
-
- def read(self, size=maxint):
- assert size >= 0
- here = self._start + self._pos
- self._checkwindow(here, 'read')
- size = min(size, self._end - here)
- self._fileobj.seek(here, os.SEEK_SET)
- bytes = self._fileobj.read(size)
- self._pos += len(bytes)
- return bytes
-
-
-def read_data(file, endian, num=1):
- """
- Read a given number of 32-bits unsigned integers from the given file
- with the given endianness.
- """
- res = struct.unpack(endian + 'L' * num, file.read(num * 4))
- if len(res) == 1:
- return res[0]
- return res
-
-
-def mach_o_change(path, what, value):
- """
- Replace a given name (what) in any LC_LOAD_DYLIB command found in
- the given binary with a new name (value), provided it's shorter.
- """
-
- def do_macho(file, bits, endian):
- # Read Mach-O header (the magic number is assumed read by the caller)
- cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags = read_data(file, endian, 6)
- # 64-bits header has one more field.
- if bits == 64:
- read_data(file, endian)
- # The header is followed by ncmds commands
- for n in range(ncmds):
- where = file.tell()
- # Read command header
- cmd, cmdsize = read_data(file, endian, 2)
- if cmd == LC_LOAD_DYLIB:
- # The first data field in LC_LOAD_DYLIB commands is the
- # offset of the name, starting from the beginning of the
- # command.
- name_offset = read_data(file, endian)
- file.seek(where + name_offset, os.SEEK_SET)
- # Read the NUL terminated string
- load = file.read(cmdsize - name_offset).decode()
- load = load[:load.index('\0')]
- # If the string is what is being replaced, overwrite it.
- if load == what:
- file.seek(where + name_offset, os.SEEK_SET)
- file.write(value.encode() + '\0'.encode())
- # Seek to the next command
- file.seek(where + cmdsize, os.SEEK_SET)
-
- def do_file(file, offset=0, size=maxint):
- file = fileview(file, offset, size)
- # Read magic number
- magic = read_data(file, BIG_ENDIAN)
- if magic == FAT_MAGIC:
- # Fat binaries contain nfat_arch Mach-O binaries
- nfat_arch = read_data(file, BIG_ENDIAN)
- for n in range(nfat_arch):
- # Read arch header
- cputype, cpusubtype, offset, size, align = read_data(file, BIG_ENDIAN, 5)
- do_file(file, offset, size)
- elif magic == MH_MAGIC:
- do_macho(file, 32, BIG_ENDIAN)
- elif magic == MH_CIGAM:
- do_macho(file, 32, LITTLE_ENDIAN)
- elif magic == MH_MAGIC_64:
- do_macho(file, 64, BIG_ENDIAN)
- elif magic == MH_CIGAM_64:
- do_macho(file, 64, LITTLE_ENDIAN)
-
- assert(len(what) >= len(value))
-
- with open(path, 'r+b') as f:
- do_file(f)
-
-
-if __name__ == '__main__':
- main()
-
-# TODO:
-# Copy python.exe.manifest
-# Monkeypatch distutils.sysconfig
diff --git a/thirdparty/virtualenv.py.ABOUT b/thirdparty/virtualenv.py.ABOUT
deleted file mode 100644
index 2f51356..0000000
--- a/thirdparty/virtualenv.py.ABOUT
+++ /dev/null
@@ -1,17 +0,0 @@
-about_resource: virtualenv.py
-version: 16.0
-download_url: https://raw.githubusercontent.com/pypa/virtualenv/16.0.0/virtualenv.py
-
-vcs_tool: git
-vcs_repository: https://github.com/pypa/virtualenv.git
-
-name: virtualenv
-homepage_url: http://virtualenv.org/
-owner: The virtualenv developers
-
-license_url: https://raw.github.com/pypa/virtualenv/develop/LICENSE.txt
-license_file: virtualenv.LICENSE
-license_expression: mit
-copyright: Copyright (c) 2007 Ian Bicking and Contributors
- Copyright (c) 2009 Ian Bicking, The Open Planning Project
- Copyright (c) The virtualenv developers
diff --git a/thirdparty/wheel-0.31.1-py2.py3-none-any.whl b/thirdparty/wheel-0.31.1-py2.py3-none-any.whl
deleted file mode 100644
index cfd7b90..0000000
Binary files a/thirdparty/wheel-0.31.1-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/wheel-0.31.1-py2.py3-none-any.whl.ABOUT b/thirdparty/wheel-0.31.1-py2.py3-none-any.whl.ABOUT
deleted file mode 100644
index 2eec978..0000000
--- a/thirdparty/wheel-0.31.1-py2.py3-none-any.whl.ABOUT
+++ /dev/null
@@ -1,13 +0,0 @@
-about_resource: wheel-0.31.1-py2.py3-none-any.whl
-checksum_md5: c6fad0d4eb25cfb29f986a5558479dc1
-checksum_sha1: c6f78e969470216bca108cd961e2380fea23613f
-contact: distutils-sig@python.org
-copyright: copyright (c) 2012-2014 Daniel Holth and contributors.
-download_url: https://files.pythonhosted.org/packages/81/30/e935244ca6165187ae8be876b6316ae201b71485538ffac1d718843025a9/wheel-0.31.1-py2.py3-none-any.whl#sha256=80044e51ec5bbf6c894ba0bc48d26a8c20a9ba629f4ca19ea26ecfcf87685f5f
-homepage_url: https://bitbucket.org/pypa/wheel
-license_expression: mit
-name: Wheel
-notice_file: wheel.LICENSE
-owner: Python Packaging Authority
-owner_url: https://www.pypa.io/en/latest/
-version: 0.31.1
diff --git a/thirdparty/wheel.LICENSE b/thirdparty/wheel.LICENSE
deleted file mode 100644
index c3441e6..0000000
--- a/thirdparty/wheel.LICENSE
+++ /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/thirdparty/wincertstore-0.2-py2.py3-none-any.whl b/thirdparty/wincertstore-0.2-py2.py3-none-any.whl
deleted file mode 100644
index d3bde98..0000000
Binary files a/thirdparty/wincertstore-0.2-py2.py3-none-any.whl and /dev/null differ
diff --git a/thirdparty/wincertstore.ABOUT b/thirdparty/wincertstore.ABOUT
deleted file mode 100644
index 4064dd7..0000000
--- a/thirdparty/wincertstore.ABOUT
+++ /dev/null
@@ -1,13 +0,0 @@
-about_resource: wincertstore-0.2-py2.py3-none-any.whl
-version: 0.2
-download_url: https://pypi.python.org/packages/2.7/w/wincertstore/wincertstore-0.2-py2.py3-none-any.whl
-
-name: wincertstore
-
-license_expression: psf
-license_file: wincertstore.LICENSE
-
-contact: christian@python.org
-owner: Christian Heimes
-homepage_url: https://bitbucket.org/tiran/wincertstore
-description: Python module to extract CA and CRL certs from Windows' cert store (ctypes based).
diff --git a/thirdparty/wincertstore.LICENSE b/thirdparty/wincertstore.LICENSE
deleted file mode 100644
index 311690c..0000000
--- a/thirdparty/wincertstore.LICENSE
+++ /dev/null
@@ -1,49 +0,0 @@
-PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
---------------------------------------------
-
-1. This LICENSE AGREEMENT is between the Python Software Foundation
-("PSF"), and the Individual or Organization ("Licensee") accessing and
-otherwise using this software ("Python") in source or binary form and
-its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, PSF
-hereby grants Licensee a nonexclusive, royalty-free, world-wide
-license to reproduce, analyze, test, perform and/or display publicly,
-prepare derivative works, distribute, and otherwise use Python
-alone or in any derivative version, provided, however, that PSF's
-License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Python Software Foundation;
-All Rights Reserved" are retained in Python alone or in any derivative
-version prepared by Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python.
-
-4. PSF is making Python available to Licensee on an "AS IS"
-basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between PSF and
-Licensee. This License Agreement does not grant permission to use PSF
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using Python, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
-
diff --git a/tox.ini b/tox.ini
index b929647..c50e81d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,11 +1,10 @@
[tox]
-envlist = py27,py36
+envlist = py36,py37,py38,py39
[testenv]
# install pytest in the virtualenv where commands will be executed
deps = pytest
commands =
- ./configure
pytest -vvs
\ No newline at end of file