Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
后端镜像
Pdm
提交
eea52ae3
P
Pdm
项目概览
后端镜像
/
Pdm
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
Pdm
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
eea52ae3
编写于
1月 15, 2021
作者:
F
Frost Ming
提交者:
GitHub
1月 15, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #222 from frostming/feature/219
Auto disable PEP 582 when a venv-like python is given
上级
76c3a8d0
9170a7ba
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
60 addition
and
29 deletion
+60
-29
.github/workflows/ci.yml
.github/workflows/ci.yml
+3
-3
docs/docs/project.md
docs/docs/project.md
+2
-0
news/219.feature
news/219.feature
+1
-0
pdm/models/caches.py
pdm/models/caches.py
+5
-5
pdm/models/environment.py
pdm/models/environment.py
+8
-5
pdm/project/config.py
pdm/project/config.py
+5
-4
pdm/project/core.py
pdm/project/core.py
+10
-2
pdm/utils.py
pdm/utils.py
+6
-4
tests/conftest.py
tests/conftest.py
+1
-1
tests/test_project.py
tests/test_project.py
+19
-5
未找到文件。
.github/workflows/ci.yml
浏览文件 @
eea52ae3
...
@@ -53,10 +53,10 @@ jobs:
...
@@ -53,10 +53,10 @@ jobs:
with
:
with
:
path
:
__pypackages__
path
:
__pypackages__
# Look to see if there is a cache hit for the corresponding requirements file
# Look to see if there is a cache hit for the corresponding requirements file
key
:
${{ runner.os }}-packages-${{ steps.set_variables.outputs.PY }}-${{ hashFiles('pdm.lock') }}
key
:
${{ runner.os }}-
${{ matrix.arch }}-
packages-${{ steps.set_variables.outputs.PY }}-${{ hashFiles('pdm.lock') }}
restore-keys
:
|
restore-keys
:
|
${{ runner.os }}-packages-${{ steps.set_variables.outputs.PY }}-
${{ runner.os }}-
${{ matrix.arch }}-
packages-${{ steps.set_variables.outputs.PY }}-
${{ runner.os }}-packages-
${{ runner.os }}-
${{ matrix.arch }}-
packages-
-
name
:
Install Current PDM
-
name
:
Install Current PDM
run
:
|
run
:
|
pip install -U pip
pip install -U pip
...
...
docs/docs/project.md
浏览文件 @
eea52ae3
...
@@ -125,6 +125,8 @@ by the configuration item `use_venv`. When it is set to `True` PDM will use the
...
@@ -125,6 +125,8 @@ by the configuration item `use_venv`. When it is set to `True` PDM will use the
-
an virtualenv is already activated.
-
an virtualenv is already activated.
-
any of
`venv`
,
`.venv`
,
`env`
is an valid virtualenv folder.
-
any of
`venv`
,
`.venv`
,
`env`
is an valid virtualenv folder.
Besides, when
`use-venv`
is on and the interpreter path given is a venv-like path, PDM will reuse that venv directory as well.
## Import project metadata from existing project files
## Import project metadata from existing project files
If you are already other package manager tools like Pipenv or Poetry, it is easy to migrate to PDM.
If you are already other package manager tools like Pipenv or Poetry, it is easy to migrate to PDM.
...
...
news/219.feature
0 → 100644
浏览文件 @
eea52ae3
Auto
disable
PEP
582
when
a
venv-like python is given as the interpreter path.
pdm/models/caches.py
浏览文件 @
eea52ae3
import
hashlib
import
hashlib
import
json
import
json
from
pathlib
import
Path
from
pathlib
import
Path
from
typing
import
TYPE_CHECKING
,
Any
,
Dict
,
Optional
from
typing
import
TYPE_CHECKING
,
Dict
,
Optional
from
pip._vendor
import
requests
from
pdm._types
import
CandidateInfo
from
pdm._types
import
CandidateInfo
from
pdm.exceptions
import
CorruptedCacheError
from
pdm.exceptions
import
CorruptedCacheError
...
@@ -11,6 +9,8 @@ from pdm.models import pip_shims
...
@@ -11,6 +9,8 @@ from pdm.models import pip_shims
from
pdm.utils
import
open_file
from
pdm.utils
import
open_file
if
TYPE_CHECKING
:
if
TYPE_CHECKING
:
from
pip._vendor
import
requests
from
pdm.models.candidates
import
Candidate
from
pdm.models.candidates
import
Candidate
...
@@ -19,7 +19,7 @@ class CandidateInfoCache:
...
@@ -19,7 +19,7 @@ class CandidateInfoCache:
def
__init__
(
self
,
cache_file
:
Path
)
->
None
:
def
__init__
(
self
,
cache_file
:
Path
)
->
None
:
self
.
cache_file
=
cache_file
self
.
cache_file
=
cache_file
self
.
_cache
=
{}
# type: Dict[str,
Any
]
self
.
_cache
=
{}
# type: Dict[str,
CandidateInfo
]
self
.
_read_cache
()
self
.
_read_cache
()
def
_read_cache
(
self
)
->
None
:
def
_read_cache
(
self
)
->
None
:
...
@@ -80,7 +80,7 @@ class HashCache(pip_shims.SafeFileCache):
...
@@ -80,7 +80,7 @@ class HashCache(pip_shims.SafeFileCache):
Hashes are only cached when the URL appears to contain a hash in it and the
Hashes are only cached when the URL appears to contain a hash in it and the
cache key includes the hash value returned from the server). This ought to
cache key includes the hash value returned from the server). This ought to
avoid ssues where the location on the server changes.
avoid
i
ssues where the location on the server changes.
"""
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
...
...
pdm/models/environment.py
浏览文件 @
eea52ae3
...
@@ -102,10 +102,8 @@ class Environment:
...
@@ -102,10 +102,8 @@ class Environment:
def
python_executable
(
self
)
->
str
:
def
python_executable
(
self
)
->
str
:
"""Get the Python interpreter path."""
"""Get the Python interpreter path."""
config
=
self
.
project
.
config
config
=
self
.
project
.
config
if
config
.
get
(
"python.path"
):
if
self
.
project
.
project_config
.
get
(
"python.path"
):
return
config
[
"python.path"
]
return
self
.
project
.
project_config
[
"python.path"
]
if
PYENV_INSTALLED
and
config
.
get
(
"python.use_pyenv"
,
True
):
return
os
.
path
.
join
(
PYENV_ROOT
,
"shims"
,
"python"
)
if
"VIRTUAL_ENV"
in
os
.
environ
:
if
"VIRTUAL_ENV"
in
os
.
environ
:
stream
.
echo
(
stream
.
echo
(
"An activated virtualenv is detected, reuse the interpreter now."
,
"An activated virtualenv is detected, reuse the interpreter now."
,
...
@@ -113,6 +111,8 @@ class Environment:
...
@@ -113,6 +111,8 @@ class Environment:
verbosity
=
stream
.
DETAIL
,
verbosity
=
stream
.
DETAIL
,
)
)
return
get_venv_python
(
self
.
project
.
root
)
return
get_venv_python
(
self
.
project
.
root
)
if
PYENV_INSTALLED
and
config
.
get
(
"python.use_pyenv"
,
True
):
return
os
.
path
.
join
(
PYENV_ROOT
,
"shims"
,
"python"
)
# First try what `python` refers to.
# First try what `python` refers to.
path
=
shutil
.
which
(
"python"
)
path
=
shutil
.
which
(
"python"
)
...
@@ -131,6 +131,9 @@ class Environment:
...
@@ -131,6 +131,9 @@ class Environment:
if
self
.
python_requires
.
contains
(
version
):
if
self
.
python_requires
.
contains
(
version
):
path
=
sys
.
executable
path
=
sys
.
executable
if
path
:
if
path
:
if
os
.
path
.
normcase
(
path
)
==
os
.
path
.
normcase
(
sys
.
executable
):
# Refer to the base interpreter to allow for venvs
path
=
getattr
(
sys
,
"_base_executable"
,
sys
.
executable
)
stream
.
echo
(
stream
.
echo
(
"Using Python interpreter: {} ({})"
.
format
(
stream
.
green
(
path
),
version
)
"Using Python interpreter: {} ({})"
.
format
(
stream
.
green
(
path
),
version
)
)
)
...
@@ -414,7 +417,7 @@ class Environment:
...
@@ -414,7 +417,7 @@ class Environment:
scripts
=
self
.
get_paths
()[
"scripts"
]
scripts
=
self
.
get_paths
()[
"scripts"
]
maker
=
ScriptMaker
(
None
,
None
)
maker
=
ScriptMaker
(
None
,
None
)
maker
.
executable
=
new_path
maker
.
executable
=
new_path
shebang
=
maker
.
_get_shebang
(
"utf-8"
).
rstrip
()
shebang
=
maker
.
_get_shebang
(
"utf-8"
).
rstrip
()
.
replace
(
b
"
\\
"
,
b
"
\\\\
"
)
for
child
in
Path
(
scripts
).
iterdir
():
for
child
in
Path
(
scripts
).
iterdir
():
if
not
child
.
is_file
()
or
child
.
suffix
not
in
(
".exe"
,
".py"
,
""
):
if
not
child
.
is_file
()
or
child
.
suffix
not
in
(
".exe"
,
".py"
,
""
):
continue
continue
...
...
pdm/project/config.py
浏览文件 @
eea52ae3
...
@@ -149,15 +149,16 @@ class Config(MutableMapping):
...
@@ -149,15 +149,16 @@ class Config(MutableMapping):
fp
.
write
(
tomlkit
.
dumps
(
toml_data
))
fp
.
write
(
tomlkit
.
dumps
(
toml_data
))
def
__getitem__
(
self
,
key
:
str
)
->
Any
:
def
__getitem__
(
self
,
key
:
str
)
->
Any
:
if
key
not
in
self
.
_data
:
raise
NoConfigError
(
key
)
env_var
=
self
.
_config_map
[
key
].
env_var
env_var
=
self
.
_config_map
[
key
].
env_var
if
env_var
is
not
None
and
env_var
in
os
.
environ
:
if
env_var
is
not
None
and
env_var
in
os
.
environ
:
env_value
=
os
.
environ
[
env_var
]
env_value
=
os
.
environ
[
env_var
]
if
isinstance
(
self
.
_config_map
[
key
].
default
,
bool
):
if
isinstance
(
self
.
_config_map
[
key
].
default
,
bool
):
env_value
=
ensure_boolean
(
env_value
)
env_value
=
ensure_boolean
(
env_value
)
return
env_value
return
env_value
return
self
.
_data
[
key
]
try
:
return
self
.
_data
[
key
]
except
KeyError
:
raise
NoConfigError
(
key
)
from
None
def
__setitem__
(
self
,
key
:
str
,
value
:
Any
)
->
None
:
def
__setitem__
(
self
,
key
:
str
,
value
:
Any
)
->
None
:
if
key
not
in
self
.
_config_map
:
if
key
not
in
self
.
_config_map
:
...
@@ -176,7 +177,7 @@ class Config(MutableMapping):
...
@@ -176,7 +177,7 @@ class Config(MutableMapping):
stream
.
echo
(
stream
.
echo
(
stream
.
yellow
(
stream
.
yellow
(
"WARNING: the config is shadowed by env var '{}', "
"WARNING: the config is shadowed by env var '{}', "
"
set value
won't take effect."
.
format
(
env_var
)
"
the value set
won't take effect."
.
format
(
env_var
)
)
)
)
)
self
.
_data
[
key
]
=
value
self
.
_data
[
key
]
=
value
...
...
pdm/project/core.py
浏览文件 @
eea52ae3
...
@@ -142,11 +142,19 @@ class Project:
...
@@ -142,11 +142,19 @@ class Project:
"=="
+
get_python_version
(
env
.
python_executable
,
True
)[
0
]
"=="
+
get_python_version
(
env
.
python_executable
,
True
)[
0
]
)
)
return
env
return
env
if
self
.
config
[
"use_venv"
]:
if
not
self
.
project_config
.
get
(
"python.path"
)
and
self
.
config
[
"use_venv"
]:
venv_python
=
get_venv_python
(
self
.
root
)
venv_python
=
get_venv_python
(
self
.
root
)
if
venv_python
:
if
venv_python
:
self
.
project_config
[
"python.path"
]
=
venv_python
self
.
project_config
[
"python.path"
]
=
venv_python
return
GlobalEnvironment
(
self
)
if
(
self
.
config
[
"use_venv"
]
and
self
.
project_config
.
get
(
"python.path"
)
and
Path
(
self
.
project_config
.
get
(
"python.path"
))
.
parent
.
parent
.
joinpath
(
"pyvenv.cfg"
)
.
exists
()
):
# Only recognize venv created by python -m venv and virtualenv>20
return
GlobalEnvironment
(
self
)
return
Environment
(
self
)
return
Environment
(
self
)
@
property
@
property
...
...
pdm/utils.py
浏览文件 @
eea52ae3
...
@@ -10,7 +10,7 @@ import tempfile
...
@@ -10,7 +10,7 @@ import tempfile
import
urllib.parse
as
parse
import
urllib.parse
as
parse
from
contextlib
import
contextmanager
from
contextlib
import
contextmanager
from
pathlib
import
Path
from
pathlib
import
Path
from
typing
import
Any
,
Dict
,
List
,
Optional
,
Tuple
,
Union
from
typing
import
Any
,
Callable
,
Dict
,
Generic
,
List
,
Optional
,
Tuple
,
TypeVar
,
Union
from
distlib.wheel
import
Wheel
from
distlib.wheel
import
Wheel
from
tomlkit.container
import
Container
from
tomlkit.container
import
Container
...
@@ -29,13 +29,15 @@ try:
...
@@ -29,13 +29,15 @@ try:
from
functools
import
cached_property
from
functools
import
cached_property
except
ImportError
:
except
ImportError
:
class
cached_property
:
_T
=
TypeVar
(
"_T"
)
def
__init__
(
self
,
func
):
class
cached_property
(
Generic
[
_T
]):
def
__init__
(
self
,
func
:
Callable
[[
Any
],
_T
]):
self
.
func
=
func
self
.
func
=
func
self
.
attr_name
=
func
.
__name__
self
.
attr_name
=
func
.
__name__
self
.
__doc__
=
func
.
__doc__
self
.
__doc__
=
func
.
__doc__
def
__get__
(
self
,
inst
,
cls
=
None
)
:
def
__get__
(
self
,
inst
:
Any
,
cls
=
None
)
->
_T
:
if
inst
is
None
:
if
inst
is
None
:
return
self
return
self
if
self
.
attr_name
not
in
inst
.
__dict__
:
if
self
.
attr_name
not
in
inst
.
__dict__
:
...
...
tests/conftest.py
浏览文件 @
eea52ae3
...
@@ -229,7 +229,7 @@ def project_no_init(tmp_path, mocker):
...
@@ -229,7 +229,7 @@ def project_no_init(tmp_path, mocker):
mocker
.
patch
(
"pdm.project.core.Config.HOME_CONFIG"
,
tmp_path
)
mocker
.
patch
(
"pdm.project.core.Config.HOME_CONFIG"
,
tmp_path
)
old_config_map
=
Config
.
_config_map
.
copy
()
old_config_map
=
Config
.
_config_map
.
copy
()
p
.
global_config
[
"cache_dir"
]
=
tmp_path
.
joinpath
(
"caches"
).
as_posix
()
p
.
global_config
[
"cache_dir"
]
=
tmp_path
.
joinpath
(
"caches"
).
as_posix
()
do_use
(
p
,
sys
.
executable
)
do_use
(
p
,
getattr
(
sys
,
"_base_executable"
,
sys
.
executable
)
)
with
temp_environ
():
with
temp_environ
():
os
.
environ
.
pop
(
"VIRTUAL_ENV"
,
None
)
os
.
environ
.
pop
(
"VIRTUAL_ENV"
,
None
)
os
.
environ
.
pop
(
"PYTHONPATH"
,
None
)
os
.
environ
.
pop
(
"PYTHONPATH"
,
None
)
...
...
tests/test_project.py
浏览文件 @
eea52ae3
import
os
import
os
import
sys
import
sys
import
venv
from
pathlib
import
Path
from
pathlib
import
Path
import
distlib.wheel
import
distlib.wheel
...
@@ -57,19 +58,17 @@ def test_global_project(tmp_path):
...
@@ -57,19 +58,17 @@ def test_global_project(tmp_path):
assert
project
.
environment
.
is_global
assert
project
.
environment
.
is_global
def
test_project_use_venv
(
project
,
mocker
):
def
test_project_use_venv
(
project
):
del
project
.
project_config
[
"python.path"
]
del
project
.
project_config
[
"python.path"
]
scripts
=
"Scripts"
if
os
.
name
==
"nt"
else
"bin"
scripts
=
"Scripts"
if
os
.
name
==
"nt"
else
"bin"
suffix
=
".exe"
if
os
.
name
==
"nt"
else
""
suffix
=
".exe"
if
os
.
name
==
"nt"
else
""
venv
.
create
(
project
.
root
/
"venv"
)
os
.
environ
[
"VIRTUAL_ENV"
]
=
"/path/to/env"
mocker
.
patch
(
"pdm.models.environment.get_python_version"
,
return_value
=
"3.7.0"
)
project
.
project_config
[
"use_venv"
]
=
True
project
.
project_config
[
"use_venv"
]
=
True
env
=
project
.
environment
env
=
project
.
environment
assert
(
assert
(
Path
(
env
.
python_executable
)
Path
(
env
.
python_executable
)
==
Path
(
"/path/to/env"
)
/
scripts
/
f
"python
{
suffix
}
"
==
project
.
root
/
"venv"
/
scripts
/
f
"python
{
suffix
}
"
)
)
assert
env
.
is_global
assert
env
.
is_global
...
@@ -95,3 +94,18 @@ def test_project_packages_path(project):
...
@@ -95,3 +94,18 @@ def test_project_packages_path(project):
assert
packages_path
.
name
==
version
+
"-32"
assert
packages_path
.
name
==
version
+
"-32"
else
:
else
:
assert
packages_path
.
name
==
version
assert
packages_path
.
name
==
version
def
test_project_auto_detect_venv
(
project
):
venv
.
create
(
project
.
root
/
"test_venv"
)
scripts
=
"Scripts"
if
os
.
name
==
"nt"
else
"bin"
suffix
=
".exe"
if
os
.
name
==
"nt"
else
""
project
.
project_config
[
"use_venv"
]
=
True
project
.
project_config
[
"python.path"
]
=
(
project
.
root
/
"test_venv"
/
scripts
/
f
"python
{
suffix
}
"
).
as_posix
()
assert
project
.
environment
.
is_global
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录