From 76ca3e3ba19b51899c68bccf9b8dcd376ec15720 Mon Sep 17 00:00:00 2001 From: jxltom Date: Sat, 1 Dec 2018 20:58:30 +0800 Subject: [PATCH 01/40] Set PIPENV_ACTIVATE after virtualenv_location is being used --- pipenv/core.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pipenv/core.py b/pipenv/core.py index 121adb57..be83af7a 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -2159,11 +2159,6 @@ def do_shell(three=None, python=False, fancy=False, shell_args=None, pypi_mirror three=three, python=python, validate=False, pypi_mirror=pypi_mirror, ) - # Set an environment variable, so we know we're in the environment. - os.environ["PIPENV_ACTIVE"] = vistir.misc.fs_str("1") - - os.environ.pop("PIP_SHIMS_BASE_MODULE", None) - # Support shell compatibility mode. if PIPENV_SHELL_FANCY: fancy = True @@ -2179,6 +2174,12 @@ def do_shell(three=None, python=False, fancy=False, shell_args=None, pypi_mirror shell_args, ) + # Set an environment variable, so we know we're in the environment. + # Only set PIPENV_ACTIVE after finishing reading virtualenv_location + # otherwise its value will be changed + os.environ["PIPENV_ACTIVE"] = vistir.misc.fs_str("1") + os.environ.pop("PIP_SHIMS_BASE_MODULE", None) + if fancy: shell.fork(*fork_args) return From 5e29e7635ee583456de1d453bee49fca9becd0e3 Mon Sep 17 00:00:00 2001 From: jxltom Date: Sat, 1 Dec 2018 21:01:25 +0800 Subject: [PATCH 02/40] Add bugfix news for 3339 --- news/3339.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/3339.bugfix diff --git a/news/3339.bugfix b/news/3339.bugfix new file mode 100644 index 00000000..8e67e36f --- /dev/null +++ b/news/3339.bugfix @@ -0,0 +1 @@ +Fix a bug where custom virtualenv can not be activated with pipenv shell From d165d656365e3edd63833e7b8d3c2ea2d3aafe6f Mon Sep 17 00:00:00 2001 From: jxltom Date: Sat, 1 Dec 2018 22:23:27 +0800 Subject: [PATCH 03/40] Add blank line since these two environment variable has different purpose --- pipenv/core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pipenv/core.py b/pipenv/core.py index be83af7a..cb7ce9e2 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -2178,6 +2178,7 @@ def do_shell(three=None, python=False, fancy=False, shell_args=None, pypi_mirror # Only set PIPENV_ACTIVE after finishing reading virtualenv_location # otherwise its value will be changed os.environ["PIPENV_ACTIVE"] = vistir.misc.fs_str("1") + os.environ.pop("PIP_SHIMS_BASE_MODULE", None) if fancy: From dbb3603a05a35277a44f1317ba717f1780bf05e9 Mon Sep 17 00:00:00 2001 From: jxltom Date: Mon, 3 Dec 2018 09:27:23 +0800 Subject: [PATCH 04/40] Fix a bug where activated virtualenv is not being used in pipenv run --- pipenv/core.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pipenv/core.py b/pipenv/core.py index cb7ce9e2..818d0beb 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -2315,14 +2315,19 @@ def do_run(command, args, three=None, python=False, pypi_mirror=None): three=three, python=python, validate=False, pypi_mirror=pypi_mirror, ) - # Set an environment variable, so we know we're in the environment. - os.environ["PIPENV_ACTIVE"] = vistir.misc.fs_str("1") - - os.environ.pop("PIP_SHIMS_BASE_MODULE", None) load_dot_env() # Activate virtualenv under the current interpreter's environment inline_activate_virtual_environment() + + # Set an environment variable, so we know we're in the environment. + # Only set PIPENV_ACTIVE after finishing reading virtualenv_location + # such as in inline_activate_virtual_environment + # otherwise its value will be changed + os.environ["PIPENV_ACTIVE"] = vistir.misc.fs_str("1") + + os.environ.pop("PIP_SHIMS_BASE_MODULE", None) + try: script = project.build_script(command, args) except ScriptEmptyError: From d47604892a915ddf0b2a130dadaf01376442ae6a Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Mon, 3 Dec 2018 16:25:52 -0500 Subject: [PATCH 05/40] Enable output of script line for 'run' in verbose mode --- pipenv/core.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pipenv/core.py b/pipenv/core.py index f26a2edc..686c7e95 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -2303,6 +2303,8 @@ def do_run(command, args, three=None, python=False, pypi_mirror=None): inline_activate_virtual_environment() try: script = project.build_script(command, args) + cmd_string = ' '.join([script.command] + script.args) + logging.getLogger("pip").info("Run: '{0}'".format(cmd_string)) except ScriptEmptyError: click.echo("Can't run script {0!r}-it's empty?", err=True) if os.name == "nt": From aee66c607481a36e52dd414873d0e40e9f12b5c3 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Mon, 3 Dec 2018 20:15:03 -0500 Subject: [PATCH 06/40] fixup! use click.echo > stderr --- pipenv/core.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pipenv/core.py b/pipenv/core.py index 686c7e95..48253efd 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -2304,7 +2304,8 @@ def do_run(command, args, three=None, python=False, pypi_mirror=None): try: script = project.build_script(command, args) cmd_string = ' '.join([script.command] + script.args) - logging.getLogger("pip").info("Run: '{0}'".format(cmd_string)) + if environments.is_verbose(): + click.echo(crayons.normal("Run: {0}".format(cmd_string)), err=True) except ScriptEmptyError: click.echo("Can't run script {0!r}-it's empty?", err=True) if os.name == "nt": From d191deb744b39eebc88c82c576295e86c061d53d Mon Sep 17 00:00:00 2001 From: Omer Katz Date: Tue, 4 Dec 2018 17:50:41 +0200 Subject: [PATCH 07/40] Mention Linuxbrew in installation docs. --- docs/index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/index.rst b/docs/index.rst index b6822409..11c9d34d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -52,6 +52,8 @@ Install Pipenv Today! If you're on MacOS, you can install Pipenv easily with Homebrew:: $ brew install pipenv + +You can also use Linuxbrew on Linux using the same command. Or, if you're using Fedora 28:: From 453ed705a8c7bbce38aab1a0950f613019943da8 Mon Sep 17 00:00:00 2001 From: Dan Ryan Date: Tue, 4 Dec 2018 12:03:56 -0500 Subject: [PATCH 08/40] fixup! use `$` Co-Authored-By: refack --- pipenv/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/core.py b/pipenv/core.py index 48253efd..084042e0 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -2305,7 +2305,7 @@ def do_run(command, args, three=None, python=False, pypi_mirror=None): script = project.build_script(command, args) cmd_string = ' '.join([script.command] + script.args) if environments.is_verbose(): - click.echo(crayons.normal("Run: {0}".format(cmd_string)), err=True) + click.echo(crayons.normal("$ {0}".format(cmd_string)), err=True) except ScriptEmptyError: click.echo("Can't run script {0!r}-it's empty?", err=True) if os.name == "nt": From 5c8ecfc86f83cb3d8aeff0fe79a31850bc655232 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Tue, 4 Dec 2018 12:10:37 -0500 Subject: [PATCH 09/40] fixup! add `news` --- news/3348.feature.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/3348.feature.rst diff --git a/news/3348.feature.rst b/news/3348.feature.rst new file mode 100644 index 00000000..50547a3d --- /dev/null +++ b/news/3348.feature.rst @@ -0,0 +1 @@ +Added support for ``--verbose`` output to ``pipenv run``. \ No newline at end of file From 64ae1ed8a4234e5d5b94c10e18b109a58572f3c7 Mon Sep 17 00:00:00 2001 From: nonylene Date: Wed, 5 Dec 2018 06:19:32 +0900 Subject: [PATCH 10/40] Fix `--site-packages` flag is not recognized `site_packages` argument in `cli` function always set to false because `--site-packages` flag was defined in global state (https://github.com/pypa/pipenv/blob/97657b2797b8a8f045776470d74add6048a95b67/pipenv/cli/options.py#L62). Fixes #3351 --- pipenv/cli/command.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pipenv/cli/command.py b/pipenv/cli/command.py index ae7111f1..ec1bef61 100644 --- a/pipenv/cli/command.py +++ b/pipenv/cli/command.py @@ -70,7 +70,6 @@ def cli( python=False, help=False, py=False, - site_packages=False, envs=False, man=False, completion=False, @@ -198,7 +197,7 @@ def cli( ) ctx.abort() # --two / --three was passed… - if (state.python or state.three is not None) or site_packages: + if (state.python or state.three is not None) or state.site_packages: ensure_project( three=state.three, python=state.python, From eff802a62da7292c39e62449f2cbcad46bb48277 Mon Sep 17 00:00:00 2001 From: nonylene Date: Wed, 5 Dec 2018 06:28:36 +0900 Subject: [PATCH 11/40] Create 3352.bugfix.rst --- news/3352.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/3352.bugfix.rst diff --git a/news/3352.bugfix.rst b/news/3352.bugfix.rst new file mode 100644 index 00000000..d2d9c675 --- /dev/null +++ b/news/3352.bugfix.rst @@ -0,0 +1 @@ +Fix a bug that ``--site-packages`` flag is not recognized. From e229f7e03812910ba78373f0ca4cb193e57915b3 Mon Sep 17 00:00:00 2001 From: nonylene Date: Wed, 5 Dec 2018 06:41:06 +0900 Subject: [PATCH 12/40] Rename 3352.bugfix.rst to 3351.bugfix.rst --- news/{3352.bugfix.rst => 3351.bugfix.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename news/{3352.bugfix.rst => 3351.bugfix.rst} (100%) diff --git a/news/3352.bugfix.rst b/news/3351.bugfix.rst similarity index 100% rename from news/3352.bugfix.rst rename to news/3351.bugfix.rst From 7f5676e2b8f360de0dcb181736c482a1d73e76a8 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Thu, 6 Dec 2018 14:14:29 +0800 Subject: [PATCH 13/40] add news --- news/3362.trivial.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/3362.trivial.rst diff --git a/news/3362.trivial.rst b/news/3362.trivial.rst new file mode 100644 index 00000000..2216b071 --- /dev/null +++ b/news/3362.trivial.rst @@ -0,0 +1 @@ +The inline tables won't be rewritten now. From 27f83a8631220e6c799e80597484a0439c0271e1 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Thu, 6 Dec 2018 15:54:18 +0800 Subject: [PATCH 14/40] preserve inline spaces in toml --- pipenv/utils.py | 34 +++++++++++++++++++++---------- tests/integration/test_project.py | 7 ++++++- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/pipenv/utils.py b/pipenv/utils.py index 9f03465c..b0920764 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -83,19 +83,31 @@ def cleanup_toml(tml): def convert_toml_outline_tables(parsed): """Converts all outline tables to inline tables.""" - if isinstance(parsed, tomlkit.container.Container): - empty_inline_table = tomlkit.inline_table - else: - empty_inline_table = toml.TomlDecoder().get_empty_inline_table + def convert_tomlkit_table(section): + for key, value in section._body: + if not key: + continue + if hasattr(value, "keys") and not isinstance(value, tomlkit.items.InlineTable): + table = tomlkit.inline_table() + table.update(value.value) + section[key.key] = table + + def convert_toml_table(section): + for package, value in section.items(): + if hasattr(value, "keys") and not isinstance(toml.decoder.InlineTableDict): + table = toml.TomlDecoder().get_empty_inline_table() + table.update(value) + section[package] = table + for section in ("packages", "dev-packages"): table_data = parsed.get(section, {}) - for package, value in table_data.items(): - if hasattr(value, "keys") and not isinstance( - value, (tomlkit.items.InlineTable, toml.decoder.InlineTableDict) - ): - table = empty_inline_table() - table.update(value) - table_data[package] = table + if not table_data: + continue + if isinstance(parsed, tomlkit.container.Container): + convert_tomlkit_table(table_data) + else: + convert_toml_table(table_data) + return parsed diff --git a/tests/integration/test_project.py b/tests/integration/test_project.py index f9a2ba12..bec98d59 100644 --- a/tests/integration/test_project.py +++ b/tests/integration/test_project.py @@ -154,16 +154,21 @@ def test_rewrite_outline_table(PipenvInstance, pypi): with PipenvInstance(pypi=pypi, chdir=True) as p: with open(p.pipfile_path, 'w') as f: contents = """ +[packages] +six = {version = "*", editable = true} + [packages.requests] version = "*" """.strip() f.write(contents) - c = p.pipenv('install click') + c = p.pipenv("install -e click") assert c.return_code == 0 with open(p.pipfile_path) as f: contents = f.read() assert "[packages.requests]" not in contents + assert 'six = {version = "*", editable = true}' in contents assert 'requests = {version = "*"}' in contents + assert 'click = {' in contents @pytest.mark.install From 560d4ff5aa86eeedfb8bf48c4c59259745d7bf58 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Thu, 6 Dec 2018 16:00:33 +0800 Subject: [PATCH 15/40] fix a typo --- pipenv/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/utils.py b/pipenv/utils.py index b0920764..67f3e9a6 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -94,7 +94,7 @@ def convert_toml_outline_tables(parsed): def convert_toml_table(section): for package, value in section.items(): - if hasattr(value, "keys") and not isinstance(toml.decoder.InlineTableDict): + if hasattr(value, "keys") and not isinstance(value, toml.decoder.InlineTableDict): table = toml.TomlDecoder().get_empty_inline_table() table.update(value) section[package] = table From 8efaea620e3f7dfbcaa424263b713c4ccf929bb1 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Thu, 6 Dec 2018 16:02:37 +0800 Subject: [PATCH 16/40] Raise condition evaluation --- pipenv/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pipenv/utils.py b/pipenv/utils.py index 67f3e9a6..08847e59 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -99,11 +99,12 @@ def convert_toml_outline_tables(parsed): table.update(value) section[package] = table + is_tomlkit_parsed = isinstance(parsed, tomlkit.container.Container) for section in ("packages", "dev-packages"): table_data = parsed.get(section, {}) if not table_data: continue - if isinstance(parsed, tomlkit.container.Container): + if is_tomlkit_parsed: convert_tomlkit_table(table_data) else: convert_toml_table(table_data) From aadb24b9df3f39b6b56263cf4c45e205cc3d2e6f Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Fri, 7 Dec 2018 09:00:04 +0800 Subject: [PATCH 17/40] Move to install test suite --- tests/integration/test_install_basic.py | 22 ++++++++++++++++++++++ tests/integration/test_project.py | 24 +----------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/tests/integration/test_install_basic.py b/tests/integration/test_install_basic.py index 317351a0..f858f8ac 100644 --- a/tests/integration/test_install_basic.py +++ b/tests/integration/test_install_basic.py @@ -446,3 +446,25 @@ def test_install_package_with_dots(PipenvInstance, pypi): c = p.pipenv("install backports.html") assert c.ok assert "backports.html" in p.pipfile["packages"] + + +@pytest.mark.install +def test_rewrite_outline_table(PipenvInstance, pypi): + with PipenvInstance(pypi=pypi, chdir=True) as p: + with open(p.pipfile_path, 'w') as f: + contents = """ +[packages] +six = {version = "*", editable = true} + +[packages.requests] +version = "*" + """.strip() + f.write(contents) + c = p.pipenv("install -e click") + assert c.return_code == 0 + with open(p.pipfile_path) as f: + contents = f.read() + assert "[packages.requests]" not in contents + assert 'six = {version = "*", editable = true}' in contents + assert 'requests = {version = "*"}' in contents + assert 'click = {' in contents diff --git a/tests/integration/test_project.py b/tests/integration/test_project.py index bec98d59..6a4a858a 100644 --- a/tests/integration/test_project.py +++ b/tests/integration/test_project.py @@ -148,29 +148,6 @@ six = {{version = "*", index = "pypi"}} assert c.return_code == 0 -@pytest.mark.install -@pytest.mark.project -def test_rewrite_outline_table(PipenvInstance, pypi): - with PipenvInstance(pypi=pypi, chdir=True) as p: - with open(p.pipfile_path, 'w') as f: - contents = """ -[packages] -six = {version = "*", editable = true} - -[packages.requests] -version = "*" - """.strip() - f.write(contents) - c = p.pipenv("install -e click") - assert c.return_code == 0 - with open(p.pipfile_path) as f: - contents = f.read() - assert "[packages.requests]" not in contents - assert 'six = {version = "*", editable = true}' in contents - assert 'requests = {version = "*"}' in contents - assert 'click = {' in contents - - @pytest.mark.install @pytest.mark.project def test_include_editable_packages(PipenvInstance, pypi, testsroot, pathlib_tmpdir): @@ -190,6 +167,7 @@ def test_include_editable_packages(PipenvInstance, pypi, testsroot, pathlib_tmpd @pytest.mark.project +@pytest.mark.virtualenv def test_run_in_virtualenv(PipenvInstance, pypi, virtualenv): with PipenvInstance(chdir=True, pypi=pypi) as p: os.environ.pop("PIPENV_IGNORE_VIRTUALENVS", None) From f81e86181ce828768a5f03c25c695394ad90ad29 Mon Sep 17 00:00:00 2001 From: nonylene Date: Sun, 9 Dec 2018 05:17:25 +0900 Subject: [PATCH 18/40] Add test for `pipenv --python --site-packages` --- tests/integration/test_cli.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/integration/test_cli.py b/tests/integration/test_cli.py index 946b98f7..a38883e0 100644 --- a/tests/integration/test_cli.py +++ b/tests/integration/test_cli.py @@ -41,6 +41,20 @@ def test_pipenv_py(PipenvInstance): assert os.path.basename(python).startswith('python') +@pytest.mark.cli +def test_pipenv_site_packages(PipenvInstance): + with PipenvInstance() as p: + c = p.pipenv('--python python --site-packages') + assert c.return_code == 0 + assert 'Making site-packages available' in c.err + + # no-global-site-packages.txt under stdlib dir should not exist. + c = p.pipenv('run python -c "import sysconfig; print(sysconfig.get_path(\'stdlib\'))"') + assert c.return_code == 0 + stdlib_path = c.out.strip() + assert not os.path.isfile(os.path.join(stdlib_path, 'no-global-site-packages.txt')) + + @pytest.mark.cli def test_pipenv_support(PipenvInstance): with PipenvInstance() as p: From 497fdf8d6b04f2a671f729652fb99f9d1e4a0abd Mon Sep 17 00:00:00 2001 From: Omer Katz Date: Sun, 9 Dec 2018 18:19:14 +0200 Subject: [PATCH 19/40] Updated install documentation. --- docs/install.rst | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/docs/install.rst b/docs/install.rst index f529e249..4dcdf511 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -52,16 +52,16 @@ check this by running:: $ pip --version pip 9.0.1 -If you installed Python from source, with an installer from `python.org`_, or -via `Homebrew`_ you should already have pip. If you're on Linux and installed +If you installed Python from source, with an installer from `python.org`_, via `Homebrew`_ or via `Linuxbrew`_ you should already have pip. If you're on Linux and installed using your OS package manager, you may have to `install pip `_ separately. -If you plan to install Pipenv using Homebrew you can skip this step. The -Homebrew installer takes care of pip for you. +If you plan to install Pipenv using Homebrew or Linuxbrew you can skip this step. The +Homebrew/Linuxbrew installer takes care of pip for you. .. _getting started tutorial: https://opentechschool.github.io/python-beginners/en/getting_started.html#what-is-python-exactly .. _python.org: https://python.org .. _Homebrew: https://brew.sh +.. _Linuxbrew: https://linuxbrew.sh/ .. _Installing Python: http://docs.python-guide.org/en/latest/starting/installation/ @@ -97,6 +97,22 @@ To upgrade pipenv at any time:: $ brew upgrade pipenv +☤ Linuxbrew Installation of Pipenv +--------------------------------- + +Linuxbrew is a Linux port of the popular open-source package management system for macOS. + +Installing pipenv via Linuxbrew will keep pipenv and all of its dependencies in +an isolated virtual environment so it doesn't interfere with the rest of your +Python installation. + +Once you have installed `Linuxbrew`_ simply run:: + + $ brew install pipenv + +To upgrade pipenv at any time:: + + $ brew upgrade pipenv ☤ Pragmatic Installation of Pipenv ---------------------------------- From 2fdc4fa6cb669c60ec5b5c5b8ae0c34f04e0863d Mon Sep 17 00:00:00 2001 From: GreatBahram Date: Tue, 11 Dec 2018 09:03:08 +0330 Subject: [PATCH 20/40] simple bug fix in setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4a6b9389..6583cff1 100644 --- a/setup.py +++ b/setup.py @@ -68,7 +68,7 @@ class DebCommand(Command): class UploadCommand(Command): - """Support setup.py publish.""" + """Support setup.py upload.""" description = "Build and publish the package." user_options = [] From f2c60f49083d80a76114d9f78ff2fd112c2a1317 Mon Sep 17 00:00:00 2001 From: Alexander Allakhverdiyev Date: Fri, 14 Dec 2018 12:07:26 -0800 Subject: [PATCH 21/40] Fix unhashable type error in --selective-upgrade --- pipenv/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/core.py b/pipenv/core.py index 084042e0..c10cd70b 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -1829,7 +1829,7 @@ def do_install( if not is_star(section[package__name]) and is_star(package__val): # Support for VCS dependencies. package_args[i] = convert_deps_to_pip( - {packages: section[package__name]}, project=project, r=False + {package.name: section[package__name]}, project=project, r=False )[0] except KeyError: pass From e400d81a42d53fc6828f745ba53f073a038dbd51 Mon Sep 17 00:00:00 2001 From: Alexander Allakhverdiyev Date: Fri, 14 Dec 2018 12:17:43 -0800 Subject: [PATCH 22/40] use a better variable --- pipenv/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/core.py b/pipenv/core.py index c10cd70b..4fb7939e 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -1829,7 +1829,7 @@ def do_install( if not is_star(section[package__name]) and is_star(package__val): # Support for VCS dependencies. package_args[i] = convert_deps_to_pip( - {package.name: section[package__name]}, project=project, r=False + {package__name: section[package__name]}, project=project, r=False )[0] except KeyError: pass From f4f5acbd38c112f9566934bda6b550fda03dc965 Mon Sep 17 00:00:00 2001 From: Alexander Allakhverdiyev Date: Fri, 14 Dec 2018 19:37:52 -0800 Subject: [PATCH 23/40] added news file --- news/3384.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/3384.bugfix.rst diff --git a/news/3384.bugfix.rst b/news/3384.bugfix.rst new file mode 100644 index 00000000..2deed024 --- /dev/null +++ b/news/3384.bugfix.rst @@ -0,0 +1 @@ +Fix unhashable type error during install --selective-upgrade From c433262847703db95bb46d3458ae05ad66e597f0 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Fri, 14 Dec 2018 20:22:06 -0800 Subject: [PATCH 24/40] Update news/3384.bugfix.rst Co-Authored-By: alexallah --- news/3384.bugfix.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/news/3384.bugfix.rst b/news/3384.bugfix.rst index 2deed024..f85cd168 100644 --- a/news/3384.bugfix.rst +++ b/news/3384.bugfix.rst @@ -1 +1 @@ -Fix unhashable type error during install --selective-upgrade +Fix unhashable type error during ``$ pipenv install --selective-upgrade`` From 844f7f80e248076c5cb023a6846b8857f66c3bfb Mon Sep 17 00:00:00 2001 From: jxltom Date: Sun, 16 Dec 2018 10:45:29 +0800 Subject: [PATCH 25/40] Merge homebrew and linuxbrew installation into same section --- docs/index.rst | 4 +--- docs/install.rst | 22 +++------------------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 11c9d34d..a832ee8e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -49,11 +49,9 @@ You can quickly play with Pipenv right in your browser: Install Pipenv Today! --------------------- -If you're on MacOS, you can install Pipenv easily with Homebrew:: +If you're on MacOS, you can install Pipenv easily with Homebrew. You can also use Linuxbrew on Linux using the same command:: $ brew install pipenv - -You can also use Linuxbrew on Linux using the same command. Or, if you're using Fedora 28:: diff --git a/docs/install.rst b/docs/install.rst index 4dcdf511..4039cdb5 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -83,13 +83,13 @@ cases. ☤ Homebrew Installation of Pipenv --------------------------------- -Homebrew is a popular open-source package management system for macOS. +`Homebrew`_ is a popular open-source package management system for macOS. For Linux users, `Linuxbrew`_ is a Linux port of that. -Installing pipenv via Homebrew will keep pipenv and all of its dependencies in +Installing pipenv via Homebrew or Linuxbrew will keep pipenv and all of its dependencies in an isolated virtual environment so it doesn't interfere with the rest of your Python installation. -Once you have installed `Homebrew`_ simply run:: +Once you have installed Homebrew or Linuxbrew simply run:: $ brew install pipenv @@ -97,22 +97,6 @@ To upgrade pipenv at any time:: $ brew upgrade pipenv -☤ Linuxbrew Installation of Pipenv ---------------------------------- - -Linuxbrew is a Linux port of the popular open-source package management system for macOS. - -Installing pipenv via Linuxbrew will keep pipenv and all of its dependencies in -an isolated virtual environment so it doesn't interfere with the rest of your -Python installation. - -Once you have installed `Linuxbrew`_ simply run:: - - $ brew install pipenv - -To upgrade pipenv at any time:: - - $ brew upgrade pipenv ☤ Pragmatic Installation of Pipenv ---------------------------------- From 16db36e60fd759d35cb99c779354124d13eea20e Mon Sep 17 00:00:00 2001 From: jxltom Date: Sun, 16 Dec 2018 19:46:54 +0800 Subject: [PATCH 26/40] Test for pipenv behavior in activated virtualenv --- tests/integration/test_project.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/integration/test_project.py b/tests/integration/test_project.py index 6a4a858a..42754521 100644 --- a/tests/integration/test_project.py +++ b/tests/integration/test_project.py @@ -170,7 +170,15 @@ def test_include_editable_packages(PipenvInstance, pypi, testsroot, pathlib_tmpd @pytest.mark.virtualenv def test_run_in_virtualenv(PipenvInstance, pypi, virtualenv): with PipenvInstance(chdir=True, pypi=pypi) as p: + os.environ['PIPENV_IGNORE_VIRTUALENVS'] = '1' + c = p.pipenv('run which pip') + assert c.return_code == 0 + assert 'virtualenv' not in c.out + os.environ.pop("PIPENV_IGNORE_VIRTUALENVS", None) + c = p.pipenv('run which pip') + assert c.return_code == 0 + assert 'virtualenv' in c.out project = Project() assert project.virtualenv_location == str(virtualenv) c = p.pipenv("run pip install click") From c794e7e566290fc1d3c14de20069ca2a6354cb2f Mon Sep 17 00:00:00 2001 From: Rohan Talip Date: Mon, 17 Dec 2018 15:22:36 -0800 Subject: [PATCH 27/40] Replaced double hyphens with a single hyphen --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 740f11d5..c3a46889 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,11 @@ Pipenv: Python Development Workflow for Humans **Pipenv** is a tool that aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world. -*Windows is a first--class citizen, in our world.* +*Windows is a first-class citizen, in our world.* It automatically creates and manages a virtualenv for your projects, as well as adds/removes packages from your `Pipfile` as you -install/uninstall packages. It also generates the ever--important +install/uninstall packages. It also generates the ever-important `Pipfile.lock`, which is used to produce deterministic builds. ![image](http://media.kennethreitz.com.s3.amazonaws.com/pipenv.gif) From 976c04cb2a3e7603245c4881cf6dd67021d3a8a1 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Sat, 29 Dec 2018 21:06:21 -0500 Subject: [PATCH 28/40] Remove Python 2.6 dependencies from setup.py Support for Python 2.6 was removed in (or before) 47604c644bf18bbbb39800833fcf0dd96526f1eb. Therefore, no need to include these dependencies. --- setup.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/setup.py b/setup.py index 6583cff1..069a5252 100644 --- a/setup.py +++ b/setup.py @@ -27,8 +27,6 @@ required = [ "setuptools>=36.2.1", "virtualenv-clone>=0.2.5", "virtualenv", - 'requests[security];python_version<"2.7"', - 'ordereddict;python_version<"2.7"', 'enum34; python_version<"3"', 'typing; python_version<"3.5"' ] From 37c79915dfc6a86627133a47ef2491dca32edf39 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Fri, 4 Jan 2019 21:44:11 +0800 Subject: [PATCH 29/40] Remove typing dep --- setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 6583cff1..dd73dafd 100644 --- a/setup.py +++ b/setup.py @@ -29,8 +29,7 @@ required = [ "virtualenv", 'requests[security];python_version<"2.7"', 'ordereddict;python_version<"2.7"', - 'enum34; python_version<"3"', - 'typing; python_version<"3.5"' + 'enum34; python_version<"3"' ] From ba9f5057b8505c2d7e5d842bfad0117cb0f04613 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Wed, 9 Jan 2019 10:07:26 +0800 Subject: [PATCH 30/40] Populate source when getting lockfile --- news/3427.bugfix.rst | 1 + pipenv/project.py | 2 +- tests/integration/test_lock.py | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 news/3427.bugfix.rst diff --git a/news/3427.bugfix.rst b/news/3427.bugfix.rst new file mode 100644 index 00000000..42f659f0 --- /dev/null +++ b/news/3427.bugfix.rst @@ -0,0 +1 @@ +Fix a bug that ``ValidationError`` is thrown when some fields are missing in source section. diff --git a/pipenv/project.py b/pipenv/project.py index e8550a04..edbcff87 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -780,7 +780,7 @@ class Project(object): return { "hash": {"sha256": self.calculate_pipfile_hash()}, "pipfile-spec": PIPFILE_SPEC_CURRENT, - "sources": sources, + "sources": [self.populate_source(s) for s in sources], "requires": self.parsed_pipfile.get("requires", {}) } diff --git a/tests/integration/test_lock.py b/tests/integration/test_lock.py index ab5178a0..75095ac0 100644 --- a/tests/integration/test_lock.py +++ b/tests/integration/test_lock.py @@ -491,6 +491,7 @@ def test_lockfile_with_empty_dict(PipenvInstance): @pytest.mark.lock +@pytest.mark.skip_lock @pytest.mark.install def test_lock_with_incomplete_source(PipenvInstance, pypi): with PipenvInstance(pypi=pypi, chdir=True) as p: @@ -502,6 +503,8 @@ url = "https://test.pypi.org/simple" [packages] requests = "*" """) + c = p.pipenv('install --skip-lock') + assert c.return_code == 0 c = p.pipenv('install') assert c.return_code == 0 assert p.lockfile['_meta']['sources'] From 32981ac83b4f9167fca5438cd2d5bf63873de27a Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Thu, 10 Jan 2019 13:10:32 -0500 Subject: [PATCH 31/40] Create PEEP-003.md --- peeps/PEEP-003.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 peeps/PEEP-003.md diff --git a/peeps/PEEP-003.md b/peeps/PEEP-003.md new file mode 100644 index 00000000..d0493eaa --- /dev/null +++ b/peeps/PEEP-003.md @@ -0,0 +1,9 @@ +# PEEP-003: Revocation of Power of BDFL + +**ACCEPTED** + +Pipenv will be governed by a board of maintainers (trusted collaborators to the project on GitHub), not a BDFL. + +The BDFL retains his title, however, revokes himself of his powers. + +PEEP approval will be determined by available members of the board of maintainers, in private or public channels. From 18fe121d506c45e61a582b8c95280b632c811ae6 Mon Sep 17 00:00:00 2001 From: Kenyon Ralph Date: Sun, 13 Jan 2019 20:11:46 -0800 Subject: [PATCH 32/40] core: nonexistent virtualenv warning msg: add missing space --- pipenv/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipenv/core.py b/pipenv/core.py index 4fb7939e..b49ae1e9 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -2491,7 +2491,7 @@ def do_graph(bare=False, json=False, json_tree=False, reverse=False): if not project.virtualenv_exists: click.echo( u"{0}: No virtualenv has been created for this project yet! Consider " - u"running {1} first to automatically generate one for you or see" + u"running {1} first to automatically generate one for you or see " u"{2} for further instructions.".format( crayons.red("Warning", bold=True), crayons.green("`pipenv install`"), From bd1bebb9578351645fec0def3fb3d4eefa72320b Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Thu, 17 Jan 2019 09:41:35 +0800 Subject: [PATCH 33/40] Fix order of hashes --- news/3446.trivial.rst | 1 + pipenv/core.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 news/3446.trivial.rst diff --git a/news/3446.trivial.rst b/news/3446.trivial.rst new file mode 100644 index 00000000..1eb98bbb --- /dev/null +++ b/news/3446.trivial.rst @@ -0,0 +1 @@ +Fix the wrong order of old and new hashes in message. diff --git a/pipenv/core.py b/pipenv/core.py index b49ae1e9..0cbb956b 100644 --- a/pipenv/core.py +++ b/pipenv/core.py @@ -1186,9 +1186,9 @@ def do_init( ) else: if old_hash: - msg = fix_utf8("Pipfile.lock ({1}) out of date, updating to ({0})…") + msg = fix_utf8("Pipfile.lock ({0}) out of date, updating to ({1})…") else: - msg = fix_utf8("Pipfile.lock is corrupted, replaced with ({0})…") + msg = fix_utf8("Pipfile.lock is corrupted, replaced with ({1})…") click.echo( crayons.red(msg.format(old_hash[-6:], new_hash[-6:]), bold=True), err=True, From 9dab05d64e9f68cae618e44d31d8815447b9f2a8 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Thu, 17 Jan 2019 12:04:05 +0800 Subject: [PATCH 34/40] Update the index names in lock file --- news/3449.bugfix.rst | 1 + pipenv/project.py | 9 +++++---- pipenv/utils.py | 3 ++- tests/integration/conftest.py | 4 ++-- tests/integration/test_lock.py | 24 ++++++++++++++++++++++++ 5 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 news/3449.bugfix.rst diff --git a/news/3449.bugfix.rst b/news/3449.bugfix.rst new file mode 100644 index 00000000..72e8d228 --- /dev/null +++ b/news/3449.bugfix.rst @@ -0,0 +1 @@ +Update the index names in lock file when source name in Pipfile is changed. diff --git a/pipenv/project.py b/pipenv/project.py index edbcff87..94962231 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -869,7 +869,7 @@ class Project(object): source = self.get_source(url=source) return source - def get_source(self, name=None, url=None): + def get_source(self, name=None, url=None, pipfile_only=False): def find_source(sources, name=None, url=None): source = None if name: @@ -879,9 +879,10 @@ class Project(object): if source: return first(source) - found_source = find_source(self.sources, name=name, url=url) - if found_source: - return found_source + if not pipfile_only: + found_source = find_source(self.sources, name=name, url=url) + if found_source: + return found_source found_source = find_source(self.pipfile_sources, name=name, url=url) if found_source: return found_source diff --git a/pipenv/utils.py b/pipenv/utils.py index 08847e59..2751a2ff 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -236,7 +236,8 @@ def get_resolver_metadata(deps, index_lookup, markers_lookup, project, sources): constraints.append(req.constraint_line) if url: - index_lookup[req.name] = project.get_source(url=url).get("name") + index_lookup[req.name] = project.get_source( + url=url, pipfile_only=True).get("name") # strip the marker and re-add it later after resolution # but we will need a fallback in case resolution fails # eg pypiwin32 diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 91861db3..b5b5bc85 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -129,7 +129,7 @@ class _Pipfile(object): def __init__(self, path): self.path = path self.document = tomlkit.document() - self.document["sources"] = tomlkit.aot() + self.document["source"] = tomlkit.aot() self.document["requires"] = tomlkit.table() self.document["packages"] = tomlkit.table() self.document["dev_packages"] = tomlkit.table() @@ -155,7 +155,7 @@ class _Pipfile(object): source_table["url"] = os.environ.get("PIPENV_TEST_INDEX") source_table["verify_ssl"] = False source_table["name"] = "pipenv_test_index" - self.document["sources"].append(source_table) + self.document["source"].append(source_table) return tomlkit.dumps(self.document) def write(self): diff --git a/tests/integration/test_lock.py b/tests/integration/test_lock.py index 75095ac0..d993b1a2 100644 --- a/tests/integration/test_lock.py +++ b/tests/integration/test_lock.py @@ -564,3 +564,27 @@ def test_vcs_lock_respects_top_level_pins(PipenvInstance, pypi): assert "git" in p.lockfile["default"]["requests"] assert "urllib3" in p.lockfile["default"] assert p.lockfile["default"]["urllib3"]["version"] == "==1.21.1" + + +@pytest.mark.lock +def test_lock_after_update_source_name(PipenvInstance, pypi): + with PipenvInstance(pypi=pypi, chdir=True) as p: + contents = """ +[[source]] +url = "https://test.pypi.org/simple" +verify_ssl = true +name = "test" + +[packages] +six = "*" + """.strip() + with open(p.pipfile_path, 'w') as f: + f.write(contents) + c = p.pipenv("lock") + assert c.return_code == 0 + assert p.lockfile["default"]["six"]["index"] == "test" + with open(p.pipfile_path, 'w') as f: + f.write(contents.replace('name = "test"', 'name = "custom"')) + c = p.pipenv("lock") + assert c.return_code == 0 + assert p.lockfile["default"]["six"]["index"] == "custom" From c3e94364a065de4eb013e5da2e953b9c7793c1d6 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Thu, 17 Jan 2019 12:57:02 +0800 Subject: [PATCH 35/40] Use the source passed in --- pipenv/project.py | 9 ++++----- pipenv/utils.py | 8 ++++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/pipenv/project.py b/pipenv/project.py index 94962231..edbcff87 100644 --- a/pipenv/project.py +++ b/pipenv/project.py @@ -869,7 +869,7 @@ class Project(object): source = self.get_source(url=source) return source - def get_source(self, name=None, url=None, pipfile_only=False): + def get_source(self, name=None, url=None): def find_source(sources, name=None, url=None): source = None if name: @@ -879,10 +879,9 @@ class Project(object): if source: return first(source) - if not pipfile_only: - found_source = find_source(self.sources, name=name, url=url) - if found_source: - return found_source + found_source = find_source(self.sources, name=name, url=url) + if found_source: + return found_source found_source = find_source(self.pipfile_sources, name=name, url=url) if found_source: return found_source diff --git a/pipenv/utils.py b/pipenv/utils.py index 2751a2ff..3cf6dc2f 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -234,10 +234,10 @@ def get_resolver_metadata(deps, index_lookup, markers_lookup, project, sources): dep = " ".join(remainder) req = Requirement.from_line(dep) constraints.append(req.constraint_line) - if url: - index_lookup[req.name] = project.get_source( - url=url, pipfile_only=True).get("name") + source = first(s for s in sources if url.startswith(s.get("url"))) + if source: + index_lookup[req.name] = source.get("name") # strip the marker and re-add it later after resolution # but we will need a fallback in case resolution fails # eg pypiwin32 @@ -837,7 +837,7 @@ def convert_deps_to_pip(deps, project=None, r=True, include_index=True): dependencies = [] for dep_name, dep in deps.items(): - indexes = project.sources if hasattr(project, "sources") else [] + indexes = project.pipfile_sources if hasattr(project, "pipfile_sources") else [] new_dep = Requirement.from_pipfile(dep_name, dep) if new_dep.index: include_index = True From b5c88e9c32a9184d71da0de5c7bc95331c469477 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Thu, 17 Jan 2019 15:47:32 +0800 Subject: [PATCH 36/40] ensure the existence of 'url' --- pipenv/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pipenv/utils.py b/pipenv/utils.py index 3cf6dc2f..c2a6c1bc 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -235,7 +235,8 @@ def get_resolver_metadata(deps, index_lookup, markers_lookup, project, sources): req = Requirement.from_line(dep) constraints.append(req.constraint_line) if url: - source = first(s for s in sources if url.startswith(s.get("url"))) + source = first( + s for s in sources if s.get("url") and url.startswith(s["url"])) if source: index_lookup[req.name] = source.get("name") # strip the marker and re-add it later after resolution From b60439db370e1f40f0a0ff3b03547c877b938c75 Mon Sep 17 00:00:00 2001 From: Adam Goldschmidt Date: Wed, 16 Jan 2019 20:21:03 +0200 Subject: [PATCH 37/40] handle non-URL sources - raise PipenvUsageError --- news/2373.bugfix.rst | 1 + pipenv/utils.py | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 news/2373.bugfix.rst diff --git a/news/2373.bugfix.rst b/news/2373.bugfix.rst new file mode 100644 index 00000000..2cc1c251 --- /dev/null +++ b/news/2373.bugfix.rst @@ -0,0 +1 @@ +Raise `PipenvUsageError` when [[source]] does not contain url field. \ No newline at end of file diff --git a/pipenv/utils.py b/pipenv/utils.py index 08847e59..87f36d1b 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -31,6 +31,7 @@ import crayons import parse from . import environments +from .exceptions import PipenvUsageError from .pep508checker import lookup @@ -203,20 +204,23 @@ def prepare_pip_source_args(sources, pip_args=None): pip_args = [] if sources: # Add the source to notpip. - pip_args.extend(["-i", sources[0]["url"]]) + package_url = sources[0].get("url") + if not package_url: + raise PipenvUsageError("Please provide a source URL.") + pip_args.extend(["-i", package_url]) # Trust the host if it's not verified. if not sources[0].get("verify_ssl", True): pip_args.extend( - ["--trusted-host", urllib3_util.parse_url(sources[0]["url"]).host] + ["--trusted-host", urllib3_util.parse_url(package_url).host] ) # Add additional sources as extra indexes. if len(sources) > 1: for source in sources[1:]: - pip_args.extend(["--extra-index-url", source["url"]]) + pip_args.extend(["--extra-index-url", source.get("url")]) # Trust the host if it's not verified. if not source.get("verify_ssl", True): pip_args.extend( - ["--trusted-host", urllib3_util.parse_url(source["url"]).host] + ["--trusted-host", urllib3_util.parse_url(source.get("url")).host] ) return pip_args From 3b4c592f30140f63ecef6121973eddae07552632 Mon Sep 17 00:00:00 2001 From: Adam Goldschmidt Date: Wed, 16 Jan 2019 20:29:19 +0200 Subject: [PATCH 38/40] add test to invalid prepare_pip_source_args and change error to be more descriptive. (+1 squashed commit) Squashed commits: [b00fb5ba] fixed test getting empty URL in source --- pipenv/utils.py | 9 ++++++--- tests/unit/test_utils.py | 6 ++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pipenv/utils.py b/pipenv/utils.py index 87f36d1b..5ed21264 100644 --- a/pipenv/utils.py +++ b/pipenv/utils.py @@ -206,7 +206,7 @@ def prepare_pip_source_args(sources, pip_args=None): # Add the source to notpip. package_url = sources[0].get("url") if not package_url: - raise PipenvUsageError("Please provide a source URL.") + raise PipenvUsageError("[[source]] section does not contain a URL.") pip_args.extend(["-i", package_url]) # Trust the host if it's not verified. if not sources[0].get("verify_ssl", True): @@ -216,11 +216,14 @@ def prepare_pip_source_args(sources, pip_args=None): # Add additional sources as extra indexes. if len(sources) > 1: for source in sources[1:]: - pip_args.extend(["--extra-index-url", source.get("url")]) + url = source.get("url") + if not url: # not harmless, just don't continue + continue + pip_args.extend(["--extra-index-url", url]) # Trust the host if it's not verified. if not source.get("verify_ssl", True): pip_args.extend( - ["--trusted-host", urllib3_util.parse_url(source.get("url")).host] + ["--trusted-host", urllib3_util.parse_url(url).host] ) return pip_args diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index aeaf3ed3..ac5eb29b 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -8,6 +8,7 @@ from mock import Mock, patch import pipenv.utils import pythonfinder.utils +from pipenv.exceptions import PipenvUsageError # Pipfile format <-> requirements.txt format. @@ -374,6 +375,11 @@ twine = "*" == expected_args ) + def test_invalid_prepare_pip_source_args(self): + sources = [{}] + with pytest.raises(PipenvUsageError): + pipenv.utils.prepare_pip_source_args(sources, pip_args=None) + @pytest.mark.utils def test_parse_python_version(self): ver = pipenv.utils.parse_python_version("Python 3.6.5\n") From c3e3cfb0152bb0dbf789db5499488cbd867f12a8 Mon Sep 17 00:00:00 2001 From: Adam Goldschmidt Date: Wed, 16 Jan 2019 21:26:38 +0200 Subject: [PATCH 39/40] add .news file to describe the fix --- news/2373.bugfix.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/news/2373.bugfix.rst b/news/2373.bugfix.rst index 2cc1c251..9b42add1 100644 --- a/news/2373.bugfix.rst +++ b/news/2373.bugfix.rst @@ -1 +1 @@ -Raise `PipenvUsageError` when [[source]] does not contain url field. \ No newline at end of file +Raise `PipenvUsageError` when [[source]] does not contain url field. From 3235bb7253d87d8e387057ea7a466c490c587b2e Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Fri, 18 Jan 2019 16:39:47 +0800 Subject: [PATCH 40/40] Exclude peeps folder when trigger pipelines --- .azure-pipelines/linux.yml | 1 + .azure-pipelines/windows.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.azure-pipelines/linux.yml b/.azure-pipelines/linux.yml index a2f34d4c..e39c45e7 100644 --- a/.azure-pipelines/linux.yml +++ b/.azure-pipelines/linux.yml @@ -8,6 +8,7 @@ trigger: exclude: - docs/* - news/* + - peeps/* - README.md - pipenv/*.txt - CHANGELOG.rst diff --git a/.azure-pipelines/windows.yml b/.azure-pipelines/windows.yml index 35d5c16e..0f04afbe 100644 --- a/.azure-pipelines/windows.yml +++ b/.azure-pipelines/windows.yml @@ -8,6 +8,7 @@ trigger: exclude: - docs/* - news/* + - peeps/* - README.md - pipenv/*.txt - CHANGELOG.rst