Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
后端镜像
Pdm
提交
1772f9cd
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 搜索 >>
提交
1772f9cd
编写于
5月 27, 2022
作者:
F
Frost Ming
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
perf(resolver): Speed up the resolution with lazy find_matches (#1098)
上级
9eafd623
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
51 addition
and
34 deletion
+51
-34
news/1098.feature.md
news/1098.feature.md
+1
-0
pdm/resolver/providers.py
pdm/resolver/providers.py
+49
-33
setup.cfg
setup.cfg
+1
-1
未找到文件。
news/1098.feature.md
0 → 100644
浏览文件 @
1772f9cd
Lazy load the candidates returned by
`find_matches()`
to speed up the resolution.
pdm/resolver/providers.py
浏览文件 @
1772f9cd
from
__future__
import
annotations
from
typing
import
TYPE_CHECKING
from
typing
import
TYPE_CHECKING
,
Callable
,
cast
from
packaging.specifiers
import
InvalidSpecifier
,
SpecifierSet
from
resolvelib
import
AbstractProvider
...
...
@@ -65,7 +65,7 @@ class BaseProvider(AbstractProvider):
candidates
:
dict
[
str
,
Iterator
[
Candidate
]],
information
:
dict
[
str
,
Iterator
[
RequirementInformation
]],
backtrack_causes
:
Sequence
[
RequirementInformation
],
)
->
Comparable
:
)
->
tuple
[
Comparable
,
...]
:
is_top
=
any
(
parent
is
None
for
_
,
parent
in
information
[
identifier
])
is_backtrack_cause
=
any
(
requirement
.
identify
()
==
identifier
...
...
@@ -134,20 +134,24 @@ class BaseProvider(AbstractProvider):
identifier
:
str
,
requirements
:
Mapping
[
str
,
Iterator
[
Requirement
]],
incompatibilities
:
Mapping
[
str
,
Iterator
[
Candidate
]],
)
->
Iterable
[
Candidate
]:
incompat
=
list
(
incompatibilities
[
identifier
])
if
identifier
==
"python"
:
candidates
=
find_python_matches
(
identifier
,
requirements
)
return
[
c
for
c
in
candidates
if
c
not
in
incompat
]
elif
identifier
in
self
.
overrides
:
return
self
.
get_override_candidates
(
identifier
)
reqs
=
sorted
(
requirements
[
identifier
],
key
=
self
.
requirement_preference
)
candidates
=
self
.
_find_candidates
(
reqs
[
0
])
return
[
can
for
can
in
candidates
if
can
not
in
incompat
and
all
(
self
.
is_satisfied_by
(
r
,
can
)
for
r
in
reqs
)
]
)
->
Callable
[[],
Iterator
[
Candidate
]]:
def
matches_gen
()
->
Iterator
[
Candidate
]:
incompat
=
list
(
incompatibilities
[
identifier
])
if
identifier
==
"python"
:
candidates
=
find_python_matches
(
identifier
,
requirements
)
return
(
c
for
c
in
candidates
if
c
not
in
incompat
)
elif
identifier
in
self
.
overrides
:
return
iter
(
self
.
get_override_candidates
(
identifier
))
reqs
=
sorted
(
requirements
[
identifier
],
key
=
self
.
requirement_preference
)
candidates
=
self
.
_find_candidates
(
reqs
[
0
])
return
(
can
for
can
in
candidates
if
can
not
in
incompat
and
all
(
self
.
is_satisfied_by
(
r
,
can
)
for
r
in
reqs
)
)
return
matches_gen
def
is_satisfied_by
(
self
,
requirement
:
Requirement
,
candidate
:
Candidate
)
->
bool
:
if
isinstance
(
requirement
,
PythonRequirement
):
...
...
@@ -156,15 +160,19 @@ class BaseProvider(AbstractProvider):
return
True
if
not
requirement
.
is_named
:
return
not
candidate
.
req
.
is_named
and
url_without_fragments
(
candidate
.
req
.
url
)
==
url_without_fragments
(
requirement
.
url
)
version
=
candidate
.
version
or
candidate
.
metadata
.
version
candidate
.
req
.
url
# type: ignore
)
==
url_without_fragments
(
requirement
.
url
# type: ignore
)
version
=
candidate
.
version
# Allow prereleases if: 1) it is not specified in the tool settings or
# 2) the candidate doesn't come from PyPI index.
allow_prereleases
=
(
self
.
allow_prereleases
in
(
True
,
None
)
or
not
candidate
.
req
.
is_named
)
return
requirement
.
specifier
.
contains
(
version
,
allow_prereleases
)
return
cast
(
SpecifierSet
,
requirement
.
specifier
).
contains
(
version
,
allow_prereleases
)
def
get_dependencies
(
self
,
candidate
:
Candidate
)
->
list
[
Requirement
]:
if
isinstance
(
candidate
,
PythonCandidate
):
...
...
@@ -222,20 +230,28 @@ class ReusePinProvider(BaseProvider):
identifier
:
str
,
requirements
:
Mapping
[
str
,
Iterator
[
Requirement
]],
incompatibilities
:
Mapping
[
str
,
Iterator
[
Candidate
]],
)
->
Iterable
[
Candidate
]:
)
->
Callable
[[],
Iterator
[
Candidate
]]:
super_find
=
super
().
find_matches
(
identifier
,
requirements
,
incompatibilities
)
bare_name
=
strip_extras
(
identifier
)[
0
]
if
bare_name
not
in
self
.
tracked_names
and
identifier
in
self
.
preferred_pins
:
pin
=
self
.
preferred_pins
[
identifier
]
incompat
=
list
(
incompatibilities
[
identifier
])
demanded_req
=
next
(
requirements
[
identifier
],
None
)
if
demanded_req
and
demanded_req
.
is_named
:
pin
.
req
=
demanded_req
pin
.
_preferred
=
True
if
pin
not
in
incompat
and
all
(
self
.
is_satisfied_by
(
r
,
pin
)
for
r
in
requirements
[
identifier
]
def
matches_gen
()
->
Iterator
[
Candidate
]:
if
(
bare_name
not
in
self
.
tracked_names
and
identifier
in
self
.
preferred_pins
):
yield
pin
yield
from
super
().
find_matches
(
identifier
,
requirements
,
incompatibilities
)
pin
=
self
.
preferred_pins
[
identifier
]
incompat
=
list
(
incompatibilities
[
identifier
])
demanded_req
=
next
(
requirements
[
identifier
],
None
)
if
demanded_req
and
demanded_req
.
is_named
:
pin
.
req
=
demanded_req
pin
.
_preferred
=
True
# type: ignore
if
pin
not
in
incompat
and
all
(
self
.
is_satisfied_by
(
r
,
pin
)
for
r
in
requirements
[
identifier
]
):
yield
pin
yield
from
super_find
()
return
matches_gen
class
EagerUpdateProvider
(
ReusePinProvider
):
...
...
@@ -276,7 +292,7 @@ class EagerUpdateProvider(ReusePinProvider):
candidates
:
dict
[
str
,
Iterator
[
Candidate
]],
information
:
dict
[
str
,
Iterator
[
RequirementInformation
]],
backtrack_causes
:
Sequence
[
RequirementInformation
],
)
->
Comparable
:
)
->
tuple
[
Comparable
,
...]
:
# Resolve tracking packages so we have a chance to unpin them first.
(
python
,
*
others
)
=
super
().
get_preference
(
identifier
,
resolutions
,
candidates
,
information
,
backtrack_causes
...
...
setup.cfg
浏览文件 @
1772f9cd
...
...
@@ -46,4 +46,4 @@ ignore_missing_imports = True
disallow_incomplete_defs = True
disallow_untyped_defs = True
disallow_untyped_decorators = True
exclude = pdm/(pep582/|models/in_process/.+\.py
|resolver/providers\.py
)
exclude = pdm/(pep582/|models/in_process/.+\.py)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录