Skip to content

App data seeder by default should use bundled only #1833

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.5.0
rev: v3.0.0
hooks:
- id: check-ast
- id: check-builtin-literals
Expand All @@ -15,10 +15,6 @@ repos:
rev: v2.0.1
hooks:
- id: add-trailing-comma
- repo: https://github.com/asottile/yesqa
rev: v1.1.0
hooks:
- id: yesqa
- repo: https://github.com/asottile/pyupgrade
rev: v2.4.1
hooks:
Expand Down
2 changes: 2 additions & 0 deletions docs/changelog/1821.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
By default install only bundled packages (latest compatible wheel between the embed packages that come with virtualenv,
and wheels found inside the provided :option:`extra-search-dir`) - by :user:`gaborbernat`.
1 change: 1 addition & 0 deletions docs/changelog/1821.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Display the installed seed package versions in the final summary output - by :user:`gaborbernat`.
13 changes: 12 additions & 1 deletion src/virtualenv/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,18 @@ def __str__(self):
" creator {}".format(ensure_text(str(self.session.creator))),
]
if self.session.seeder.enabled:
lines += (" seeder {}".format(ensure_text(str(self.session.seeder))),)
lines += (
" seeder {}".format(ensure_text(str(self.session.seeder))),
" added seed packages: {}".format(
", ".join(
sorted(
"==".join(i.stem.split("-"))
for i in self.session.creator.purelib.iterdir()
if i.suffix == ".dist-info"
),
),
),
)
if self.session.activators:
lines.append(" activators {}".format(",".join(i.__class__.__name__ for i in self.session.activators)))
return os.linesep.join(lines)
Expand Down
57 changes: 29 additions & 28 deletions src/virtualenv/seed/embed/base_embed.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,39 @@
from virtualenv.util.six import ensure_str, ensure_text

from ..seeder import Seeder
from .wheels.acquire import Version


@add_metaclass(ABCMeta)
class BaseEmbed(Seeder):
packages = ["pip", "setuptools", "wheel"]
distributions = {
"pip": Version.bundle,
"setuptools": Version.bundle,
"wheel": Version.bundle,
}

def __init__(self, options):
super(BaseEmbed, self).__init__(options, enabled=options.no_seed is False)
self.download = options.download
self.extra_search_dir = [i.resolve() for i in options.extra_search_dir if i.exists()]

def latest_is_none(key):
value = getattr(options, key)
return None if value == "latest" else value

self.pip_version = latest_is_none("pip")
self.setuptools_version = latest_is_none("setuptools")
self.wheel_version = latest_is_none("wheel")
self.pip_version = options.pip
self.setuptools_version = options.setuptools
self.wheel_version = options.wheel

self.no_pip = options.no_pip
self.no_setuptools = options.no_setuptools
self.no_wheel = options.no_wheel
self.app_data = options.app_data.folder

if not self.package_version():
if not self.distribution_to_versions():
self.enabled = False

def package_version(self):
def distribution_to_versions(self):
return {
package: getattr(self, "{}_version".format(package))
for package in self.packages
if getattr(self, "no_{}".format(package)) is False
distribution: getattr(self, "{}_version".format(distribution))
for distribution in self.distributions
if getattr(self, "no_{}".format(distribution)) is False
}

@classmethod
Expand All @@ -50,38 +51,38 @@ def add_parser_arguments(cls, parser, interpreter, app_data):
"--never-download",
dest="download",
action="store_false",
help="pass to disable download of the latest {} from PyPI".format("/".join(cls.packages)),
help="pass to disable download of the latest {} from PyPI".format("/".join(cls.distributions)),
default=True,
)
group.add_argument(
"--download",
dest="download",
action="store_true",
help="pass to enable download of the latest {} from PyPI".format("/".join(cls.packages)),
help="pass to enable download of the latest {} from PyPI".format("/".join(cls.distributions)),
default=False,
)
parser.add_argument(
"--extra-search-dir",
metavar="d",
type=Path,
nargs="+",
help="a path containing wheels the seeder may also use beside bundled (can be set 1+ times)",
help="a path containing wheels that extend the bundled list (can be set 1+ times)",
default=[],
)
for package in cls.packages:
for distribution, default in cls.distributions.items():
parser.add_argument(
"--{}".format(package),
dest=package,
"--{}".format(distribution),
dest=distribution,
metavar="version",
help="{} version to install, bundle for bundled".format(package),
default="latest",
help="{} version to install, bundle for bundled".format(distribution),
default=default,
)
for package in cls.packages:
for distribution in cls.distributions:
parser.add_argument(
"--no-{}".format(package),
dest="no_{}".format(package),
"--no-{}".format(distribution),
dest="no_{}".format(distribution),
action="store_true",
help="do not install {}".format(package),
help="do not install {}".format(distribution),
default=False,
)

Expand All @@ -91,11 +92,11 @@ def __unicode__(self):
if self.extra_search_dir:
result += "extra_search_dir={},".format(", ".join(ensure_text(str(i)) for i in self.extra_search_dir))
result += "download={},".format(self.download)
for package in self.packages:
if getattr(self, "no_{}".format(package)):
for distribution in self.distributions:
if getattr(self, "no_{}".format(distribution)):
continue
result += " {}{},".format(
package, "={}".format(getattr(self, "{}_version".format(package), None) or "latest"),
distribution, "={}".format(getattr(self, "{}_version".format(distribution), None) or "latest"),
)
return result[:-1] + ")"

Expand Down
16 changes: 9 additions & 7 deletions src/virtualenv/seed/embed/pip_invoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from virtualenv.discovery.cached_py_info import LogCmd
from virtualenv.info import PY3
from virtualenv.seed.embed.base_embed import BaseEmbed
from virtualenv.seed.embed.wheels.acquire import get_bundled_wheel, pip_wheel_env_run
from virtualenv.seed.embed.wheels.acquire import Version, get_bundled_wheel, pip_wheel_env_run
from virtualenv.util.subprocess import Popen
from virtualenv.util.zipapp import ensure_file_on_disk

Expand All @@ -32,18 +32,20 @@ def run(self, creator):
raise RuntimeError("failed seed with code {}".format(process.returncode))

@contextmanager
def get_pip_install_cmd(self, exe, version):
def get_pip_install_cmd(self, exe, for_py_version):
cmd = [str(exe), "-m", "pip", "-q", "install", "--only-binary", ":all:"]
if not self.download:
cmd.append("--no-index")
pkg_versions = self.package_version()
for key, ver in pkg_versions.items():
cmd.append("{}{}".format(key, "=={}".format(ver) if ver is not None else ""))
distribution_to_version = self.distribution_to_versions()
cmd.extend(Version.as_pip_req(key, Version.of_version(ver)) for key, ver in distribution_to_version.items())
with ExitStack() as stack:
folders = set()
for context in (ensure_file_on_disk(get_bundled_wheel(p, version), self.app_data) for p in pkg_versions):
for context in (
ensure_file_on_disk(get_bundled_wheel(distribution, for_py_version).path, self.app_data)
for distribution in distribution_to_version
):
folders.add(stack.enter_context(context).parent)
folders.update(set(self.extra_search_dir))
for folder in folders:
cmd.extend(["--find-links", str(folder)])
cmd.extend(self.extra_search_dir)
yield cmd
Loading