com.googler.python 1.0.8 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/python3.4.2/lib/python3.4/site-packages/pip/__init__.py +1 -277
- package/python3.4.2/lib/python3.4/site-packages/pip/__main__.py +19 -7
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/__init__.py +246 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/basecommand.py +373 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/{baseparser.py → _internal/baseparser.py} +240 -224
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/build_env.py +92 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/cache.py +202 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/cmdoptions.py +609 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/__init__.py +79 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/check.py +42 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/completion.py +94 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/configuration.py +227 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/download.py +233 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/freeze.py +96 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/hash.py +57 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/{commands → _internal/commands}/help.py +36 -33
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/install.py +477 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/list.py +343 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/search.py +135 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/show.py +164 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/uninstall.py +71 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/commands/wheel.py +179 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/compat.py +235 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/configuration.py +378 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/download.py +922 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/exceptions.py +249 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/index.py +1117 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/locations.py +194 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/models/__init__.py +4 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/models/index.py +15 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/{_vendor/requests/packages/urllib3/contrib → _internal/operations}/__init__.py +0 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/operations/check.py +106 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/operations/freeze.py +252 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/operations/prepare.py +378 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/pep425tags.py +317 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/req/__init__.py +69 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/req/req_file.py +338 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/req/req_install.py +1115 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/req/req_set.py +164 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/req/req_uninstall.py +455 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/resolve.py +354 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/{status_codes.py → _internal/status_codes.py} +8 -6
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/__init__.py +0 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/appdirs.py +258 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/deprecation.py +77 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/encoding.py +33 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/filesystem.py +28 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/glibc.py +84 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/hashes.py +94 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/logging.py +132 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/misc.py +851 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/outdated.py +163 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/packaging.py +70 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/setuptools_build.py +8 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/temp_dir.py +82 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/typing.py +29 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/utils/ui.py +421 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/vcs/__init__.py +471 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/vcs/bazaar.py +113 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/vcs/git.py +311 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/vcs/mercurial.py +105 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/vcs/subversion.py +271 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_internal/wheel.py +817 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/__init__.py +109 -8
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/appdirs.py +604 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/__init__.py +11 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/_cmd.py +60 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/adapter.py +134 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/cache.py +39 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/caches/__init__.py +2 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py +133 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py +43 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/compat.py +29 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/controller.py +373 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/filewrapper.py +78 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/heuristics.py +138 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/serialize.py +194 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/cachecontrol/wrapper.py +27 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/certifi/__init__.py +3 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/certifi/__main__.py +2 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests → certifi}/cacert.pem +1765 -2358
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/certifi/core.py +37 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/__init__.py +39 -32
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/big5freq.py +386 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/big5prober.py +47 -42
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/chardistribution.py +233 -231
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/charsetgroupprober.py +106 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/charsetprober.py +145 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/cli/__init__.py +1 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/cli/chardetect.py +85 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/codingstatemachine.py +88 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/compat.py +34 -34
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/cp949prober.py +49 -44
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/enums.py +76 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/escprober.py +101 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/escsm.py +246 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/eucjpprober.py +92 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/euckrfreq.py +195 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/euckrprober.py +47 -42
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/euctwfreq.py +387 -428
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/euctwprober.py +46 -41
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/gb2312freq.py +283 -472
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/gb2312prober.py +46 -41
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/hebrewprober.py +292 -283
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/jisfreq.py +325 -569
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/jpcntx.py +233 -219
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/langbulgarianmodel.py +228 -229
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/langcyrillicmodel.py +333 -329
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/langgreekmodel.py +225 -225
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/langhebrewmodel.py +200 -201
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/langhungarianmodel.py +225 -225
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/langthaimodel.py +199 -200
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/langturkishmodel.py +193 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/latin1prober.py +145 -139
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/mbcharsetprober.py +91 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/mbcsgroupprober.py +54 -54
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/mbcssm.py +572 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/sbcharsetprober.py +132 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/sbcsgroupprober.py +73 -69
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/sjisprober.py +92 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/universaldetector.py +286 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/chardet → chardet}/utf8prober.py +82 -76
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/chardet/version.py +9 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/colorama/__init__.py +7 -7
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/colorama/ansi.py +102 -50
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/colorama/ansitowin32.py +236 -190
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/colorama/initialise.py +82 -56
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/colorama/win32.py +156 -137
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/colorama/winterm.py +162 -120
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/__init__.py +23 -23
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/_backport/__init__.py +6 -6
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/_backport/misc.py +41 -41
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/_backport/shutil.py +761 -761
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg +84 -84
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/_backport/sysconfig.py +788 -788
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/_backport/tarfile.py +2607 -2607
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/compat.py +1117 -1064
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/database.py +1318 -1301
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/index.py +516 -488
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/locators.py +1292 -1194
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/manifest.py +393 -364
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/markers.py +131 -190
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/metadata.py +1068 -1026
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/resources.py +355 -317
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/scripts.py +415 -323
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/t32.exe +0 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/t64.exe +0 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/util.py +1755 -1575
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/version.py +736 -721
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/w32.exe +0 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/w64.exe +0 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distlib/wheel.py +984 -958
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/distro.py +1104 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/__init__.py +35 -23
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{ihatexml.py → _ihatexml.py} +288 -285
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{inputstream.py → _inputstream.py} +923 -881
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{tokenizer.py → _tokenizer.py} +1721 -1731
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{trie → _trie}/__init__.py +14 -12
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{trie → _trie}/_base.py +37 -37
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{trie → _trie}/datrie.py +44 -44
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{trie → _trie}/py.py +67 -67
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/{utils.py → _utils.py} +124 -82
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/constants.py +2947 -3104
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py +29 -20
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/{_base.py → base.py} +12 -12
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py +73 -65
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/lint.py +93 -93
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/optionaltags.py +207 -205
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/sanitizer.py +896 -12
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/filters/whitespace.py +38 -38
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/html5parser.py +2791 -2713
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/serializer.py +409 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py +30 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py +54 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treeadapters/sax.py +50 -44
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py +88 -76
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treebuilders/{_base.py → base.py} +417 -377
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treebuilders/dom.py +236 -227
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treebuilders/etree.py +340 -337
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py +366 -369
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py +154 -57
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/{_base.py → base.py} +252 -200
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/dom.py +43 -46
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/etree.py +130 -138
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/{lxmletree.py → etree_lxml.py} +213 -208
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/{genshistream.py → genshi.py} +69 -69
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/__init__.py +2 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/codec.py +118 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/compat.py +12 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/core.py +387 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/idnadata.py +1585 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/intranges.py +53 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/package_data.py +2 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/idna/uts46data.py +7634 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/ipaddress.py +2419 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/lockfile/__init__.py +347 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/lockfile/linklockfile.py +73 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/lockfile/mkdirlockfile.py +84 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/lockfile/pidlockfile.py +190 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/lockfile/sqlitelockfile.py +156 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/lockfile/symlinklockfile.py +70 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/msgpack/__init__.py +66 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/msgpack/_version.py +1 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/msgpack/exceptions.py +41 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/msgpack/fallback.py +971 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/__about__.py +21 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/__init__.py +14 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/_compat.py +30 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/_structures.py +70 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/markers.py +301 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/requirements.py +130 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/specifiers.py +774 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/utils.py +63 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/packaging/version.py +441 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{pkg_resources.py → pkg_resources/__init__.py} +3125 -2762
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/pkg_resources/py31compat.py +22 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/progress/__init__.py +127 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/progress/bar.py +88 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/progress/counter.py +48 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/progress/helpers.py +91 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/progress/spinner.py +44 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/pyparsing.py +5720 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/pytoml/__init__.py +3 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/pytoml/core.py +13 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/pytoml/parser.py +374 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/pytoml/writer.py +127 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/__init__.py +123 -77
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/__version__.py +14 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/_internal_utils.py +42 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/adapters.py +525 -388
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/api.py +152 -120
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/auth.py +293 -193
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/certs.py +18 -24
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/compat.py +73 -115
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/cookies.py +542 -454
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/exceptions.py +122 -75
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/help.py +120 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/hooks.py +34 -45
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/models.py +948 -803
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages.py +16 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/sessions.py +737 -637
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/status_codes.py +91 -88
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/structures.py +105 -127
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/utils.py +904 -673
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/retrying.py +267 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/six.py +891 -646
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/__init__.py +97 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/_collections.py +319 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/connection.py +373 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/connectionpool.py +905 -710
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/__init__.py +0 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py +0 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py +593 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py +343 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/appengine.py +296 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/contrib/ntlmpool.py +112 -120
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py +455 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/securetransport.py +810 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/contrib/socks.py +188 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/exceptions.py +246 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/fields.py +178 -177
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/filepost.py +94 -100
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/packages/__init__.py +5 -4
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py +0 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py +53 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/packages/ordered_dict.py +259 -260
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/packages/six.py +868 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/packages/ssl_match_hostname/__init__.py +19 -13
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/packages/ssl_match_hostname/_implementation.py +157 -105
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/poolmanager.py +440 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/request.py +148 -141
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/response.py +626 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/__init__.py +54 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/connection.py +130 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/request.py +118 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/response.py +81 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/retry.py +401 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/selectors.py +581 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/ssl_.py +341 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/util/timeout.py +242 -234
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/{requests/packages/urllib3 → urllib3}/util/url.py +230 -162
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/urllib3/util/wait.py +40 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/webencodings/__init__.py +342 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/webencodings/labels.py +231 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/webencodings/mklabels.py +59 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/webencodings/tests.py +153 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/webencodings/x_user_defined.py +325 -0
- package/python3.4.2/lib/python3.4/site-packages/pip-10.0.0.dist-info/LICENSE.txt +20 -0
- package/python3.4.2/lib/python3.4/site-packages/pip-10.0.0.dist-info/METADATA +78 -0
- package/python3.4.2/lib/python3.4/site-packages/pip-10.0.0.dist-info/RECORD +294 -0
- package/python3.4.2/lib/python3.4/site-packages/{pip-1.5.6.dist-info → pip-10.0.0.dist-info}/WHEEL +6 -6
- package/python3.4.2/lib/python3.4/site-packages/pip-10.0.0.dist-info/entry_points.txt +5 -0
- package/python3.4.2/lib/python3.4/site-packages/{pip-1.5.6.dist-info → pip-10.0.0.dist-info}/top_level.txt +0 -0
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/_markerlib/__init__.py +0 -16
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/_markerlib/markers.py +0 -119
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/sanitizer.py +0 -271
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/serializer/__init__.py +0 -16
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/serializer/htmlserializer.py +0 -320
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/html5lib/treewalkers/pulldom.py +0 -63
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/re-vendor.py +0 -34
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/__init__.py +0 -3
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/big5freq.py +0 -925
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/chardetect.py +0 -46
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/charsetgroupprober.py +0 -106
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/charsetprober.py +0 -62
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/codingstatemachine.py +0 -61
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/constants.py +0 -39
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/escprober.py +0 -86
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/escsm.py +0 -242
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/eucjpprober.py +0 -90
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/euckrfreq.py +0 -596
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/mbcharsetprober.py +0 -86
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/mbcssm.py +0 -575
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/sbcharsetprober.py +0 -120
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/sjisprober.py +0 -91
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/chardet/universaldetector.py +0 -170
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/__init__.py +0 -58
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/_collections.py +0 -205
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/connection.py +0 -204
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/contrib/pyopenssl.py +0 -422
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/exceptions.py +0 -126
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/packages/six.py +0 -385
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/poolmanager.py +0 -258
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/response.py +0 -308
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/util/__init__.py +0 -27
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/util/connection.py +0 -45
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/util/request.py +0 -68
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/util/response.py +0 -13
- package/python3.4.2/lib/python3.4/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py +0 -133
- package/python3.4.2/lib/python3.4/site-packages/pip/backwardcompat/__init__.py +0 -138
- package/python3.4.2/lib/python3.4/site-packages/pip/basecommand.py +0 -201
- package/python3.4.2/lib/python3.4/site-packages/pip/cmdoptions.py +0 -371
- package/python3.4.2/lib/python3.4/site-packages/pip/commands/__init__.py +0 -88
- package/python3.4.2/lib/python3.4/site-packages/pip/commands/bundle.py +0 -42
- package/python3.4.2/lib/python3.4/site-packages/pip/commands/completion.py +0 -59
- package/python3.4.2/lib/python3.4/site-packages/pip/commands/freeze.py +0 -114
- package/python3.4.2/lib/python3.4/site-packages/pip/commands/install.py +0 -314
- package/python3.4.2/lib/python3.4/site-packages/pip/commands/list.py +0 -162
- package/python3.4.2/lib/python3.4/site-packages/pip/commands/search.py +0 -132
- package/python3.4.2/lib/python3.4/site-packages/pip/commands/show.py +0 -80
- package/python3.4.2/lib/python3.4/site-packages/pip/commands/uninstall.py +0 -59
- package/python3.4.2/lib/python3.4/site-packages/pip/commands/unzip.py +0 -7
- package/python3.4.2/lib/python3.4/site-packages/pip/commands/wheel.py +0 -195
- package/python3.4.2/lib/python3.4/site-packages/pip/commands/zip.py +0 -351
- package/python3.4.2/lib/python3.4/site-packages/pip/download.py +0 -644
- package/python3.4.2/lib/python3.4/site-packages/pip/exceptions.py +0 -46
- package/python3.4.2/lib/python3.4/site-packages/pip/index.py +0 -990
- package/python3.4.2/lib/python3.4/site-packages/pip/locations.py +0 -171
- package/python3.4.2/lib/python3.4/site-packages/pip/log.py +0 -276
- package/python3.4.2/lib/python3.4/site-packages/pip/pep425tags.py +0 -102
- package/python3.4.2/lib/python3.4/site-packages/pip/req.py +0 -1931
- package/python3.4.2/lib/python3.4/site-packages/pip/runner.py +0 -18
- package/python3.4.2/lib/python3.4/site-packages/pip/util.py +0 -720
- package/python3.4.2/lib/python3.4/site-packages/pip/vcs/__init__.py +0 -251
- package/python3.4.2/lib/python3.4/site-packages/pip/vcs/bazaar.py +0 -131
- package/python3.4.2/lib/python3.4/site-packages/pip/vcs/git.py +0 -194
- package/python3.4.2/lib/python3.4/site-packages/pip/vcs/mercurial.py +0 -151
- package/python3.4.2/lib/python3.4/site-packages/pip/vcs/subversion.py +0 -273
- package/python3.4.2/lib/python3.4/site-packages/pip/wheel.py +0 -560
- package/python3.4.2/lib/python3.4/site-packages/pip-1.5.6.dist-info/DESCRIPTION.rst +0 -71
- package/python3.4.2/lib/python3.4/site-packages/pip-1.5.6.dist-info/METADATA +0 -98
- package/python3.4.2/lib/python3.4/site-packages/pip-1.5.6.dist-info/RECORD +0 -373
- package/python3.4.2/lib/python3.4/site-packages/pip-1.5.6.dist-info/entry_points.txt +0 -5
- package/python3.4.2/lib/python3.4/site-packages/pip-1.5.6.dist-info/metadata.json +0 -1
|
@@ -1,1931 +0,0 @@
|
|
|
1
|
-
from email.parser import FeedParser
|
|
2
|
-
import os
|
|
3
|
-
import imp
|
|
4
|
-
import locale
|
|
5
|
-
import re
|
|
6
|
-
import sys
|
|
7
|
-
import shutil
|
|
8
|
-
import tempfile
|
|
9
|
-
import textwrap
|
|
10
|
-
import zipfile
|
|
11
|
-
|
|
12
|
-
from distutils.util import change_root
|
|
13
|
-
from pip.locations import (bin_py, running_under_virtualenv,PIP_DELETE_MARKER_FILENAME,
|
|
14
|
-
write_delete_marker_file, bin_user)
|
|
15
|
-
from pip.exceptions import (InstallationError, UninstallationError, UnsupportedWheel,
|
|
16
|
-
BestVersionAlreadyInstalled, InvalidWheelFilename,
|
|
17
|
-
DistributionNotFound, PreviousBuildDirError)
|
|
18
|
-
from pip.vcs import vcs
|
|
19
|
-
from pip.log import logger
|
|
20
|
-
from pip.util import (display_path, rmtree, ask, ask_path_exists, backup_dir,
|
|
21
|
-
is_installable_dir, is_local, dist_is_local,
|
|
22
|
-
dist_in_usersite, dist_in_site_packages, renames,
|
|
23
|
-
normalize_path, egg_link_path, make_path_relative,
|
|
24
|
-
call_subprocess, is_prerelease, normalize_name)
|
|
25
|
-
from pip.backwardcompat import (urlparse, urllib, uses_pycache,
|
|
26
|
-
ConfigParser, string_types, HTTPError,
|
|
27
|
-
get_python_version, b)
|
|
28
|
-
from pip.index import Link
|
|
29
|
-
from pip.locations import build_prefix
|
|
30
|
-
from pip.download import (PipSession, get_file_content, is_url, url_to_path,
|
|
31
|
-
path_to_url, is_archive_file,
|
|
32
|
-
unpack_vcs_link, is_vcs_url, is_file_url,
|
|
33
|
-
unpack_file_url, unpack_http_url)
|
|
34
|
-
import pip.wheel
|
|
35
|
-
from pip.wheel import move_wheel_files, Wheel, wheel_ext
|
|
36
|
-
from pip._vendor import pkg_resources, six
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def read_text_file(filename):
|
|
40
|
-
"""Return the contents of *filename*.
|
|
41
|
-
|
|
42
|
-
Try to decode the file contents with utf-8, the preffered system encoding
|
|
43
|
-
(e.g., cp1252 on some Windows machines) and latin1, in that order. Decoding
|
|
44
|
-
a byte string with latin1 will never raise an error. In the worst case, the
|
|
45
|
-
returned string will contain some garbage characters.
|
|
46
|
-
|
|
47
|
-
"""
|
|
48
|
-
with open(filename, 'rb') as fp:
|
|
49
|
-
data = fp.read()
|
|
50
|
-
|
|
51
|
-
encodings = ['utf-8', locale.getpreferredencoding(False), 'latin1']
|
|
52
|
-
for enc in encodings:
|
|
53
|
-
try:
|
|
54
|
-
data = data.decode(enc)
|
|
55
|
-
except UnicodeDecodeError:
|
|
56
|
-
continue
|
|
57
|
-
break
|
|
58
|
-
|
|
59
|
-
assert type(data) != bytes # Latin1 should have worked.
|
|
60
|
-
return data
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
class InstallRequirement(object):
|
|
64
|
-
|
|
65
|
-
def __init__(self, req, comes_from, source_dir=None, editable=False,
|
|
66
|
-
url=None, as_egg=False, update=True, prereleases=None,
|
|
67
|
-
editable_options=None, from_bundle=False, pycompile=True):
|
|
68
|
-
self.extras = ()
|
|
69
|
-
if isinstance(req, string_types):
|
|
70
|
-
req = pkg_resources.Requirement.parse(req)
|
|
71
|
-
self.extras = req.extras
|
|
72
|
-
self.req = req
|
|
73
|
-
self.comes_from = comes_from
|
|
74
|
-
self.source_dir = source_dir
|
|
75
|
-
self.editable = editable
|
|
76
|
-
|
|
77
|
-
if editable_options is None:
|
|
78
|
-
editable_options = {}
|
|
79
|
-
|
|
80
|
-
self.editable_options = editable_options
|
|
81
|
-
self.url = url
|
|
82
|
-
self.as_egg = as_egg
|
|
83
|
-
self._egg_info_path = None
|
|
84
|
-
# This holds the pkg_resources.Distribution object if this requirement
|
|
85
|
-
# is already available:
|
|
86
|
-
self.satisfied_by = None
|
|
87
|
-
# This hold the pkg_resources.Distribution object if this requirement
|
|
88
|
-
# conflicts with another installed distribution:
|
|
89
|
-
self.conflicts_with = None
|
|
90
|
-
self._temp_build_dir = None
|
|
91
|
-
self._is_bundle = None
|
|
92
|
-
# True if the editable should be updated:
|
|
93
|
-
self.update = update
|
|
94
|
-
# Set to True after successful installation
|
|
95
|
-
self.install_succeeded = None
|
|
96
|
-
# UninstallPathSet of uninstalled distribution (for possible rollback)
|
|
97
|
-
self.uninstalled = None
|
|
98
|
-
self.use_user_site = False
|
|
99
|
-
self.target_dir = None
|
|
100
|
-
self.from_bundle = from_bundle
|
|
101
|
-
|
|
102
|
-
self.pycompile = pycompile
|
|
103
|
-
|
|
104
|
-
# True if pre-releases are acceptable
|
|
105
|
-
if prereleases:
|
|
106
|
-
self.prereleases = True
|
|
107
|
-
elif self.req is not None:
|
|
108
|
-
self.prereleases = any([is_prerelease(x[1]) and x[0] != "!=" for x in self.req.specs])
|
|
109
|
-
else:
|
|
110
|
-
self.prereleases = False
|
|
111
|
-
|
|
112
|
-
@classmethod
|
|
113
|
-
def from_editable(cls, editable_req, comes_from=None, default_vcs=None):
|
|
114
|
-
name, url, extras_override = parse_editable(editable_req, default_vcs)
|
|
115
|
-
if url.startswith('file:'):
|
|
116
|
-
source_dir = url_to_path(url)
|
|
117
|
-
else:
|
|
118
|
-
source_dir = None
|
|
119
|
-
|
|
120
|
-
res = cls(name, comes_from, source_dir=source_dir,
|
|
121
|
-
editable=True,
|
|
122
|
-
url=url,
|
|
123
|
-
editable_options=extras_override,
|
|
124
|
-
prereleases=True)
|
|
125
|
-
|
|
126
|
-
if extras_override is not None:
|
|
127
|
-
res.extras = extras_override
|
|
128
|
-
|
|
129
|
-
return res
|
|
130
|
-
|
|
131
|
-
@classmethod
|
|
132
|
-
def from_line(cls, name, comes_from=None, prereleases=None):
|
|
133
|
-
"""Creates an InstallRequirement from a name, which might be a
|
|
134
|
-
requirement, directory containing 'setup.py', filename, or URL.
|
|
135
|
-
"""
|
|
136
|
-
url = None
|
|
137
|
-
name = name.strip()
|
|
138
|
-
req = None
|
|
139
|
-
path = os.path.normpath(os.path.abspath(name))
|
|
140
|
-
link = None
|
|
141
|
-
|
|
142
|
-
if is_url(name):
|
|
143
|
-
link = Link(name)
|
|
144
|
-
elif os.path.isdir(path) and (os.path.sep in name or name.startswith('.')):
|
|
145
|
-
if not is_installable_dir(path):
|
|
146
|
-
raise InstallationError("Directory %r is not installable. File 'setup.py' not found." % name)
|
|
147
|
-
link = Link(path_to_url(name))
|
|
148
|
-
elif is_archive_file(path):
|
|
149
|
-
if not os.path.isfile(path):
|
|
150
|
-
logger.warn('Requirement %r looks like a filename, but the file does not exist', name)
|
|
151
|
-
link = Link(path_to_url(name))
|
|
152
|
-
|
|
153
|
-
# If the line has an egg= definition, but isn't editable, pull the requirement out.
|
|
154
|
-
# Otherwise, assume the name is the req for the non URL/path/archive case.
|
|
155
|
-
if link and req is None:
|
|
156
|
-
url = link.url_without_fragment
|
|
157
|
-
req = link.egg_fragment #when fragment is None, this will become an 'unnamed' requirement
|
|
158
|
-
|
|
159
|
-
# Handle relative file URLs
|
|
160
|
-
if link.scheme == 'file' and re.search(r'\.\./', url):
|
|
161
|
-
url = path_to_url(os.path.normpath(os.path.abspath(link.path)))
|
|
162
|
-
|
|
163
|
-
# fail early for invalid or unsupported wheels
|
|
164
|
-
if link.ext == wheel_ext:
|
|
165
|
-
wheel = Wheel(link.filename) # can raise InvalidWheelFilename
|
|
166
|
-
if not wheel.supported():
|
|
167
|
-
raise UnsupportedWheel("%s is not a supported wheel on this platform." % wheel.filename)
|
|
168
|
-
|
|
169
|
-
else:
|
|
170
|
-
req = name
|
|
171
|
-
|
|
172
|
-
return cls(req, comes_from, url=url, prereleases=prereleases)
|
|
173
|
-
|
|
174
|
-
def __str__(self):
|
|
175
|
-
if self.req:
|
|
176
|
-
s = str(self.req)
|
|
177
|
-
if self.url:
|
|
178
|
-
s += ' from %s' % self.url
|
|
179
|
-
else:
|
|
180
|
-
s = self.url
|
|
181
|
-
if self.satisfied_by is not None:
|
|
182
|
-
s += ' in %s' % display_path(self.satisfied_by.location)
|
|
183
|
-
if self.comes_from:
|
|
184
|
-
if isinstance(self.comes_from, string_types):
|
|
185
|
-
comes_from = self.comes_from
|
|
186
|
-
else:
|
|
187
|
-
comes_from = self.comes_from.from_path()
|
|
188
|
-
if comes_from:
|
|
189
|
-
s += ' (from %s)' % comes_from
|
|
190
|
-
return s
|
|
191
|
-
|
|
192
|
-
def from_path(self):
|
|
193
|
-
if self.req is None:
|
|
194
|
-
return None
|
|
195
|
-
s = str(self.req)
|
|
196
|
-
if self.comes_from:
|
|
197
|
-
if isinstance(self.comes_from, string_types):
|
|
198
|
-
comes_from = self.comes_from
|
|
199
|
-
else:
|
|
200
|
-
comes_from = self.comes_from.from_path()
|
|
201
|
-
if comes_from:
|
|
202
|
-
s += '->' + comes_from
|
|
203
|
-
return s
|
|
204
|
-
|
|
205
|
-
def build_location(self, build_dir, unpack=True):
|
|
206
|
-
if self._temp_build_dir is not None:
|
|
207
|
-
return self._temp_build_dir
|
|
208
|
-
if self.req is None:
|
|
209
|
-
self._temp_build_dir = tempfile.mkdtemp('-build', 'pip-')
|
|
210
|
-
self._ideal_build_dir = build_dir
|
|
211
|
-
return self._temp_build_dir
|
|
212
|
-
if self.editable:
|
|
213
|
-
name = self.name.lower()
|
|
214
|
-
else:
|
|
215
|
-
name = self.name
|
|
216
|
-
# FIXME: Is there a better place to create the build_dir? (hg and bzr need this)
|
|
217
|
-
if not os.path.exists(build_dir):
|
|
218
|
-
_make_build_dir(build_dir)
|
|
219
|
-
return os.path.join(build_dir, name)
|
|
220
|
-
|
|
221
|
-
def correct_build_location(self):
|
|
222
|
-
"""If the build location was a temporary directory, this will move it
|
|
223
|
-
to a new more permanent location"""
|
|
224
|
-
if self.source_dir is not None:
|
|
225
|
-
return
|
|
226
|
-
assert self.req is not None
|
|
227
|
-
assert self._temp_build_dir
|
|
228
|
-
old_location = self._temp_build_dir
|
|
229
|
-
new_build_dir = self._ideal_build_dir
|
|
230
|
-
del self._ideal_build_dir
|
|
231
|
-
if self.editable:
|
|
232
|
-
name = self.name.lower()
|
|
233
|
-
else:
|
|
234
|
-
name = self.name
|
|
235
|
-
new_location = os.path.join(new_build_dir, name)
|
|
236
|
-
if not os.path.exists(new_build_dir):
|
|
237
|
-
logger.debug('Creating directory %s' % new_build_dir)
|
|
238
|
-
_make_build_dir(new_build_dir)
|
|
239
|
-
if os.path.exists(new_location):
|
|
240
|
-
raise InstallationError(
|
|
241
|
-
'A package already exists in %s; please remove it to continue'
|
|
242
|
-
% display_path(new_location))
|
|
243
|
-
logger.debug('Moving package %s from %s to new location %s'
|
|
244
|
-
% (self, display_path(old_location), display_path(new_location)))
|
|
245
|
-
shutil.move(old_location, new_location)
|
|
246
|
-
self._temp_build_dir = new_location
|
|
247
|
-
self.source_dir = new_location
|
|
248
|
-
self._egg_info_path = None
|
|
249
|
-
|
|
250
|
-
@property
|
|
251
|
-
def name(self):
|
|
252
|
-
if self.req is None:
|
|
253
|
-
return None
|
|
254
|
-
return self.req.project_name
|
|
255
|
-
|
|
256
|
-
@property
|
|
257
|
-
def url_name(self):
|
|
258
|
-
if self.req is None:
|
|
259
|
-
return None
|
|
260
|
-
return urllib.quote(self.req.unsafe_name)
|
|
261
|
-
|
|
262
|
-
@property
|
|
263
|
-
def setup_py(self):
|
|
264
|
-
try:
|
|
265
|
-
import setuptools
|
|
266
|
-
except ImportError:
|
|
267
|
-
# Setuptools is not available
|
|
268
|
-
raise InstallationError(
|
|
269
|
-
"setuptools must be installed to install from a source "
|
|
270
|
-
"distribution"
|
|
271
|
-
)
|
|
272
|
-
|
|
273
|
-
setup_file = 'setup.py'
|
|
274
|
-
|
|
275
|
-
if self.editable_options and 'subdirectory' in self.editable_options:
|
|
276
|
-
setup_py = os.path.join(self.source_dir,
|
|
277
|
-
self.editable_options['subdirectory'],
|
|
278
|
-
setup_file)
|
|
279
|
-
|
|
280
|
-
else:
|
|
281
|
-
setup_py = os.path.join(self.source_dir, setup_file)
|
|
282
|
-
|
|
283
|
-
# Python2 __file__ should not be unicode
|
|
284
|
-
if six.PY2 and isinstance(setup_py, six.text_type):
|
|
285
|
-
setup_py = setup_py.encode(sys.getfilesystemencoding())
|
|
286
|
-
|
|
287
|
-
return setup_py
|
|
288
|
-
|
|
289
|
-
def run_egg_info(self, force_root_egg_info=False):
|
|
290
|
-
assert self.source_dir
|
|
291
|
-
if self.name:
|
|
292
|
-
logger.notify('Running setup.py (path:%s) egg_info for package %s' % (self.setup_py, self.name))
|
|
293
|
-
else:
|
|
294
|
-
logger.notify('Running setup.py (path:%s) egg_info for package from %s' % (self.setup_py, self.url))
|
|
295
|
-
logger.indent += 2
|
|
296
|
-
try:
|
|
297
|
-
|
|
298
|
-
# if it's distribute>=0.7, it won't contain an importable
|
|
299
|
-
# setuptools, and having an egg-info dir blocks the ability of
|
|
300
|
-
# setup.py to find setuptools plugins, so delete the egg-info dir if
|
|
301
|
-
# no setuptools. it will get recreated by the run of egg_info
|
|
302
|
-
# NOTE: this self.name check only works when installing from a specifier
|
|
303
|
-
# (not archive path/urls)
|
|
304
|
-
# TODO: take this out later
|
|
305
|
-
if self.name == 'distribute' and not os.path.isdir(os.path.join(self.source_dir, 'setuptools')):
|
|
306
|
-
rmtree(os.path.join(self.source_dir, 'distribute.egg-info'))
|
|
307
|
-
|
|
308
|
-
script = self._run_setup_py
|
|
309
|
-
script = script.replace('__SETUP_PY__', repr(self.setup_py))
|
|
310
|
-
script = script.replace('__PKG_NAME__', repr(self.name))
|
|
311
|
-
egg_info_cmd = [sys.executable, '-c', script, 'egg_info']
|
|
312
|
-
# We can't put the .egg-info files at the root, because then the source code will be mistaken
|
|
313
|
-
# for an installed egg, causing problems
|
|
314
|
-
if self.editable or force_root_egg_info:
|
|
315
|
-
egg_base_option = []
|
|
316
|
-
else:
|
|
317
|
-
egg_info_dir = os.path.join(self.source_dir, 'pip-egg-info')
|
|
318
|
-
if not os.path.exists(egg_info_dir):
|
|
319
|
-
os.makedirs(egg_info_dir)
|
|
320
|
-
egg_base_option = ['--egg-base', 'pip-egg-info']
|
|
321
|
-
call_subprocess(
|
|
322
|
-
egg_info_cmd + egg_base_option,
|
|
323
|
-
cwd=self.source_dir, filter_stdout=self._filter_install, show_stdout=False,
|
|
324
|
-
command_level=logger.VERBOSE_DEBUG,
|
|
325
|
-
command_desc='python setup.py egg_info')
|
|
326
|
-
finally:
|
|
327
|
-
logger.indent -= 2
|
|
328
|
-
if not self.req:
|
|
329
|
-
self.req = pkg_resources.Requirement.parse(
|
|
330
|
-
"%(Name)s==%(Version)s" % self.pkg_info())
|
|
331
|
-
self.correct_build_location()
|
|
332
|
-
|
|
333
|
-
## FIXME: This is a lame hack, entirely for PasteScript which has
|
|
334
|
-
## a self-provided entry point that causes this awkwardness
|
|
335
|
-
_run_setup_py = """
|
|
336
|
-
__file__ = __SETUP_PY__
|
|
337
|
-
from setuptools.command import egg_info
|
|
338
|
-
import pkg_resources
|
|
339
|
-
import os
|
|
340
|
-
import tokenize
|
|
341
|
-
def replacement_run(self):
|
|
342
|
-
self.mkpath(self.egg_info)
|
|
343
|
-
installer = self.distribution.fetch_build_egg
|
|
344
|
-
for ep in pkg_resources.iter_entry_points('egg_info.writers'):
|
|
345
|
-
# require=False is the change we're making:
|
|
346
|
-
writer = ep.load(require=False)
|
|
347
|
-
if writer:
|
|
348
|
-
writer(self, ep.name, os.path.join(self.egg_info,ep.name))
|
|
349
|
-
self.find_sources()
|
|
350
|
-
egg_info.egg_info.run = replacement_run
|
|
351
|
-
exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))
|
|
352
|
-
"""
|
|
353
|
-
|
|
354
|
-
def egg_info_data(self, filename):
|
|
355
|
-
if self.satisfied_by is not None:
|
|
356
|
-
if not self.satisfied_by.has_metadata(filename):
|
|
357
|
-
return None
|
|
358
|
-
return self.satisfied_by.get_metadata(filename)
|
|
359
|
-
assert self.source_dir
|
|
360
|
-
filename = self.egg_info_path(filename)
|
|
361
|
-
if not os.path.exists(filename):
|
|
362
|
-
return None
|
|
363
|
-
data = read_text_file(filename)
|
|
364
|
-
return data
|
|
365
|
-
|
|
366
|
-
def egg_info_path(self, filename):
|
|
367
|
-
if self._egg_info_path is None:
|
|
368
|
-
if self.editable:
|
|
369
|
-
base = self.source_dir
|
|
370
|
-
else:
|
|
371
|
-
base = os.path.join(self.source_dir, 'pip-egg-info')
|
|
372
|
-
filenames = os.listdir(base)
|
|
373
|
-
if self.editable:
|
|
374
|
-
filenames = []
|
|
375
|
-
for root, dirs, files in os.walk(base):
|
|
376
|
-
for dir in vcs.dirnames:
|
|
377
|
-
if dir in dirs:
|
|
378
|
-
dirs.remove(dir)
|
|
379
|
-
# Iterate over a copy of ``dirs``, since mutating
|
|
380
|
-
# a list while iterating over it can cause trouble.
|
|
381
|
-
# (See https://github.com/pypa/pip/pull/462.)
|
|
382
|
-
for dir in list(dirs):
|
|
383
|
-
# Don't search in anything that looks like a virtualenv environment
|
|
384
|
-
if (os.path.exists(os.path.join(root, dir, 'bin', 'python'))
|
|
385
|
-
or os.path.exists(os.path.join(root, dir, 'Scripts', 'Python.exe'))):
|
|
386
|
-
dirs.remove(dir)
|
|
387
|
-
# Also don't search through tests
|
|
388
|
-
if dir == 'test' or dir == 'tests':
|
|
389
|
-
dirs.remove(dir)
|
|
390
|
-
filenames.extend([os.path.join(root, dir)
|
|
391
|
-
for dir in dirs])
|
|
392
|
-
filenames = [f for f in filenames if f.endswith('.egg-info')]
|
|
393
|
-
|
|
394
|
-
if not filenames:
|
|
395
|
-
raise InstallationError('No files/directories in %s (from %s)' % (base, filename))
|
|
396
|
-
assert filenames, "No files/directories in %s (from %s)" % (base, filename)
|
|
397
|
-
|
|
398
|
-
# if we have more than one match, we pick the toplevel one. This can
|
|
399
|
-
# easily be the case if there is a dist folder which contains an
|
|
400
|
-
# extracted tarball for testing purposes.
|
|
401
|
-
if len(filenames) > 1:
|
|
402
|
-
filenames.sort(key=lambda x: x.count(os.path.sep) +
|
|
403
|
-
(os.path.altsep and
|
|
404
|
-
x.count(os.path.altsep) or 0))
|
|
405
|
-
self._egg_info_path = os.path.join(base, filenames[0])
|
|
406
|
-
return os.path.join(self._egg_info_path, filename)
|
|
407
|
-
|
|
408
|
-
def egg_info_lines(self, filename):
|
|
409
|
-
data = self.egg_info_data(filename)
|
|
410
|
-
if not data:
|
|
411
|
-
return []
|
|
412
|
-
result = []
|
|
413
|
-
for line in data.splitlines():
|
|
414
|
-
line = line.strip()
|
|
415
|
-
if not line or line.startswith('#'):
|
|
416
|
-
continue
|
|
417
|
-
result.append(line)
|
|
418
|
-
return result
|
|
419
|
-
|
|
420
|
-
def pkg_info(self):
|
|
421
|
-
p = FeedParser()
|
|
422
|
-
data = self.egg_info_data('PKG-INFO')
|
|
423
|
-
if not data:
|
|
424
|
-
logger.warn('No PKG-INFO file found in %s' % display_path(self.egg_info_path('PKG-INFO')))
|
|
425
|
-
p.feed(data or '')
|
|
426
|
-
return p.close()
|
|
427
|
-
|
|
428
|
-
@property
|
|
429
|
-
def dependency_links(self):
|
|
430
|
-
return self.egg_info_lines('dependency_links.txt')
|
|
431
|
-
|
|
432
|
-
_requirements_section_re = re.compile(r'\[(.*?)\]')
|
|
433
|
-
|
|
434
|
-
def requirements(self, extras=()):
|
|
435
|
-
in_extra = None
|
|
436
|
-
for line in self.egg_info_lines('requires.txt'):
|
|
437
|
-
match = self._requirements_section_re.match(line.lower())
|
|
438
|
-
if match:
|
|
439
|
-
in_extra = match.group(1)
|
|
440
|
-
continue
|
|
441
|
-
if in_extra and in_extra not in extras:
|
|
442
|
-
logger.debug('skipping extra %s' % in_extra)
|
|
443
|
-
# Skip requirement for an extra we aren't requiring
|
|
444
|
-
continue
|
|
445
|
-
yield line
|
|
446
|
-
|
|
447
|
-
@property
|
|
448
|
-
def absolute_versions(self):
|
|
449
|
-
for qualifier, version in self.req.specs:
|
|
450
|
-
if qualifier == '==':
|
|
451
|
-
yield version
|
|
452
|
-
|
|
453
|
-
@property
|
|
454
|
-
def installed_version(self):
|
|
455
|
-
return self.pkg_info()['version']
|
|
456
|
-
|
|
457
|
-
def assert_source_matches_version(self):
|
|
458
|
-
assert self.source_dir
|
|
459
|
-
version = self.installed_version
|
|
460
|
-
if version not in self.req:
|
|
461
|
-
logger.warn('Requested %s, but installing version %s' % (self, self.installed_version))
|
|
462
|
-
else:
|
|
463
|
-
logger.debug('Source in %s has version %s, which satisfies requirement %s'
|
|
464
|
-
% (display_path(self.source_dir), version, self))
|
|
465
|
-
|
|
466
|
-
def update_editable(self, obtain=True):
|
|
467
|
-
if not self.url:
|
|
468
|
-
logger.info("Cannot update repository at %s; repository location is unknown" % self.source_dir)
|
|
469
|
-
return
|
|
470
|
-
assert self.editable
|
|
471
|
-
assert self.source_dir
|
|
472
|
-
if self.url.startswith('file:'):
|
|
473
|
-
# Static paths don't get updated
|
|
474
|
-
return
|
|
475
|
-
assert '+' in self.url, "bad url: %r" % self.url
|
|
476
|
-
if not self.update:
|
|
477
|
-
return
|
|
478
|
-
vc_type, url = self.url.split('+', 1)
|
|
479
|
-
backend = vcs.get_backend(vc_type)
|
|
480
|
-
if backend:
|
|
481
|
-
vcs_backend = backend(self.url)
|
|
482
|
-
if obtain:
|
|
483
|
-
vcs_backend.obtain(self.source_dir)
|
|
484
|
-
else:
|
|
485
|
-
vcs_backend.export(self.source_dir)
|
|
486
|
-
else:
|
|
487
|
-
assert 0, (
|
|
488
|
-
'Unexpected version control type (in %s): %s'
|
|
489
|
-
% (self.url, vc_type))
|
|
490
|
-
|
|
491
|
-
def uninstall(self, auto_confirm=False):
|
|
492
|
-
"""
|
|
493
|
-
Uninstall the distribution currently satisfying this requirement.
|
|
494
|
-
|
|
495
|
-
Prompts before removing or modifying files unless
|
|
496
|
-
``auto_confirm`` is True.
|
|
497
|
-
|
|
498
|
-
Refuses to delete or modify files outside of ``sys.prefix`` -
|
|
499
|
-
thus uninstallation within a virtual environment can only
|
|
500
|
-
modify that virtual environment, even if the virtualenv is
|
|
501
|
-
linked to global site-packages.
|
|
502
|
-
|
|
503
|
-
"""
|
|
504
|
-
if not self.check_if_exists():
|
|
505
|
-
raise UninstallationError("Cannot uninstall requirement %s, not installed" % (self.name,))
|
|
506
|
-
dist = self.satisfied_by or self.conflicts_with
|
|
507
|
-
|
|
508
|
-
paths_to_remove = UninstallPathSet(dist)
|
|
509
|
-
|
|
510
|
-
pip_egg_info_path = os.path.join(dist.location,
|
|
511
|
-
dist.egg_name()) + '.egg-info'
|
|
512
|
-
dist_info_path = os.path.join(dist.location,
|
|
513
|
-
'-'.join(dist.egg_name().split('-')[:2])
|
|
514
|
-
) + '.dist-info'
|
|
515
|
-
# workaround for http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=618367
|
|
516
|
-
debian_egg_info_path = pip_egg_info_path.replace(
|
|
517
|
-
'-py%s' % pkg_resources.PY_MAJOR, '')
|
|
518
|
-
easy_install_egg = dist.egg_name() + '.egg'
|
|
519
|
-
develop_egg_link = egg_link_path(dist)
|
|
520
|
-
|
|
521
|
-
pip_egg_info_exists = os.path.exists(pip_egg_info_path)
|
|
522
|
-
debian_egg_info_exists = os.path.exists(debian_egg_info_path)
|
|
523
|
-
dist_info_exists = os.path.exists(dist_info_path)
|
|
524
|
-
if pip_egg_info_exists or debian_egg_info_exists:
|
|
525
|
-
# package installed by pip
|
|
526
|
-
if pip_egg_info_exists:
|
|
527
|
-
egg_info_path = pip_egg_info_path
|
|
528
|
-
else:
|
|
529
|
-
egg_info_path = debian_egg_info_path
|
|
530
|
-
paths_to_remove.add(egg_info_path)
|
|
531
|
-
if dist.has_metadata('installed-files.txt'):
|
|
532
|
-
for installed_file in dist.get_metadata('installed-files.txt').splitlines():
|
|
533
|
-
path = os.path.normpath(os.path.join(egg_info_path, installed_file))
|
|
534
|
-
paths_to_remove.add(path)
|
|
535
|
-
#FIXME: need a test for this elif block
|
|
536
|
-
#occurs with --single-version-externally-managed/--record outside of pip
|
|
537
|
-
elif dist.has_metadata('top_level.txt'):
|
|
538
|
-
if dist.has_metadata('namespace_packages.txt'):
|
|
539
|
-
namespaces = dist.get_metadata('namespace_packages.txt')
|
|
540
|
-
else:
|
|
541
|
-
namespaces = []
|
|
542
|
-
for top_level_pkg in [p for p
|
|
543
|
-
in dist.get_metadata('top_level.txt').splitlines()
|
|
544
|
-
if p and p not in namespaces]:
|
|
545
|
-
path = os.path.join(dist.location, top_level_pkg)
|
|
546
|
-
paths_to_remove.add(path)
|
|
547
|
-
paths_to_remove.add(path + '.py')
|
|
548
|
-
paths_to_remove.add(path + '.pyc')
|
|
549
|
-
|
|
550
|
-
elif dist.location.endswith(easy_install_egg):
|
|
551
|
-
# package installed by easy_install
|
|
552
|
-
paths_to_remove.add(dist.location)
|
|
553
|
-
easy_install_pth = os.path.join(os.path.dirname(dist.location),
|
|
554
|
-
'easy-install.pth')
|
|
555
|
-
paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg)
|
|
556
|
-
|
|
557
|
-
elif develop_egg_link:
|
|
558
|
-
# develop egg
|
|
559
|
-
fh = open(develop_egg_link, 'r')
|
|
560
|
-
link_pointer = os.path.normcase(fh.readline().strip())
|
|
561
|
-
fh.close()
|
|
562
|
-
assert (link_pointer == dist.location), 'Egg-link %s does not match installed location of %s (at %s)' % (link_pointer, self.name, dist.location)
|
|
563
|
-
paths_to_remove.add(develop_egg_link)
|
|
564
|
-
easy_install_pth = os.path.join(os.path.dirname(develop_egg_link),
|
|
565
|
-
'easy-install.pth')
|
|
566
|
-
paths_to_remove.add_pth(easy_install_pth, dist.location)
|
|
567
|
-
elif dist_info_exists:
|
|
568
|
-
for path in pip.wheel.uninstallation_paths(dist):
|
|
569
|
-
paths_to_remove.add(path)
|
|
570
|
-
|
|
571
|
-
# find distutils scripts= scripts
|
|
572
|
-
if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'):
|
|
573
|
-
for script in dist.metadata_listdir('scripts'):
|
|
574
|
-
if dist_in_usersite(dist):
|
|
575
|
-
bin_dir = bin_user
|
|
576
|
-
else:
|
|
577
|
-
bin_dir = bin_py
|
|
578
|
-
paths_to_remove.add(os.path.join(bin_dir, script))
|
|
579
|
-
if sys.platform == 'win32':
|
|
580
|
-
paths_to_remove.add(os.path.join(bin_dir, script) + '.bat')
|
|
581
|
-
|
|
582
|
-
# find console_scripts
|
|
583
|
-
if dist.has_metadata('entry_points.txt'):
|
|
584
|
-
config = ConfigParser.SafeConfigParser()
|
|
585
|
-
config.readfp(FakeFile(dist.get_metadata_lines('entry_points.txt')))
|
|
586
|
-
if config.has_section('console_scripts'):
|
|
587
|
-
for name, value in config.items('console_scripts'):
|
|
588
|
-
if dist_in_usersite(dist):
|
|
589
|
-
bin_dir = bin_user
|
|
590
|
-
else:
|
|
591
|
-
bin_dir = bin_py
|
|
592
|
-
paths_to_remove.add(os.path.join(bin_dir, name))
|
|
593
|
-
if sys.platform == 'win32':
|
|
594
|
-
paths_to_remove.add(os.path.join(bin_dir, name) + '.exe')
|
|
595
|
-
paths_to_remove.add(os.path.join(bin_dir, name) + '.exe.manifest')
|
|
596
|
-
paths_to_remove.add(os.path.join(bin_dir, name) + '-script.py')
|
|
597
|
-
|
|
598
|
-
paths_to_remove.remove(auto_confirm)
|
|
599
|
-
self.uninstalled = paths_to_remove
|
|
600
|
-
|
|
601
|
-
def rollback_uninstall(self):
|
|
602
|
-
if self.uninstalled:
|
|
603
|
-
self.uninstalled.rollback()
|
|
604
|
-
else:
|
|
605
|
-
logger.error("Can't rollback %s, nothing uninstalled."
|
|
606
|
-
% (self.project_name,))
|
|
607
|
-
|
|
608
|
-
def commit_uninstall(self):
|
|
609
|
-
if self.uninstalled:
|
|
610
|
-
self.uninstalled.commit()
|
|
611
|
-
else:
|
|
612
|
-
logger.error("Can't commit %s, nothing uninstalled."
|
|
613
|
-
% (self.project_name,))
|
|
614
|
-
|
|
615
|
-
def archive(self, build_dir):
|
|
616
|
-
assert self.source_dir
|
|
617
|
-
create_archive = True
|
|
618
|
-
archive_name = '%s-%s.zip' % (self.name, self.installed_version)
|
|
619
|
-
archive_path = os.path.join(build_dir, archive_name)
|
|
620
|
-
if os.path.exists(archive_path):
|
|
621
|
-
response = ask_path_exists(
|
|
622
|
-
'The file %s exists. (i)gnore, (w)ipe, (b)ackup ' %
|
|
623
|
-
display_path(archive_path), ('i', 'w', 'b'))
|
|
624
|
-
if response == 'i':
|
|
625
|
-
create_archive = False
|
|
626
|
-
elif response == 'w':
|
|
627
|
-
logger.warn('Deleting %s' % display_path(archive_path))
|
|
628
|
-
os.remove(archive_path)
|
|
629
|
-
elif response == 'b':
|
|
630
|
-
dest_file = backup_dir(archive_path)
|
|
631
|
-
logger.warn('Backing up %s to %s'
|
|
632
|
-
% (display_path(archive_path), display_path(dest_file)))
|
|
633
|
-
shutil.move(archive_path, dest_file)
|
|
634
|
-
if create_archive:
|
|
635
|
-
zip = zipfile.ZipFile(archive_path, 'w', zipfile.ZIP_DEFLATED)
|
|
636
|
-
dir = os.path.normcase(os.path.abspath(self.source_dir))
|
|
637
|
-
for dirpath, dirnames, filenames in os.walk(dir):
|
|
638
|
-
if 'pip-egg-info' in dirnames:
|
|
639
|
-
dirnames.remove('pip-egg-info')
|
|
640
|
-
for dirname in dirnames:
|
|
641
|
-
dirname = os.path.join(dirpath, dirname)
|
|
642
|
-
name = self._clean_zip_name(dirname, dir)
|
|
643
|
-
zipdir = zipfile.ZipInfo(self.name + '/' + name + '/')
|
|
644
|
-
zipdir.external_attr = 0x1ED << 16 # 0o755
|
|
645
|
-
zip.writestr(zipdir, '')
|
|
646
|
-
for filename in filenames:
|
|
647
|
-
if filename == PIP_DELETE_MARKER_FILENAME:
|
|
648
|
-
continue
|
|
649
|
-
filename = os.path.join(dirpath, filename)
|
|
650
|
-
name = self._clean_zip_name(filename, dir)
|
|
651
|
-
zip.write(filename, self.name + '/' + name)
|
|
652
|
-
zip.close()
|
|
653
|
-
logger.indent -= 2
|
|
654
|
-
logger.notify('Saved %s' % display_path(archive_path))
|
|
655
|
-
|
|
656
|
-
def _clean_zip_name(self, name, prefix):
|
|
657
|
-
assert name.startswith(prefix+os.path.sep), (
|
|
658
|
-
"name %r doesn't start with prefix %r" % (name, prefix))
|
|
659
|
-
name = name[len(prefix)+1:]
|
|
660
|
-
name = name.replace(os.path.sep, '/')
|
|
661
|
-
return name
|
|
662
|
-
|
|
663
|
-
def install(self, install_options, global_options=(), root=None):
|
|
664
|
-
if self.editable:
|
|
665
|
-
self.install_editable(install_options, global_options)
|
|
666
|
-
return
|
|
667
|
-
if self.is_wheel:
|
|
668
|
-
version = pip.wheel.wheel_version(self.source_dir)
|
|
669
|
-
pip.wheel.check_compatibility(version, self.name)
|
|
670
|
-
|
|
671
|
-
self.move_wheel_files(self.source_dir, root=root)
|
|
672
|
-
self.install_succeeded = True
|
|
673
|
-
return
|
|
674
|
-
|
|
675
|
-
temp_location = tempfile.mkdtemp('-record', 'pip-')
|
|
676
|
-
record_filename = os.path.join(temp_location, 'install-record.txt')
|
|
677
|
-
try:
|
|
678
|
-
install_args = [sys.executable]
|
|
679
|
-
install_args.append('-c')
|
|
680
|
-
install_args.append(
|
|
681
|
-
"import setuptools, tokenize;__file__=%r;"\
|
|
682
|
-
"exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))" % self.setup_py)
|
|
683
|
-
install_args += list(global_options) + ['install','--record', record_filename]
|
|
684
|
-
|
|
685
|
-
if not self.as_egg:
|
|
686
|
-
install_args += ['--single-version-externally-managed']
|
|
687
|
-
|
|
688
|
-
if root is not None:
|
|
689
|
-
install_args += ['--root', root]
|
|
690
|
-
|
|
691
|
-
if self.pycompile:
|
|
692
|
-
install_args += ["--compile"]
|
|
693
|
-
else:
|
|
694
|
-
install_args += ["--no-compile"]
|
|
695
|
-
|
|
696
|
-
if running_under_virtualenv():
|
|
697
|
-
## FIXME: I'm not sure if this is a reasonable location; probably not
|
|
698
|
-
## but we can't put it in the default location, as that is a virtualenv symlink that isn't writable
|
|
699
|
-
install_args += ['--install-headers',
|
|
700
|
-
os.path.join(sys.prefix, 'include', 'site',
|
|
701
|
-
'python' + get_python_version())]
|
|
702
|
-
logger.notify('Running setup.py install for %s' % self.name)
|
|
703
|
-
logger.indent += 2
|
|
704
|
-
try:
|
|
705
|
-
call_subprocess(install_args + install_options,
|
|
706
|
-
cwd=self.source_dir, filter_stdout=self._filter_install, show_stdout=False)
|
|
707
|
-
finally:
|
|
708
|
-
logger.indent -= 2
|
|
709
|
-
if not os.path.exists(record_filename):
|
|
710
|
-
logger.notify('Record file %s not found' % record_filename)
|
|
711
|
-
return
|
|
712
|
-
self.install_succeeded = True
|
|
713
|
-
if self.as_egg:
|
|
714
|
-
# there's no --always-unzip option we can pass to install command
|
|
715
|
-
# so we unable to save the installed-files.txt
|
|
716
|
-
return
|
|
717
|
-
|
|
718
|
-
def prepend_root(path):
|
|
719
|
-
if root is None or not os.path.isabs(path):
|
|
720
|
-
return path
|
|
721
|
-
else:
|
|
722
|
-
return change_root(root, path)
|
|
723
|
-
|
|
724
|
-
f = open(record_filename)
|
|
725
|
-
for line in f:
|
|
726
|
-
line = line.strip()
|
|
727
|
-
if line.endswith('.egg-info'):
|
|
728
|
-
egg_info_dir = prepend_root(line)
|
|
729
|
-
break
|
|
730
|
-
else:
|
|
731
|
-
logger.warn('Could not find .egg-info directory in install record for %s' % self)
|
|
732
|
-
## FIXME: put the record somewhere
|
|
733
|
-
## FIXME: should this be an error?
|
|
734
|
-
return
|
|
735
|
-
f.close()
|
|
736
|
-
new_lines = []
|
|
737
|
-
f = open(record_filename)
|
|
738
|
-
for line in f:
|
|
739
|
-
filename = line.strip()
|
|
740
|
-
if os.path.isdir(filename):
|
|
741
|
-
filename += os.path.sep
|
|
742
|
-
new_lines.append(make_path_relative(prepend_root(filename), egg_info_dir))
|
|
743
|
-
f.close()
|
|
744
|
-
f = open(os.path.join(egg_info_dir, 'installed-files.txt'), 'w')
|
|
745
|
-
f.write('\n'.join(new_lines)+'\n')
|
|
746
|
-
f.close()
|
|
747
|
-
finally:
|
|
748
|
-
if os.path.exists(record_filename):
|
|
749
|
-
os.remove(record_filename)
|
|
750
|
-
os.rmdir(temp_location)
|
|
751
|
-
|
|
752
|
-
def remove_temporary_source(self):
|
|
753
|
-
"""Remove the source files from this requirement, if they are marked
|
|
754
|
-
for deletion"""
|
|
755
|
-
if self.is_bundle or os.path.exists(self.delete_marker_filename):
|
|
756
|
-
logger.info('Removing source in %s' % self.source_dir)
|
|
757
|
-
if self.source_dir:
|
|
758
|
-
rmtree(self.source_dir)
|
|
759
|
-
self.source_dir = None
|
|
760
|
-
if self._temp_build_dir and os.path.exists(self._temp_build_dir):
|
|
761
|
-
rmtree(self._temp_build_dir)
|
|
762
|
-
self._temp_build_dir = None
|
|
763
|
-
|
|
764
|
-
def install_editable(self, install_options, global_options=()):
|
|
765
|
-
logger.notify('Running setup.py develop for %s' % self.name)
|
|
766
|
-
logger.indent += 2
|
|
767
|
-
try:
|
|
768
|
-
## FIXME: should we do --install-headers here too?
|
|
769
|
-
call_subprocess(
|
|
770
|
-
[sys.executable, '-c',
|
|
771
|
-
"import setuptools, tokenize; __file__=%r; exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\\r\\n', '\\n'), __file__, 'exec'))" % self.setup_py]
|
|
772
|
-
+ list(global_options) + ['develop', '--no-deps'] + list(install_options),
|
|
773
|
-
|
|
774
|
-
cwd=self.source_dir, filter_stdout=self._filter_install,
|
|
775
|
-
show_stdout=False)
|
|
776
|
-
finally:
|
|
777
|
-
logger.indent -= 2
|
|
778
|
-
self.install_succeeded = True
|
|
779
|
-
|
|
780
|
-
def _filter_install(self, line):
|
|
781
|
-
level = logger.NOTIFY
|
|
782
|
-
for regex in [r'^running .*', r'^writing .*', '^creating .*', '^[Cc]opying .*',
|
|
783
|
-
r'^reading .*', r"^removing .*\.egg-info' \(and everything under it\)$",
|
|
784
|
-
r'^byte-compiling ',
|
|
785
|
-
# Not sure what this warning is, but it seems harmless:
|
|
786
|
-
r"^warning: manifest_maker: standard file '-c' not found$"]:
|
|
787
|
-
if re.search(regex, line.strip()):
|
|
788
|
-
level = logger.INFO
|
|
789
|
-
break
|
|
790
|
-
return (level, line)
|
|
791
|
-
|
|
792
|
-
def check_if_exists(self):
|
|
793
|
-
"""Find an installed distribution that satisfies or conflicts
|
|
794
|
-
with this requirement, and set self.satisfied_by or
|
|
795
|
-
self.conflicts_with appropriately."""
|
|
796
|
-
|
|
797
|
-
if self.req is None:
|
|
798
|
-
return False
|
|
799
|
-
try:
|
|
800
|
-
# DISTRIBUTE TO SETUPTOOLS UPGRADE HACK (1 of 3 parts)
|
|
801
|
-
# if we've already set distribute as a conflict to setuptools
|
|
802
|
-
# then this check has already run before. we don't want it to
|
|
803
|
-
# run again, and return False, since it would block the uninstall
|
|
804
|
-
# TODO: remove this later
|
|
805
|
-
if (self.req.project_name == 'setuptools'
|
|
806
|
-
and self.conflicts_with
|
|
807
|
-
and self.conflicts_with.project_name == 'distribute'):
|
|
808
|
-
return True
|
|
809
|
-
else:
|
|
810
|
-
self.satisfied_by = pkg_resources.get_distribution(self.req)
|
|
811
|
-
except pkg_resources.DistributionNotFound:
|
|
812
|
-
return False
|
|
813
|
-
except pkg_resources.VersionConflict:
|
|
814
|
-
existing_dist = pkg_resources.get_distribution(self.req.project_name)
|
|
815
|
-
if self.use_user_site:
|
|
816
|
-
if dist_in_usersite(existing_dist):
|
|
817
|
-
self.conflicts_with = existing_dist
|
|
818
|
-
elif running_under_virtualenv() and dist_in_site_packages(existing_dist):
|
|
819
|
-
raise InstallationError("Will not install to the user site because it will lack sys.path precedence to %s in %s"
|
|
820
|
-
%(existing_dist.project_name, existing_dist.location))
|
|
821
|
-
else:
|
|
822
|
-
self.conflicts_with = existing_dist
|
|
823
|
-
return True
|
|
824
|
-
|
|
825
|
-
@property
|
|
826
|
-
def is_wheel(self):
|
|
827
|
-
return self.url and '.whl' in self.url
|
|
828
|
-
|
|
829
|
-
@property
|
|
830
|
-
def is_bundle(self):
|
|
831
|
-
if self._is_bundle is not None:
|
|
832
|
-
return self._is_bundle
|
|
833
|
-
base = self._temp_build_dir
|
|
834
|
-
if not base:
|
|
835
|
-
## FIXME: this doesn't seem right:
|
|
836
|
-
return False
|
|
837
|
-
self._is_bundle = (os.path.exists(os.path.join(base, 'pip-manifest.txt'))
|
|
838
|
-
or os.path.exists(os.path.join(base, 'pyinstall-manifest.txt')))
|
|
839
|
-
return self._is_bundle
|
|
840
|
-
|
|
841
|
-
def bundle_requirements(self):
|
|
842
|
-
for dest_dir in self._bundle_editable_dirs:
|
|
843
|
-
package = os.path.basename(dest_dir)
|
|
844
|
-
## FIXME: svnism:
|
|
845
|
-
for vcs_backend in vcs.backends:
|
|
846
|
-
url = rev = None
|
|
847
|
-
vcs_bundle_file = os.path.join(
|
|
848
|
-
dest_dir, vcs_backend.bundle_file)
|
|
849
|
-
if os.path.exists(vcs_bundle_file):
|
|
850
|
-
vc_type = vcs_backend.name
|
|
851
|
-
fp = open(vcs_bundle_file)
|
|
852
|
-
content = fp.read()
|
|
853
|
-
fp.close()
|
|
854
|
-
url, rev = vcs_backend().parse_vcs_bundle_file(content)
|
|
855
|
-
break
|
|
856
|
-
if url:
|
|
857
|
-
url = '%s+%s@%s' % (vc_type, url, rev)
|
|
858
|
-
else:
|
|
859
|
-
url = None
|
|
860
|
-
yield InstallRequirement(
|
|
861
|
-
package, self, editable=True, url=url,
|
|
862
|
-
update=False, source_dir=dest_dir, from_bundle=True)
|
|
863
|
-
for dest_dir in self._bundle_build_dirs:
|
|
864
|
-
package = os.path.basename(dest_dir)
|
|
865
|
-
yield InstallRequirement(package, self,source_dir=dest_dir, from_bundle=True)
|
|
866
|
-
|
|
867
|
-
def move_bundle_files(self, dest_build_dir, dest_src_dir):
|
|
868
|
-
base = self._temp_build_dir
|
|
869
|
-
assert base
|
|
870
|
-
src_dir = os.path.join(base, 'src')
|
|
871
|
-
build_dir = os.path.join(base, 'build')
|
|
872
|
-
bundle_build_dirs = []
|
|
873
|
-
bundle_editable_dirs = []
|
|
874
|
-
for source_dir, dest_dir, dir_collection in [
|
|
875
|
-
(src_dir, dest_src_dir, bundle_editable_dirs),
|
|
876
|
-
(build_dir, dest_build_dir, bundle_build_dirs)]:
|
|
877
|
-
if os.path.exists(source_dir):
|
|
878
|
-
for dirname in os.listdir(source_dir):
|
|
879
|
-
dest = os.path.join(dest_dir, dirname)
|
|
880
|
-
dir_collection.append(dest)
|
|
881
|
-
if os.path.exists(dest):
|
|
882
|
-
logger.warn('The directory %s (containing package %s) already exists; cannot move source from bundle %s'
|
|
883
|
-
% (dest, dirname, self))
|
|
884
|
-
continue
|
|
885
|
-
if not os.path.exists(dest_dir):
|
|
886
|
-
logger.info('Creating directory %s' % dest_dir)
|
|
887
|
-
os.makedirs(dest_dir)
|
|
888
|
-
shutil.move(os.path.join(source_dir, dirname), dest)
|
|
889
|
-
if not os.listdir(source_dir):
|
|
890
|
-
os.rmdir(source_dir)
|
|
891
|
-
self._temp_build_dir = None
|
|
892
|
-
self._bundle_build_dirs = bundle_build_dirs
|
|
893
|
-
self._bundle_editable_dirs = bundle_editable_dirs
|
|
894
|
-
|
|
895
|
-
def move_wheel_files(self, wheeldir, root=None):
|
|
896
|
-
move_wheel_files(
|
|
897
|
-
self.name, self.req, wheeldir,
|
|
898
|
-
user=self.use_user_site,
|
|
899
|
-
home=self.target_dir,
|
|
900
|
-
root=root,
|
|
901
|
-
pycompile=self.pycompile,
|
|
902
|
-
)
|
|
903
|
-
|
|
904
|
-
@property
|
|
905
|
-
def delete_marker_filename(self):
|
|
906
|
-
assert self.source_dir
|
|
907
|
-
return os.path.join(self.source_dir, PIP_DELETE_MARKER_FILENAME)
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
class Requirements(object):
|
|
911
|
-
|
|
912
|
-
def __init__(self):
|
|
913
|
-
self._keys = []
|
|
914
|
-
self._dict = {}
|
|
915
|
-
|
|
916
|
-
def keys(self):
|
|
917
|
-
return self._keys
|
|
918
|
-
|
|
919
|
-
def values(self):
|
|
920
|
-
return [self._dict[key] for key in self._keys]
|
|
921
|
-
|
|
922
|
-
def __contains__(self, item):
|
|
923
|
-
return item in self._keys
|
|
924
|
-
|
|
925
|
-
def __setitem__(self, key, value):
|
|
926
|
-
if key not in self._keys:
|
|
927
|
-
self._keys.append(key)
|
|
928
|
-
self._dict[key] = value
|
|
929
|
-
|
|
930
|
-
def __getitem__(self, key):
|
|
931
|
-
return self._dict[key]
|
|
932
|
-
|
|
933
|
-
def __repr__(self):
|
|
934
|
-
values = ['%s: %s' % (repr(k), repr(self[k])) for k in self.keys()]
|
|
935
|
-
return 'Requirements({%s})' % ', '.join(values)
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
class RequirementSet(object):
|
|
939
|
-
|
|
940
|
-
def __init__(self, build_dir, src_dir, download_dir, download_cache=None,
|
|
941
|
-
upgrade=False, ignore_installed=False, as_egg=False,
|
|
942
|
-
target_dir=None, ignore_dependencies=False,
|
|
943
|
-
force_reinstall=False, use_user_site=False, session=None,
|
|
944
|
-
pycompile=True, wheel_download_dir=None):
|
|
945
|
-
self.build_dir = build_dir
|
|
946
|
-
self.src_dir = src_dir
|
|
947
|
-
self.download_dir = download_dir
|
|
948
|
-
if download_cache:
|
|
949
|
-
download_cache = os.path.expanduser(download_cache)
|
|
950
|
-
self.download_cache = download_cache
|
|
951
|
-
self.upgrade = upgrade
|
|
952
|
-
self.ignore_installed = ignore_installed
|
|
953
|
-
self.force_reinstall = force_reinstall
|
|
954
|
-
self.requirements = Requirements()
|
|
955
|
-
# Mapping of alias: real_name
|
|
956
|
-
self.requirement_aliases = {}
|
|
957
|
-
self.unnamed_requirements = []
|
|
958
|
-
self.ignore_dependencies = ignore_dependencies
|
|
959
|
-
self.successfully_downloaded = []
|
|
960
|
-
self.successfully_installed = []
|
|
961
|
-
self.reqs_to_cleanup = []
|
|
962
|
-
self.as_egg = as_egg
|
|
963
|
-
self.use_user_site = use_user_site
|
|
964
|
-
self.target_dir = target_dir #set from --target option
|
|
965
|
-
self.session = session or PipSession()
|
|
966
|
-
self.pycompile = pycompile
|
|
967
|
-
self.wheel_download_dir = wheel_download_dir
|
|
968
|
-
|
|
969
|
-
def __str__(self):
|
|
970
|
-
reqs = [req for req in self.requirements.values()
|
|
971
|
-
if not req.comes_from]
|
|
972
|
-
reqs.sort(key=lambda req: req.name.lower())
|
|
973
|
-
return ' '.join([str(req.req) for req in reqs])
|
|
974
|
-
|
|
975
|
-
def add_requirement(self, install_req):
|
|
976
|
-
name = install_req.name
|
|
977
|
-
install_req.as_egg = self.as_egg
|
|
978
|
-
install_req.use_user_site = self.use_user_site
|
|
979
|
-
install_req.target_dir = self.target_dir
|
|
980
|
-
install_req.pycompile = self.pycompile
|
|
981
|
-
if not name:
|
|
982
|
-
#url or path requirement w/o an egg fragment
|
|
983
|
-
self.unnamed_requirements.append(install_req)
|
|
984
|
-
else:
|
|
985
|
-
if self.has_requirement(name):
|
|
986
|
-
raise InstallationError(
|
|
987
|
-
'Double requirement given: %s (already in %s, name=%r)'
|
|
988
|
-
% (install_req, self.get_requirement(name), name))
|
|
989
|
-
self.requirements[name] = install_req
|
|
990
|
-
## FIXME: what about other normalizations? E.g., _ vs. -?
|
|
991
|
-
if name.lower() != name:
|
|
992
|
-
self.requirement_aliases[name.lower()] = name
|
|
993
|
-
|
|
994
|
-
def has_requirement(self, project_name):
|
|
995
|
-
for name in project_name, project_name.lower():
|
|
996
|
-
if name in self.requirements or name in self.requirement_aliases:
|
|
997
|
-
return True
|
|
998
|
-
return False
|
|
999
|
-
|
|
1000
|
-
@property
|
|
1001
|
-
def has_requirements(self):
|
|
1002
|
-
return list(self.requirements.values()) or self.unnamed_requirements
|
|
1003
|
-
|
|
1004
|
-
@property
|
|
1005
|
-
def has_editables(self):
|
|
1006
|
-
if any(req.editable for req in self.requirements.values()):
|
|
1007
|
-
return True
|
|
1008
|
-
if any(req.editable for req in self.unnamed_requirements):
|
|
1009
|
-
return True
|
|
1010
|
-
return False
|
|
1011
|
-
|
|
1012
|
-
@property
|
|
1013
|
-
def is_download(self):
|
|
1014
|
-
if self.download_dir:
|
|
1015
|
-
self.download_dir = os.path.expanduser(self.download_dir)
|
|
1016
|
-
if os.path.exists(self.download_dir):
|
|
1017
|
-
return True
|
|
1018
|
-
else:
|
|
1019
|
-
logger.fatal('Could not find download directory')
|
|
1020
|
-
raise InstallationError(
|
|
1021
|
-
"Could not find or access download directory '%s'"
|
|
1022
|
-
% display_path(self.download_dir))
|
|
1023
|
-
return False
|
|
1024
|
-
|
|
1025
|
-
def get_requirement(self, project_name):
|
|
1026
|
-
for name in project_name, project_name.lower():
|
|
1027
|
-
if name in self.requirements:
|
|
1028
|
-
return self.requirements[name]
|
|
1029
|
-
if name in self.requirement_aliases:
|
|
1030
|
-
return self.requirements[self.requirement_aliases[name]]
|
|
1031
|
-
raise KeyError("No project with the name %r" % project_name)
|
|
1032
|
-
|
|
1033
|
-
def uninstall(self, auto_confirm=False):
|
|
1034
|
-
for req in self.requirements.values():
|
|
1035
|
-
req.uninstall(auto_confirm=auto_confirm)
|
|
1036
|
-
req.commit_uninstall()
|
|
1037
|
-
|
|
1038
|
-
def locate_files(self):
|
|
1039
|
-
## FIXME: duplicates code from prepare_files; relevant code should
|
|
1040
|
-
## probably be factored out into a separate method
|
|
1041
|
-
unnamed = list(self.unnamed_requirements)
|
|
1042
|
-
reqs = list(self.requirements.values())
|
|
1043
|
-
while reqs or unnamed:
|
|
1044
|
-
if unnamed:
|
|
1045
|
-
req_to_install = unnamed.pop(0)
|
|
1046
|
-
else:
|
|
1047
|
-
req_to_install = reqs.pop(0)
|
|
1048
|
-
install_needed = True
|
|
1049
|
-
if not self.ignore_installed and not req_to_install.editable:
|
|
1050
|
-
req_to_install.check_if_exists()
|
|
1051
|
-
if req_to_install.satisfied_by:
|
|
1052
|
-
if self.upgrade:
|
|
1053
|
-
#don't uninstall conflict if user install and and conflict is not user install
|
|
1054
|
-
if not (self.use_user_site and not dist_in_usersite(req_to_install.satisfied_by)):
|
|
1055
|
-
req_to_install.conflicts_with = req_to_install.satisfied_by
|
|
1056
|
-
req_to_install.satisfied_by = None
|
|
1057
|
-
else:
|
|
1058
|
-
install_needed = False
|
|
1059
|
-
if req_to_install.satisfied_by:
|
|
1060
|
-
logger.notify('Requirement already satisfied '
|
|
1061
|
-
'(use --upgrade to upgrade): %s'
|
|
1062
|
-
% req_to_install)
|
|
1063
|
-
|
|
1064
|
-
if req_to_install.editable:
|
|
1065
|
-
if req_to_install.source_dir is None:
|
|
1066
|
-
req_to_install.source_dir = req_to_install.build_location(self.src_dir)
|
|
1067
|
-
elif install_needed:
|
|
1068
|
-
req_to_install.source_dir = req_to_install.build_location(self.build_dir, not self.is_download)
|
|
1069
|
-
|
|
1070
|
-
if req_to_install.source_dir is not None and not os.path.isdir(req_to_install.source_dir):
|
|
1071
|
-
raise InstallationError('Could not install requirement %s '
|
|
1072
|
-
'because source folder %s does not exist '
|
|
1073
|
-
'(perhaps --no-download was used without first running '
|
|
1074
|
-
'an equivalent install with --no-install?)'
|
|
1075
|
-
% (req_to_install, req_to_install.source_dir))
|
|
1076
|
-
|
|
1077
|
-
def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
|
|
1078
|
-
"""Prepare process. Create temp directories, download and/or unpack files."""
|
|
1079
|
-
unnamed = list(self.unnamed_requirements)
|
|
1080
|
-
reqs = list(self.requirements.values())
|
|
1081
|
-
while reqs or unnamed:
|
|
1082
|
-
if unnamed:
|
|
1083
|
-
req_to_install = unnamed.pop(0)
|
|
1084
|
-
else:
|
|
1085
|
-
req_to_install = reqs.pop(0)
|
|
1086
|
-
install = True
|
|
1087
|
-
best_installed = False
|
|
1088
|
-
not_found = None
|
|
1089
|
-
if not self.ignore_installed and not req_to_install.editable:
|
|
1090
|
-
req_to_install.check_if_exists()
|
|
1091
|
-
if req_to_install.satisfied_by:
|
|
1092
|
-
if self.upgrade:
|
|
1093
|
-
if not self.force_reinstall and not req_to_install.url:
|
|
1094
|
-
try:
|
|
1095
|
-
url = finder.find_requirement(
|
|
1096
|
-
req_to_install, self.upgrade)
|
|
1097
|
-
except BestVersionAlreadyInstalled:
|
|
1098
|
-
best_installed = True
|
|
1099
|
-
install = False
|
|
1100
|
-
except DistributionNotFound:
|
|
1101
|
-
not_found = sys.exc_info()[1]
|
|
1102
|
-
else:
|
|
1103
|
-
# Avoid the need to call find_requirement again
|
|
1104
|
-
req_to_install.url = url.url
|
|
1105
|
-
|
|
1106
|
-
if not best_installed:
|
|
1107
|
-
#don't uninstall conflict if user install and conflict is not user install
|
|
1108
|
-
if not (self.use_user_site and not dist_in_usersite(req_to_install.satisfied_by)):
|
|
1109
|
-
req_to_install.conflicts_with = req_to_install.satisfied_by
|
|
1110
|
-
req_to_install.satisfied_by = None
|
|
1111
|
-
else:
|
|
1112
|
-
install = False
|
|
1113
|
-
if req_to_install.satisfied_by:
|
|
1114
|
-
if best_installed:
|
|
1115
|
-
logger.notify('Requirement already up-to-date: %s'
|
|
1116
|
-
% req_to_install)
|
|
1117
|
-
else:
|
|
1118
|
-
logger.notify('Requirement already satisfied '
|
|
1119
|
-
'(use --upgrade to upgrade): %s'
|
|
1120
|
-
% req_to_install)
|
|
1121
|
-
if req_to_install.editable:
|
|
1122
|
-
logger.notify('Obtaining %s' % req_to_install)
|
|
1123
|
-
elif install:
|
|
1124
|
-
if req_to_install.url and req_to_install.url.lower().startswith('file:'):
|
|
1125
|
-
logger.notify('Unpacking %s' % display_path(url_to_path(req_to_install.url)))
|
|
1126
|
-
else:
|
|
1127
|
-
logger.notify('Downloading/unpacking %s' % req_to_install)
|
|
1128
|
-
logger.indent += 2
|
|
1129
|
-
try:
|
|
1130
|
-
is_bundle = False
|
|
1131
|
-
is_wheel = False
|
|
1132
|
-
if req_to_install.editable:
|
|
1133
|
-
if req_to_install.source_dir is None:
|
|
1134
|
-
location = req_to_install.build_location(self.src_dir)
|
|
1135
|
-
req_to_install.source_dir = location
|
|
1136
|
-
else:
|
|
1137
|
-
location = req_to_install.source_dir
|
|
1138
|
-
if not os.path.exists(self.build_dir):
|
|
1139
|
-
_make_build_dir(self.build_dir)
|
|
1140
|
-
req_to_install.update_editable(not self.is_download)
|
|
1141
|
-
if self.is_download:
|
|
1142
|
-
req_to_install.run_egg_info()
|
|
1143
|
-
req_to_install.archive(self.download_dir)
|
|
1144
|
-
else:
|
|
1145
|
-
req_to_install.run_egg_info()
|
|
1146
|
-
elif install:
|
|
1147
|
-
##@@ if filesystem packages are not marked
|
|
1148
|
-
##editable in a req, a non deterministic error
|
|
1149
|
-
##occurs when the script attempts to unpack the
|
|
1150
|
-
##build directory
|
|
1151
|
-
|
|
1152
|
-
# NB: This call can result in the creation of a temporary build directory
|
|
1153
|
-
location = req_to_install.build_location(self.build_dir, not self.is_download)
|
|
1154
|
-
unpack = True
|
|
1155
|
-
url = None
|
|
1156
|
-
|
|
1157
|
-
# In the case where the req comes from a bundle, we should
|
|
1158
|
-
# assume a build dir exists and move on
|
|
1159
|
-
if req_to_install.from_bundle:
|
|
1160
|
-
pass
|
|
1161
|
-
# If a checkout exists, it's unwise to keep going. version
|
|
1162
|
-
# inconsistencies are logged later, but do not fail the
|
|
1163
|
-
# installation.
|
|
1164
|
-
elif os.path.exists(os.path.join(location, 'setup.py')):
|
|
1165
|
-
raise PreviousBuildDirError(textwrap.dedent("""
|
|
1166
|
-
pip can't proceed with requirement '%s' due to a pre-existing build directory.
|
|
1167
|
-
location: %s
|
|
1168
|
-
This is likely due to a previous installation that failed.
|
|
1169
|
-
pip is being responsible and not assuming it can delete this.
|
|
1170
|
-
Please delete it and try again.
|
|
1171
|
-
""" % (req_to_install, location)))
|
|
1172
|
-
else:
|
|
1173
|
-
## FIXME: this won't upgrade when there's an existing package unpacked in `location`
|
|
1174
|
-
if req_to_install.url is None:
|
|
1175
|
-
if not_found:
|
|
1176
|
-
raise not_found
|
|
1177
|
-
url = finder.find_requirement(req_to_install, upgrade=self.upgrade)
|
|
1178
|
-
else:
|
|
1179
|
-
## FIXME: should req_to_install.url already be a link?
|
|
1180
|
-
url = Link(req_to_install.url)
|
|
1181
|
-
assert url
|
|
1182
|
-
if url:
|
|
1183
|
-
try:
|
|
1184
|
-
|
|
1185
|
-
if (
|
|
1186
|
-
url.filename.endswith(wheel_ext)
|
|
1187
|
-
and self.wheel_download_dir
|
|
1188
|
-
):
|
|
1189
|
-
# when doing 'pip wheel`
|
|
1190
|
-
download_dir = self.wheel_download_dir
|
|
1191
|
-
do_download = True
|
|
1192
|
-
else:
|
|
1193
|
-
download_dir = self.download_dir
|
|
1194
|
-
do_download = self.is_download
|
|
1195
|
-
self.unpack_url(
|
|
1196
|
-
url, location, download_dir,
|
|
1197
|
-
do_download,
|
|
1198
|
-
)
|
|
1199
|
-
except HTTPError as exc:
|
|
1200
|
-
logger.fatal(
|
|
1201
|
-
'Could not install requirement %s because '
|
|
1202
|
-
'of error %s' % (req_to_install, exc)
|
|
1203
|
-
)
|
|
1204
|
-
raise InstallationError(
|
|
1205
|
-
'Could not install requirement %s because of HTTP error %s for URL %s'
|
|
1206
|
-
% (req_to_install, e, url))
|
|
1207
|
-
else:
|
|
1208
|
-
unpack = False
|
|
1209
|
-
if unpack:
|
|
1210
|
-
is_bundle = req_to_install.is_bundle
|
|
1211
|
-
is_wheel = url and url.filename.endswith(wheel_ext)
|
|
1212
|
-
if is_bundle:
|
|
1213
|
-
req_to_install.move_bundle_files(self.build_dir, self.src_dir)
|
|
1214
|
-
for subreq in req_to_install.bundle_requirements():
|
|
1215
|
-
reqs.append(subreq)
|
|
1216
|
-
self.add_requirement(subreq)
|
|
1217
|
-
elif self.is_download:
|
|
1218
|
-
req_to_install.source_dir = location
|
|
1219
|
-
if not is_wheel:
|
|
1220
|
-
# FIXME: see https://github.com/pypa/pip/issues/1112
|
|
1221
|
-
req_to_install.run_egg_info()
|
|
1222
|
-
if url and url.scheme in vcs.all_schemes:
|
|
1223
|
-
req_to_install.archive(self.download_dir)
|
|
1224
|
-
elif is_wheel:
|
|
1225
|
-
req_to_install.source_dir = location
|
|
1226
|
-
req_to_install.url = url.url
|
|
1227
|
-
else:
|
|
1228
|
-
req_to_install.source_dir = location
|
|
1229
|
-
req_to_install.run_egg_info()
|
|
1230
|
-
if force_root_egg_info:
|
|
1231
|
-
# We need to run this to make sure that the .egg-info/
|
|
1232
|
-
# directory is created for packing in the bundle
|
|
1233
|
-
req_to_install.run_egg_info(force_root_egg_info=True)
|
|
1234
|
-
req_to_install.assert_source_matches_version()
|
|
1235
|
-
#@@ sketchy way of identifying packages not grabbed from an index
|
|
1236
|
-
if bundle and req_to_install.url:
|
|
1237
|
-
self.copy_to_build_dir(req_to_install)
|
|
1238
|
-
install = False
|
|
1239
|
-
# req_to_install.req is only avail after unpack for URL pkgs
|
|
1240
|
-
# repeat check_if_exists to uninstall-on-upgrade (#14)
|
|
1241
|
-
if not self.ignore_installed:
|
|
1242
|
-
req_to_install.check_if_exists()
|
|
1243
|
-
if req_to_install.satisfied_by:
|
|
1244
|
-
if self.upgrade or self.ignore_installed:
|
|
1245
|
-
#don't uninstall conflict if user install and and conflict is not user install
|
|
1246
|
-
if not (self.use_user_site and not dist_in_usersite(req_to_install.satisfied_by)):
|
|
1247
|
-
req_to_install.conflicts_with = req_to_install.satisfied_by
|
|
1248
|
-
req_to_install.satisfied_by = None
|
|
1249
|
-
else:
|
|
1250
|
-
logger.notify(
|
|
1251
|
-
'Requirement already satisfied (use '
|
|
1252
|
-
'--upgrade to upgrade): %s' %
|
|
1253
|
-
req_to_install
|
|
1254
|
-
)
|
|
1255
|
-
install = False
|
|
1256
|
-
if is_wheel:
|
|
1257
|
-
dist = list(
|
|
1258
|
-
pkg_resources.find_distributions(location)
|
|
1259
|
-
)[0]
|
|
1260
|
-
if not req_to_install.req:
|
|
1261
|
-
req_to_install.req = dist.as_requirement()
|
|
1262
|
-
self.add_requirement(req_to_install)
|
|
1263
|
-
if not self.ignore_dependencies:
|
|
1264
|
-
for subreq in dist.requires(
|
|
1265
|
-
req_to_install.extras):
|
|
1266
|
-
if self.has_requirement(
|
|
1267
|
-
subreq.project_name):
|
|
1268
|
-
continue
|
|
1269
|
-
subreq = InstallRequirement(str(subreq),
|
|
1270
|
-
req_to_install)
|
|
1271
|
-
reqs.append(subreq)
|
|
1272
|
-
self.add_requirement(subreq)
|
|
1273
|
-
|
|
1274
|
-
# sdists
|
|
1275
|
-
elif not is_bundle:
|
|
1276
|
-
## FIXME: shouldn't be globally added:
|
|
1277
|
-
finder.add_dependency_links(req_to_install.dependency_links)
|
|
1278
|
-
if (req_to_install.extras):
|
|
1279
|
-
logger.notify("Installing extra requirements: %r" % ','.join(req_to_install.extras))
|
|
1280
|
-
if not self.ignore_dependencies:
|
|
1281
|
-
for req in req_to_install.requirements(req_to_install.extras):
|
|
1282
|
-
try:
|
|
1283
|
-
name = pkg_resources.Requirement.parse(req).project_name
|
|
1284
|
-
except ValueError:
|
|
1285
|
-
e = sys.exc_info()[1]
|
|
1286
|
-
## FIXME: proper warning
|
|
1287
|
-
logger.error('Invalid requirement: %r (%s) in requirement %s' % (req, e, req_to_install))
|
|
1288
|
-
continue
|
|
1289
|
-
if self.has_requirement(name):
|
|
1290
|
-
## FIXME: check for conflict
|
|
1291
|
-
continue
|
|
1292
|
-
subreq = InstallRequirement(req, req_to_install)
|
|
1293
|
-
reqs.append(subreq)
|
|
1294
|
-
self.add_requirement(subreq)
|
|
1295
|
-
if not self.has_requirement(req_to_install.name):
|
|
1296
|
-
#'unnamed' requirements will get added here
|
|
1297
|
-
self.add_requirement(req_to_install)
|
|
1298
|
-
|
|
1299
|
-
# cleanup tmp src
|
|
1300
|
-
if not is_bundle:
|
|
1301
|
-
if (
|
|
1302
|
-
self.is_download or
|
|
1303
|
-
req_to_install._temp_build_dir is not None
|
|
1304
|
-
):
|
|
1305
|
-
self.reqs_to_cleanup.append(req_to_install)
|
|
1306
|
-
|
|
1307
|
-
if install:
|
|
1308
|
-
self.successfully_downloaded.append(req_to_install)
|
|
1309
|
-
if bundle and (req_to_install.url and req_to_install.url.startswith('file:///')):
|
|
1310
|
-
self.copy_to_build_dir(req_to_install)
|
|
1311
|
-
finally:
|
|
1312
|
-
logger.indent -= 2
|
|
1313
|
-
|
|
1314
|
-
def cleanup_files(self, bundle=False):
|
|
1315
|
-
"""Clean up files, remove builds."""
|
|
1316
|
-
logger.notify('Cleaning up...')
|
|
1317
|
-
logger.indent += 2
|
|
1318
|
-
for req in self.reqs_to_cleanup:
|
|
1319
|
-
req.remove_temporary_source()
|
|
1320
|
-
|
|
1321
|
-
remove_dir = []
|
|
1322
|
-
if self._pip_has_created_build_dir():
|
|
1323
|
-
remove_dir.append(self.build_dir)
|
|
1324
|
-
|
|
1325
|
-
# The source dir of a bundle can always be removed.
|
|
1326
|
-
# FIXME: not if it pre-existed the bundle!
|
|
1327
|
-
if bundle:
|
|
1328
|
-
remove_dir.append(self.src_dir)
|
|
1329
|
-
|
|
1330
|
-
for dir in remove_dir:
|
|
1331
|
-
if os.path.exists(dir):
|
|
1332
|
-
logger.info('Removing temporary dir %s...' % dir)
|
|
1333
|
-
rmtree(dir)
|
|
1334
|
-
|
|
1335
|
-
logger.indent -= 2
|
|
1336
|
-
|
|
1337
|
-
def _pip_has_created_build_dir(self):
|
|
1338
|
-
return (self.build_dir == build_prefix and
|
|
1339
|
-
os.path.exists(os.path.join(self.build_dir, PIP_DELETE_MARKER_FILENAME)))
|
|
1340
|
-
|
|
1341
|
-
def copy_to_build_dir(self, req_to_install):
|
|
1342
|
-
target_dir = req_to_install.editable and self.src_dir or self.build_dir
|
|
1343
|
-
logger.info("Copying %s to %s" % (req_to_install.name, target_dir))
|
|
1344
|
-
dest = os.path.join(target_dir, req_to_install.name)
|
|
1345
|
-
shutil.copytree(req_to_install.source_dir, dest)
|
|
1346
|
-
call_subprocess(["python", "%s/setup.py" % dest, "clean"], cwd=dest,
|
|
1347
|
-
command_desc='python setup.py clean')
|
|
1348
|
-
|
|
1349
|
-
def unpack_url(self, link, location, download_dir=None,
|
|
1350
|
-
only_download=False):
|
|
1351
|
-
if download_dir is None:
|
|
1352
|
-
download_dir = self.download_dir
|
|
1353
|
-
|
|
1354
|
-
# non-editable vcs urls
|
|
1355
|
-
if is_vcs_url(link):
|
|
1356
|
-
if only_download:
|
|
1357
|
-
loc = download_dir
|
|
1358
|
-
else:
|
|
1359
|
-
loc = location
|
|
1360
|
-
unpack_vcs_link(link, loc, only_download)
|
|
1361
|
-
|
|
1362
|
-
# file urls
|
|
1363
|
-
elif is_file_url(link):
|
|
1364
|
-
unpack_file_url(link, location, download_dir)
|
|
1365
|
-
if only_download:
|
|
1366
|
-
write_delete_marker_file(location)
|
|
1367
|
-
|
|
1368
|
-
# http urls
|
|
1369
|
-
else:
|
|
1370
|
-
unpack_http_url(
|
|
1371
|
-
link,
|
|
1372
|
-
location,
|
|
1373
|
-
self.download_cache,
|
|
1374
|
-
download_dir,
|
|
1375
|
-
self.session,
|
|
1376
|
-
)
|
|
1377
|
-
if only_download:
|
|
1378
|
-
write_delete_marker_file(location)
|
|
1379
|
-
|
|
1380
|
-
def install(self, install_options, global_options=(), *args, **kwargs):
|
|
1381
|
-
"""Install everything in this set (after having downloaded and unpacked the packages)"""
|
|
1382
|
-
to_install = [r for r in self.requirements.values()
|
|
1383
|
-
if not r.satisfied_by]
|
|
1384
|
-
|
|
1385
|
-
# DISTRIBUTE TO SETUPTOOLS UPGRADE HACK (1 of 3 parts)
|
|
1386
|
-
# move the distribute-0.7.X wrapper to the end because it does not
|
|
1387
|
-
# install a setuptools package. by moving it to the end, we ensure it's
|
|
1388
|
-
# setuptools dependency is handled first, which will provide the
|
|
1389
|
-
# setuptools package
|
|
1390
|
-
# TODO: take this out later
|
|
1391
|
-
distribute_req = pkg_resources.Requirement.parse("distribute>=0.7")
|
|
1392
|
-
for req in to_install:
|
|
1393
|
-
if req.name == 'distribute' and req.installed_version in distribute_req:
|
|
1394
|
-
to_install.remove(req)
|
|
1395
|
-
to_install.append(req)
|
|
1396
|
-
|
|
1397
|
-
if to_install:
|
|
1398
|
-
logger.notify('Installing collected packages: %s' % ', '.join([req.name for req in to_install]))
|
|
1399
|
-
logger.indent += 2
|
|
1400
|
-
try:
|
|
1401
|
-
for requirement in to_install:
|
|
1402
|
-
|
|
1403
|
-
# DISTRIBUTE TO SETUPTOOLS UPGRADE HACK (1 of 3 parts)
|
|
1404
|
-
# when upgrading from distribute-0.6.X to the new merged
|
|
1405
|
-
# setuptools in py2, we need to force setuptools to uninstall
|
|
1406
|
-
# distribute. In py3, which is always using distribute, this
|
|
1407
|
-
# conversion is already happening in distribute's pkg_resources.
|
|
1408
|
-
# It's ok *not* to check if setuptools>=0.7 because if someone
|
|
1409
|
-
# were actually trying to ugrade from distribute to setuptools
|
|
1410
|
-
# 0.6.X, then all this could do is actually help, although that
|
|
1411
|
-
# upgade path was certainly never "supported"
|
|
1412
|
-
# TODO: remove this later
|
|
1413
|
-
if requirement.name == 'setuptools':
|
|
1414
|
-
try:
|
|
1415
|
-
# only uninstall distribute<0.7. For >=0.7, setuptools
|
|
1416
|
-
# will also be present, and that's what we need to
|
|
1417
|
-
# uninstall
|
|
1418
|
-
distribute_requirement = pkg_resources.Requirement.parse("distribute<0.7")
|
|
1419
|
-
existing_distribute = pkg_resources.get_distribution("distribute")
|
|
1420
|
-
if existing_distribute in distribute_requirement:
|
|
1421
|
-
requirement.conflicts_with = existing_distribute
|
|
1422
|
-
except pkg_resources.DistributionNotFound:
|
|
1423
|
-
# distribute wasn't installed, so nothing to do
|
|
1424
|
-
pass
|
|
1425
|
-
|
|
1426
|
-
if requirement.conflicts_with:
|
|
1427
|
-
logger.notify('Found existing installation: %s'
|
|
1428
|
-
% requirement.conflicts_with)
|
|
1429
|
-
logger.indent += 2
|
|
1430
|
-
try:
|
|
1431
|
-
requirement.uninstall(auto_confirm=True)
|
|
1432
|
-
finally:
|
|
1433
|
-
logger.indent -= 2
|
|
1434
|
-
try:
|
|
1435
|
-
requirement.install(install_options, global_options, *args, **kwargs)
|
|
1436
|
-
except:
|
|
1437
|
-
# if install did not succeed, rollback previous uninstall
|
|
1438
|
-
if requirement.conflicts_with and not requirement.install_succeeded:
|
|
1439
|
-
requirement.rollback_uninstall()
|
|
1440
|
-
raise
|
|
1441
|
-
else:
|
|
1442
|
-
if requirement.conflicts_with and requirement.install_succeeded:
|
|
1443
|
-
requirement.commit_uninstall()
|
|
1444
|
-
requirement.remove_temporary_source()
|
|
1445
|
-
finally:
|
|
1446
|
-
logger.indent -= 2
|
|
1447
|
-
self.successfully_installed = to_install
|
|
1448
|
-
|
|
1449
|
-
def create_bundle(self, bundle_filename):
|
|
1450
|
-
## FIXME: can't decide which is better; zip is easier to read
|
|
1451
|
-
## random files from, but tar.bz2 is smaller and not as lame a
|
|
1452
|
-
## format.
|
|
1453
|
-
|
|
1454
|
-
## FIXME: this file should really include a manifest of the
|
|
1455
|
-
## packages, maybe some other metadata files. It would make
|
|
1456
|
-
## it easier to detect as well.
|
|
1457
|
-
zip = zipfile.ZipFile(bundle_filename, 'w', zipfile.ZIP_DEFLATED)
|
|
1458
|
-
vcs_dirs = []
|
|
1459
|
-
for dir, basename in (self.build_dir, 'build'), (self.src_dir, 'src'):
|
|
1460
|
-
dir = os.path.normcase(os.path.abspath(dir))
|
|
1461
|
-
for dirpath, dirnames, filenames in os.walk(dir):
|
|
1462
|
-
for backend in vcs.backends:
|
|
1463
|
-
vcs_backend = backend()
|
|
1464
|
-
vcs_url = vcs_rev = None
|
|
1465
|
-
if vcs_backend.dirname in dirnames:
|
|
1466
|
-
for vcs_dir in vcs_dirs:
|
|
1467
|
-
if dirpath.startswith(vcs_dir):
|
|
1468
|
-
# vcs bundle file already in parent directory
|
|
1469
|
-
break
|
|
1470
|
-
else:
|
|
1471
|
-
vcs_url, vcs_rev = vcs_backend.get_info(
|
|
1472
|
-
os.path.join(dir, dirpath))
|
|
1473
|
-
vcs_dirs.append(dirpath)
|
|
1474
|
-
vcs_bundle_file = vcs_backend.bundle_file
|
|
1475
|
-
vcs_guide = vcs_backend.guide % {'url': vcs_url,
|
|
1476
|
-
'rev': vcs_rev}
|
|
1477
|
-
dirnames.remove(vcs_backend.dirname)
|
|
1478
|
-
break
|
|
1479
|
-
if 'pip-egg-info' in dirnames:
|
|
1480
|
-
dirnames.remove('pip-egg-info')
|
|
1481
|
-
for dirname in dirnames:
|
|
1482
|
-
dirname = os.path.join(dirpath, dirname)
|
|
1483
|
-
name = self._clean_zip_name(dirname, dir)
|
|
1484
|
-
zip.writestr(basename + '/' + name + '/', '')
|
|
1485
|
-
for filename in filenames:
|
|
1486
|
-
if filename == PIP_DELETE_MARKER_FILENAME:
|
|
1487
|
-
continue
|
|
1488
|
-
filename = os.path.join(dirpath, filename)
|
|
1489
|
-
name = self._clean_zip_name(filename, dir)
|
|
1490
|
-
zip.write(filename, basename + '/' + name)
|
|
1491
|
-
if vcs_url:
|
|
1492
|
-
name = os.path.join(dirpath, vcs_bundle_file)
|
|
1493
|
-
name = self._clean_zip_name(name, dir)
|
|
1494
|
-
zip.writestr(basename + '/' + name, vcs_guide)
|
|
1495
|
-
|
|
1496
|
-
zip.writestr('pip-manifest.txt', self.bundle_requirements())
|
|
1497
|
-
zip.close()
|
|
1498
|
-
|
|
1499
|
-
BUNDLE_HEADER = '''\
|
|
1500
|
-
# This is a pip bundle file, that contains many source packages
|
|
1501
|
-
# that can be installed as a group. You can install this like:
|
|
1502
|
-
# pip this_file.zip
|
|
1503
|
-
# The rest of the file contains a list of all the packages included:
|
|
1504
|
-
'''
|
|
1505
|
-
|
|
1506
|
-
def bundle_requirements(self):
|
|
1507
|
-
parts = [self.BUNDLE_HEADER]
|
|
1508
|
-
for req in [req for req in self.requirements.values()
|
|
1509
|
-
if not req.comes_from]:
|
|
1510
|
-
parts.append('%s==%s\n' % (req.name, req.installed_version))
|
|
1511
|
-
parts.append('# These packages were installed to satisfy the above requirements:\n')
|
|
1512
|
-
for req in [req for req in self.requirements.values()
|
|
1513
|
-
if req.comes_from]:
|
|
1514
|
-
parts.append('%s==%s\n' % (req.name, req.installed_version))
|
|
1515
|
-
## FIXME: should we do something with self.unnamed_requirements?
|
|
1516
|
-
return ''.join(parts)
|
|
1517
|
-
|
|
1518
|
-
def _clean_zip_name(self, name, prefix):
|
|
1519
|
-
assert name.startswith(prefix+os.path.sep), (
|
|
1520
|
-
"name %r doesn't start with prefix %r" % (name, prefix))
|
|
1521
|
-
name = name[len(prefix)+1:]
|
|
1522
|
-
name = name.replace(os.path.sep, '/')
|
|
1523
|
-
return name
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
def _make_build_dir(build_dir):
|
|
1527
|
-
os.makedirs(build_dir)
|
|
1528
|
-
write_delete_marker_file(build_dir)
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
_scheme_re = re.compile(r'^(http|https|file):', re.I)
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
def parse_requirements(filename, finder=None, comes_from=None, options=None,
|
|
1535
|
-
session=None):
|
|
1536
|
-
if session is None:
|
|
1537
|
-
session = PipSession()
|
|
1538
|
-
|
|
1539
|
-
skip_match = None
|
|
1540
|
-
skip_regex = options.skip_requirements_regex if options else None
|
|
1541
|
-
if skip_regex:
|
|
1542
|
-
skip_match = re.compile(skip_regex)
|
|
1543
|
-
reqs_file_dir = os.path.dirname(os.path.abspath(filename))
|
|
1544
|
-
filename, content = get_file_content(filename,
|
|
1545
|
-
comes_from=comes_from,
|
|
1546
|
-
session=session,
|
|
1547
|
-
)
|
|
1548
|
-
for line_number, line in enumerate(content.splitlines()):
|
|
1549
|
-
line_number += 1
|
|
1550
|
-
line = line.strip()
|
|
1551
|
-
|
|
1552
|
-
# Remove comments from file
|
|
1553
|
-
line = re.sub(r"(^|\s)#.*$", "", line)
|
|
1554
|
-
|
|
1555
|
-
if not line or line.startswith('#'):
|
|
1556
|
-
continue
|
|
1557
|
-
if skip_match and skip_match.search(line):
|
|
1558
|
-
continue
|
|
1559
|
-
if line.startswith('-r') or line.startswith('--requirement'):
|
|
1560
|
-
if line.startswith('-r'):
|
|
1561
|
-
req_url = line[2:].strip()
|
|
1562
|
-
else:
|
|
1563
|
-
req_url = line[len('--requirement'):].strip().strip('=')
|
|
1564
|
-
if _scheme_re.search(filename):
|
|
1565
|
-
# Relative to a URL
|
|
1566
|
-
req_url = urlparse.urljoin(filename, req_url)
|
|
1567
|
-
elif not _scheme_re.search(req_url):
|
|
1568
|
-
req_url = os.path.join(os.path.dirname(filename), req_url)
|
|
1569
|
-
for item in parse_requirements(req_url, finder, comes_from=filename, options=options, session=session):
|
|
1570
|
-
yield item
|
|
1571
|
-
elif line.startswith('-Z') or line.startswith('--always-unzip'):
|
|
1572
|
-
# No longer used, but previously these were used in
|
|
1573
|
-
# requirement files, so we'll ignore.
|
|
1574
|
-
pass
|
|
1575
|
-
elif line.startswith('-f') or line.startswith('--find-links'):
|
|
1576
|
-
if line.startswith('-f'):
|
|
1577
|
-
line = line[2:].strip()
|
|
1578
|
-
else:
|
|
1579
|
-
line = line[len('--find-links'):].strip().lstrip('=')
|
|
1580
|
-
## FIXME: it would be nice to keep track of the source of
|
|
1581
|
-
## the find_links:
|
|
1582
|
-
# support a find-links local path relative to a requirements file
|
|
1583
|
-
relative_to_reqs_file = os.path.join(reqs_file_dir, line)
|
|
1584
|
-
if os.path.exists(relative_to_reqs_file):
|
|
1585
|
-
line = relative_to_reqs_file
|
|
1586
|
-
if finder:
|
|
1587
|
-
finder.find_links.append(line)
|
|
1588
|
-
elif line.startswith('-i') or line.startswith('--index-url'):
|
|
1589
|
-
if line.startswith('-i'):
|
|
1590
|
-
line = line[2:].strip()
|
|
1591
|
-
else:
|
|
1592
|
-
line = line[len('--index-url'):].strip().lstrip('=')
|
|
1593
|
-
if finder:
|
|
1594
|
-
finder.index_urls = [line]
|
|
1595
|
-
elif line.startswith('--extra-index-url'):
|
|
1596
|
-
line = line[len('--extra-index-url'):].strip().lstrip('=')
|
|
1597
|
-
if finder:
|
|
1598
|
-
finder.index_urls.append(line)
|
|
1599
|
-
elif line.startswith('--use-wheel'):
|
|
1600
|
-
finder.use_wheel = True
|
|
1601
|
-
elif line.startswith('--no-index'):
|
|
1602
|
-
finder.index_urls = []
|
|
1603
|
-
elif line.startswith("--allow-external"):
|
|
1604
|
-
line = line[len("--allow-external"):].strip().lstrip("=")
|
|
1605
|
-
finder.allow_external |= set([normalize_name(line).lower()])
|
|
1606
|
-
elif line.startswith("--allow-all-external"):
|
|
1607
|
-
finder.allow_all_external = True
|
|
1608
|
-
# Remove in 1.7
|
|
1609
|
-
elif line.startswith("--no-allow-external"):
|
|
1610
|
-
pass
|
|
1611
|
-
# Remove in 1.7
|
|
1612
|
-
elif line.startswith("--no-allow-insecure"):
|
|
1613
|
-
pass
|
|
1614
|
-
# Remove after 1.7
|
|
1615
|
-
elif line.startswith("--allow-insecure"):
|
|
1616
|
-
line = line[len("--allow-insecure"):].strip().lstrip("=")
|
|
1617
|
-
finder.allow_unverified |= set([normalize_name(line).lower()])
|
|
1618
|
-
elif line.startswith("--allow-unverified"):
|
|
1619
|
-
line = line[len("--allow-unverified"):].strip().lstrip("=")
|
|
1620
|
-
finder.allow_unverified |= set([normalize_name(line).lower()])
|
|
1621
|
-
else:
|
|
1622
|
-
comes_from = '-r %s (line %s)' % (filename, line_number)
|
|
1623
|
-
if line.startswith('-e') or line.startswith('--editable'):
|
|
1624
|
-
if line.startswith('-e'):
|
|
1625
|
-
line = line[2:].strip()
|
|
1626
|
-
else:
|
|
1627
|
-
line = line[len('--editable'):].strip().lstrip('=')
|
|
1628
|
-
req = InstallRequirement.from_editable(
|
|
1629
|
-
line, comes_from=comes_from, default_vcs=options.default_vcs if options else None)
|
|
1630
|
-
else:
|
|
1631
|
-
req = InstallRequirement.from_line(line, comes_from, prereleases=getattr(options, "pre", None))
|
|
1632
|
-
yield req
|
|
1633
|
-
|
|
1634
|
-
def _strip_postfix(req):
|
|
1635
|
-
"""
|
|
1636
|
-
Strip req postfix ( -dev, 0.2, etc )
|
|
1637
|
-
"""
|
|
1638
|
-
## FIXME: use package_to_requirement?
|
|
1639
|
-
match = re.search(r'^(.*?)(?:-dev|-\d.*)$', req)
|
|
1640
|
-
if match:
|
|
1641
|
-
# Strip off -dev, -0.2, etc.
|
|
1642
|
-
req = match.group(1)
|
|
1643
|
-
return req
|
|
1644
|
-
|
|
1645
|
-
def _build_req_from_url(url):
|
|
1646
|
-
|
|
1647
|
-
parts = [p for p in url.split('#', 1)[0].split('/') if p]
|
|
1648
|
-
|
|
1649
|
-
req = None
|
|
1650
|
-
if parts[-2] in ('tags', 'branches', 'tag', 'branch'):
|
|
1651
|
-
req = parts[-3]
|
|
1652
|
-
elif parts[-1] == 'trunk':
|
|
1653
|
-
req = parts[-2]
|
|
1654
|
-
return req
|
|
1655
|
-
|
|
1656
|
-
def _build_editable_options(req):
|
|
1657
|
-
|
|
1658
|
-
"""
|
|
1659
|
-
This method generates a dictionary of the query string
|
|
1660
|
-
parameters contained in a given editable URL.
|
|
1661
|
-
"""
|
|
1662
|
-
regexp = re.compile(r"[\?#&](?P<name>[^&=]+)=(?P<value>[^&=]+)")
|
|
1663
|
-
matched = regexp.findall(req)
|
|
1664
|
-
|
|
1665
|
-
if matched:
|
|
1666
|
-
ret = dict()
|
|
1667
|
-
for option in matched:
|
|
1668
|
-
(name, value) = option
|
|
1669
|
-
if name in ret:
|
|
1670
|
-
raise Exception("%s option already defined" % name)
|
|
1671
|
-
ret[name] = value
|
|
1672
|
-
return ret
|
|
1673
|
-
return None
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
def parse_editable(editable_req, default_vcs=None):
|
|
1677
|
-
"""Parses svn+http://blahblah@rev#egg=Foobar into a requirement
|
|
1678
|
-
(Foobar) and a URL"""
|
|
1679
|
-
|
|
1680
|
-
url = editable_req
|
|
1681
|
-
extras = None
|
|
1682
|
-
|
|
1683
|
-
# If a file path is specified with extras, strip off the extras.
|
|
1684
|
-
m = re.match(r'^(.+)(\[[^\]]+\])$', url)
|
|
1685
|
-
if m:
|
|
1686
|
-
url_no_extras = m.group(1)
|
|
1687
|
-
extras = m.group(2)
|
|
1688
|
-
else:
|
|
1689
|
-
url_no_extras = url
|
|
1690
|
-
|
|
1691
|
-
if os.path.isdir(url_no_extras):
|
|
1692
|
-
if not os.path.exists(os.path.join(url_no_extras, 'setup.py')):
|
|
1693
|
-
raise InstallationError("Directory %r is not installable. File 'setup.py' not found." % url_no_extras)
|
|
1694
|
-
# Treating it as code that has already been checked out
|
|
1695
|
-
url_no_extras = path_to_url(url_no_extras)
|
|
1696
|
-
|
|
1697
|
-
if url_no_extras.lower().startswith('file:'):
|
|
1698
|
-
if extras:
|
|
1699
|
-
return None, url_no_extras, pkg_resources.Requirement.parse('__placeholder__' + extras).extras
|
|
1700
|
-
else:
|
|
1701
|
-
return None, url_no_extras, None
|
|
1702
|
-
|
|
1703
|
-
for version_control in vcs:
|
|
1704
|
-
if url.lower().startswith('%s:' % version_control):
|
|
1705
|
-
url = '%s+%s' % (version_control, url)
|
|
1706
|
-
break
|
|
1707
|
-
|
|
1708
|
-
if '+' not in url:
|
|
1709
|
-
if default_vcs:
|
|
1710
|
-
url = default_vcs + '+' + url
|
|
1711
|
-
else:
|
|
1712
|
-
raise InstallationError(
|
|
1713
|
-
'%s should either be a path to a local project or a VCS url beginning with svn+, git+, hg+, or bzr+' % editable_req)
|
|
1714
|
-
|
|
1715
|
-
vc_type = url.split('+', 1)[0].lower()
|
|
1716
|
-
|
|
1717
|
-
if not vcs.get_backend(vc_type):
|
|
1718
|
-
error_message = 'For --editable=%s only ' % editable_req + \
|
|
1719
|
-
', '.join([backend.name + '+URL' for backend in vcs.backends]) + \
|
|
1720
|
-
' is currently supported'
|
|
1721
|
-
raise InstallationError(error_message)
|
|
1722
|
-
|
|
1723
|
-
try:
|
|
1724
|
-
options = _build_editable_options(editable_req)
|
|
1725
|
-
except Exception:
|
|
1726
|
-
message = sys.exc_info()[1]
|
|
1727
|
-
raise InstallationError(
|
|
1728
|
-
'--editable=%s error in editable options:%s' % (editable_req, message))
|
|
1729
|
-
|
|
1730
|
-
if not options or 'egg' not in options:
|
|
1731
|
-
req = _build_req_from_url(editable_req)
|
|
1732
|
-
if not req:
|
|
1733
|
-
raise InstallationError('--editable=%s is not the right format; it must have #egg=Package' % editable_req)
|
|
1734
|
-
else:
|
|
1735
|
-
req = options['egg']
|
|
1736
|
-
|
|
1737
|
-
package = _strip_postfix(req)
|
|
1738
|
-
return package, url, options
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
class UninstallPathSet(object):
|
|
1742
|
-
"""A set of file paths to be removed in the uninstallation of a
|
|
1743
|
-
requirement."""
|
|
1744
|
-
def __init__(self, dist):
|
|
1745
|
-
self.paths = set()
|
|
1746
|
-
self._refuse = set()
|
|
1747
|
-
self.pth = {}
|
|
1748
|
-
self.dist = dist
|
|
1749
|
-
self.save_dir = None
|
|
1750
|
-
self._moved_paths = []
|
|
1751
|
-
|
|
1752
|
-
def _permitted(self, path):
|
|
1753
|
-
"""
|
|
1754
|
-
Return True if the given path is one we are permitted to
|
|
1755
|
-
remove/modify, False otherwise.
|
|
1756
|
-
|
|
1757
|
-
"""
|
|
1758
|
-
return is_local(path)
|
|
1759
|
-
|
|
1760
|
-
def _can_uninstall(self):
|
|
1761
|
-
if not dist_is_local(self.dist):
|
|
1762
|
-
logger.notify("Not uninstalling %s at %s, outside environment %s"
|
|
1763
|
-
% (self.dist.project_name, normalize_path(self.dist.location), sys.prefix))
|
|
1764
|
-
return False
|
|
1765
|
-
return True
|
|
1766
|
-
|
|
1767
|
-
def add(self, path):
|
|
1768
|
-
path = normalize_path(path)
|
|
1769
|
-
if not os.path.exists(path):
|
|
1770
|
-
return
|
|
1771
|
-
if self._permitted(path):
|
|
1772
|
-
self.paths.add(path)
|
|
1773
|
-
else:
|
|
1774
|
-
self._refuse.add(path)
|
|
1775
|
-
|
|
1776
|
-
# __pycache__ files can show up after 'installed-files.txt' is created, due to imports
|
|
1777
|
-
if os.path.splitext(path)[1] == '.py' and uses_pycache:
|
|
1778
|
-
self.add(imp.cache_from_source(path))
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
def add_pth(self, pth_file, entry):
|
|
1782
|
-
pth_file = normalize_path(pth_file)
|
|
1783
|
-
if self._permitted(pth_file):
|
|
1784
|
-
if pth_file not in self.pth:
|
|
1785
|
-
self.pth[pth_file] = UninstallPthEntries(pth_file)
|
|
1786
|
-
self.pth[pth_file].add(entry)
|
|
1787
|
-
else:
|
|
1788
|
-
self._refuse.add(pth_file)
|
|
1789
|
-
|
|
1790
|
-
def compact(self, paths):
|
|
1791
|
-
"""Compact a path set to contain the minimal number of paths
|
|
1792
|
-
necessary to contain all paths in the set. If /a/path/ and
|
|
1793
|
-
/a/path/to/a/file.txt are both in the set, leave only the
|
|
1794
|
-
shorter path."""
|
|
1795
|
-
short_paths = set()
|
|
1796
|
-
for path in sorted(paths, key=len):
|
|
1797
|
-
if not any([(path.startswith(shortpath) and
|
|
1798
|
-
path[len(shortpath.rstrip(os.path.sep))] == os.path.sep)
|
|
1799
|
-
for shortpath in short_paths]):
|
|
1800
|
-
short_paths.add(path)
|
|
1801
|
-
return short_paths
|
|
1802
|
-
|
|
1803
|
-
def _stash(self, path):
|
|
1804
|
-
return os.path.join(
|
|
1805
|
-
self.save_dir, os.path.splitdrive(path)[1].lstrip(os.path.sep))
|
|
1806
|
-
|
|
1807
|
-
def remove(self, auto_confirm=False):
|
|
1808
|
-
"""Remove paths in ``self.paths`` with confirmation (unless
|
|
1809
|
-
``auto_confirm`` is True)."""
|
|
1810
|
-
if not self._can_uninstall():
|
|
1811
|
-
return
|
|
1812
|
-
if not self.paths:
|
|
1813
|
-
logger.notify("Can't uninstall '%s'. No files were found to uninstall." % self.dist.project_name)
|
|
1814
|
-
return
|
|
1815
|
-
logger.notify('Uninstalling %s:' % self.dist.project_name)
|
|
1816
|
-
logger.indent += 2
|
|
1817
|
-
paths = sorted(self.compact(self.paths))
|
|
1818
|
-
try:
|
|
1819
|
-
if auto_confirm:
|
|
1820
|
-
response = 'y'
|
|
1821
|
-
else:
|
|
1822
|
-
for path in paths:
|
|
1823
|
-
logger.notify(path)
|
|
1824
|
-
response = ask('Proceed (y/n)? ', ('y', 'n'))
|
|
1825
|
-
if self._refuse:
|
|
1826
|
-
logger.notify('Not removing or modifying (outside of prefix):')
|
|
1827
|
-
for path in self.compact(self._refuse):
|
|
1828
|
-
logger.notify(path)
|
|
1829
|
-
if response == 'y':
|
|
1830
|
-
self.save_dir = tempfile.mkdtemp(suffix='-uninstall',
|
|
1831
|
-
prefix='pip-')
|
|
1832
|
-
for path in paths:
|
|
1833
|
-
new_path = self._stash(path)
|
|
1834
|
-
logger.info('Removing file or directory %s' % path)
|
|
1835
|
-
self._moved_paths.append(path)
|
|
1836
|
-
renames(path, new_path)
|
|
1837
|
-
for pth in self.pth.values():
|
|
1838
|
-
pth.remove()
|
|
1839
|
-
logger.notify('Successfully uninstalled %s' % self.dist.project_name)
|
|
1840
|
-
|
|
1841
|
-
finally:
|
|
1842
|
-
logger.indent -= 2
|
|
1843
|
-
|
|
1844
|
-
def rollback(self):
|
|
1845
|
-
"""Rollback the changes previously made by remove()."""
|
|
1846
|
-
if self.save_dir is None:
|
|
1847
|
-
logger.error("Can't roll back %s; was not uninstalled" % self.dist.project_name)
|
|
1848
|
-
return False
|
|
1849
|
-
logger.notify('Rolling back uninstall of %s' % self.dist.project_name)
|
|
1850
|
-
for path in self._moved_paths:
|
|
1851
|
-
tmp_path = self._stash(path)
|
|
1852
|
-
logger.info('Replacing %s' % path)
|
|
1853
|
-
renames(tmp_path, path)
|
|
1854
|
-
for pth in self.pth:
|
|
1855
|
-
pth.rollback()
|
|
1856
|
-
|
|
1857
|
-
def commit(self):
|
|
1858
|
-
"""Remove temporary save dir: rollback will no longer be possible."""
|
|
1859
|
-
if self.save_dir is not None:
|
|
1860
|
-
rmtree(self.save_dir)
|
|
1861
|
-
self.save_dir = None
|
|
1862
|
-
self._moved_paths = []
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
class UninstallPthEntries(object):
|
|
1866
|
-
def __init__(self, pth_file):
|
|
1867
|
-
if not os.path.isfile(pth_file):
|
|
1868
|
-
raise UninstallationError("Cannot remove entries from nonexistent file %s" % pth_file)
|
|
1869
|
-
self.file = pth_file
|
|
1870
|
-
self.entries = set()
|
|
1871
|
-
self._saved_lines = None
|
|
1872
|
-
|
|
1873
|
-
def add(self, entry):
|
|
1874
|
-
entry = os.path.normcase(entry)
|
|
1875
|
-
# On Windows, os.path.normcase converts the entry to use
|
|
1876
|
-
# backslashes. This is correct for entries that describe absolute
|
|
1877
|
-
# paths outside of site-packages, but all the others use forward
|
|
1878
|
-
# slashes.
|
|
1879
|
-
if sys.platform == 'win32' and not os.path.splitdrive(entry)[0]:
|
|
1880
|
-
entry = entry.replace('\\', '/')
|
|
1881
|
-
self.entries.add(entry)
|
|
1882
|
-
|
|
1883
|
-
def remove(self):
|
|
1884
|
-
logger.info('Removing pth entries from %s:' % self.file)
|
|
1885
|
-
fh = open(self.file, 'rb')
|
|
1886
|
-
# windows uses '\r\n' with py3k, but uses '\n' with py2.x
|
|
1887
|
-
lines = fh.readlines()
|
|
1888
|
-
self._saved_lines = lines
|
|
1889
|
-
fh.close()
|
|
1890
|
-
if any(b('\r\n') in line for line in lines):
|
|
1891
|
-
endline = '\r\n'
|
|
1892
|
-
else:
|
|
1893
|
-
endline = '\n'
|
|
1894
|
-
for entry in self.entries:
|
|
1895
|
-
try:
|
|
1896
|
-
logger.info('Removing entry: %s' % entry)
|
|
1897
|
-
lines.remove(b(entry + endline))
|
|
1898
|
-
except ValueError:
|
|
1899
|
-
pass
|
|
1900
|
-
fh = open(self.file, 'wb')
|
|
1901
|
-
fh.writelines(lines)
|
|
1902
|
-
fh.close()
|
|
1903
|
-
|
|
1904
|
-
def rollback(self):
|
|
1905
|
-
if self._saved_lines is None:
|
|
1906
|
-
logger.error('Cannot roll back changes to %s, none were made' % self.file)
|
|
1907
|
-
return False
|
|
1908
|
-
logger.info('Rolling %s back to previous state' % self.file)
|
|
1909
|
-
fh = open(self.file, 'wb')
|
|
1910
|
-
fh.writelines(self._saved_lines)
|
|
1911
|
-
fh.close()
|
|
1912
|
-
return True
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
class FakeFile(object):
|
|
1916
|
-
"""Wrap a list of lines in an object with readline() to make
|
|
1917
|
-
ConfigParser happy."""
|
|
1918
|
-
def __init__(self, lines):
|
|
1919
|
-
self._gen = (l for l in lines)
|
|
1920
|
-
|
|
1921
|
-
def readline(self):
|
|
1922
|
-
try:
|
|
1923
|
-
try:
|
|
1924
|
-
return next(self._gen)
|
|
1925
|
-
except NameError:
|
|
1926
|
-
return self._gen.next()
|
|
1927
|
-
except StopIteration:
|
|
1928
|
-
return ''
|
|
1929
|
-
|
|
1930
|
-
def __iter__(self):
|
|
1931
|
-
return self._gen
|