mirror of
https://github.com/pypa/pip
synced 2023-12-13 21:30:23 +01:00
Merge pull request #7499 from chrahunt/feature/add-old-entrypoints
Add old pip entrypoints
This commit is contained in:
commit
3f4bb75fa4
2
news/7498.feature
Normal file
2
news/7498.feature
Normal file
|
@ -0,0 +1,2 @@
|
|||
Define all old pip console script entrypoints to prevent import issues in
|
||||
stale wrapper scripts.
|
8
setup.py
8
setup.py
|
@ -70,9 +70,11 @@ setup(
|
|||
},
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"pip=pip._internal.main:main",
|
||||
"pip{}=pip._internal.main:main".format(sys.version_info[0]),
|
||||
"pip{}.{}=pip._internal.main:main".format(*sys.version_info[:2]),
|
||||
"pip=pip._internal.cli.main:main",
|
||||
"pip{}=pip._internal.cli.main:main".format(sys.version_info[0]),
|
||||
"pip{}.{}=pip._internal.cli.main:main".format(
|
||||
*sys.version_info[:2]
|
||||
),
|
||||
],
|
||||
},
|
||||
|
||||
|
|
|
@ -1 +1,18 @@
|
|||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import List, Optional
|
||||
|
||||
|
||||
__version__ = "20.0.dev0"
|
||||
|
||||
|
||||
def main(args=None):
|
||||
# type: (Optional[List[str]]) -> int
|
||||
"""This is an internal API only meant for use by pip's own console scripts.
|
||||
|
||||
For additional details, see https://github.com/pypa/pip/issues/7498.
|
||||
"""
|
||||
from pip._internal.utils.entrypoints import _wrapper
|
||||
|
||||
return _wrapper(args)
|
||||
|
|
|
@ -13,7 +13,7 @@ if __package__ == '':
|
|||
path = os.path.dirname(os.path.dirname(__file__))
|
||||
sys.path.insert(0, path)
|
||||
|
||||
from pip._internal.main import main as _main # isort:skip # noqa
|
||||
from pip._internal.cli.main import main as _main # isort:skip # noqa
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(_main())
|
||||
|
|
|
@ -1,2 +1,18 @@
|
|||
#!/usr/bin/env python
|
||||
import pip._internal.utils.inject_securetransport # noqa
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import Optional, List
|
||||
|
||||
|
||||
def main(args=None):
|
||||
# type: (Optional[List[str]]) -> int
|
||||
"""This is preserved for old console scripts that may still be referencing
|
||||
it.
|
||||
|
||||
For additional details, see https://github.com/pypa/pip/issues/7498.
|
||||
"""
|
||||
from pip._internal.utils.entrypoints import _wrapper
|
||||
|
||||
return _wrapper(args)
|
||||
|
|
75
src/pip/_internal/cli/main.py
Normal file
75
src/pip/_internal/cli/main.py
Normal file
|
@ -0,0 +1,75 @@
|
|||
"""Primary application entrypoint.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import locale
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from pip._internal.cli.autocompletion import autocomplete
|
||||
from pip._internal.cli.main_parser import parse_command
|
||||
from pip._internal.commands import create_command
|
||||
from pip._internal.exceptions import PipError
|
||||
from pip._internal.utils import deprecation
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import List, Optional
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Do not import and use main() directly! Using it directly is actively
|
||||
# discouraged by pip's maintainers. The name, location and behavior of
|
||||
# this function is subject to change, so calling it directly is not
|
||||
# portable across different pip versions.
|
||||
|
||||
# In addition, running pip in-process is unsupported and unsafe. This is
|
||||
# elaborated in detail at
|
||||
# https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program.
|
||||
# That document also provides suggestions that should work for nearly
|
||||
# all users that are considering importing and using main() directly.
|
||||
|
||||
# However, we know that certain users will still want to invoke pip
|
||||
# in-process. If you understand and accept the implications of using pip
|
||||
# in an unsupported manner, the best approach is to use runpy to avoid
|
||||
# depending on the exact location of this entry point.
|
||||
|
||||
# The following example shows how to use runpy to invoke pip in that
|
||||
# case:
|
||||
#
|
||||
# sys.argv = ["pip", your, args, here]
|
||||
# runpy.run_module("pip", run_name="__main__")
|
||||
#
|
||||
# Note that this will exit the process after running, unlike a direct
|
||||
# call to main. As it is not safe to do any processing after calling
|
||||
# main, this should not be an issue in practice.
|
||||
|
||||
def main(args=None):
|
||||
# type: (Optional[List[str]]) -> int
|
||||
if args is None:
|
||||
args = sys.argv[1:]
|
||||
|
||||
# Configure our deprecation warnings to be sent through loggers
|
||||
deprecation.install_warning_logger()
|
||||
|
||||
autocomplete()
|
||||
|
||||
try:
|
||||
cmd_name, cmd_args = parse_command(args)
|
||||
except PipError as exc:
|
||||
sys.stderr.write("ERROR: %s" % exc)
|
||||
sys.stderr.write(os.linesep)
|
||||
sys.exit(1)
|
||||
|
||||
# Needed for locale.getpreferredencoding(False) to work
|
||||
# in pip._internal.utils.encoding.auto_decode
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
except locale.Error as e:
|
||||
# setlocale can apparently crash if locale are uninitialized
|
||||
logger.debug("Ignoring error %s when setting locale", e)
|
||||
command = create_command(cmd_name, isolated=("--isolated" in cmd_args))
|
||||
|
||||
return command.main(cmd_args)
|
|
@ -1,75 +1,16 @@
|
|||
"""Primary application entrypoint.
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import locale
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from pip._internal.cli.autocompletion import autocomplete
|
||||
from pip._internal.cli.main_parser import parse_command
|
||||
from pip._internal.commands import create_command
|
||||
from pip._internal.exceptions import PipError
|
||||
from pip._internal.utils import deprecation
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import List, Optional
|
||||
from typing import Optional, List
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Do not import and use main() directly! Using it directly is actively
|
||||
# discouraged by pip's maintainers. The name, location and behavior of
|
||||
# this function is subject to change, so calling it directly is not
|
||||
# portable across different pip versions.
|
||||
|
||||
# In addition, running pip in-process is unsupported and unsafe. This is
|
||||
# elaborated in detail at
|
||||
# https://pip.pypa.io/en/stable/user_guide/#using-pip-from-your-program.
|
||||
# That document also provides suggestions that should work for nearly
|
||||
# all users that are considering importing and using main() directly.
|
||||
|
||||
# However, we know that certain users will still want to invoke pip
|
||||
# in-process. If you understand and accept the implications of using pip
|
||||
# in an unsupported manner, the best approach is to use runpy to avoid
|
||||
# depending on the exact location of this entry point.
|
||||
|
||||
# The following example shows how to use runpy to invoke pip in that
|
||||
# case:
|
||||
#
|
||||
# sys.argv = ["pip", your, args, here]
|
||||
# runpy.run_module("pip", run_name="__main__")
|
||||
#
|
||||
# Note that this will exit the process after running, unlike a direct
|
||||
# call to main. As it is not safe to do any processing after calling
|
||||
# main, this should not be an issue in practice.
|
||||
|
||||
def main(args=None):
|
||||
# type: (Optional[List[str]]) -> int
|
||||
if args is None:
|
||||
args = sys.argv[1:]
|
||||
"""This is preserved for old console scripts that may still be referencing
|
||||
it.
|
||||
|
||||
# Configure our deprecation warnings to be sent through loggers
|
||||
deprecation.install_warning_logger()
|
||||
For additional details, see https://github.com/pypa/pip/issues/7498.
|
||||
"""
|
||||
from pip._internal.utils.entrypoints import _wrapper
|
||||
|
||||
autocomplete()
|
||||
|
||||
try:
|
||||
cmd_name, cmd_args = parse_command(args)
|
||||
except PipError as exc:
|
||||
sys.stderr.write("ERROR: %s" % exc)
|
||||
sys.stderr.write(os.linesep)
|
||||
sys.exit(1)
|
||||
|
||||
# Needed for locale.getpreferredencoding(False) to work
|
||||
# in pip._internal.utils.encoding.auto_decode
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
except locale.Error as e:
|
||||
# setlocale can apparently crash if locale are uninitialized
|
||||
logger.debug("Ignoring error %s when setting locale", e)
|
||||
command = create_command(cmd_name, isolated=("--isolated" in cmd_args))
|
||||
|
||||
return command.main(cmd_args)
|
||||
return _wrapper(args)
|
||||
|
|
31
src/pip/_internal/utils/entrypoints.py
Normal file
31
src/pip/_internal/utils/entrypoints.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
import sys
|
||||
|
||||
from pip._internal.cli.main import main
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import Optional, List
|
||||
|
||||
|
||||
def _wrapper(args=None):
|
||||
# type: (Optional[List[str]]) -> int
|
||||
"""Central wrapper for all old entrypoints.
|
||||
|
||||
Historically pip has had several entrypoints defined. Because of issues
|
||||
arising from PATH, sys.path, multiple Pythons, their interactions, and most
|
||||
of them having a pip installed, users suffer every time an entrypoint gets
|
||||
moved.
|
||||
|
||||
To alleviate this pain, and provide a mechanism for warning users and
|
||||
directing them to an appropriate place for help, we now define all of
|
||||
our old entrypoints as wrappers for the current one.
|
||||
"""
|
||||
sys.stderr.write(
|
||||
"WARNING: pip is being invoked by an old script wrapper. This will "
|
||||
"fail in a future version of pip.\n"
|
||||
"Please see https://github.com/pypa/pip/issues/5599 for advice on "
|
||||
"fixing the underlying issue.\n"
|
||||
"To avoid this problem you can invoke Python with '-m pip' instead of "
|
||||
"running pip directly.\n"
|
||||
)
|
||||
return main(args)
|
|
@ -13,7 +13,7 @@ import six
|
|||
from pip._vendor.contextlib2 import ExitStack
|
||||
from setuptools.wheel import Wheel
|
||||
|
||||
from pip._internal.main import main as pip_entry_point
|
||||
from pip._internal.cli.main import main as pip_entry_point
|
||||
from pip._internal.utils.temp_dir import global_tempdir_manager
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
from tests.lib import DATA_DIR, SRC_DIR, TestData
|
||||
|
|
34
tests/functional/test_cli.py
Normal file
34
tests/functional/test_cli.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
"""Basic CLI functionality checks.
|
||||
"""
|
||||
from textwrap import dedent
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.parametrize("entrypoint", [
|
||||
("fake_pip = pip._internal.main:main",),
|
||||
("fake_pip = pip._internal:main",),
|
||||
("fake_pip = pip:main",),
|
||||
])
|
||||
def test_entrypoints_work(entrypoint, script):
|
||||
fake_pkg = script.temp_path / "fake_pkg"
|
||||
fake_pkg.mkdir()
|
||||
fake_pkg.joinpath("setup.py").write_text(dedent("""
|
||||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
name="fake-pip",
|
||||
version="0.1.0",
|
||||
entry_points={{
|
||||
"console_scripts": [
|
||||
{!r}
|
||||
]
|
||||
}}
|
||||
)
|
||||
""".format(entrypoint)))
|
||||
|
||||
script.pip("install", "-vvv", str(fake_pkg))
|
||||
result = script.pip("-V")
|
||||
result2 = script.run("fake_pip", "-V", allow_stderr_warning=True)
|
||||
assert result.stdout == result2.stdout
|
||||
assert "old script wrapper" in result2.stderr
|
|
@ -4,9 +4,9 @@ from contextlib import contextmanager
|
|||
import pytest
|
||||
|
||||
import pip._internal.configuration
|
||||
from pip._internal.cli.main import main
|
||||
from pip._internal.commands import create_command
|
||||
from pip._internal.exceptions import PipError
|
||||
from pip._internal.main import main
|
||||
from tests.lib.options_helpers import AddFakeCommandMixin
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue