@@ -0,0 +1,11 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<module type="PYTHON_MODULE" version="4"> | |||
<component name="NewModuleRootManager"> | |||
<content url="file://$MODULE_DIR$" /> | |||
<orderEntry type="inheritedJdk" /> | |||
<orderEntry type="sourceFolder" forTests="false" /> | |||
</component> | |||
<component name="TestRunnerService"> | |||
<option name="PROJECT_TEST_RUNNER" value="Unittests" /> | |||
</component> | |||
</module> |
@@ -0,0 +1,6 @@ | |||
<component name="InspectionProjectProfileManager"> | |||
<settings> | |||
<option name="USE_PROJECT_PROFILE" value="false" /> | |||
<version value="1.0" /> | |||
</settings> | |||
</component> |
@@ -0,0 +1,7 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="JavaScriptSettings"> | |||
<option name="languageLevel" value="ES6" /> | |||
</component> | |||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7" project-jdk-type="Python SDK" /> | |||
</project> |
@@ -0,0 +1,8 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="ProjectModuleManager"> | |||
<modules> | |||
<module fileurl="file://$PROJECT_DIR$/.idea/Web_Engineering.iml" filepath="$PROJECT_DIR$/.idea/Web_Engineering.iml" /> | |||
</modules> | |||
</component> | |||
</project> |
@@ -0,0 +1,106 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="ChangeListManager"> | |||
<list default="true" id="8ccc1b48-23e0-4e30-98d2-f52b8f3df07a" name="Default Changelist" comment="" /> | |||
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> | |||
<option name="SHOW_DIALOG" value="false" /> | |||
<option name="HIGHLIGHT_CONFLICTS" value="true" /> | |||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" /> | |||
<option name="LAST_RESOLUTION" value="IGNORE" /> | |||
</component> | |||
<component name="FileTemplateManagerImpl"> | |||
<option name="RECENT_TEMPLATES"> | |||
<list> | |||
<option value="Python Script" /> | |||
</list> | |||
</option> | |||
</component> | |||
<component name="ProjectId" id="1SEugOsGOB8hi2cwkLDRm5UoPiR" /> | |||
<component name="PropertiesComponent"> | |||
<property name="WebServerToolWindowFactoryState" value="false" /> | |||
</component> | |||
<component name="RunDashboard"> | |||
<option name="ruleStates"> | |||
<list> | |||
<RuleState> | |||
<option name="name" value="ConfigurationTypeDashboardGroupingRule" /> | |||
</RuleState> | |||
<RuleState> | |||
<option name="name" value="StatusDashboardGroupingRule" /> | |||
</RuleState> | |||
</list> | |||
</option> | |||
</component> | |||
<component name="RunManager" selected="Python.client_app"> | |||
<configuration name="client_app" type="PythonConfigurationType" factoryName="Python"> | |||
<module name="Web_Engineering" /> | |||
<option name="INTERPRETER_OPTIONS" value="" /> | |||
<option name="PARENT_ENVS" value="true" /> | |||
<envs> | |||
<env name="PYTHONUNBUFFERED" value="1" /> | |||
</envs> | |||
<option name="SDK_HOME" value="" /> | |||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> | |||
<option name="IS_MODULE_SDK" value="true" /> | |||
<option name="ADD_CONTENT_ROOTS" value="true" /> | |||
<option name="ADD_SOURCE_ROOTS" value="true" /> | |||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> | |||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/client_app.py" /> | |||
<option name="PARAMETERS" value="" /> | |||
<option name="SHOW_COMMAND_LINE" value="false" /> | |||
<option name="EMULATE_TERMINAL" value="false" /> | |||
<option name="MODULE_MODE" value="false" /> | |||
<option name="REDIRECT_INPUT" value="false" /> | |||
<option name="INPUT_FILE" value="" /> | |||
<method v="2" /> | |||
</configuration> | |||
<configuration name="server_app" type="PythonConfigurationType" factoryName="Python" temporary="true"> | |||
<module name="Web_Engineering" /> | |||
<option name="INTERPRETER_OPTIONS" value="" /> | |||
<option name="PARENT_ENVS" value="true" /> | |||
<envs> | |||
<env name="PYTHONUNBUFFERED" value="1" /> | |||
</envs> | |||
<option name="SDK_HOME" value="" /> | |||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" /> | |||
<option name="IS_MODULE_SDK" value="true" /> | |||
<option name="ADD_CONTENT_ROOTS" value="true" /> | |||
<option name="ADD_SOURCE_ROOTS" value="true" /> | |||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" /> | |||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/server_app.py" /> | |||
<option name="PARAMETERS" value="" /> | |||
<option name="SHOW_COMMAND_LINE" value="false" /> | |||
<option name="EMULATE_TERMINAL" value="false" /> | |||
<option name="MODULE_MODE" value="false" /> | |||
<option name="REDIRECT_INPUT" value="false" /> | |||
<option name="INPUT_FILE" value="" /> | |||
<method v="2" /> | |||
</configuration> | |||
<recent_temporary> | |||
<list> | |||
<item itemvalue="Python.server_app" /> | |||
</list> | |||
</recent_temporary> | |||
</component> | |||
<component name="SvnConfiguration"> | |||
<configuration /> | |||
</component> | |||
<component name="TaskManager"> | |||
<task active="true" id="Default" summary="Default task"> | |||
<changelist id="8ccc1b48-23e0-4e30-98d2-f52b8f3df07a" name="Default Changelist" comment="" /> | |||
<created>1571141186964</created> | |||
<option name="number" value="Default" /> | |||
<option name="presentableId" value="Default" /> | |||
<updated>1571141186964</updated> | |||
<workItem from="1571141189448" duration="1240000" /> | |||
</task> | |||
<servers /> | |||
</component> | |||
<component name="TypeScriptGeneratedFilesManager"> | |||
<option name="version" value="1" /> | |||
</component> | |||
<component name="com.intellij.coverage.CoverageDataManagerImpl"> | |||
<SUITE FILE_PATH="coverage/Web_Engineering$client_app.coverage" NAME="client_app Coverage Results" MODIFIED="1571142046824" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" /> | |||
<SUITE FILE_PATH="coverage/Web_Engineering$server_app.coverage" NAME="server_app Coverage Results" MODIFIED="1571142041364" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" /> | |||
</component> | |||
</project> |
@@ -0,0 +1,14 @@ | |||
import socket | |||
s = socket.socket() | |||
host = socket.gethostname() | |||
port = 61233 | |||
eingabe = " " | |||
while eingabe != "STOP": | |||
eingabe = input("Bitte String eingeben ") | |||
s.connect((host, port)) | |||
s.send(eingabe.encode("utf-8")) | |||
bytes = s.recv(1024) | |||
print(bytes.decode("utf-8")) | |||
s.close() |
@@ -0,0 +1,17 @@ | |||
import socket | |||
s = socket.socket() | |||
host = socket.gethostname() | |||
port = 61233 | |||
s.bind((host, port)) | |||
s.listen() | |||
while True: | |||
(connection, addr) = s.accept() | |||
print("Verbindung von ", addr) | |||
data = connection.recv(1024) | |||
data = data.decode("utf-8") | |||
#print("Data = %s" % (data)) | |||
data = data.upper() | |||
#data = "hi" | |||
connection.send(data.encode("utf-8")) | |||
connection.close() |
@@ -0,0 +1,76 @@ | |||
# This file must be used with "source bin/activate" *from bash* | |||
# you cannot run it directly | |||
deactivate () { | |||
# reset old environment variables | |||
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then | |||
PATH="${_OLD_VIRTUAL_PATH:-}" | |||
export PATH | |||
unset _OLD_VIRTUAL_PATH | |||
fi | |||
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then | |||
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" | |||
export PYTHONHOME | |||
unset _OLD_VIRTUAL_PYTHONHOME | |||
fi | |||
# This should detect bash and zsh, which have a hash command that must | |||
# be called to get it to forget past commands. Without forgetting | |||
# past commands the $PATH changes we made may not be respected | |||
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then | |||
hash -r | |||
fi | |||
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then | |||
PS1="${_OLD_VIRTUAL_PS1:-}" | |||
export PS1 | |||
unset _OLD_VIRTUAL_PS1 | |||
fi | |||
unset VIRTUAL_ENV | |||
if [ ! "$1" = "nondestructive" ] ; then | |||
# Self destruct! | |||
unset -f deactivate | |||
fi | |||
} | |||
# unset irrelevant variables | |||
deactivate nondestructive | |||
VIRTUAL_ENV="/Users/irakha63255/Desktop/Neues_Projekt/venv" | |||
export VIRTUAL_ENV | |||
_OLD_VIRTUAL_PATH="$PATH" | |||
PATH="$VIRTUAL_ENV/bin:$PATH" | |||
export PATH | |||
# unset PYTHONHOME if set | |||
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) | |||
# could use `if (set -u; : $PYTHONHOME) ;` in bash | |||
if [ -n "${PYTHONHOME:-}" ] ; then | |||
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" | |||
unset PYTHONHOME | |||
fi | |||
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then | |||
_OLD_VIRTUAL_PS1="${PS1:-}" | |||
if [ "x(venv) " != x ] ; then | |||
PS1="(venv) ${PS1:-}" | |||
else | |||
if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then | |||
# special case for Aspen magic directories | |||
# see http://www.zetadev.com/software/aspen/ | |||
PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" | |||
else | |||
PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" | |||
fi | |||
fi | |||
export PS1 | |||
fi | |||
# This should detect bash and zsh, which have a hash command that must | |||
# be called to get it to forget past commands. Without forgetting | |||
# past commands the $PATH changes we made may not be respected | |||
if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then | |||
hash -r | |||
fi |
@@ -0,0 +1,37 @@ | |||
# This file must be used with "source bin/activate.csh" *from csh*. | |||
# You cannot run it directly. | |||
# Created by Davide Di Blasi <davidedb@gmail.com>. | |||
# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com> | |||
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' | |||
# Unset irrelevant variables. | |||
deactivate nondestructive | |||
setenv VIRTUAL_ENV "/Users/irakha63255/Desktop/Neues_Projekt/venv" | |||
set _OLD_VIRTUAL_PATH="$PATH" | |||
setenv PATH "$VIRTUAL_ENV/bin:$PATH" | |||
set _OLD_VIRTUAL_PROMPT="$prompt" | |||
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then | |||
if ("venv" != "") then | |||
set env_name = "venv" | |||
else | |||
if (`basename "VIRTUAL_ENV"` == "__") then | |||
# special case for Aspen magic directories | |||
# see http://www.zetadev.com/software/aspen/ | |||
set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` | |||
else | |||
set env_name = `basename "$VIRTUAL_ENV"` | |||
endif | |||
endif | |||
set prompt = "[$env_name] $prompt" | |||
unset env_name | |||
endif | |||
alias pydoc python -m pydoc | |||
rehash |
@@ -0,0 +1,75 @@ | |||
# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) | |||
# you cannot run it directly | |||
function deactivate -d "Exit virtualenv and return to normal shell environment" | |||
# reset old environment variables | |||
if test -n "$_OLD_VIRTUAL_PATH" | |||
set -gx PATH $_OLD_VIRTUAL_PATH | |||
set -e _OLD_VIRTUAL_PATH | |||
end | |||
if test -n "$_OLD_VIRTUAL_PYTHONHOME" | |||
set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME | |||
set -e _OLD_VIRTUAL_PYTHONHOME | |||
end | |||
if test -n "$_OLD_FISH_PROMPT_OVERRIDE" | |||
functions -e fish_prompt | |||
set -e _OLD_FISH_PROMPT_OVERRIDE | |||
functions -c _old_fish_prompt fish_prompt | |||
functions -e _old_fish_prompt | |||
end | |||
set -e VIRTUAL_ENV | |||
if test "$argv[1]" != "nondestructive" | |||
# Self destruct! | |||
functions -e deactivate | |||
end | |||
end | |||
# unset irrelevant variables | |||
deactivate nondestructive | |||
set -gx VIRTUAL_ENV "/Users/irakha63255/Desktop/Neues_Projekt/venv" | |||
set -gx _OLD_VIRTUAL_PATH $PATH | |||
set -gx PATH "$VIRTUAL_ENV/bin" $PATH | |||
# unset PYTHONHOME if set | |||
if set -q PYTHONHOME | |||
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME | |||
set -e PYTHONHOME | |||
end | |||
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" | |||
# fish uses a function instead of an env var to generate the prompt. | |||
# save the current fish_prompt function as the function _old_fish_prompt | |||
functions -c fish_prompt _old_fish_prompt | |||
# with the original prompt function renamed, we can override with our own. | |||
function fish_prompt | |||
# Save the return status of the last command | |||
set -l old_status $status | |||
# Prompt override? | |||
if test -n "(venv) " | |||
printf "%s%s" "(venv) " (set_color normal) | |||
else | |||
# ...Otherwise, prepend env | |||
set -l _checkbase (basename "$VIRTUAL_ENV") | |||
if test $_checkbase = "__" | |||
# special case for Aspen magic directories | |||
# see http://www.zetadev.com/software/aspen/ | |||
printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) | |||
else | |||
printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) | |||
end | |||
end | |||
# Restore the return status of the previous command. | |||
echo "exit $old_status" | . | |||
_old_fish_prompt | |||
end | |||
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" | |||
end |
@@ -0,0 +1,12 @@ | |||
#!/Users/irakha63255/Desktop/Neues_Projekt/venv/bin/python | |||
# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==39.1.0','console_scripts','easy_install' | |||
__requires__ = 'setuptools==39.1.0' | |||
import re | |||
import sys | |||
from pkg_resources import load_entry_point | |||
if __name__ == '__main__': | |||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) | |||
sys.exit( | |||
load_entry_point('setuptools==39.1.0', 'console_scripts', 'easy_install')() | |||
) |
@@ -0,0 +1,12 @@ | |||
#!/Users/irakha63255/Desktop/Neues_Projekt/venv/bin/python | |||
# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==39.1.0','console_scripts','easy_install-3.7' | |||
__requires__ = 'setuptools==39.1.0' | |||
import re | |||
import sys | |||
from pkg_resources import load_entry_point | |||
if __name__ == '__main__': | |||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) | |||
sys.exit( | |||
load_entry_point('setuptools==39.1.0', 'console_scripts', 'easy_install-3.7')() | |||
) |
@@ -0,0 +1,12 @@ | |||
#!/Users/irakha63255/Desktop/Neues_Projekt/venv/bin/python | |||
# EASY-INSTALL-ENTRY-SCRIPT: 'pip==10.0.1','console_scripts','pip' | |||
__requires__ = 'pip==10.0.1' | |||
import re | |||
import sys | |||
from pkg_resources import load_entry_point | |||
if __name__ == '__main__': | |||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) | |||
sys.exit( | |||
load_entry_point('pip==10.0.1', 'console_scripts', 'pip')() | |||
) |
@@ -0,0 +1,12 @@ | |||
#!/Users/irakha63255/Desktop/Neues_Projekt/venv/bin/python | |||
# EASY-INSTALL-ENTRY-SCRIPT: 'pip==10.0.1','console_scripts','pip3' | |||
__requires__ = 'pip==10.0.1' | |||
import re | |||
import sys | |||
from pkg_resources import load_entry_point | |||
if __name__ == '__main__': | |||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) | |||
sys.exit( | |||
load_entry_point('pip==10.0.1', 'console_scripts', 'pip3')() | |||
) |
@@ -0,0 +1,12 @@ | |||
#!/Users/irakha63255/Desktop/Neues_Projekt/venv/bin/python | |||
# EASY-INSTALL-ENTRY-SCRIPT: 'pip==10.0.1','console_scripts','pip3.7' | |||
__requires__ = 'pip==10.0.1' | |||
import re | |||
import sys | |||
from pkg_resources import load_entry_point | |||
if __name__ == '__main__': | |||
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) | |||
sys.exit( | |||
load_entry_point('pip==10.0.1', 'console_scripts', 'pip3.7')() | |||
) |
@@ -0,0 +1,2 @@ | |||
./setuptools-39.1.0-py3.7.egg | |||
./pip-10.0.1-py3.7.egg |
@@ -0,0 +1,69 @@ | |||
Metadata-Version: 2.1 | |||
Name: pip | |||
Version: 10.0.1 | |||
Summary: The PyPA recommended tool for installing Python packages. | |||
Home-page: https://pip.pypa.io/ | |||
Author: The pip developers | |||
Author-email: python-virtualenv@groups.google.com | |||
License: MIT | |||
Description: pip | |||
=== | |||
The `PyPA recommended`_ tool for installing Python packages. | |||
.. image:: https://img.shields.io/pypi/v/pip.svg | |||
:target: https://pypi.org/project/pip/ | |||
.. image:: https://img.shields.io/travis/pypa/pip/master.svg | |||
:target: http://travis-ci.org/pypa/pip | |||
.. image:: https://img.shields.io/appveyor/ci/pypa/pip.svg | |||
:target: https://ci.appveyor.com/project/pypa/pip/history | |||
.. image:: https://readthedocs.org/projects/pip/badge/?version=latest | |||
:target: https://pip.pypa.io/en/latest | |||
* `Installation`_ | |||
* `Documentation`_ | |||
* `Changelog`_ | |||
* `GitHub Page`_ | |||
* `Issue Tracking`_ | |||
* `User mailing list`_ | |||
* `Dev mailing list`_ | |||
* User IRC: #pypa on Freenode. | |||
* Dev IRC: #pypa-dev on Freenode. | |||
Code of Conduct | |||
--------------- | |||
Everyone interacting in the pip project's codebases, issue trackers, chat | |||
rooms and mailing lists is expected to follow the `PyPA Code of Conduct`_. | |||
.. _PyPA recommended: https://packaging.python.org/en/latest/current/ | |||
.. _Installation: https://pip.pypa.io/en/stable/installing.html | |||
.. _Documentation: https://pip.pypa.io/en/stable/ | |||
.. _Changelog: https://pip.pypa.io/en/stable/news.html | |||
.. _GitHub Page: https://github.com/pypa/pip | |||
.. _Issue Tracking: https://github.com/pypa/pip/issues | |||
.. _User mailing list: http://groups.google.com/group/python-virtualenv | |||
.. _Dev mailing list: http://groups.google.com/group/pypa-dev | |||
.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ | |||
Keywords: easy_install distutils setuptools egg virtualenv | |||
Platform: UNKNOWN | |||
Classifier: Development Status :: 5 - Production/Stable | |||
Classifier: Intended Audience :: Developers | |||
Classifier: License :: OSI Approved :: MIT License | |||
Classifier: Topic :: Software Development :: Build Tools | |||
Classifier: Programming Language :: Python | |||
Classifier: Programming Language :: Python :: 2 | |||
Classifier: Programming Language :: Python :: 2.7 | |||
Classifier: Programming Language :: Python :: 3 | |||
Classifier: Programming Language :: Python :: 3.3 | |||
Classifier: Programming Language :: Python :: 3.4 | |||
Classifier: Programming Language :: Python :: 3.5 | |||
Classifier: Programming Language :: Python :: 3.6 | |||
Classifier: Programming Language :: Python :: Implementation :: CPython | |||
Classifier: Programming Language :: Python :: Implementation :: PyPy | |||
Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.* | |||
Provides-Extra: testing |
@@ -0,0 +1,347 @@ | |||
AUTHORS.txt | |||
LICENSE.txt | |||
MANIFEST.in | |||
NEWS.rst | |||
README.rst | |||
pyproject.toml | |||
setup.cfg | |||
setup.py | |||
docs/Makefile | |||
docs/__init__.py | |||
docs/conf.py | |||
docs/configuration.rst | |||
docs/cookbook.rst | |||
docs/development.rst | |||
docs/docutils.conf | |||
docs/index.rst | |||
docs/installing.rst | |||
docs/logic.rst | |||
docs/make.bat | |||
docs/news.rst | |||
docs/pipext.py | |||
docs/quickstart.rst | |||
docs/usage.rst | |||
docs/user_guide.rst | |||
docs/man/pip.rst | |||
docs/man/commands/check.rst | |||
docs/man/commands/config.rst | |||
docs/man/commands/download.rst | |||
docs/man/commands/freeze.rst | |||
docs/man/commands/hash.rst | |||
docs/man/commands/help.rst | |||
docs/man/commands/install.rst | |||
docs/man/commands/list.rst | |||
docs/man/commands/search.rst | |||
docs/man/commands/show.rst | |||
docs/man/commands/uninstall.rst | |||
docs/man/commands/wheel.rst | |||
docs/reference/index.rst | |||
docs/reference/pip.rst | |||
docs/reference/pip_check.rst | |||
docs/reference/pip_config.rst | |||
docs/reference/pip_download.rst | |||
docs/reference/pip_freeze.rst | |||
docs/reference/pip_hash.rst | |||
docs/reference/pip_install.rst | |||
docs/reference/pip_list.rst | |||
docs/reference/pip_search.rst | |||
docs/reference/pip_show.rst | |||
docs/reference/pip_uninstall.rst | |||
docs/reference/pip_wheel.rst | |||
src/pip/__init__.py | |||
src/pip/__main__.py | |||
src/pip.egg-info/PKG-INFO | |||
src/pip.egg-info/SOURCES.txt | |||
src/pip.egg-info/dependency_links.txt | |||
src/pip.egg-info/entry_points.txt | |||
src/pip.egg-info/not-zip-safe | |||
src/pip.egg-info/requires.txt | |||
src/pip.egg-info/top_level.txt | |||
src/pip/_internal/__init__.py | |||
src/pip/_internal/basecommand.py | |||
src/pip/_internal/baseparser.py | |||
src/pip/_internal/build_env.py | |||
src/pip/_internal/cache.py | |||
src/pip/_internal/cmdoptions.py | |||
src/pip/_internal/compat.py | |||
src/pip/_internal/configuration.py | |||
src/pip/_internal/download.py | |||
src/pip/_internal/exceptions.py | |||
src/pip/_internal/index.py | |||
src/pip/_internal/locations.py | |||
src/pip/_internal/pep425tags.py | |||
src/pip/_internal/resolve.py | |||
src/pip/_internal/status_codes.py | |||
src/pip/_internal/wheel.py | |||
src/pip/_internal/commands/__init__.py | |||
src/pip/_internal/commands/check.py | |||
src/pip/_internal/commands/completion.py | |||
src/pip/_internal/commands/configuration.py | |||
src/pip/_internal/commands/download.py | |||
src/pip/_internal/commands/freeze.py | |||
src/pip/_internal/commands/hash.py | |||
src/pip/_internal/commands/help.py | |||
src/pip/_internal/commands/install.py | |||
src/pip/_internal/commands/list.py | |||
src/pip/_internal/commands/search.py | |||
src/pip/_internal/commands/show.py | |||
src/pip/_internal/commands/uninstall.py | |||
src/pip/_internal/commands/wheel.py | |||
src/pip/_internal/models/__init__.py | |||
src/pip/_internal/models/index.py | |||
src/pip/_internal/operations/__init__.py | |||
src/pip/_internal/operations/check.py | |||
src/pip/_internal/operations/freeze.py | |||
src/pip/_internal/operations/prepare.py | |||
src/pip/_internal/req/__init__.py | |||
src/pip/_internal/req/req_file.py | |||
src/pip/_internal/req/req_install.py | |||
src/pip/_internal/req/req_set.py | |||
src/pip/_internal/req/req_uninstall.py | |||
src/pip/_internal/utils/__init__.py | |||
src/pip/_internal/utils/appdirs.py | |||
src/pip/_internal/utils/deprecation.py | |||
src/pip/_internal/utils/encoding.py | |||
src/pip/_internal/utils/filesystem.py | |||
src/pip/_internal/utils/glibc.py | |||
src/pip/_internal/utils/hashes.py | |||
src/pip/_internal/utils/logging.py | |||
src/pip/_internal/utils/misc.py | |||
src/pip/_internal/utils/outdated.py | |||
src/pip/_internal/utils/packaging.py | |||
src/pip/_internal/utils/setuptools_build.py | |||
src/pip/_internal/utils/temp_dir.py | |||
src/pip/_internal/utils/typing.py | |||
src/pip/_internal/utils/ui.py | |||
src/pip/_internal/vcs/__init__.py | |||
src/pip/_internal/vcs/bazaar.py | |||
src/pip/_internal/vcs/git.py | |||
src/pip/_internal/vcs/mercurial.py | |||
src/pip/_internal/vcs/subversion.py | |||
src/pip/_vendor/README.rst | |||
src/pip/_vendor/__init__.py | |||
src/pip/_vendor/appdirs.py | |||
src/pip/_vendor/distro.py | |||
src/pip/_vendor/ipaddress.py | |||
src/pip/_vendor/pyparsing.py | |||
src/pip/_vendor/retrying.py | |||
src/pip/_vendor/six.py | |||
src/pip/_vendor/vendor.txt | |||
src/pip/_vendor/cachecontrol/__init__.py | |||
src/pip/_vendor/cachecontrol/_cmd.py | |||
src/pip/_vendor/cachecontrol/adapter.py | |||
src/pip/_vendor/cachecontrol/cache.py | |||
src/pip/_vendor/cachecontrol/compat.py | |||
src/pip/_vendor/cachecontrol/controller.py | |||
src/pip/_vendor/cachecontrol/filewrapper.py | |||
src/pip/_vendor/cachecontrol/heuristics.py | |||
src/pip/_vendor/cachecontrol/serialize.py | |||
src/pip/_vendor/cachecontrol/wrapper.py | |||
src/pip/_vendor/cachecontrol/caches/__init__.py | |||
src/pip/_vendor/cachecontrol/caches/file_cache.py | |||
src/pip/_vendor/cachecontrol/caches/redis_cache.py | |||
src/pip/_vendor/certifi/__init__.py | |||
src/pip/_vendor/certifi/__main__.py | |||
src/pip/_vendor/certifi/cacert.pem | |||
src/pip/_vendor/certifi/core.py | |||
src/pip/_vendor/chardet/__init__.py | |||
src/pip/_vendor/chardet/big5freq.py | |||
src/pip/_vendor/chardet/big5prober.py | |||
src/pip/_vendor/chardet/chardistribution.py | |||
src/pip/_vendor/chardet/charsetgroupprober.py | |||
src/pip/_vendor/chardet/charsetprober.py | |||
src/pip/_vendor/chardet/codingstatemachine.py | |||
src/pip/_vendor/chardet/compat.py | |||
src/pip/_vendor/chardet/cp949prober.py | |||
src/pip/_vendor/chardet/enums.py | |||
src/pip/_vendor/chardet/escprober.py | |||
src/pip/_vendor/chardet/escsm.py | |||
src/pip/_vendor/chardet/eucjpprober.py | |||
src/pip/_vendor/chardet/euckrfreq.py | |||
src/pip/_vendor/chardet/euckrprober.py | |||
src/pip/_vendor/chardet/euctwfreq.py | |||
src/pip/_vendor/chardet/euctwprober.py | |||
src/pip/_vendor/chardet/gb2312freq.py | |||
src/pip/_vendor/chardet/gb2312prober.py | |||
src/pip/_vendor/chardet/hebrewprober.py | |||
src/pip/_vendor/chardet/jisfreq.py | |||
src/pip/_vendor/chardet/jpcntx.py | |||
src/pip/_vendor/chardet/langbulgarianmodel.py | |||
src/pip/_vendor/chardet/langcyrillicmodel.py | |||
src/pip/_vendor/chardet/langgreekmodel.py | |||
src/pip/_vendor/chardet/langhebrewmodel.py | |||
src/pip/_vendor/chardet/langhungarianmodel.py | |||
src/pip/_vendor/chardet/langthaimodel.py | |||
src/pip/_vendor/chardet/langturkishmodel.py | |||
src/pip/_vendor/chardet/latin1prober.py | |||
src/pip/_vendor/chardet/mbcharsetprober.py | |||
src/pip/_vendor/chardet/mbcsgroupprober.py | |||
src/pip/_vendor/chardet/mbcssm.py | |||
src/pip/_vendor/chardet/sbcharsetprober.py | |||
src/pip/_vendor/chardet/sbcsgroupprober.py | |||
src/pip/_vendor/chardet/sjisprober.py | |||
src/pip/_vendor/chardet/universaldetector.py | |||
src/pip/_vendor/chardet/utf8prober.py | |||
src/pip/_vendor/chardet/version.py | |||
src/pip/_vendor/chardet/cli/__init__.py | |||
src/pip/_vendor/chardet/cli/chardetect.py | |||
src/pip/_vendor/colorama/__init__.py | |||
src/pip/_vendor/colorama/ansi.py | |||
src/pip/_vendor/colorama/ansitowin32.py | |||
src/pip/_vendor/colorama/initialise.py | |||
src/pip/_vendor/colorama/win32.py | |||
src/pip/_vendor/colorama/winterm.py | |||
src/pip/_vendor/distlib/__init__.py | |||
src/pip/_vendor/distlib/compat.py | |||
src/pip/_vendor/distlib/database.py | |||
src/pip/_vendor/distlib/index.py | |||
src/pip/_vendor/distlib/locators.py | |||
src/pip/_vendor/distlib/manifest.py | |||
src/pip/_vendor/distlib/markers.py | |||
src/pip/_vendor/distlib/metadata.py | |||
src/pip/_vendor/distlib/resources.py | |||
src/pip/_vendor/distlib/scripts.py | |||
src/pip/_vendor/distlib/t32.exe | |||
src/pip/_vendor/distlib/t64.exe | |||
src/pip/_vendor/distlib/util.py | |||
src/pip/_vendor/distlib/version.py | |||
src/pip/_vendor/distlib/w32.exe | |||
src/pip/_vendor/distlib/w64.exe | |||
src/pip/_vendor/distlib/wheel.py | |||
src/pip/_vendor/distlib/_backport/__init__.py | |||
src/pip/_vendor/distlib/_backport/misc.py | |||
src/pip/_vendor/distlib/_backport/shutil.py | |||
src/pip/_vendor/distlib/_backport/sysconfig.cfg | |||
src/pip/_vendor/distlib/_backport/sysconfig.py | |||
src/pip/_vendor/distlib/_backport/tarfile.py | |||
src/pip/_vendor/html5lib/__init__.py | |||
src/pip/_vendor/html5lib/_ihatexml.py | |||
src/pip/_vendor/html5lib/_inputstream.py | |||
src/pip/_vendor/html5lib/_tokenizer.py | |||
src/pip/_vendor/html5lib/_utils.py | |||
src/pip/_vendor/html5lib/constants.py | |||
src/pip/_vendor/html5lib/html5parser.py | |||
src/pip/_vendor/html5lib/serializer.py | |||
src/pip/_vendor/html5lib/_trie/__init__.py | |||
src/pip/_vendor/html5lib/_trie/_base.py | |||
src/pip/_vendor/html5lib/_trie/datrie.py | |||
src/pip/_vendor/html5lib/_trie/py.py | |||
src/pip/_vendor/html5lib/filters/__init__.py | |||
src/pip/_vendor/html5lib/filters/alphabeticalattributes.py | |||
src/pip/_vendor/html5lib/filters/base.py | |||
src/pip/_vendor/html5lib/filters/inject_meta_charset.py | |||
src/pip/_vendor/html5lib/filters/lint.py | |||
src/pip/_vendor/html5lib/filters/optionaltags.py | |||
src/pip/_vendor/html5lib/filters/sanitizer.py | |||
src/pip/_vendor/html5lib/filters/whitespace.py | |||
src/pip/_vendor/html5lib/treeadapters/__init__.py | |||
src/pip/_vendor/html5lib/treeadapters/genshi.py | |||
src/pip/_vendor/html5lib/treeadapters/sax.py | |||
src/pip/_vendor/html5lib/treebuilders/__init__.py | |||
src/pip/_vendor/html5lib/treebuilders/base.py | |||
src/pip/_vendor/html5lib/treebuilders/dom.py | |||
src/pip/_vendor/html5lib/treebuilders/etree.py | |||
src/pip/_vendor/html5lib/treebuilders/etree_lxml.py | |||
src/pip/_vendor/html5lib/treewalkers/__init__.py | |||
src/pip/_vendor/html5lib/treewalkers/base.py | |||
src/pip/_vendor/html5lib/treewalkers/dom.py | |||
src/pip/_vendor/html5lib/treewalkers/etree.py | |||
src/pip/_vendor/html5lib/treewalkers/etree_lxml.py | |||
src/pip/_vendor/html5lib/treewalkers/genshi.py | |||
src/pip/_vendor/idna/__init__.py | |||
src/pip/_vendor/idna/codec.py | |||
src/pip/_vendor/idna/compat.py | |||
src/pip/_vendor/idna/core.py | |||
src/pip/_vendor/idna/idnadata.py | |||
src/pip/_vendor/idna/intranges.py | |||
src/pip/_vendor/idna/package_data.py | |||
src/pip/_vendor/idna/uts46data.py | |||
src/pip/_vendor/lockfile/__init__.py | |||
src/pip/_vendor/lockfile/linklockfile.py | |||
src/pip/_vendor/lockfile/mkdirlockfile.py | |||
src/pip/_vendor/lockfile/pidlockfile.py | |||
src/pip/_vendor/lockfile/sqlitelockfile.py | |||
src/pip/_vendor/lockfile/symlinklockfile.py | |||
src/pip/_vendor/msgpack/__init__.py | |||
src/pip/_vendor/msgpack/_version.py | |||
src/pip/_vendor/msgpack/exceptions.py | |||
src/pip/_vendor/msgpack/fallback.py | |||
src/pip/_vendor/packaging/__about__.py | |||
src/pip/_vendor/packaging/__init__.py | |||
src/pip/_vendor/packaging/_compat.py | |||
src/pip/_vendor/packaging/_structures.py | |||
src/pip/_vendor/packaging/markers.py | |||
src/pip/_vendor/packaging/requirements.py | |||
src/pip/_vendor/packaging/specifiers.py | |||
src/pip/_vendor/packaging/utils.py | |||
src/pip/_vendor/packaging/version.py | |||
src/pip/_vendor/pkg_resources/__init__.py | |||
src/pip/_vendor/pkg_resources/py31compat.py | |||
src/pip/_vendor/progress/__init__.py | |||
src/pip/_vendor/progress/bar.py | |||
src/pip/_vendor/progress/counter.py | |||
src/pip/_vendor/progress/helpers.py | |||
src/pip/_vendor/progress/spinner.py | |||
src/pip/_vendor/pytoml/__init__.py | |||
src/pip/_vendor/pytoml/core.py | |||
src/pip/_vendor/pytoml/parser.py | |||
src/pip/_vendor/pytoml/writer.py | |||
src/pip/_vendor/requests/__init__.py | |||
src/pip/_vendor/requests/__version__.py | |||
src/pip/_vendor/requests/_internal_utils.py | |||
src/pip/_vendor/requests/adapters.py | |||
src/pip/_vendor/requests/api.py | |||
src/pip/_vendor/requests/auth.py | |||
src/pip/_vendor/requests/certs.py | |||
src/pip/_vendor/requests/compat.py | |||
src/pip/_vendor/requests/cookies.py | |||
src/pip/_vendor/requests/exceptions.py | |||
src/pip/_vendor/requests/help.py | |||
src/pip/_vendor/requests/hooks.py | |||
src/pip/_vendor/requests/models.py | |||
src/pip/_vendor/requests/packages.py | |||
src/pip/_vendor/requests/sessions.py | |||
src/pip/_vendor/requests/status_codes.py | |||
src/pip/_vendor/requests/structures.py | |||
src/pip/_vendor/requests/utils.py | |||
src/pip/_vendor/urllib3/__init__.py | |||
src/pip/_vendor/urllib3/_collections.py | |||
src/pip/_vendor/urllib3/connection.py | |||
src/pip/_vendor/urllib3/connectionpool.py | |||
src/pip/_vendor/urllib3/exceptions.py | |||
src/pip/_vendor/urllib3/fields.py | |||
src/pip/_vendor/urllib3/filepost.py | |||
src/pip/_vendor/urllib3/poolmanager.py | |||
src/pip/_vendor/urllib3/request.py | |||
src/pip/_vendor/urllib3/response.py | |||
src/pip/_vendor/urllib3/contrib/__init__.py | |||
src/pip/_vendor/urllib3/contrib/appengine.py | |||
src/pip/_vendor/urllib3/contrib/ntlmpool.py | |||
src/pip/_vendor/urllib3/contrib/pyopenssl.py | |||
src/pip/_vendor/urllib3/contrib/securetransport.py | |||
src/pip/_vendor/urllib3/contrib/socks.py | |||
src/pip/_vendor/urllib3/contrib/_securetransport/__init__.py | |||
src/pip/_vendor/urllib3/contrib/_securetransport/bindings.py | |||
src/pip/_vendor/urllib3/contrib/_securetransport/low_level.py | |||
src/pip/_vendor/urllib3/packages/__init__.py | |||
src/pip/_vendor/urllib3/packages/ordered_dict.py | |||
src/pip/_vendor/urllib3/packages/six.py | |||
src/pip/_vendor/urllib3/packages/backports/__init__.py | |||
src/pip/_vendor/urllib3/packages/backports/makefile.py | |||
src/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py | |||
src/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py | |||
src/pip/_vendor/urllib3/util/__init__.py | |||
src/pip/_vendor/urllib3/util/connection.py | |||
src/pip/_vendor/urllib3/util/request.py | |||
src/pip/_vendor/urllib3/util/response.py | |||
src/pip/_vendor/urllib3/util/retry.py | |||
src/pip/_vendor/urllib3/util/selectors.py | |||
src/pip/_vendor/urllib3/util/ssl_.py | |||
src/pip/_vendor/urllib3/util/timeout.py | |||
src/pip/_vendor/urllib3/util/url.py | |||
src/pip/_vendor/urllib3/util/wait.py | |||
src/pip/_vendor/webencodings/__init__.py | |||
src/pip/_vendor/webencodings/labels.py | |||
src/pip/_vendor/webencodings/mklabels.py | |||
src/pip/_vendor/webencodings/tests.py | |||
src/pip/_vendor/webencodings/x_user_defined.py |
@@ -0,0 +1 @@ | |||
@@ -0,0 +1,5 @@ | |||
[console_scripts] | |||
pip = pip._internal:main | |||
pip3 = pip._internal:main | |||
pip3.7 = pip._internal:main | |||
@@ -0,0 +1 @@ | |||
@@ -0,0 +1,8 @@ | |||
[testing] | |||
pytest | |||
mock | |||
pretend | |||
scripttest>=1.3 | |||
virtualenv>=1.10 | |||
freezegun |
@@ -0,0 +1 @@ | |||
pip |
@@ -0,0 +1 @@ | |||
__version__ = "10.0.1" |
@@ -0,0 +1,19 @@ | |||
from __future__ import absolute_import | |||
import os | |||
import sys | |||
# If we are running from a wheel, add the wheel to sys.path | |||
# This allows the usage python pip-*.whl/pip install pip-*.whl | |||
if __package__ == '': | |||
# __file__ is pip-*.whl/pip/__main__.py | |||
# first dirname call strips of '/__main__.py', second strips off '/pip' | |||
# Resulting path is the name of the wheel itself | |||
# Add that to sys.path so we can import pip | |||
path = os.path.dirname(os.path.dirname(__file__)) | |||
sys.path.insert(0, path) | |||
from pip._internal import main as _main # noqa | |||
if __name__ == '__main__': | |||
sys.exit(_main()) |
@@ -0,0 +1,246 @@ | |||
#!/usr/bin/env python | |||
from __future__ import absolute_import | |||
import locale | |||
import logging | |||
import os | |||
import optparse | |||
import warnings | |||
import sys | |||
# 2016-06-17 barry@debian.org: urllib3 1.14 added optional support for socks, | |||
# but if invoked (i.e. imported), it will issue a warning to stderr if socks | |||
# isn't available. requests unconditionally imports urllib3's socks contrib | |||
# module, triggering this warning. The warning breaks DEP-8 tests (because of | |||
# the stderr output) and is just plain annoying in normal usage. I don't want | |||
# to add socks as yet another dependency for pip, nor do I want to allow-stder | |||
# in the DEP-8 tests, so just suppress the warning. pdb tells me this has to | |||
# be done before the import of pip.vcs. | |||
from pip._vendor.urllib3.exceptions import DependencyWarning | |||
warnings.filterwarnings("ignore", category=DependencyWarning) # noqa | |||
# We want to inject the use of SecureTransport as early as possible so that any | |||
# references or sessions or what have you are ensured to have it, however we | |||
# only want to do this in the case that we're running on macOS and the linked | |||
# OpenSSL is too old to handle TLSv1.2 | |||
try: | |||
import ssl | |||
except ImportError: | |||
pass | |||
else: | |||
# Checks for OpenSSL 1.0.1 on MacOS | |||
if sys.platform == "darwin" and ssl.OPENSSL_VERSION_NUMBER < 0x1000100f: | |||
try: | |||
from pip._vendor.urllib3.contrib import securetransport | |||
except (ImportError, OSError): | |||
pass | |||
else: | |||
securetransport.inject_into_urllib3() | |||
from pip import __version__ | |||
from pip._internal import cmdoptions | |||
from pip._internal.exceptions import CommandError, PipError | |||
from pip._internal.utils.misc import get_installed_distributions, get_prog | |||
from pip._internal.utils import deprecation | |||
from pip._internal.vcs import git, mercurial, subversion, bazaar # noqa | |||
from pip._internal.baseparser import ( | |||
ConfigOptionParser, UpdatingDefaultsHelpFormatter, | |||
) | |||
from pip._internal.commands import get_summaries, get_similar_commands | |||
from pip._internal.commands import commands_dict | |||
from pip._vendor.urllib3.exceptions import InsecureRequestWarning | |||
logger = logging.getLogger(__name__) | |||
# Hide the InsecureRequestWarning from urllib3 | |||
warnings.filterwarnings("ignore", category=InsecureRequestWarning) | |||
def autocomplete(): | |||
"""Command and option completion for the main option parser (and options) | |||
and its subcommands (and options). | |||
Enable by sourcing one of the completion shell scripts (bash, zsh or fish). | |||
""" | |||
# Don't complete if user hasn't sourced bash_completion file. | |||
if 'PIP_AUTO_COMPLETE' not in os.environ: | |||
return | |||
cwords = os.environ['COMP_WORDS'].split()[1:] | |||
cword = int(os.environ['COMP_CWORD']) | |||
try: | |||
current = cwords[cword - 1] | |||
except IndexError: | |||
current = '' | |||
subcommands = [cmd for cmd, summary in get_summaries()] | |||
options = [] | |||
# subcommand | |||
try: | |||
subcommand_name = [w for w in cwords if w in subcommands][0] | |||
except IndexError: | |||
subcommand_name = None | |||
parser = create_main_parser() | |||
# subcommand options | |||
if subcommand_name: | |||
# special case: 'help' subcommand has no options | |||
if subcommand_name == 'help': | |||
sys.exit(1) | |||
# special case: list locally installed dists for show and uninstall | |||
should_list_installed = ( | |||
subcommand_name in ['show', 'uninstall'] and | |||
not current.startswith('-') | |||
) | |||
if should_list_installed: | |||
installed = [] | |||
lc = current.lower() | |||
for dist in get_installed_distributions(local_only=True): | |||
if dist.key.startswith(lc) and dist.key not in cwords[1:]: | |||
installed.append(dist.key) | |||
# if there are no dists installed, fall back to option completion | |||
if installed: | |||
for dist in installed: | |||
print(dist) | |||
sys.exit(1) | |||
subcommand = commands_dict[subcommand_name]() | |||
for opt in subcommand.parser.option_list_all: | |||
if opt.help != optparse.SUPPRESS_HELP: | |||
for opt_str in opt._long_opts + opt._short_opts: | |||
options.append((opt_str, opt.nargs)) | |||
# filter out previously specified options from available options | |||
prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]] | |||
options = [(x, v) for (x, v) in options if x not in prev_opts] | |||
# filter options by current input | |||
options = [(k, v) for k, v in options if k.startswith(current)] | |||
for option in options: | |||
opt_label = option[0] | |||
# append '=' to options which require args | |||
if option[1] and option[0][:2] == "--": | |||
opt_label += '=' | |||
print(opt_label) | |||
else: | |||
# show main parser options only when necessary | |||
if current.startswith('-') or current.startswith('--'): | |||
opts = [i.option_list for i in parser.option_groups] | |||
opts.append(parser.option_list) | |||
opts = (o for it in opts for o in it) | |||
for opt in opts: | |||
if opt.help != optparse.SUPPRESS_HELP: | |||
subcommands += opt._long_opts + opt._short_opts | |||
print(' '.join([x for x in subcommands if x.startswith(current)])) | |||
sys.exit(1) | |||
def create_main_parser(): | |||
parser_kw = { | |||
'usage': '\n%prog <command> [options]', | |||
'add_help_option': False, | |||
'formatter': UpdatingDefaultsHelpFormatter(), | |||
'name': 'global', | |||
'prog': get_prog(), | |||
} | |||
parser = ConfigOptionParser(**parser_kw) | |||
parser.disable_interspersed_args() | |||
pip_pkg_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |||
parser.version = 'pip %s from %s (python %s)' % ( | |||
__version__, pip_pkg_dir, sys.version[:3], | |||
) | |||
# add the general options | |||
gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser) | |||
parser.add_option_group(gen_opts) | |||
parser.main = True # so the help formatter knows | |||
# create command listing for description | |||
command_summaries = get_summaries() | |||
description = [''] + ['%-27s %s' % (i, j) for i, j in command_summaries] | |||
parser.description = '\n'.join(description) | |||
return parser | |||
def parseopts(args): | |||
parser = create_main_parser() | |||
# Note: parser calls disable_interspersed_args(), so the result of this | |||
# call is to split the initial args into the general options before the | |||
# subcommand and everything else. | |||
# For example: | |||
# args: ['--timeout=5', 'install', '--user', 'INITools'] | |||
# general_options: ['--timeout==5'] | |||
# args_else: ['install', '--user', 'INITools'] | |||
general_options, args_else = parser.parse_args(args) | |||
# --version | |||
if general_options.version: | |||
sys.stdout.write(parser.version) | |||
sys.stdout.write(os.linesep) | |||
sys.exit() | |||
# pip || pip help -> print_help() | |||
if not args_else or (args_else[0] == 'help' and len(args_else) == 1): | |||
parser.print_help() | |||
sys.exit() | |||
# the subcommand name | |||
cmd_name = args_else[0] | |||
if cmd_name not in commands_dict: | |||
guess = get_similar_commands(cmd_name) | |||
msg = ['unknown command "%s"' % cmd_name] | |||
if guess: | |||
msg.append('maybe you meant "%s"' % guess) | |||
raise CommandError(' - '.join(msg)) | |||
# all the args without the subcommand | |||
cmd_args = args[:] | |||
cmd_args.remove(cmd_name) | |||
return cmd_name, cmd_args | |||
def check_isolated(args): | |||
isolated = False | |||
if "--isolated" in args: | |||
isolated = True | |||
return isolated | |||
def main(args=None): | |||
if args is None: | |||
args = sys.argv[1:] | |||
# Configure our deprecation warnings to be sent through loggers | |||
deprecation.install_warning_logger() | |||
autocomplete() | |||
try: | |||
cmd_name, cmd_args = parseopts(args) | |||
except PipError as exc: | |||
sys.stderr.write("ERROR: %s" % exc) | |||
sys.stderr.write(os.linesep) | |||
sys.exit(1) | |||
# Needed for locale.getpreferredencoding(False) to work | |||
# in pip._internal.utils.encoding.auto_decode | |||
try: | |||
locale.setlocale(locale.LC_ALL, '') | |||
except locale.Error as e: | |||
# setlocale can apparently crash if locale are uninitialized | |||
logger.debug("Ignoring error %s when setting locale", e) | |||
command = commands_dict[cmd_name](isolated=check_isolated(cmd_args)) | |||
return command.main(cmd_args) |
@@ -0,0 +1,373 @@ | |||
"""Base Command class, and related routines""" | |||
from __future__ import absolute_import | |||
import logging | |||
import logging.config | |||
import optparse | |||
import os | |||
import sys | |||
import warnings | |||
from pip._internal import cmdoptions | |||
from pip._internal.baseparser import ( | |||
ConfigOptionParser, UpdatingDefaultsHelpFormatter, | |||
) | |||
from pip._internal.compat import WINDOWS | |||
from pip._internal.download import PipSession | |||
from pip._internal.exceptions import ( | |||
BadCommand, CommandError, InstallationError, PreviousBuildDirError, | |||
UninstallationError, | |||
) | |||
from pip._internal.index import PackageFinder | |||
from pip._internal.locations import running_under_virtualenv | |||
from pip._internal.req.req_file import parse_requirements | |||
from pip._internal.req.req_install import InstallRequirement | |||
from pip._internal.status_codes import ( | |||
ERROR, PREVIOUS_BUILD_DIR_ERROR, SUCCESS, UNKNOWN_ERROR, | |||
VIRTUALENV_NOT_FOUND, | |||
) | |||
from pip._internal.utils import deprecation | |||
from pip._internal.utils.logging import IndentingFormatter | |||
from pip._internal.utils.misc import get_prog, normalize_path | |||
from pip._internal.utils.outdated import pip_version_check | |||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING | |||
if MYPY_CHECK_RUNNING: | |||
from typing import Optional | |||
__all__ = ['Command'] | |||
logger = logging.getLogger(__name__) | |||
class Command(object): | |||
name = None # type: Optional[str] | |||
usage = None # type: Optional[str] | |||
hidden = False # type: bool | |||
ignore_require_venv = False # type: bool | |||
log_streams = ("ext://sys.stdout", "ext://sys.stderr") | |||
def __init__(self, isolated=False): | |||
parser_kw = { | |||
'usage': self.usage, | |||
'prog': '%s %s' % (get_prog(), self.name), | |||
'formatter': UpdatingDefaultsHelpFormatter(), | |||
'add_help_option': False, | |||
'name': self.name, | |||
'description': self.__doc__, | |||
'isolated': isolated, | |||
} | |||
self.parser = ConfigOptionParser(**parser_kw) | |||
# Commands should add options to this option group | |||
optgroup_name = '%s Options' % self.name.capitalize() | |||
self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) | |||
# Add the general options | |||
gen_opts = cmdoptions.make_option_group( | |||
cmdoptions.general_group, | |||
self.parser, | |||
) | |||
self.parser.add_option_group(gen_opts) | |||
def _build_session(self, options, retries=None, timeout=None): | |||
session = PipSession( | |||
cache=( | |||
normalize_path(os.path.join(options.cache_dir, "http")) | |||
if options.cache_dir else None | |||
), | |||
retries=retries if retries is not None else options.retries, | |||
insecure_hosts=options.trusted_hosts, | |||
) | |||
# Handle custom ca-bundles from the user | |||
if options.cert: | |||
session.verify = options.cert | |||
# Handle SSL client certificate | |||
if options.client_cert: | |||
session.cert = options.client_cert | |||
# Handle timeouts | |||
if options.timeout or timeout: | |||
session.timeout = ( | |||
timeout if timeout is not None else options.timeout | |||
) | |||
# Handle configured proxies | |||
if options.proxy: | |||
session.proxies = { | |||
"http": options.proxy, | |||
"https": options.proxy, | |||
} | |||
# Determine if we can prompt the user for authentication or not | |||
session.auth.prompting = not options.no_input | |||
return session | |||
def parse_args(self, args): | |||
# factored out for testability | |||
return self.parser.parse_args(args) | |||
def main(self, args): | |||
options, args = self.parse_args(args) | |||
# Set verbosity so that it can be used elsewhere. | |||
self.verbosity = options.verbose - options.quiet | |||
if self.verbosity >= 1: | |||
level = "DEBUG" | |||
elif self.verbosity == -1: | |||
level = "WARNING" | |||
elif self.verbosity == -2: | |||
level = "ERROR" | |||
elif self.verbosity <= -3: | |||
level = "CRITICAL" | |||
else: | |||
level = "INFO" | |||
# The root logger should match the "console" level *unless* we | |||
# specified "--log" to send debug logs to a file. | |||
root_level = level | |||
if options.log: | |||
root_level = "DEBUG" | |||
logger_class = "pip._internal.utils.logging.ColorizedStreamHandler" | |||
handler_class = "pip._internal.utils.logging.BetterRotatingFileHandler" | |||
logging.config.dictConfig({ | |||
"version": 1, | |||
"disable_existing_loggers": False, | |||
"filters": { | |||
"exclude_warnings": { | |||
"()": "pip._internal.utils.logging.MaxLevelFilter", | |||
"level": logging.WARNING, | |||
}, | |||
}, | |||
"formatters": { | |||
"indent": { | |||
"()": IndentingFormatter, | |||
"format": "%(message)s", | |||
}, | |||
}, | |||
"handlers": { | |||
"console": { | |||
"level": level, | |||
"class": logger_class, | |||
"no_color": options.no_color, | |||
"stream": self.log_streams[0], | |||
"filters": ["exclude_warnings"], | |||
"formatter": "indent", | |||
}, | |||
"console_errors": { | |||
"level": "WARNING", | |||
"class": logger_class, | |||
"no_color": options.no_color, | |||
"stream": self.log_streams[1], | |||
"formatter": "indent", | |||
}, | |||
"user_log": { | |||
"level": "DEBUG", | |||
"class": handler_class, | |||
"filename": options.log or "/dev/null", | |||
"delay": True, | |||
"formatter": "indent", | |||
}, | |||
}, | |||
"root": { | |||
"level": root_level, | |||
"handlers": list(filter(None, [ | |||
"console", | |||
"console_errors", | |||
"user_log" if options.log else None, | |||
])), | |||
}, | |||
# Disable any logging besides WARNING unless we have DEBUG level | |||
# logging enabled. These use both pip._vendor and the bare names | |||
# for the case where someone unbundles our libraries. | |||
"loggers": { | |||
name: { | |||
"level": ( | |||
"WARNING" if level in ["INFO", "ERROR"] else "DEBUG" | |||
) | |||
} for name in [ | |||
"pip._vendor", "distlib", "requests", "urllib3" | |||
] | |||
}, | |||
}) | |||
if sys.version_info[:2] == (3, 3): | |||
warnings.warn( | |||
"Python 3.3 supported has been deprecated and support for it " | |||
"will be dropped in the future. Please upgrade your Python.", | |||
deprecation.RemovedInPip11Warning, | |||
) | |||
# TODO: try to get these passing down from the command? | |||
# without resorting to os.environ to hold these. | |||
if options.no_input: | |||
os.environ['PIP_NO_INPUT'] = '1' | |||
if options.exists_action: | |||
os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action) | |||
if options.require_venv and not self.ignore_require_venv: | |||
# If a venv is required check if it can really be found | |||
if not running_under_virtualenv(): | |||
logger.critical( | |||
'Could not find an activated virtualenv (required).' | |||
) | |||
sys.exit(VIRTUALENV_NOT_FOUND) | |||
original_root_handlers = set(logging.root.handlers) | |||
try: | |||
status = self.run(options, args) | |||
# FIXME: all commands should return an exit status | |||
# and when it is done, isinstance is not needed anymore | |||
if isinstance(status, int): | |||
return status | |||
except PreviousBuildDirError as exc: | |||
logger.critical(str(exc)) | |||
logger.debug('Exception information:', exc_info=True) | |||
return PREVIOUS_BUILD_DIR_ERROR | |||
except (InstallationError, UninstallationError, BadCommand) as exc: | |||
logger.critical(str(exc)) | |||
logger.debug('Exception information:', exc_info=True) | |||
return ERROR | |||
except CommandError as exc: | |||
logger.critical('ERROR: %s', exc) | |||
logger.debug('Exception information:', exc_info=True) | |||
return ERROR | |||
except KeyboardInterrupt: | |||
logger.critical('Operation cancelled by user') | |||
logger.debug('Exception information:', exc_info=True) | |||
return ERROR | |||
except: | |||
logger.critical('Exception:', exc_info=True) | |||
return UNKNOWN_ERROR | |||
finally: | |||
# Check if we're using the latest version of pip available | |||
if (not options.disable_pip_version_check and not | |||
getattr(options, "no_index", False)): | |||
with self._build_session( | |||
options, | |||
retries=0, | |||
timeout=min(5, options.timeout)) as session: | |||
pip_version_check(session, options) | |||
# Avoid leaking loggers | |||
for handler in set(logging.root.handlers) - original_root_handlers: | |||
# this method benefit from the Logger class internal lock | |||
logging.root.removeHandler(handler) | |||
return SUCCESS | |||
class RequirementCommand(Command): | |||
@staticmethod | |||
def populate_requirement_set(requirement_set, args, options, finder, | |||
session, name, wheel_cache): | |||
""" | |||
Marshal cmd line args into a requirement set. | |||
""" | |||
# NOTE: As a side-effect, options.require_hashes and | |||
# requirement_set.require_hashes may be updated | |||
for filename in options.constraints: | |||
for req_to_add in parse_requirements( | |||
filename, | |||
constraint=True, finder=finder, options=options, | |||
session=session, wheel_cache=wheel_cache): | |||
req_to_add.is_direct = True | |||
requirement_set.add_requirement(req_to_add) | |||
for req in args: | |||
req_to_add = InstallRequirement.from_line( | |||
req, None, isolated=options.isolated_mode, | |||
wheel_cache=wheel_cache | |||
) | |||
req_to_add.is_direct = True | |||
requirement_set.add_requirement(req_to_add) | |||
for req in options.editables: | |||
req_to_add = InstallRequirement.from_editable( | |||
req, | |||
isolated=options.isolated_mode, | |||
wheel_cache=wheel_cache | |||
) | |||
req_to_add.is_direct = True | |||
requirement_set.add_requirement(req_to_add) | |||
for filename in options.requirements: | |||
for req_to_add in parse_requirements( | |||
filename, | |||
finder=finder, options=options, session=session, | |||
wheel_cache=wheel_cache): | |||
req_to_add.is_direct = True | |||
requirement_set.add_requirement(req_to_add) | |||
# If --require-hashes was a line in a requirements file, tell | |||
# RequirementSet about it: | |||
requirement_set.require_hashes = options.require_hashes | |||
if not (args or options.editables or options.requirements): | |||
opts = {'name': name} | |||
if options.find_links: | |||
raise CommandError( | |||
'You must give at least one requirement to %(name)s ' | |||
'(maybe you meant "pip %(name)s %(links)s"?)' % | |||
dict(opts, links=' '.join(options.find_links))) | |||
else: | |||
raise CommandError( | |||
'You must give at least one requirement to %(name)s ' | |||
'(see "pip help %(name)s")' % opts) | |||
# On Windows, any operation modifying pip should be run as: | |||
# python -m pip ... | |||
# See https://github.com/pypa/pip/issues/1299 for more discussion | |||
should_show_use_python_msg = ( | |||
WINDOWS and | |||
requirement_set.has_requirement("pip") and | |||
os.path.basename(sys.argv[0]).startswith("pip") | |||
) | |||
if should_show_use_python_msg: | |||
new_command = [ | |||
sys.executable, "-m", "pip" | |||
] + sys.argv[1:] | |||
raise CommandError( | |||
'To modify pip, please run the following command:\n{}' | |||
.format(" ".join(new_command)) | |||
) | |||
def _build_package_finder(self, options, session, | |||
platform=None, python_versions=None, | |||
abi=None, implementation=None): | |||
""" | |||
Create a package finder appropriate to this requirement command. | |||
""" | |||
index_urls = [options.index_url] + options.extra_index_urls | |||
if options.no_index: | |||
logger.debug('Ignoring indexes: %s', ','.join(index_urls)) | |||
index_urls = [] | |||
return PackageFinder( | |||
find_links=options.find_links, | |||
format_control=options.format_control, | |||
index_urls=index_urls, | |||
trusted_hosts=options.trusted_hosts, | |||
allow_all_prereleases=options.pre, | |||
process_dependency_links=options.process_dependency_links, | |||
session=session, | |||
platform=platform, | |||
versions=python_versions, | |||
abi=abi, | |||
implementation=implementation, | |||
) |
@@ -0,0 +1,240 @@ | |||
"""Base option parser setup""" | |||
from __future__ import absolute_import | |||
import logging | |||
import optparse | |||
import sys | |||
import textwrap | |||
from distutils.util import strtobool | |||
from pip._vendor.six import string_types | |||
from pip._internal.compat import get_terminal_size | |||
from pip._internal.configuration import Configuration, ConfigurationError | |||
logger = logging.getLogger(__name__) | |||
class PrettyHelpFormatter(optparse.IndentedHelpFormatter): | |||
"""A prettier/less verbose help formatter for optparse.""" | |||
def __init__(self, *args, **kwargs): | |||
# help position must be aligned with __init__.parseopts.description | |||
kwargs['max_help_position'] = 30 | |||
kwargs['indent_increment'] = 1 | |||
kwargs['width'] = get_terminal_size()[0] - 2 | |||
optparse.IndentedHelpFormatter.__init__(self, *args, **kwargs) | |||
def format_option_strings(self, option): | |||
return self._format_option_strings(option, ' <%s>', ', ') | |||
def _format_option_strings(self, option, mvarfmt=' <%s>', optsep=', '): | |||
""" | |||
Return a comma-separated list of option strings and metavars. | |||
:param option: tuple of (short opt, long opt), e.g: ('-f', '--format') | |||
:param mvarfmt: metavar format string - evaluated as mvarfmt % metavar | |||
:param optsep: separator | |||
""" | |||
opts = [] | |||
if option._short_opts: | |||
opts.append(option._short_opts[0]) | |||
if option._long_opts: | |||
opts.append(option._long_opts[0]) | |||
if len(opts) > 1: | |||
opts.insert(1, optsep) | |||
if option.takes_value(): | |||
metavar = option.metavar or option.dest.lower() | |||
opts.append(mvarfmt % metavar.lower()) | |||
return ''.join(opts) | |||
def format_heading(self, heading): | |||
if heading == 'Options': | |||
return '' | |||
return heading + ':\n' | |||
def format_usage(self, usage): | |||
""" | |||
Ensure there is only one newline between usage and the first heading | |||
if there is no description. | |||
""" | |||
msg = '\nUsage: %s\n' % self.indent_lines(textwrap.dedent(usage), " ") | |||
return msg | |||
def format_description(self, description): | |||
# leave full control over description to us | |||
if description: | |||
if hasattr(self.parser, 'main'): | |||
label = 'Commands' | |||
else: | |||
label = 'Description' | |||
# some doc strings have initial newlines, some don't | |||
description = description.lstrip('\n') | |||
# some doc strings have final newlines and spaces, some don't | |||
description = description.rstrip() | |||
# dedent, then reindent | |||
description = self.indent_lines(textwrap.dedent(description), " ") | |||
description = '%s:\n%s\n' % (label, description) | |||
return description | |||
else: | |||
return '' | |||
def format_epilog(self, epilog): | |||
# leave full control over epilog to us | |||
if epilog: | |||
return epilog | |||
else: | |||
return '' | |||
def indent_lines(self, text, indent): | |||
new_lines = [indent + line for line in text.split('\n')] | |||
return "\n".join(new_lines) | |||
class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter): | |||
"""Custom help formatter for use in ConfigOptionParser. | |||
This is updates the defaults before expanding them, allowing | |||
them to show up correctly in the help listing. | |||
""" | |||
def expand_default(self, option): | |||
if self.parser is not None: | |||
self.parser._update_defaults(self.parser.defaults) | |||
return optparse.IndentedHelpFormatter.expand_default(self, option) | |||
class CustomOptionParser(optparse.OptionParser): | |||
def insert_option_group(self, idx, *args, **kwargs): | |||
"""Insert an OptionGroup at a given position.""" | |||
group = self.add_option_group(*args, **kwargs) | |||
self.option_groups.pop() | |||
self.option_groups.insert(idx, group) | |||
return group | |||
@property | |||
def option_list_all(self): | |||
"""Get a list of all options, including those in option groups.""" | |||
res = self.option_list[:] | |||
for i in self.option_groups: | |||
res.extend(i.option_list) | |||
return res | |||
class ConfigOptionParser(CustomOptionParser): | |||
"""Custom option parser which updates its defaults by checking the | |||
configuration files and environmental variables""" | |||
def __init__(self, *args, **kwargs): | |||
self.name = kwargs.pop('name') | |||
isolated = kwargs.pop("isolated", False) | |||
self.config = Configuration(isolated) | |||
assert self.name | |||
optparse.OptionParser.__init__(self, *args, **kwargs) | |||
def check_default(self, option, key, val): | |||
try: | |||
return option.check_value(key, val) | |||
except optparse.OptionValueError as exc: | |||
print("An error occurred during configuration: %s" % exc) | |||
sys.exit(3) | |||
def _get_ordered_configuration_items(self): | |||
# Configuration gives keys in an unordered manner. Order them. | |||
override_order = ["global", self.name, ":env:"] | |||
# Pool the options into different groups | |||
section_items = {name: [] for name in override_order} | |||
for section_key, val in self.config.items(): | |||
# ignore empty values | |||
if not val: | |||
logger.debug( | |||
"Ignoring configuration key '%s' as it's value is empty.", | |||
section_key | |||
) | |||
continue | |||
section, key = section_key.split(".", 1) | |||
if section in override_order: | |||
section_items[section].append((key, val)) | |||
# Yield each group in their override order | |||
for section in override_order: | |||
for key, val in section_items[section]: | |||
yield key, val | |||
def _update_defaults(self, defaults): | |||
"""Updates the given defaults with values from the config files and | |||
the environ. Does a little special handling for certain types of | |||
options (lists).""" | |||
# Accumulate complex default state. | |||
self.values = optparse.Values(self.defaults) | |||
late_eval = set() | |||
# Then set the options with those values | |||
for key, val in self._get_ordered_configuration_items(): | |||
# '--' because configuration supports only long names | |||
option = self.get_option('--' + key) | |||
# Ignore options not present in this parser. E.g. non-globals put | |||
# in [global] by users that want them to apply to all applicable | |||
# commands. | |||
if option is None: | |||
continue | |||
if option.action in ('store_true', 'store_false', 'count'): | |||
val = strtobool(val) | |||
elif option.action == 'append': | |||
val = val.split() | |||
val = [self.check_default(option, key, v) for v in val] | |||
elif option.action == 'callback': | |||
late_eval.add(option.dest) | |||
opt_str = option.get_opt_string() | |||
val = option.convert_value(opt_str, val) | |||
# From take_action | |||
args = option.callback_args or () | |||
kwargs = option.callback_kwargs or {} | |||
option.callback(option, opt_str, val, self, *args, **kwargs) | |||
else: | |||
val = self.check_default(option, key, val) | |||
defaults[option.dest] = val | |||
for key in late_eval: | |||
defaults[key] = getattr(self.values, key) | |||
self.values = None | |||
return defaults | |||
def get_default_values(self): | |||
"""Overriding to make updating the defaults after instantiation of | |||
the option parser possible, _update_defaults() does the dirty work.""" | |||
if not self.process_default_values: | |||
# Old, pre-Optik 1.5 behaviour. | |||
return optparse.Values(self.defaults) | |||
# Load the configuration, or error out in case of an error | |||
try: | |||
self.config.load() | |||
except ConfigurationError as err: | |||
self.exit(2, err.args[0]) | |||
defaults = self._update_defaults(self.defaults.copy()) # ours | |||
for option in self._get_all_options(): | |||
default = defaults.get(option.dest) | |||
if isinstance(default, string_types): | |||
opt_str = option.get_opt_string() | |||
defaults[option.dest] = option.check_value(opt_str, default) | |||
return optparse.Values(defaults) | |||
def error(self, msg): | |||
self.print_usage(sys.stderr) | |||
self.exit(2, "%s\n" % msg) |
@@ -0,0 +1,92 @@ | |||
"""Build Environment used for isolation during sdist building | |||
""" | |||
import os | |||
from distutils.sysconfig import get_python_lib | |||
from sysconfig import get_paths | |||
from pip._internal.utils.temp_dir import TempDirectory | |||
class BuildEnvironment(object): | |||
"""Creates and manages an isolated environment to install build deps | |||
""" | |||
def __init__(self, no_clean): | |||
self._temp_dir = TempDirectory(kind="build-env") | |||
self._no_clean = no_clean | |||
@property | |||
def path(self): | |||
return self._temp_dir.path | |||
def __enter__(self): | |||
self._temp_dir.create() | |||
self.save_path = os.environ.get('PATH', None) | |||
self.save_pythonpath = os.environ.get('PYTHONPATH', None) | |||
self.save_nousersite = os.environ.get('PYTHONNOUSERSITE', None) | |||
install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix' | |||
install_dirs = get_paths(install_scheme, vars={ | |||
'base': self.path, | |||
'platbase': self.path, | |||
}) | |||
scripts = install_dirs['scripts'] | |||
if self.save_path: | |||
os.environ['PATH'] = scripts + os.pathsep + self.save_path | |||
else: | |||
os.environ['PATH'] = scripts + os.pathsep + os.defpath | |||
# Note: prefer distutils' sysconfig to get the | |||
# library paths so PyPy is correctly supported. | |||
purelib = get_python_lib(plat_specific=0, prefix=self.path) | |||
platlib = get_python_lib(plat_specific=1, prefix=self.path) | |||
if purelib == platlib: | |||
lib_dirs = purelib | |||
else: | |||
lib_dirs = purelib + os.pathsep + platlib | |||
if self.save_pythonpath: | |||
os.environ['PYTHONPATH'] = lib_dirs + os.pathsep + \ | |||
self.save_pythonpath | |||
else: | |||
os.environ['PYTHONPATH'] = lib_dirs | |||
os.environ['PYTHONNOUSERSITE'] = '1' | |||
return self.path | |||
def __exit__(self, exc_type, exc_val, exc_tb): | |||
if not self._no_clean: | |||
self._temp_dir.cleanup() | |||
def restore_var(varname, old_value): | |||
if old_value is None: | |||
os.environ.pop(varname, None) | |||
else: | |||
os.environ[varname] = old_value | |||
restore_var('PATH', self.save_path) | |||
restore_var('PYTHONPATH', self.save_pythonpath) | |||
restore_var('PYTHONNOUSERSITE', self.save_nousersite) | |||
def cleanup(self): | |||
self._temp_dir.cleanup() | |||
class NoOpBuildEnvironment(BuildEnvironment): | |||
"""A no-op drop-in replacement for BuildEnvironment | |||
""" | |||
def __init__(self, no_clean): | |||
pass | |||
def __enter__(self): | |||
pass | |||
def __exit__(self, exc_type, exc_val, exc_tb): | |||
pass | |||
def cleanup(self): | |||
pass |
@@ -0,0 +1,202 @@ | |||
"""Cache Management | |||
""" | |||
import errno | |||
import hashlib | |||
import logging | |||
import os | |||
from pip._vendor.packaging.utils import canonicalize_name | |||
from pip._internal import index | |||
from pip._internal.compat import expanduser | |||
from pip._internal.download import path_to_url | |||
from pip._internal.utils.temp_dir import TempDirectory | |||
from pip._internal.wheel import InvalidWheelFilename, Wheel | |||
logger = logging.getLogger(__name__) | |||
class Cache(object): | |||
"""An abstract class - provides cache directories for data from links | |||
:param cache_dir: The root of the cache. | |||
:param format_control: A pip.index.FormatControl object to limit | |||
binaries being read from the cache. | |||
:param allowed_formats: which formats of files the cache should store. | |||
('binary' and 'source' are the only allowed values) | |||
""" | |||
def __init__(self, cache_dir, format_control, allowed_formats): | |||
super(Cache, self).__init__() | |||
self.cache_dir = expanduser(cache_dir) if cache_dir else None | |||
self.format_control = format_control | |||
self.allowed_formats = allowed_formats | |||
_valid_formats = {"source", "binary"} | |||
assert self.allowed_formats.union(_valid_formats) == _valid_formats | |||
def _get_cache_path_parts(self, link): | |||
"""Get parts of part that must be os.path.joined with cache_dir | |||
""" | |||
# We want to generate an url to use as our cache key, we don't want to | |||
# just re-use the URL because it might have other items in the fragment | |||
# and we don't care about those. | |||
key_parts = [link.url_without_fragment] | |||
if link.hash_name is not None and link.hash is not None: | |||
key_parts.append("=".join([link.hash_name, link.hash])) | |||
key_url = "#".join(key_parts) | |||
# Encode our key url with sha224, we'll use this because it has similar | |||
# security properties to sha256, but with a shorter total output (and | |||
# thus less secure). However the differences don't make a lot of | |||
# difference for our use case here. | |||
hashed = hashlib.sha224(key_url.encode()).hexdigest() | |||
# We want to nest the directories some to prevent having a ton of top | |||
# level directories where we might run out of sub directories on some | |||
# FS. | |||
parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] | |||
return parts | |||
def _get_candidates(self, link, package_name): | |||
can_not_cache = ( | |||
not self.cache_dir or | |||
not package_name or | |||
not link | |||
) | |||
if can_not_cache: | |||
return [] | |||
canonical_name = canonicalize_name(package_name) | |||
formats = index.fmt_ctl_formats( | |||
self.format_control, canonical_name | |||
) | |||
if not self.allowed_formats.intersection(formats): | |||
return [] | |||
root = self.get_path_for_link(link) | |||
try: | |||
return os.listdir(root) | |||
except OSError as err: | |||
if err.errno in {errno.ENOENT, errno.ENOTDIR}: | |||
return [] | |||
raise | |||
def get_path_for_link(self, link): | |||
"""Return a directory to store cached items in for link. | |||
""" | |||
raise NotImplementedError() | |||
def get(self, link, package_name): | |||
"""Returns a link to a cached item if it exists, otherwise returns the | |||
passed link. | |||
""" | |||
raise NotImplementedError() | |||
def _link_for_candidate(self, link, candidate): | |||
root = self.get_path_for_link(link) | |||
path = os.path.join(root, candidate) | |||
return index.Link(path_to_url(path)) | |||
def cleanup(self): | |||
pass | |||
class SimpleWheelCache(Cache): | |||
"""A cache of wheels for future installs. | |||
""" | |||
def __init__(self, cache_dir, format_control): | |||
super(SimpleWheelCache, self).__init__( | |||
cache_dir, format_control, {"binary"} | |||
) | |||
def get_path_for_link(self, link): | |||
"""Return a directory to store cached wheels for link | |||
Because there are M wheels for any one sdist, we provide a directory | |||
to cache them in, and then consult that directory when looking up | |||
cache hits. | |||
We only insert things into the cache if they have plausible version | |||
numbers, so that we don't contaminate the cache with things that were | |||
not unique. E.g. ./package might have dozens of installs done for it | |||
and build a version of 0.0...and if we built and cached a wheel, we'd | |||
end up using the same wheel even if the source has been edited. | |||
:param link: The link of the sdist for which this will cache wheels. | |||
""" | |||
parts = self._get_cache_path_parts(link) | |||
# Store wheels within the root cache_dir | |||
return os.path.join(self.cache_dir, "wheels", *parts) | |||
def get(self, link, package_name): | |||
candidates = [] | |||
for wheel_name in self._get_candidates(link, package_name): | |||
try: | |||
wheel = Wheel(wheel_name) | |||
except InvalidWheelFilename: | |||
continue | |||
if not wheel.supported(): | |||
# Built for a different python/arch/etc | |||
continue | |||
candidates.append((wheel.support_index_min(), wheel_name)) | |||
if not candidates: | |||
return link | |||
return self._link_for_candidate(link, min(candidates)[1]) | |||
class EphemWheelCache(SimpleWheelCache): | |||
"""A SimpleWheelCache that creates it's own temporary cache directory | |||
""" | |||
def __init__(self, format_control): | |||
self._temp_dir = TempDirectory(kind="ephem-wheel-cache") | |||
self._temp_dir.create() | |||