Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
镜像
Python_Packaging_Authority
pip
提交
a8510bc5
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,发现更多精彩内容 >>
未验证
提交
a8510bc5
编写于
7月 02, 2019
作者:
C
Chris Jerdonek
提交者:
GitHub
7月 02, 2019
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #6638 from cjerdonek/debug-command
Add a "pip debug" command
上级
ec73d72f
d67acca7
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
251 addition
and
37 deletion
+251
-37
news/6638.feature
news/6638.feature
+2
-0
src/pip/_internal/cli/base_command.py
src/pip/_internal/cli/base_command.py
+1
-11
src/pip/_internal/cli/cmdoptions.py
src/pip/_internal/cli/cmdoptions.py
+22
-0
src/pip/_internal/cli/main_parser.py
src/pip/_internal/cli/main_parser.py
+2
-8
src/pip/_internal/commands/__init__.py
src/pip/_internal/commands/__init__.py
+2
-0
src/pip/_internal/commands/debug.py
src/pip/_internal/commands/debug.py
+102
-0
src/pip/_internal/commands/download.py
src/pip/_internal/commands/download.py
+4
-8
src/pip/_internal/commands/install.py
src/pip/_internal/commands/install.py
+4
-8
src/pip/_internal/models/target_python.py
src/pip/_internal/models/target_python.py
+26
-2
src/pip/_internal/utils/misc.py
src/pip/_internal/utils/misc.py
+13
-0
tests/functional/test_debug.py
tests/functional/test_debug.py
+50
-0
tests/unit/test_target_python.py
tests/unit/test_target_python.py
+23
-0
未找到文件。
news/6638.feature
0 → 100644
浏览文件 @
a8510bc5
Add
a
new command ``pip debug`` that can display e.g. the list of compatible
tags
for
the
current
Python.
src/pip/_internal/cli/base_command.py
浏览文件 @
a8510bc5
...
...
@@ -324,10 +324,7 @@ class RequirementCommand(Command):
self
,
options
,
# type: Values
session
,
# type: PipSession
platform
=
None
,
# type: Optional[str]
py_version_info
=
None
,
# type: Optional[Tuple[int, ...]]
abi
=
None
,
# type: Optional[str]
implementation
=
None
,
# type: Optional[str]
target_python
=
None
,
# type: Optional[TargetPython]
ignore_requires_python
=
None
,
# type: Optional[bool]
):
# type: (...) -> PackageFinder
...
...
@@ -346,13 +343,6 @@ class RequirementCommand(Command):
ignore_requires_python
=
ignore_requires_python
,
)
target_python
=
TargetPython
(
platform
=
platform
,
py_version_info
=
py_version_info
,
abi
=
abi
,
implementation
=
implementation
,
)
return
PackageFinder
.
create
(
search_scope
=
search_scope
,
selection_prefs
=
selection_prefs
,
...
...
src/pip/_internal/cli/cmdoptions.py
浏览文件 @
a8510bc5
...
...
@@ -22,6 +22,7 @@ from pip._internal.locations import USER_CACHE_DIR, src_prefix
from
pip._internal.models.format_control
import
FormatControl
from
pip._internal.models.index
import
PyPI
from
pip._internal.models.search_scope
import
SearchScope
from
pip._internal.models.target_python
import
TargetPython
from
pip._internal.utils.hashes
import
STRONG_HASHES
from
pip._internal.utils.misc
import
redact_password_from_url
from
pip._internal.utils.typing
import
MYPY_CHECK_RUNNING
...
...
@@ -356,6 +357,7 @@ def find_links():
def
make_search_scope
(
options
,
suppress_no_index
=
False
):
# type: (Values, bool) -> SearchScope
"""
:param suppress_no_index: Whether to ignore the --no-index option
when constructing the SearchScope object.
...
...
@@ -600,6 +602,26 @@ abi = partial(
)
# type: Callable[..., Option]
def
add_target_python_options
(
cmd_opts
):
# type: (OptionGroup) -> None
cmd_opts
.
add_option
(
platform
())
cmd_opts
.
add_option
(
python_version
())
cmd_opts
.
add_option
(
implementation
())
cmd_opts
.
add_option
(
abi
())
def
make_target_python
(
options
):
# type: (Values) -> TargetPython
target_python
=
TargetPython
(
platform
=
options
.
platform
,
py_version_info
=
options
.
python_version
,
abi
=
options
.
abi
,
implementation
=
options
.
implementation
,
)
return
target_python
def
prefer_binary
():
# type: () -> Option
return
Option
(
...
...
src/pip/_internal/cli/main_parser.py
浏览文件 @
a8510bc5
...
...
@@ -4,7 +4,6 @@
import
os
import
sys
from
pip
import
__version__
from
pip._internal.cli
import
cmdoptions
from
pip._internal.cli.parser
import
(
ConfigOptionParser
,
UpdatingDefaultsHelpFormatter
,
...
...
@@ -13,7 +12,7 @@ from pip._internal.commands import (
commands_dict
,
get_similar_commands
,
get_summaries
,
)
from
pip._internal.exceptions
import
CommandError
from
pip._internal.utils.misc
import
get_prog
from
pip._internal.utils.misc
import
get_p
ip_version
,
get_p
rog
from
pip._internal.utils.typing
import
MYPY_CHECK_RUNNING
if
MYPY_CHECK_RUNNING
:
...
...
@@ -39,12 +38,7 @@ def create_main_parser():
parser
=
ConfigOptionParser
(
**
parser_kw
)
parser
.
disable_interspersed_args
()
pip_pkg_dir
=
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
".."
,
".."
,
))
parser
.
version
=
'pip %s from %s (python %s)'
%
(
__version__
,
pip_pkg_dir
,
sys
.
version
[:
3
],
)
parser
.
version
=
get_pip_version
()
# add the general options
gen_opts
=
cmdoptions
.
make_option_group
(
cmdoptions
.
general_group
,
parser
)
...
...
src/pip/_internal/commands/__init__.py
浏览文件 @
a8510bc5
...
...
@@ -5,6 +5,7 @@ from __future__ import absolute_import
from
pip._internal.commands.completion
import
CompletionCommand
from
pip._internal.commands.configuration
import
ConfigurationCommand
from
pip._internal.commands.debug
import
DebugCommand
from
pip._internal.commands.download
import
DownloadCommand
from
pip._internal.commands.freeze
import
FreezeCommand
from
pip._internal.commands.hash
import
HashCommand
...
...
@@ -36,6 +37,7 @@ commands_order = [
WheelCommand
,
HashCommand
,
CompletionCommand
,
DebugCommand
,
HelpCommand
,
]
# type: List[Type[Command]]
...
...
src/pip/_internal/commands/debug.py
0 → 100644
浏览文件 @
a8510bc5
from
__future__
import
absolute_import
import
logging
import
sys
from
pip._internal.cli
import
cmdoptions
from
pip._internal.cli.base_command
import
Command
from
pip._internal.cli.cmdoptions
import
make_target_python
from
pip._internal.cli.status_codes
import
SUCCESS
from
pip._internal.utils.logging
import
indent_log
from
pip._internal.utils.misc
import
get_pip_version
from
pip._internal.utils.typing
import
MYPY_CHECK_RUNNING
from
pip._internal.wheel
import
format_tag
if
MYPY_CHECK_RUNNING
:
from
typing
import
Any
,
List
from
optparse
import
Values
logger
=
logging
.
getLogger
(
__name__
)
def
show_value
(
name
,
value
):
# type: (str, str) -> None
logger
.
info
(
'{}: {}'
.
format
(
name
,
value
))
def
show_sys_implementation
():
# type: () -> None
logger
.
info
(
'sys.implementation:'
)
if
hasattr
(
sys
,
'implementation'
):
implementation
=
sys
.
implementation
# type: ignore
implementation_name
=
implementation
.
name
else
:
implementation_name
=
''
with
indent_log
():
show_value
(
'name'
,
implementation_name
)
def
show_tags
(
options
):
# type: (Values) -> None
tag_limit
=
10
target_python
=
make_target_python
(
options
)
tags
=
target_python
.
get_tags
()
# Display the target options that were explicitly provided.
formatted_target
=
target_python
.
format_given
()
suffix
=
''
if
formatted_target
:
suffix
=
' (target: {})'
.
format
(
formatted_target
)
msg
=
'Compatible tags: {}{}'
.
format
(
len
(
tags
),
suffix
)
logger
.
info
(
msg
)
if
options
.
verbose
<
1
and
len
(
tags
)
>
tag_limit
:
tags_limited
=
True
tags
=
tags
[:
tag_limit
]
else
:
tags_limited
=
False
with
indent_log
():
for
tag
in
tags
:
logger
.
info
(
format_tag
(
tag
))
if
tags_limited
:
msg
=
(
'...
\n
'
'[First {tag_limit} tags shown. Pass --verbose to show all.]'
).
format
(
tag_limit
=
tag_limit
)
logger
.
info
(
msg
)
class
DebugCommand
(
Command
):
"""
Display debug information.
"""
name
=
'debug'
usage
=
"""
%prog <options>"""
summary
=
'Show information useful for debugging.'
ignore_require_venv
=
True
def
__init__
(
self
,
*
args
,
**
kw
):
super
(
DebugCommand
,
self
).
__init__
(
*
args
,
**
kw
)
cmd_opts
=
self
.
cmd_opts
cmdoptions
.
add_target_python_options
(
cmd_opts
)
self
.
parser
.
insert_option_group
(
0
,
cmd_opts
)
def
run
(
self
,
options
,
args
):
# type: (Values, List[Any]) -> int
show_value
(
'pip version'
,
get_pip_version
())
show_value
(
'sys.version'
,
sys
.
version
)
show_value
(
'sys.executable'
,
sys
.
executable
)
show_value
(
'sys.platform'
,
sys
.
platform
)
show_sys_implementation
()
show_tags
(
options
)
return
SUCCESS
src/pip/_internal/commands/download.py
浏览文件 @
a8510bc5
...
...
@@ -5,6 +5,7 @@ import os
from
pip._internal.cli
import
cmdoptions
from
pip._internal.cli.base_command
import
RequirementCommand
from
pip._internal.cli.cmdoptions
import
make_target_python
from
pip._internal.legacy_resolve
import
Resolver
from
pip._internal.operations.prepare
import
RequirementPreparer
from
pip._internal.req
import
RequirementSet
...
...
@@ -69,10 +70,7 @@ class DownloadCommand(RequirementCommand):
help
=
(
"Download packages into <dir>."
),
)
cmd_opts
.
add_option
(
cmdoptions
.
platform
())
cmd_opts
.
add_option
(
cmdoptions
.
python_version
())
cmd_opts
.
add_option
(
cmdoptions
.
implementation
())
cmd_opts
.
add_option
(
cmdoptions
.
abi
())
cmdoptions
.
add_target_python_options
(
cmd_opts
)
index_opts
=
cmdoptions
.
make_option_group
(
cmdoptions
.
index_group
,
...
...
@@ -96,13 +94,11 @@ class DownloadCommand(RequirementCommand):
ensure_dir
(
options
.
download_dir
)
with
self
.
_build_session
(
options
)
as
session
:
target_python
=
make_target_python
(
options
)
finder
=
self
.
_build_package_finder
(
options
=
options
,
session
=
session
,
platform
=
options
.
platform
,
py_version_info
=
options
.
python_version
,
abi
=
options
.
abi
,
implementation
=
options
.
implementation
,
target_python
=
target_python
,
)
build_delete
=
(
not
(
options
.
no_clean
or
options
.
build_dir
))
if
options
.
cache_dir
and
not
check_path_owner
(
options
.
cache_dir
):
...
...
src/pip/_internal/commands/install.py
浏览文件 @
a8510bc5
...
...
@@ -12,6 +12,7 @@ from pip._vendor import pkg_resources
from
pip._internal.cache
import
WheelCache
from
pip._internal.cli
import
cmdoptions
from
pip._internal.cli.base_command
import
RequirementCommand
from
pip._internal.cli.cmdoptions
import
make_target_python
from
pip._internal.cli.status_codes
import
ERROR
from
pip._internal.exceptions
import
(
CommandError
,
InstallationError
,
PreviousBuildDirError
,
...
...
@@ -114,10 +115,7 @@ class InstallCommand(RequirementCommand):
'<dir>. Use --upgrade to replace existing packages in <dir> '
'with new versions.'
)
cmd_opts
.
add_option
(
cmdoptions
.
platform
())
cmd_opts
.
add_option
(
cmdoptions
.
python_version
())
cmd_opts
.
add_option
(
cmdoptions
.
implementation
())
cmd_opts
.
add_option
(
cmdoptions
.
abi
())
cmdoptions
.
add_target_python_options
(
cmd_opts
)
cmd_opts
.
add_option
(
'--user'
,
...
...
@@ -285,13 +283,11 @@ class InstallCommand(RequirementCommand):
global_options
=
options
.
global_options
or
[]
with
self
.
_build_session
(
options
)
as
session
:
target_python
=
make_target_python
(
options
)
finder
=
self
.
_build_package_finder
(
options
=
options
,
session
=
session
,
platform
=
options
.
platform
,
py_version_info
=
options
.
python_version
,
abi
=
options
.
abi
,
implementation
=
options
.
implementation
,
target_python
=
target_python
,
ignore_requires_python
=
options
.
ignore_requires_python
,
)
build_delete
=
(
not
(
options
.
no_clean
or
options
.
build_dir
))
...
...
src/pip/_internal/models/target_python.py
浏览文件 @
a8510bc5
...
...
@@ -5,7 +5,8 @@ from pip._internal.utils.misc import normalize_version_info
from
pip._internal.utils.typing
import
MYPY_CHECK_RUNNING
if
MYPY_CHECK_RUNNING
:
from
typing
import
Optional
,
Tuple
from
typing
import
List
,
Optional
,
Tuple
from
pip._internal.pep425tags
import
Pep425Tag
class
TargetPython
(
object
):
...
...
@@ -54,9 +55,32 @@ class TargetPython(object):
self
.
py_version_info
=
py_version_info
# This is used to cache the return value of get_tags().
self
.
_valid_tags
=
None
self
.
_valid_tags
=
None
# type: Optional[List[Pep425Tag]]
def
format_given
(
self
):
# type: () -> str
"""
Format the given, non-None attributes for display.
"""
display_version
=
None
if
self
.
_given_py_version_info
is
not
None
:
display_version
=
'.'
.
join
(
str
(
part
)
for
part
in
self
.
_given_py_version_info
)
key_values
=
[
(
'platform'
,
self
.
platform
),
(
'version_info'
,
display_version
),
(
'abi'
,
self
.
abi
),
(
'implementation'
,
self
.
implementation
),
]
return
' '
.
join
(
'{}={!r}'
.
format
(
key
,
value
)
for
key
,
value
in
key_values
if
value
is
not
None
)
def
get_tags
(
self
):
# type: () -> List[Pep425Tag]
"""
Return the supported tags to check wheel candidates against.
"""
...
...
src/pip/_internal/utils/misc.py
浏览文件 @
a8510bc5
...
...
@@ -28,6 +28,7 @@ from pip._vendor.six.moves.urllib import parse as urllib_parse
from
pip._vendor.six.moves.urllib
import
request
as
urllib_request
from
pip._vendor.six.moves.urllib.parse
import
unquote
as
urllib_unquote
from
pip
import
__version__
from
pip._internal.exceptions
import
CommandError
,
InstallationError
from
pip._internal.locations
import
(
running_under_virtualenv
,
site_packages
,
user_site
,
virtualenv_no_global
,
...
...
@@ -104,6 +105,18 @@ except ImportError:
logger
.
debug
(
'lzma module is not available'
)
def
get_pip_version
():
# type: () -> str
pip_pkg_dir
=
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
".."
,
".."
)
pip_pkg_dir
=
os
.
path
.
abspath
(
pip_pkg_dir
)
return
(
'pip {} from {} (python {})'
.
format
(
__version__
,
pip_pkg_dir
,
sys
.
version
[:
3
],
)
)
def
normalize_version_info
(
py_version_info
):
# type: (Optional[Tuple[int, ...]]) -> Optional[Tuple[int, int, int]]
"""
...
...
tests/functional/test_debug.py
0 → 100644
浏览文件 @
a8510bc5
import
pytest
from
pip._internal
import
pep425tags
@
pytest
.
mark
.
parametrize
(
'args'
,
[
[],
[
'--verbose'
],
]
)
def
test_debug
(
script
,
args
):
"""
Check simple option cases.
"""
args
=
[
'debug'
]
+
args
result
=
script
.
pip
(
*
args
)
stdout
=
result
.
stdout
assert
'sys.executable: '
in
stdout
assert
'sys.platform: '
in
stdout
assert
'sys.implementation:'
in
stdout
tags
=
pep425tags
.
get_supported
()
expected_tag_header
=
'Compatible tags: {}'
.
format
(
len
(
tags
))
assert
expected_tag_header
in
stdout
show_verbose_note
=
'--verbose'
not
in
args
assert
(
'...
\n
[First 10 tags shown. Pass --verbose to show all.]'
in
stdout
)
==
show_verbose_note
@
pytest
.
mark
.
parametrize
(
'args, expected'
,
[
([
'--python-version'
,
'3.7'
],
"(target: version_info='3.7')"
),
]
)
def
test_debug__target_options
(
script
,
args
,
expected
):
"""
Check passing target-related options.
"""
args
=
[
'debug'
]
+
args
result
=
script
.
pip
(
*
args
)
stdout
=
result
.
stdout
assert
'Compatible tags: '
in
stdout
assert
expected
in
stdout
tests/unit/test_target_python.py
浏览文件 @
a8510bc5
...
...
@@ -47,6 +47,29 @@ class TestTargetPython:
assert
target_python
.
py_version_info
==
CURRENT_PY_VERSION_INFO
assert
target_python
.
py_version
==
current_major_minor
@
pytest
.
mark
.
parametrize
(
'kwargs, expected'
,
[
({},
''
),
(
dict
(
py_version_info
=
(
3
,
6
)),
"version_info='3.6'"
),
(
dict
(
platform
=
'darwin'
,
py_version_info
=
(
3
,
6
)),
"platform='darwin' version_info='3.6'"
,
),
(
dict
(
platform
=
'darwin'
,
py_version_info
=
(
3
,
6
),
abi
=
'cp36m'
,
implementation
=
'cp'
),
(
"platform='darwin' version_info='3.6' abi='cp36m' "
"implementation='cp'"
),
),
])
def
test_format_given
(
self
,
kwargs
,
expected
):
target_python
=
TargetPython
(
**
kwargs
)
actual
=
target_python
.
format_given
()
assert
actual
==
expected
@
pytest
.
mark
.
parametrize
(
'py_version_info, expected_versions'
,
[
((),
[
''
]),
((
2
,
),
[
'2'
]),
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录