Skip to content

Commit

Permalink
Merge branch 'main' into semver
Browse files Browse the repository at this point in the history
  • Loading branch information
matteius committed Jan 22, 2024
2 parents 42afbad + eaca109 commit 8d49a0a
Show file tree
Hide file tree
Showing 27 changed files with 1,523 additions and 1,103 deletions.
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,55 @@ You can read more about [pip's implementation of vcs support here](https://pip.p
Launching subshell in virtual environment. Type 'exit' or 'Ctrl+D' to return.
$ ▯


### PURPOSE AND ADVANTAGES OF PIPENV

To understand the problems that Pipenv solves, it's useful to show how Python package management has evolved.

Take yourself back to the first Python iteration. We had Python, but there was no clean way to install packages.

Then came Easy Install, a package that installs other Python packages with relative ease. But it came with a catch: it wasn't easy to uninstall packages that were no longer needed.

Enter pip, which most Python users are familiar with. pip lets us install and uninstall packages. We could specify versions, run pip freeze > requirements.txt to output a list of installed packages to a text file, and use that same text file to install everything an app needed with pip install -r requirements.txt.

But pip didn't include a way to isolate packages from each other. We might work on apps that use different versions of the same libraries, so we needed a way to enable that.


Pipenv aims to solve several problems.
First, the problem of needing the pip library for package installation, plus a library for creating a virtual environment, plus a library for managing virtual environments, plus all the commands associated with those libraries. That's a lot to manage. Pipenv ships with package management and virtual environment support, so you can use one tool to install, uninstall, track, and document your dependencies and to create, use, and organize your virtual environments. When you start a project with it, Pipenv will automatically create a virtual environment for that project if you aren't already using one.

Pipenv accomplishes this dependency management by abandoning the requirements.txt norm and trading it for a new document called a Pipfile. When you install a library with Pipenv, a Pipfile for your project is automatically updated with the details of that installation, including version information and possibly the Git repository location, file path, and other information.

Second, Pipenv wants to make it easier to manage complex interdependencies.

Using Pipenv, which gives you Pipfile, lets you avoid these problems by managing dependencies for different environments for you. This command will install the main project dependencies:

pipenv install

Adding the --dev tag will install the dev/testing requirements:

pipenv install --dev
To generate a Pipfile.lock file, run:

pipenv lock

You can also run Python scripts with Pipenv. To run a top-level Python script called hello.py, run:

pipenv run python hello.py

And you will see your expected result in the console.

To start a shell, run:

pipenv shell

If you would like to convert a project that currently uses a requirements.txt file to use Pipenv, install Pipenv and run:

pipenv install requirements.txt

This will create a Pipfile and install the specified requirements.


Documentation
---------------

Expand Down
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ click==8.0.3
docutils==0.17.1
idna==3.4
imagesize==1.4.1
Jinja2==3.1.2
Jinja2==3.1.3
MarkupSafe==2.1.2
myst-parser[linkify]==0.18.1
-e .
Expand Down
1 change: 1 addition & 0 deletions news/6055.vendor.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Bump version of pipdeptree to 0.13.2
1 change: 1 addition & 0 deletions news/6056.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a bug with locking projects that contains packages with non canonical names from private indexes
2 changes: 1 addition & 1 deletion pipenv/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ def _get_requirements_for_package(cls, node, key_tree, parent=None, chain=None):
def get_package_requirements(self, pkg=None):
from itertools import chain

from pipenv.vendor.pipdeptree import PackageDAG
from pipenv.vendor.pipdeptree._models import PackageDAG

flatten = chain.from_iterable

Expand Down
20 changes: 15 additions & 5 deletions pipenv/utils/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from pipenv.patched.pip._internal.req.req_install import InstallRequirement
from pipenv.patched.pip._internal.utils.temp_dir import global_tempdir_manager
from pipenv.patched.pip._vendor import pkg_resources, rich
from pipenv.patched.pip._vendor.packaging.utils import canonicalize_name
from pipenv.project import Project
from pipenv.utils.fileutils import create_tracked_tempdir
from pipenv.utils.requirements import normalize_name
Expand Down Expand Up @@ -200,6 +201,7 @@ def create(
for package_name, dep in deps.items(): # Build up the index and markers lookups
if not dep:
continue
canonical_package_name = canonicalize_name(package_name)
is_constraint = True
install_req, _ = expansive_install_req_from_line(dep, expand_env=True)
original_deps[package_name] = dep
Expand All @@ -210,14 +212,18 @@ def create(
pipfile_entries[package_name] = pipfile_entry
if isinstance(pipfile_entry, dict):
if packages[package_name].get("index"):
index_lookup[package_name] = packages[package_name].get("index")
index_lookup[canonical_package_name] = packages[package_name].get(
"index"
)
if packages[package_name].get("skip_resolver"):
is_constraint = False
skipped[package_name] = dep
elif index:
index_lookup[package_name] = index
index_lookup[canonical_package_name] = index
else:
index_lookup[package_name] = project.get_default_index()["name"]
index_lookup[canonical_package_name] = project.get_default_index()[
"name"
]
if install_req.markers:
markers_lookup[package_name] = install_req.markers
if is_constraint:
Expand Down Expand Up @@ -546,9 +552,13 @@ def collect_hashes(self, ireq):
return set()

sources = self.sources # Enforce index restrictions
if ireq.name in self.index_lookup:
canonical_ireq_name = canonicalize_name(ireq.name)
if canonical_ireq_name in self.index_lookup:
sources = list(
filter(lambda s: s.get("name") == self.index_lookup[ireq.name], sources)
filter(
lambda s: s.get("name") == self.index_lookup[canonical_ireq_name],
sources,
)
)
source = sources[0] if len(sources) else None
if source:
Expand Down
Loading

0 comments on commit 8d49a0a

Please sign in to comment.