Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
镜像
Python_Packaging_Authority
pip
提交
104b6650
P
pip
项目概览
镜像
/
Python_Packaging_Authority
/
pip
12 个月 前同步成功
通知
0
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
pip
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
104b6650
编写于
3月 19, 2020
作者:
P
Paul Moore
提交者:
GitHub
3月 19, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #7851 from pfmoore/resolvelib_provider
Implement PipProvider
上级
9e15cd49
ffe55363
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
335 addition
and
148 deletion
+335
-148
src/pip/_internal/resolution/resolvelib/base.py
src/pip/_internal/resolution/resolvelib/base.py
+5
-8
src/pip/_internal/resolution/resolvelib/candidates.py
src/pip/_internal/resolution/resolvelib/candidates.py
+126
-0
src/pip/_internal/resolution/resolvelib/provider.py
src/pip/_internal/resolution/resolvelib/provider.py
+83
-0
src/pip/_internal/resolution/resolvelib/requirements.py
src/pip/_internal/resolution/resolvelib/requirements.py
+71
-101
src/pip/_internal/resolution/resolvelib/resolver.py
src/pip/_internal/resolution/resolvelib/resolver.py
+2
-24
tests/functional/test_install.py
tests/functional/test_install.py
+7
-2
tests/unit/resolution_resolvelib/conftest.py
tests/unit/resolution_resolvelib/conftest.py
+15
-0
tests/unit/resolution_resolvelib/test_requirement.py
tests/unit/resolution_resolvelib/test_requirement.py
+26
-13
未找到文件。
src/pip/_internal/resolution/resolvelib/base.py
浏览文件 @
104b6650
...
...
@@ -3,10 +3,10 @@ from pip._vendor.packaging.utils import canonicalize_name
from
pip._internal.utils.typing
import
MYPY_CHECK_RUNNING
if
MYPY_CHECK_RUNNING
:
from
typing
import
(
Sequence
,
Set
)
from
typing
import
Sequence
,
Set
from
pip._internal.req.req_install
import
InstallRequirement
from
pip._vendor.packaging.version
import
_BaseVersion
from
pip._internal.index.package_finder
import
PackageFinder
def
format_name
(
project
,
extras
):
...
...
@@ -23,11 +23,8 @@ class Requirement(object):
# type: () -> str
raise
NotImplementedError
(
"Subclass should override"
)
def
find_matches
(
self
,
finder
,
# type: PackageFinder
):
# type: (...) -> Sequence[Candidate]
def
find_matches
(
self
):
# type: () -> Sequence[Candidate]
raise
NotImplementedError
(
"Subclass should override"
)
def
is_satisfied_by
(
self
,
candidate
):
...
...
@@ -47,5 +44,5 @@ class Candidate(object):
raise
NotImplementedError
(
"Override in subclass"
)
def
get_dependencies
(
self
):
# type: () -> Sequence[Requirement]
# type: () -> Sequence[
Install
Requirement]
raise
NotImplementedError
(
"Override in subclass"
)
src/pip/_internal/resolution/resolvelib/candidates.py
0 → 100644
浏览文件 @
104b6650
from
pip._vendor.packaging.utils
import
canonicalize_name
from
pip._internal.req.constructors
import
install_req_from_line
from
pip._internal.req.req_install
import
InstallRequirement
from
pip._internal.utils.typing
import
MYPY_CHECK_RUNNING
from
.base
import
Candidate
if
MYPY_CHECK_RUNNING
:
from
typing
import
Any
,
Dict
,
Optional
,
Sequence
from
pip._internal.models.link
import
Link
from
pip._internal.operations.prepare
import
RequirementPreparer
from
pip._internal.resolution.base
import
InstallRequirementProvider
from
pip._vendor.packaging.version
import
_BaseVersion
from
pip._vendor.pkg_resources
import
Distribution
_CANDIDATE_CACHE
=
{}
# type: Dict[Link, Candidate]
def
make_candidate
(
link
,
# type: Link
preparer
,
# type: RequirementPreparer
parent
,
# type: InstallRequirement
make_install_req
# type: InstallRequirementProvider
):
# type: (...) -> Candidate
if
link
not
in
_CANDIDATE_CACHE
:
_CANDIDATE_CACHE
[
link
]
=
LinkCandidate
(
link
,
preparer
,
parent
=
parent
,
make_install_req
=
make_install_req
)
return
_CANDIDATE_CACHE
[
link
]
def
make_install_req_from_link
(
link
,
parent
):
# type: (Link, InstallRequirement) -> InstallRequirement
# TODO: Do we need to support editables?
return
install_req_from_line
(
link
.
url
,
comes_from
=
parent
.
comes_from
,
use_pep517
=
parent
.
use_pep517
,
isolated
=
parent
.
isolated
,
wheel_cache
=
parent
.
_wheel_cache
,
constraint
=
parent
.
constraint
,
options
=
dict
(
install_options
=
parent
.
install_options
,
global_options
=
parent
.
global_options
,
hashes
=
parent
.
hash_options
),
)
class
LinkCandidate
(
Candidate
):
def
__init__
(
self
,
link
,
# type: Link
preparer
,
# type: RequirementPreparer
parent
,
# type: InstallRequirement
make_install_req
,
# type: InstallRequirementProvider
):
# type: (...) -> None
self
.
link
=
link
self
.
_preparer
=
preparer
self
.
_ireq
=
make_install_req_from_link
(
link
,
parent
)
self
.
_make_install_req
=
make_install_req
self
.
_name
=
None
# type: Optional[str]
self
.
_version
=
None
# type: Optional[_BaseVersion]
self
.
_dist
=
None
# type: Optional[Distribution]
def
__eq__
(
self
,
other
):
# type: (Any) -> bool
if
isinstance
(
other
,
self
.
__class__
):
return
self
.
link
==
other
.
link
return
False
# Needed for Python 2, which does not implement this by default
def
__ne__
(
self
,
other
):
# type: (Any) -> bool
return
not
self
.
__eq__
(
other
)
@
property
def
name
(
self
):
# type: () -> str
"""The normalised name of the project the candidate refers to"""
if
self
.
_name
is
None
:
self
.
_name
=
canonicalize_name
(
self
.
dist
.
project_name
)
return
self
.
_name
@
property
def
version
(
self
):
# type: () -> _BaseVersion
if
self
.
_version
is
None
:
self
.
_version
=
self
.
dist
.
parsed_version
return
self
.
_version
@
property
def
dist
(
self
):
# type: () -> Distribution
if
self
.
_dist
is
None
:
abstract_dist
=
self
.
_preparer
.
prepare_linked_requirement
(
self
.
_ireq
)
self
.
_dist
=
abstract_dist
.
get_pkg_resources_distribution
()
# TODO: Only InstalledDistribution can return None here :-(
assert
self
.
_dist
is
not
None
# These should be "proper" errors, not just asserts, as they
# can result from user errors like a requirement "foo @ URL"
# when the project at URL has a name of "bar" in its metadata.
assert
(
self
.
_name
is
None
or
self
.
_name
==
canonicalize_name
(
self
.
_dist
.
project_name
))
assert
(
self
.
_version
is
None
or
self
.
_version
==
self
.
dist
.
parsed_version
)
return
self
.
_dist
def
get_dependencies
(
self
):
# type: () -> Sequence[InstallRequirement]
return
[
self
.
_make_install_req
(
str
(
r
),
self
.
_ireq
)
for
r
in
self
.
dist
.
requires
()
]
src/pip/_internal/resolution/resolvelib/provider.py
0 → 100644
浏览文件 @
104b6650
from
pip._vendor.resolvelib.providers
import
AbstractProvider
from
pip._internal.utils.typing
import
MYPY_CHECK_RUNNING
from
.requirements
import
make_requirement
if
MYPY_CHECK_RUNNING
:
from
typing
import
Any
,
Optional
,
Sequence
,
Tuple
,
Union
from
pip._internal.index.package_finder
import
PackageFinder
from
pip._internal.operations.prepare
import
RequirementPreparer
from
pip._internal.req.req_install
import
InstallRequirement
from
pip._internal.resolution.base
import
InstallRequirementProvider
from
.base
import
Requirement
,
Candidate
class
PipProvider
(
AbstractProvider
):
def
__init__
(
self
,
finder
,
# type: PackageFinder
preparer
,
# type: RequirementPreparer
make_install_req
# type: InstallRequirementProvider
):
# type: (...) -> None
self
.
_finder
=
finder
self
.
_preparer
=
preparer
self
.
_make_install_req
=
make_install_req
def
make_requirement
(
self
,
ireq
):
# type: (InstallRequirement) -> Requirement
return
make_requirement
(
ireq
,
self
.
_finder
,
self
.
_preparer
,
self
.
_make_install_req
)
def
get_install_requirement
(
self
,
c
):
# type: (Candidate) -> InstallRequirement
# The base Candidate class does not have an _ireq attribute, so we
# fetch it dynamically here, to satisfy mypy. In practice, though, we
# only ever deal with LinkedCandidate objects at the moment, which do
# have an _ireq attribute. When we have a candidate type for installed
# requirements we should probably review this.
#
# TODO: Longer term, make a proper interface for this on the candidate.
return
getattr
(
c
,
"_ireq"
,
None
)
def
identify
(
self
,
dependency
):
# type: (Union[Requirement, Candidate]) -> str
return
dependency
.
name
def
get_preference
(
self
,
resolution
,
# type: Optional[Candidate]
candidates
,
# type: Sequence[Candidate]
information
# type: Sequence[Tuple[Requirement, Candidate]]
):
# type: (...) -> Any
# Use the "usual" value for now
return
len
(
candidates
)
def
find_matches
(
self
,
requirement
):
# type: (Requirement) -> Sequence[Candidate]
return
requirement
.
find_matches
()
def
is_satisfied_by
(
self
,
requirement
,
candidate
):
# type: (Requirement, Candidate) -> bool
return
requirement
.
is_satisfied_by
(
candidate
)
def
get_dependencies
(
self
,
candidate
):
# type: (Candidate) -> Sequence[Requirement]
return
[
make_requirement
(
r
,
self
.
_finder
,
self
.
_preparer
,
self
.
_make_install_req
)
for
r
in
candidate
.
get_dependencies
()
]
src/pip/_internal/resolution/resolvelib/requirements.py
浏览文件 @
104b6650
from
pip._vendor.packaging.utils
import
canonicalize_name
from
pip._internal.req.req_install
import
InstallRequirement
from
pip._internal.utils.typing
import
MYPY_CHECK_RUNNING
from
.base
import
Candidate
,
Requirement
,
format_name
from
.base
import
Requirement
from
.candidates
import
make_candidate
if
MYPY_CHECK_RUNNING
:
from
typing
import
(
Optional
,
Sequence
)
from
pip._vendor.packaging.version
import
_BaseVersion
from
typing
import
Sequence
from
pip._internal.index.package_finder
import
PackageFinder
def
make_requirement
(
install_req
):
# type: (InstallRequirement) -> Requirement
if
install_req
.
link
:
if
install_req
.
req
and
install_req
.
req
.
name
:
return
NamedRequirement
(
install_req
)
else
:
return
UnnamedRequirement
(
install_req
)
from
pip._internal.operations.prepare
import
RequirementPreparer
from
pip._internal.req.req_install
import
InstallRequirement
from
pip._internal.resolution.base
import
InstallRequirementProvider
from
.base
import
Candidate
def
make_requirement
(
ireq
,
# type: InstallRequirement
finder
,
# type: PackageFinder
preparer
,
# type: RequirementPreparer
make_install_req
# type: InstallRequirementProvider
):
# type: (...) -> Requirement
if
ireq
.
link
:
candidate
=
make_candidate
(
ireq
.
link
,
preparer
,
ireq
,
make_install_req
)
return
ExplicitRequirement
(
candidate
)
else
:
return
VersionedRequirement
(
install_req
)
return
SpecifierRequirement
(
ireq
,
finder
,
preparer
,
make_install_req
)
class
UnnamedRequirement
(
Requirement
):
def
__init__
(
self
,
req
):
# type: (InstallRequirement) -> None
self
.
_ireq
=
req
self
.
_candidate
=
None
# type: Optional[Candidate]
class
ExplicitRequirement
(
Requirement
):
def
__init__
(
self
,
candidate
):
# type: (Candidate) -> None
self
.
candidate
=
candidate
@
property
def
name
(
self
):
# type: () -> str
assert
self
.
_ireq
.
req
is
None
or
self
.
_ireq
.
name
is
None
,
\
"Unnamed requirement has a name"
# TODO: Get the candidate and use its name...
return
""
def
_get_candidate
(
self
):
# type: () -> Candidate
if
self
.
_candidate
is
None
:
self
.
_candidate
=
Candidate
()
return
self
.
_candidate
def
find_matches
(
self
,
finder
,
# type: PackageFinder
):
# type: (...) -> Sequence[Candidate]
return
[
self
.
_get_candidate
()]
# No need to canonicalise - the candidate did this
return
self
.
candidate
.
name
def
find_matches
(
self
):
# type: () -> Sequence[Candidate]
return
[
self
.
candidate
]
def
is_satisfied_by
(
self
,
candidate
):
# type: (Candidate) -> bool
return
candidate
is
self
.
_get_candidate
()
# TODO: Typing - Candidate doesn't have a link attribute
# But I think the following would be better...
# return candidate.link == self.candidate.link
return
candidate
==
self
.
candidate
class
NamedRequirement
(
Requirement
):
def
__init__
(
self
,
req
):
# type: (InstallRequirement) -> None
self
.
_ireq
=
req
self
.
_candidate
=
None
# type: Optional[Candidate]
@
property
def
name
(
self
):
# type: () -> str
assert
self
.
_ireq
.
req
.
name
is
not
None
,
"Named requirement has no name"
canonical_name
=
canonicalize_name
(
self
.
_ireq
.
req
.
name
)
return
format_name
(
canonical_name
,
self
.
_ireq
.
req
.
extras
)
def
_get_candidate
(
self
):
# type: () -> Candidate
if
self
.
_candidate
is
None
:
self
.
_candidate
=
Candidate
()
return
self
.
_candidate
def
find_matches
(
class
SpecifierRequirement
(
Requirement
):
def
__init__
(
self
,
finder
,
# type: PackageFinder
ireq
,
# type: InstallRequirement
finder
,
# type: PackageFinder
preparer
,
# type:RequirementPreparer
make_install_req
# type: InstallRequirementProvider
):
# type: (...) -> Sequence[Candidate]
return
[
self
.
_get_candidate
()]
def
is_satisfied_by
(
self
,
candidate
):
# type: (Candidate) -> bool
return
candidate
is
self
.
_get_candidate
()
# TODO: This is temporary, to make the tests pass
class
DummyCandidate
(
Candidate
):
def
__init__
(
self
,
name
,
version
):
# type: (str, _BaseVersion) -> None
self
.
_name
=
name
self
.
_version
=
version
@
property
def
name
(
self
):
# type: () -> str
return
self
.
_name
@
property
def
version
(
self
):
# type: () -> _BaseVersion
return
self
.
_version
class
VersionedRequirement
(
Requirement
):
def
__init__
(
self
,
ireq
):
# type: (InstallRequirement) -> None
assert
ireq
.
req
is
not
None
,
"Un-specified requirement not allowed"
assert
ireq
.
req
.
url
is
None
,
"Direct reference not allowed"
# type: (...) -> None
assert
ireq
.
link
is
None
,
"This is a link, not a specifier"
assert
not
ireq
.
req
.
extras
,
"Extras not yet supported"
self
.
_ireq
=
ireq
self
.
_finder
=
finder
self
.
_preparer
=
preparer
self
.
_make_install_req
=
make_install_req
@
property
def
name
(
self
):
# type: () -> str
canonical_name
=
canonicalize_name
(
self
.
_ireq
.
req
.
name
)
return
format_name
(
canonical_name
,
self
.
_ireq
.
req
.
extras
)
return
canonical_name
def
find_matches
(
self
,
finder
,
# type: PackageFinder
):
# type: (...) -> Sequence[Candidate]
found
=
finder
.
find_best_candidate
(
def
find_matches
(
self
):
# type: () -> Sequence[Candidate]
found
=
self
.
_finder
.
find_best_candidate
(
project_name
=
self
.
_ireq
.
req
.
name
,
specifier
=
self
.
_ireq
.
req
.
specifier
,
hashes
=
self
.
_ireq
.
hashes
(
trust_internet
=
False
),
)
return
[
DummyCandidate
(
ican
.
name
,
ican
.
version
)
make_candidate
(
ican
.
link
,
self
.
_preparer
,
self
.
_ireq
,
self
.
_make_install_req
)
for
ican
in
found
.
iter_applicable
()
]
def
is_satisfied_by
(
self
,
candidate
):
# type: (Candidate) -> bool
# TODO: Should check name matches as well. Defer this
# until we have the proper Candidate object, and
# no longer have to deal with unnmed requirements...
assert
candidate
.
name
==
self
.
name
,
\
"Internal issue: Candidate is not for this requirement "
\
" {} vs {}"
.
format
(
candidate
.
name
,
self
.
name
)
return
candidate
.
version
in
self
.
_ireq
.
req
.
specifier
src/pip/_internal/resolution/resolvelib/resolver.py
浏览文件 @
104b6650
...
...
@@ -4,7 +4,9 @@ from pip._vendor.packaging.utils import canonicalize_name
from
pip._vendor.resolvelib
import
BaseReporter
from
pip._vendor.resolvelib
import
Resolver
as
RLResolver
from
pip._internal.req.req_set
import
RequirementSet
from
pip._internal.resolution.base
import
BaseResolver
from
pip._internal.resolution.resolvelib.provider
import
PipProvider
from
pip._internal.utils.typing
import
MYPY_CHECK_RUNNING
if
MYPY_CHECK_RUNNING
:
...
...
@@ -15,32 +17,8 @@ if MYPY_CHECK_RUNNING:
from
pip._internal.index.package_finder
import
PackageFinder
from
pip._internal.operations.prepare
import
RequirementPreparer
from
pip._internal.req.req_install
import
InstallRequirement
from
pip._internal.req.req_set
import
RequirementSet
from
pip._internal.resolution.base
import
InstallRequirementProvider
from
.base
import
Candidate
,
Requirement
# FIXME: Import the actual implementation.
# This is a stub to pass typing checks.
class
PipProvider
(
object
):
def
__init__
(
self
,
finder
,
# type: PackageFinder
preparer
,
# type: RequirementPreparer
make_install_req
,
# type: InstallRequirementProvider
):
# type: (...) -> None
super
(
PipProvider
,
self
).
__init__
()
def
make_requirement
(
self
,
r
):
# type: (InstallRequirement) -> Requirement
raise
NotImplementedError
()
def
get_install_requirement
(
self
,
c
):
# type: (Candidate) -> InstallRequirement
raise
NotImplementedError
()
class
Resolver
(
BaseResolver
):
def
__init__
(
...
...
tests/functional/test_install.py
浏览文件 @
104b6650
...
...
@@ -405,12 +405,17 @@ def test_vcs_url_urlquote_normalization(script, tmpdir):
)
def
test_basic_install_from_local_directory
(
script
,
data
):
@
pytest
.
mark
.
parametrize
(
"resolver"
,
[
""
,
"--unstable-feature=resolver"
])
def
test_basic_install_from_local_directory
(
script
,
data
,
resolver
):
"""
Test installing from a local directory.
"""
args
=
[
"install"
]
if
resolver
:
args
.
append
(
resolver
)
to_install
=
data
.
packages
.
joinpath
(
"FSPkg"
)
result
=
script
.
pip
(
'install'
,
to_install
)
args
.
append
(
to_install
)
result
=
script
.
pip
(
*
args
)
fspkg_folder
=
script
.
site_packages
/
'fspkg'
egg_info_folder
=
(
script
.
site_packages
/
...
...
tests/unit/resolution_resolvelib/conftest.py
浏览文件 @
104b6650
from
functools
import
partial
import
pytest
from
pip._internal.cli.req_command
import
RequirementCommand
...
...
@@ -8,7 +10,9 @@ from pip._internal.index.package_finder import PackageFinder
from
pip._internal.models.search_scope
import
SearchScope
from
pip._internal.models.selection_prefs
import
SelectionPreferences
from
pip._internal.network.session
import
PipSession
from
pip._internal.req.constructors
import
install_req_from_req_string
from
pip._internal.req.req_tracker
import
get_requirement_tracker
from
pip._internal.resolution.resolvelib.provider
import
PipProvider
from
pip._internal.utils.temp_dir
import
TempDirectory
,
global_tempdir_manager
...
...
@@ -41,3 +45,14 @@ def preparer(finder):
)
yield
preparer
@
pytest
.
fixture
def
provider
(
finder
,
preparer
):
make_install_req
=
partial
(
install_req_from_req_string
,
isolated
=
False
,
wheel_cache
=
None
,
use_pep517
=
None
,
)
yield
PipProvider
(
finder
,
preparer
,
make_install_req
)
tests/unit/resolution_resolvelib/test_requirement.py
浏览文件 @
104b6650
import
pytest
from
pip._vendor.resolvelib
import
BaseReporter
,
Resolver
from
pip._internal.req.constructors
import
install_req_from_line
from
pip._internal.resolution.resolvelib.base
import
Candidate
...
...
@@ -16,7 +17,6 @@ from pip._internal.utils.urls import path_to_url
# Create a requirement from a sdist filename
# Create a requirement from a local directory (which has no obvious name!)
# Editables
#
@
pytest
.
fixture
...
...
@@ -32,16 +32,17 @@ def test_cases(data):
# Version specifiers
(
"simple"
,
"simple"
,
3
),
(
"simple>1.0"
,
"simple"
,
2
),
(
"simple[extra]==1.0"
,
"simple[extra]"
,
1
),
#
("simple[extra]==1.0", "simple[extra]", 1),
# Wheels
(
data_file
(
"simplewheel-1.0-py2.py3-none-any.whl"
),
"simplewheel"
,
1
),
(
data_url
(
"simplewheel-1.0-py2.py3-none-any.whl"
),
"simplewheel"
,
1
),
# Direct URLs
(
"foo @ "
+
data_url
(
"simple-1.0.tar.gz"
),
"foo"
,
1
),
# TODO: The following test fails
# ("foo @ " + data_url("simple-1.0.tar.gz"), "foo", 1),
# SDists
# TODO: sdists should have a name
(
data_file
(
"simple-1.0.tar.gz"
),
""
,
1
),
(
data_url
(
"simple-1.0.tar.gz"
),
""
,
1
),
(
data_file
(
"simple-1.0.tar.gz"
),
"
simple
"
,
1
),
(
data_url
(
"simple-1.0.tar.gz"
),
"
simple
"
,
1
),
# TODO: directory, editables
]
...
...
@@ -52,24 +53,36 @@ def req_from_line(line):
return
make_requirement
(
install_req_from_line
(
line
))
def
test_rlr_requirement_has_name
(
test_cases
):
def
test_rlr_requirement_has_name
(
test_cases
,
provider
):
"""All requirements should have a name"""
for
requirement
,
name
,
matches
in
test_cases
:
req
=
req_from_line
(
requirement
)
ireq
=
install_req_from_line
(
requirement
)
req
=
provider
.
make_requirement
(
ireq
)
assert
req
.
name
==
name
def
test_rlr_correct_number_of_matches
(
test_cases
,
fin
der
):
def
test_rlr_correct_number_of_matches
(
test_cases
,
provi
der
):
"""Requirements should return the correct number of candidates"""
for
requirement
,
name
,
matches
in
test_cases
:
req
=
req_from_line
(
requirement
)
assert
len
(
req
.
find_matches
(
finder
))
==
matches
ireq
=
install_req_from_line
(
requirement
)
req
=
provider
.
make_requirement
(
ireq
)
assert
len
(
req
.
find_matches
())
==
matches
def
test_rlr_candidates_match_requirement
(
test_cases
,
fin
der
):
def
test_rlr_candidates_match_requirement
(
test_cases
,
provi
der
):
"""Candidates returned from find_matches should satisfy the requirement"""
for
requirement
,
name
,
matches
in
test_cases
:
req
=
req_from_line
(
requirement
)
for
c
in
req
.
find_matches
(
finder
):
ireq
=
install_req_from_line
(
requirement
)
req
=
provider
.
make_requirement
(
ireq
)
for
c
in
req
.
find_matches
():
assert
isinstance
(
c
,
Candidate
)
assert
req
.
is_satisfied_by
(
c
)
def
test_rlr_full_resolve
(
provider
):
"""A very basic full resolve"""
ireq
=
install_req_from_line
(
"simplewheel"
)
req
=
provider
.
make_requirement
(
ireq
)
r
=
Resolver
(
provider
,
BaseReporter
())
result
=
r
.
resolve
([
req
])
assert
set
(
result
.
mapping
.
keys
())
==
{
'simplewheel'
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录