{"action":"created","comment":{"url":"https://api.github.com/repos/pypa/pip/pulls/comments/41570712","id":41570712,"diff_hunk":"@@ -727,45 +704,6 @@ def unpack_file_url(link, location, download_dir=None):\n         _copy_file(from_path, download_dir, content_type, link)\n \n \n-def _copy_dist_from_dir(link_path, location):\n-    \"\"\"Copy distribution files in `link_path` to `location`.\n-\n-    Invoked when user requests to install a local directory. E.g.:\n-\n-        pip install .\n-        pip install ~/dev/git-repos/python-prompt-toolkit\n-\n-    \"\"\"\n-\n-    # Note: This is currently VERY SLOW if you have a lot of data in the\n-    # directory, because it copies everything with `shutil.copytree`.\n-    # What it should really do is build an sdist and install that.\n-    # See https://github.com/pypa/pip/issues/2195\n-\n-    if os.path.isdir(location):\n-        rmtree(location)\n-\n-    # build an sdist\n-    setup_py = 'setup.py'\n-    sdist_args = [sys.executable]\n-    sdist_args.append('-c')\n-    sdist_args.append(\n-        \"import setuptools, tokenize;__file__=%r;\"\n-        \"exec(compile(getattr(tokenize, 'open', open)(__file__).read()\"\n-        \".replace('\\\\r\\\\n', '\\\\n'), __file__, 'exec'))\" % setup_py)\n-    sdist_args.append('sdist')\n-    sdist_args += ['--dist-dir', location]\n-    logger.info('Running setup.py sdist for %s', link_path)\n-\n-    with indent_log():\n-        call_subprocess(sdist_args, cwd=link_path, show_stdout=False)\n-\n-    # unpack sdist into `location`\n-    sdist = os.path.join(location, os.listdir(location)[0])\n-    logger.info('Unpacking sdist %s into %s', sdist, location)\n-    unpack_file(sdist, location, content_type=None, link=None)\n-\n-","path":"pip/download.py","position":264,"original_position":264,"commit_id":"7a0a97c0815c53f1fef845881475e2fe5cfd179e","original_commit_id":"7a0a97c0815c53f1fef845881475e2fe5cfd179e","user":{"login":"xavfernandez","id":1089744,"avatar_url":"https://avatars.githubusercontent.com/u/1089744?v=3","gravatar_id":"","url":"https://api.github.com/users/xavfernandez","html_url":"https://github.com/xavfernandez","followers_url":"https://api.github.com/users/xavfernandez/followers","following_url":"https://api.github.com/users/xavfernandez/following{/other_user}","gists_url":"https://api.github.com/users/xavfernandez/gists{/gist_id}","starred_url":"https://api.github.com/users/xavfernandez/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xavfernandez/subscriptions","organizations_url":"https://api.github.com/users/xavfernandez/orgs","repos_url":"https://api.github.com/users/xavfernandez/repos","events_url":"https://api.github.com/users/xavfernandez/events{/privacy}","received_events_url":"https://api.github.com/users/xavfernandez/received_events","type":"User","site_admin":false},"body":"This could (should?) go into an other PR :-o","created_at":"2015-10-08T21:21:27Z","updated_at":"2015-10-08T21:21:27Z","html_url":"https://github.com/pypa/pip/pull/3137#discussion_r41570712","pull_request_url":"https://api.github.com/repos/pypa/pip/pulls/3137","_links":{"self":{"href":"https://api.github.com/repos/pypa/pip/pulls/comments/41570712"},"html":{"href":"https://github.com/pypa/pip/pull/3137#discussion_r41570712"},"pull_request":{"href":"https://api.github.com/repos/pypa/pip/pulls/3137"}}},"pull_request":{"url":"https://api.github.com/repos/pypa/pip/pulls/3137","id":45971429,"html_url":"https://github.com/pypa/pip/pull/3137","diff_url":"https://github.com/pypa/pip/pull/3137.diff","patch_url":"https://github.com/pypa/pip/pull/3137.patch","issue_url":"https://api.github.com/repos/pypa/pip/issues/3137","number":3137,"state":"open","locked":false,"title":"Repeatable installs via hashing","user":{"login":"erikrose","id":295816,"avatar_url":"https://avatars.githubusercontent.com/u/295816?v=3","gravatar_id":"","url":"https://api.github.com/users/erikrose","html_url":"https://github.com/erikrose","followers_url":"https://api.github.com/users/erikrose/followers","following_url":"https://api.github.com/users/erikrose/following{/other_user}","gists_url":"https://api.github.com/users/erikrose/gists{/gist_id}","starred_url":"https://api.github.com/users/erikrose/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erikrose/subscriptions","organizations_url":"https://api.github.com/users/erikrose/orgs","repos_url":"https://api.github.com/users/erikrose/repos","events_url":"https://api.github.com/users/erikrose/events{/privacy}","received_events_url":"https://api.github.com/users/erikrose/received_events","type":"User","site_admin":false},"body":"Add checks against requirements-file-dwelling hashes for most kinds of packages. Close #1175.\r\n\r\nThis lets you add `--hash=sha256:abcde…` to a line in a requirements file to verify a package against a good local hash, guaranteeing repeatable installs without needing to run your own index mirrors, in the vein of https://pypi.python.org/pypi/peep/.\r\n\r\n* Add --require-hashes option. This is handy in deployment scripts to force application authors to hash their requirements. It is also a convenient way to get pip to show computed hashes for a virgin, unhashed requirements file. Eventually, additions to `pip freeze` should fill a superset of this use case.\r\n  * In --require-hashes mode, at least one hash is required to match for each requirement, even subrequirements.\r\n  * Option-based requirements (--hash=sha256:...) turn on --require-hashes mode implicitly.\r\n  * Internet-derived URL-based hashes are \"necessary but not sufficient\": they do not satisfy --require-hashes mode when they match, but they are still used to guard against transmission errors.\r\n  * Locally stored URL-based requirements (#md5=...) are treated just like option-based ones, except they don't turn on --require-hashes. Basically, that spelling is deprecated in favor of the option syntax.\r\n  * --require-hashes disallows --egg, which would bypass its dependency control by delegating everything to setuptools.\r\n* Complain informatively, with the most devastating errors first so you don't chase your tail all day only to run up against a brick wall at the end. This also means we don't complain that a hash is missing, only for the user to find, after fixing it, that we have no idea how to even compute a hash for that type of requirement.\r\n  * Complain about unpinned requirements when hash-checking mode is on, lest they cause the user surprise later.\r\n  * Complain about missing hashes.\r\n  * Complain about requirement types we don't know how to hash (like VCS ones and local dirs).\r\n* Have InstallRequirement keep its original Link around (original_link) so we can differentiate between URL hashes from requirements files and ones downloaded from the (untrustworthy) internet.\r\n* Remove test_download_hashes, which is obsolete. Similar coverage is provided in test_utils.TestHashes and the various hash cases in test_req.py.\r\n* Add a `pip hash` command for hashing package archives.\r\n* Add hash-checking support for `pip download` and `pip wheel`.\r\n\r\nFor a later release:\r\n\r\n* Support for --hash options on the commandline, interspersed with packages\r\n* Possible additions to `pip freeze`\r\n* See https://github.com/erikrose/peep/wiki/PipHashing for details","created_at":"2015-09-25T02:27:13Z","updated_at":"2015-10-08T21:21:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"750f2b20c424826e991f8baa1b10848afbeb631d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/pypa/pip/pulls/3137/commits","review_comments_url":"https://api.github.com/repos/pypa/pip/pulls/3137/comments","review_comment_url":"https://api.github.com/repos/pypa/pip/pulls/comments{/number}","comments_url":"https://api.github.com/repos/pypa/pip/issues/3137/comments","statuses_url":"https://api.github.com/repos/pypa/pip/statuses/7a0a97c0815c53f1fef845881475e2fe5cfd179e","head":{"label":"erikrose:hashing","ref":"hashing","sha":"7a0a97c0815c53f1fef845881475e2fe5cfd179e","user":{"login":"erikrose","id":295816,"avatar_url":"https://avatars.githubusercontent.com/u/295816?v=3","gravatar_id":"","url":"https://api.github.com/users/erikrose","html_url":"https://github.com/erikrose","followers_url":"https://api.github.com/users/erikrose/followers","following_url":"https://api.github.com/users/erikrose/following{/other_user}","gists_url":"https://api.github.com/users/erikrose/gists{/gist_id}","starred_url":"https://api.github.com/users/erikrose/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erikrose/subscriptions","organizations_url":"https://api.github.com/users/erikrose/orgs","repos_url":"https://api.github.com/users/erikrose/repos","events_url":"https://api.github.com/users/erikrose/events{/privacy}","received_events_url":"https://api.github.com/users/erikrose/received_events","type":"User","site_admin":false},"repo":{"id":41885078,"name":"pip","full_name":"erikrose/pip","owner":{"login":"erikrose","id":295816,"avatar_url":"https://avatars.githubusercontent.com/u/295816?v=3","gravatar_id":"","url":"https://api.github.com/users/erikrose","html_url":"https://github.com/erikrose","followers_url":"https://api.github.com/users/erikrose/followers","following_url":"https://api.github.com/users/erikrose/following{/other_user}","gists_url":"https://api.github.com/users/erikrose/gists{/gist_id}","starred_url":"https://api.github.com/users/erikrose/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erikrose/subscriptions","organizations_url":"https://api.github.com/users/erikrose/orgs","repos_url":"https://api.github.com/users/erikrose/repos","events_url":"https://api.github.com/users/erikrose/events{/privacy}","received_events_url":"https://api.github.com/users/erikrose/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/erikrose/pip","description":"The PyPA recommended tool for installing Python packages","fork":true,"url":"https://api.github.com/repos/erikrose/pip","forks_url":"https://api.github.com/repos/erikrose/pip/forks","keys_url":"https://api.github.com/repos/erikrose/pip/keys{/key_id}","collaborators_url":"https://api.github.com/repos/erikrose/pip/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/erikrose/pip/teams","hooks_url":"https://api.github.com/repos/erikrose/pip/hooks","issue_events_url":"https://api.github.com/repos/erikrose/pip/issues/events{/number}","events_url":"https://api.github.com/repos/erikrose/pip/events","assignees_url":"https://api.github.com/repos/erikrose/pip/assignees{/user}","branches_url":"https://api.github.com/repos/erikrose/pip/branches{/branch}","tags_url":"https://api.github.com/repos/erikrose/pip/tags","blobs_url":"https://api.github.com/repos/erikrose/pip/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/erikrose/pip/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/erikrose/pip/git/refs{/sha}","trees_url":"https://api.github.com/repos/erikrose/pip/git/trees{/sha}","statuses_url":"https://api.github.com/repos/erikrose/pip/statuses/{sha}","languages_url":"https://api.github.com/repos/erikrose/pip/languages","stargazers_url":"https://api.github.com/repos/erikrose/pip/stargazers","contributors_url":"https://api.github.com/repos/erikrose/pip/contributors","subscribers_url":"https://api.github.com/repos/erikrose/pip/subscribers","subscription_url":"https://api.github.com/repos/erikrose/pip/subscription","commits_url":"https://api.github.com/repos/erikrose/pip/commits{/sha}","git_commits_url":"https://api.github.com/repos/erikrose/pip/git/commits{/sha}","comments_url":"https://api.github.com/repos/erikrose/pip/comments{/number}","issue_comment_url":"https://api.github.com/repos/erikrose/pip/issues/comments{/number}","contents_url":"https://api.github.com/repos/erikrose/pip/contents/{+path}","compare_url":"https://api.github.com/repos/erikrose/pip/compare/{base}...{head}","merges_url":"https://api.github.com/repos/erikrose/pip/merges","archive_url":"https://api.github.com/repos/erikrose/pip/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/erikrose/pip/downloads","issues_url":"https://api.github.com/repos/erikrose/pip/issues{/number}","pulls_url":"https://api.github.com/repos/erikrose/pip/pulls{/number}","milestones_url":"https://api.github.com/repos/erikrose/pip/milestones{/number}","notifications_url":"https://api.github.com/repos/erikrose/pip/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/erikrose/pip/labels{/name}","releases_url":"https://api.github.com/repos/erikrose/pip/releases{/id}","created_at":"2015-09-03T21:37:57Z","updated_at":"2015-09-03T21:37:59Z","pushed_at":"2015-10-08T17:38:01Z","git_url":"git://github.com/erikrose/pip.git","ssh_url":"git@github.com:erikrose/pip.git","clone_url":"https://github.com/erikrose/pip.git","svn_url":"https://github.com/erikrose/pip","homepage":"https://pip.pypa.io/","size":38395,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"develop"}},"base":{"label":"pypa:develop","ref":"develop","sha":"6aab626e7d88c85edb98fa36575aa8272ef3283d","user":{"login":"pypa","id":647025,"avatar_url":"https://avatars.githubusercontent.com/u/647025?v=3","gravatar_id":"","url":"https://api.github.com/users/pypa","html_url":"https://github.com/pypa","followers_url":"https://api.github.com/users/pypa/followers","following_url":"https://api.github.com/users/pypa/following{/other_user}","gists_url":"https://api.github.com/users/pypa/gists{/gist_id}","starred_url":"https://api.github.com/users/pypa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pypa/subscriptions","organizations_url":"https://api.github.com/users/pypa/orgs","repos_url":"https://api.github.com/users/pypa/repos","events_url":"https://api.github.com/users/pypa/events{/privacy}","received_events_url":"https://api.github.com/users/pypa/received_events","type":"Organization","site_admin":false},"repo":{"id":1446467,"name":"pip","full_name":"pypa/pip","owner":{"login":"pypa","id":647025,"avatar_url":"https://avatars.githubusercontent.com/u/647025?v=3","gravatar_id":"","url":"https://api.github.com/users/pypa","html_url":"https://github.com/pypa","followers_url":"https://api.github.com/users/pypa/followers","following_url":"https://api.github.com/users/pypa/following{/other_user}","gists_url":"https://api.github.com/users/pypa/gists{/gist_id}","starred_url":"https://api.github.com/users/pypa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pypa/subscriptions","organizations_url":"https://api.github.com/users/pypa/orgs","repos_url":"https://api.github.com/users/pypa/repos","events_url":"https://api.github.com/users/pypa/events{/privacy}","received_events_url":"https://api.github.com/users/pypa/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/pypa/pip","description":"The PyPA recommended tool for installing Python packages","fork":false,"url":"https://api.github.com/repos/pypa/pip","forks_url":"https://api.github.com/repos/pypa/pip/forks","keys_url":"https://api.github.com/repos/pypa/pip/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pypa/pip/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pypa/pip/teams","hooks_url":"https://api.github.com/repos/pypa/pip/hooks","issue_events_url":"https://api.github.com/repos/pypa/pip/issues/events{/number}","events_url":"https://api.github.com/repos/pypa/pip/events","assignees_url":"https://api.github.com/repos/pypa/pip/assignees{/user}","branches_url":"https://api.github.com/repos/pypa/pip/branches{/branch}","tags_url":"https://api.github.com/repos/pypa/pip/tags","blobs_url":"https://api.github.com/repos/pypa/pip/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pypa/pip/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pypa/pip/git/refs{/sha}","trees_url":"https://api.github.com/repos/pypa/pip/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pypa/pip/statuses/{sha}","languages_url":"https://api.github.com/repos/pypa/pip/languages","stargazers_url":"https://api.github.com/repos/pypa/pip/stargazers","contributors_url":"https://api.github.com/repos/pypa/pip/contributors","subscribers_url":"https://api.github.com/repos/pypa/pip/subscribers","subscription_url":"https://api.github.com/repos/pypa/pip/subscription","commits_url":"https://api.github.com/repos/pypa/pip/commits{/sha}","git_commits_url":"https://api.github.com/repos/pypa/pip/git/commits{/sha}","comments_url":"https://api.github.com/repos/pypa/pip/comments{/number}","issue_comment_url":"https://api.github.com/repos/pypa/pip/issues/comments{/number}","contents_url":"https://api.github.com/repos/pypa/pip/contents/{+path}","compare_url":"https://api.github.com/repos/pypa/pip/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pypa/pip/merges","archive_url":"https://api.github.com/repos/pypa/pip/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pypa/pip/downloads","issues_url":"https://api.github.com/repos/pypa/pip/issues{/number}","pulls_url":"https://api.github.com/repos/pypa/pip/pulls{/number}","milestones_url":"https://api.github.com/repos/pypa/pip/milestones{/number}","notifications_url":"https://api.github.com/repos/pypa/pip/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pypa/pip/labels{/name}","releases_url":"https://api.github.com/repos/pypa/pip/releases{/id}","created_at":"2011-03-06T14:30:46Z","updated_at":"2015-10-08T11:26:07Z","pushed_at":"2015-10-08T20:26:19Z","git_url":"git://github.com/pypa/pip.git","ssh_url":"git@github.com:pypa/pip.git","clone_url":"https://github.com/pypa/pip.git","svn_url":"https://github.com/pypa/pip","homepage":"https://pip.pypa.io/","size":56137,"stargazers_count":2374,"watchers_count":2374,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":930,"mirror_url":null,"open_issues_count":613,"forks":930,"open_issues":613,"watchers":2374,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/pypa/pip/pulls/3137"},"html":{"href":"https://github.com/pypa/pip/pull/3137"},"issue":{"href":"https://api.github.com/repos/pypa/pip/issues/3137"},"comments":{"href":"https://api.github.com/repos/pypa/pip/issues/3137/comments"},"review_comments":{"href":"https://api.github.com/repos/pypa/pip/pulls/3137/comments"},"review_comment":{"href":"https://api.github.com/repos/pypa/pip/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/pypa/pip/pulls/3137/commits"},"statuses":{"href":"https://api.github.com/repos/pypa/pip/statuses/7a0a97c0815c53f1fef845881475e2fe5cfd179e"}}}}