未验证 提交 102b5736 编写于 作者: F Frost Ming

new command: pdm use

上级 3845ed50
......@@ -131,3 +131,4 @@ dmypy.json
caches/
.idea/
__pypackages__
.pdm.toml
import itertools
import os
import shutil
from typing import Dict, Iterable, Optional, Sequence
......@@ -6,10 +7,11 @@ from pkg_resources import safe_name
import click
import halo
import pythonfinder
import tomlkit
from pdm.builders import SdistBuilder, WheelBuilder
from pdm.context import context
from pdm.exceptions import ProjectError
from pdm.exceptions import NoPythonVersion, ProjectError
from pdm.installers import Synchronizer, format_dist
from pdm.models.candidates import Candidate, identify
from pdm.models.requirements import parse_requirement, strip_extras
......@@ -17,6 +19,7 @@ from pdm.models.specifiers import bump_version, get_specifier
from pdm.project import Project
from pdm.resolver import BaseProvider, EagerUpdateProvider, ReusePinProvider, resolve
from pdm.resolver.reporters import SpinnerReporter
from pdm.utils import get_python_version
def format_lockfile(mapping, fetched_dependencies, summary_collection):
......@@ -386,3 +389,33 @@ def do_init(
project._pyproject.setdefault("tool", {})["pdm"] = data["tool"]["pdm"]
project._pyproject["build-system"] = data["build-system"]
project.write_pyproject()
def do_use(project: Project, python: str) -> None:
"""Use the specified python version and save in project config.
The python can be a version string or interpreter path.
"""
if os.path.isabs(python):
python_path = python
else:
python_path = shutil.which(python)
if not python_path:
finder = pythonfinder.Finder()
try:
python_path = finder.find_python_version(python).path.as_posix()
except AttributeError:
raise NoPythonVersion(f"Python {python} is not found on the system.")
python_version = ".".join(map(str, get_python_version(python_path)))
if not project.python_requires.contains(python_version):
raise NoPythonVersion(
"The target Python version {} doesn't satisfy "
"the Python requirement: {}".format(python_version, project.python_requires)
)
context.io.echo(
"Using Python interpreter: {} ({})".format(
context.io.green(python_path), python_version
)
)
project.config["python"] = python_path
project.config.save_config()
......@@ -264,3 +264,11 @@ def init(project):
author = click.prompt(f"Author name", default=git_user)
email = click.prompt(f"Author email", default=git_email)
actions.do_init(project, name, version, license, author, email)
@cli.command()
@click.argument("python")
@pass_project
def use(project, python):
"""Use the given python version as base interpreter."""
actions.do_use(project, python)
......@@ -84,6 +84,7 @@ class Environment:
@cached_property
def python_executable(self) -> str:
"""Get the Python interpreter path."""
path = None
if self.config["python"]:
path = self.config["python"]
try:
......@@ -96,11 +97,23 @@ class Environment:
for python in finder.find_all_python_versions():
version = ".".join(map(str, get_python_version(python.path.as_posix())))
if self.python_requires.contains(version):
return python.path.as_posix()
path = python.path.as_posix()
if self.python_requires.contains(".".join(map(str, sys.version_info[:3]))):
return sys.executable
path = sys.executable
if path:
python_version = ".".join(map(str, get_python_version(path)))
context.io.echo(
"Using Python interpreter: {} ({})".format(
context.io.green(path), python_version
)
)
self.config["python"] = path
self.config.save_config()
return path
raise NoPythonVersion(
"No python matching {} is found on the system.".format(self.python_requires)
"No Python that satisfies {} is found on the system.".format(
self.python_requires
)
)
def get_paths(self) -> Dict[str, str]:
......
......@@ -56,7 +56,7 @@ class Config(MutableMapping):
temp = temp.setdefault(part, {})
temp[last] = value
with file_path.open(encoding="utf-8") as fp:
with file_path.open("w", encoding="utf-8") as fp:
fp.write(tomlkit.dumps(toml_data))
self._dirty.clear()
......
import functools
import os
import shutil
import pytest
from click.testing import CliRunner
......@@ -91,3 +92,19 @@ def test_uncaught_error(invoke, mocker):
result = invoke(["list", "-v"])
assert isinstance(result.exception, RuntimeError)
def test_use_command(project, invoke):
python_path = shutil.which("python")
result = invoke(["use", "python"], obj=project)
assert result.exit_code == 0
config_content = project.root.joinpath(".pdm.toml").read_text()
assert python_path in config_content
result = invoke(["use", python_path], obj=project)
assert result.exit_code == 0
project.tool_settings["python_requires"] = ">=3.6"
project.write_pyproject()
result = invoke(["use", "2.7"], obj=project)
assert result.exit_code == 1
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册