mirror of https://github.com/pypa/pip
Send log messages >= logging.WARNING to stderr
This commit is contained in:
parent
f82d033b9a
commit
a88bc0de73
|
@ -41,6 +41,8 @@
|
||||||
* Support arch specific wheels that are not tied to a specific Python ABI.
|
* Support arch specific wheels that are not tied to a specific Python ABI.
|
||||||
(:pull:`2561`)
|
(:pull:`2561`)
|
||||||
|
|
||||||
|
* Output warnings and errors to stderr instead of stdout. (:pull:`2543`)
|
||||||
|
|
||||||
|
|
||||||
**6.0.8 (2015-02-04)**
|
**6.0.8 (2015-02-04)**
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ class Command(object):
|
||||||
name = None
|
name = None
|
||||||
usage = None
|
usage = None
|
||||||
hidden = False
|
hidden = False
|
||||||
log_stream = "ext://sys.stdout"
|
log_streams = ("ext://sys.stdout", "ext://sys.stderr")
|
||||||
|
|
||||||
def __init__(self, isolated=False):
|
def __init__(self, isolated=False):
|
||||||
parser_kw = {
|
parser_kw = {
|
||||||
|
@ -124,6 +124,12 @@ class Command(object):
|
||||||
logging_dictConfig({
|
logging_dictConfig({
|
||||||
"version": 1,
|
"version": 1,
|
||||||
"disable_existing_loggers": False,
|
"disable_existing_loggers": False,
|
||||||
|
"filters": {
|
||||||
|
"exclude_warnings": {
|
||||||
|
"()": "pip.utils.logging.MaxLevelFilter",
|
||||||
|
"level": logging.WARNING,
|
||||||
|
},
|
||||||
|
},
|
||||||
"formatters": {
|
"formatters": {
|
||||||
"indent": {
|
"indent": {
|
||||||
"()": IndentingFormatter,
|
"()": IndentingFormatter,
|
||||||
|
@ -138,7 +144,14 @@ class Command(object):
|
||||||
"console": {
|
"console": {
|
||||||
"level": level,
|
"level": level,
|
||||||
"class": "pip.utils.logging.ColorizedStreamHandler",
|
"class": "pip.utils.logging.ColorizedStreamHandler",
|
||||||
"stream": self.log_stream,
|
"stream": self.log_streams[0],
|
||||||
|
"filters": ["exclude_warnings"],
|
||||||
|
"formatter": "indent",
|
||||||
|
},
|
||||||
|
"console_errors": {
|
||||||
|
"level": "WARNING",
|
||||||
|
"class": "pip.utils.logging.ColorizedStreamHandler",
|
||||||
|
"stream": self.log_streams[1],
|
||||||
"formatter": "indent",
|
"formatter": "indent",
|
||||||
},
|
},
|
||||||
"debug_log": {
|
"debug_log": {
|
||||||
|
@ -162,6 +175,7 @@ class Command(object):
|
||||||
"level": level,
|
"level": level,
|
||||||
"handlers": list(filter(None, [
|
"handlers": list(filter(None, [
|
||||||
"console",
|
"console",
|
||||||
|
"console_errors",
|
||||||
"debug_log" if write_debug_log else None,
|
"debug_log" if write_debug_log else None,
|
||||||
"user_log" if options.log else None,
|
"user_log" if options.log else None,
|
||||||
])),
|
])),
|
||||||
|
|
|
@ -16,7 +16,7 @@ class FreezeCommand(Command):
|
||||||
usage = """
|
usage = """
|
||||||
%prog [options]"""
|
%prog [options]"""
|
||||||
summary = 'Output installed packages in requirements format.'
|
summary = 'Output installed packages in requirements format.'
|
||||||
log_stream = "ext://sys.stderr"
|
log_streams = ("ext://sys.stderr", "ext://sys.stderr")
|
||||||
|
|
||||||
def __init__(self, *args, **kw):
|
def __init__(self, *args, **kw):
|
||||||
super(FreezeCommand, self).__init__(*args, **kw)
|
super(FreezeCommand, self).__init__(*args, **kw)
|
||||||
|
|
|
@ -119,3 +119,12 @@ class BetterRotatingFileHandler(logging.handlers.RotatingFileHandler):
|
||||||
os.makedirs(os.path.dirname(self.baseFilename))
|
os.makedirs(os.path.dirname(self.baseFilename))
|
||||||
|
|
||||||
return logging.handlers.RotatingFileHandler._open(self)
|
return logging.handlers.RotatingFileHandler._open(self)
|
||||||
|
|
||||||
|
|
||||||
|
class MaxLevelFilter(logging.Filter):
|
||||||
|
|
||||||
|
def __init__(self, level):
|
||||||
|
self.level = level
|
||||||
|
|
||||||
|
def filter(self, record):
|
||||||
|
return record.levelno < self.level
|
||||||
|
|
|
@ -27,7 +27,7 @@ def test_without_setuptools(script, data):
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
"setuptools must be installed to install from a source distribution"
|
"setuptools must be installed to install from a source distribution"
|
||||||
in result.stdout
|
in result.stderr
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ def test_editable_install(script):
|
||||||
result = script.pip('install', '-e', 'INITools==0.2', expect_error=True)
|
result = script.pip('install', '-e', 'INITools==0.2', expect_error=True)
|
||||||
assert (
|
assert (
|
||||||
"INITools==0.2 should either be a path to a local project or a VCS url"
|
"INITools==0.2 should either be a path to a local project or a VCS url"
|
||||||
in result.stdout
|
in result.stderr
|
||||||
)
|
)
|
||||||
assert not result.files_created
|
assert not result.files_created
|
||||||
assert not result.files_updated
|
assert not result.files_updated
|
||||||
|
@ -205,7 +205,7 @@ def test_bad_install_with_no_download(script):
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
"perhaps --no-download was used without first running "
|
"perhaps --no-download was used without first running "
|
||||||
"an equivalent install with --no-install?" in result.stdout
|
"an equivalent install with --no-install?" in result.stderr
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -310,7 +310,7 @@ def test_install_from_local_directory_with_no_setup_py(script, data):
|
||||||
"""
|
"""
|
||||||
result = script.pip('install', data.root, expect_error=True)
|
result = script.pip('install', data.root, expect_error=True)
|
||||||
assert not result.files_created
|
assert not result.files_created
|
||||||
assert "is not installable. File 'setup.py' not found." in result.stdout
|
assert "is not installable. File 'setup.py' not found." in result.stderr
|
||||||
|
|
||||||
|
|
||||||
def test_editable_install_from_local_directory_with_no_setup_py(script, data):
|
def test_editable_install_from_local_directory_with_no_setup_py(script, data):
|
||||||
|
@ -319,7 +319,7 @@ def test_editable_install_from_local_directory_with_no_setup_py(script, data):
|
||||||
"""
|
"""
|
||||||
result = script.pip('install', '-e', data.root, expect_error=True)
|
result = script.pip('install', '-e', data.root, expect_error=True)
|
||||||
assert not result.files_created
|
assert not result.files_created
|
||||||
assert "is not installable. File 'setup.py' not found." in result.stdout
|
assert "is not installable. File 'setup.py' not found." in result.stderr
|
||||||
|
|
||||||
|
|
||||||
def test_install_as_egg(script, data):
|
def test_install_as_egg(script, data):
|
||||||
|
@ -508,7 +508,9 @@ def test_install_package_with_target(script):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test repeated call without --upgrade, no files should have changed
|
# Test repeated call without --upgrade, no files should have changed
|
||||||
result = script.pip_install_local('-t', target_dir, "simple==1.0")
|
result = script.pip_install_local(
|
||||||
|
'-t', target_dir, "simple==1.0", expect_stderr=True,
|
||||||
|
)
|
||||||
assert not Path('scratch') / 'target' / 'simple' in result.files_updated
|
assert not Path('scratch') / 'target' / 'simple' in result.files_updated
|
||||||
|
|
||||||
# Test upgrade call, check that new version is installed
|
# Test upgrade call, check that new version is installed
|
||||||
|
@ -658,6 +660,7 @@ def test_url_incorrect_case_file_index(script, data):
|
||||||
"""
|
"""
|
||||||
result = script.pip(
|
result = script.pip(
|
||||||
'install', '--index-url', data.find_links3, "dinner",
|
'install', '--index-url', data.find_links3, "dinner",
|
||||||
|
expect_stderr=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# only Upper-2.0.tar.gz should get installed.
|
# only Upper-2.0.tar.gz should get installed.
|
||||||
|
|
|
@ -80,7 +80,9 @@ def test_no_install_and_download_should_not_leave_build_dir(script):
|
||||||
script.scratch_path.join("downloaded_packages").mkdir()
|
script.scratch_path.join("downloaded_packages").mkdir()
|
||||||
assert not os.path.exists(script.venv_path / 'build')
|
assert not os.path.exists(script.venv_path / 'build')
|
||||||
result = script.pip(
|
result = script.pip(
|
||||||
'install', '--no-install', 'INITools==0.2', '-d', 'downloaded_packages'
|
'install', '--no-install', 'INITools==0.2', '-d',
|
||||||
|
'downloaded_packages',
|
||||||
|
expect_stderr=True,
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
Path('scratch') / 'downloaded_packages/build'
|
Path('scratch') / 'downloaded_packages/build'
|
||||||
|
@ -118,7 +120,10 @@ def test_download_should_not_delete_existing_build_dir(script):
|
||||||
"""
|
"""
|
||||||
script.venv_path.join("build").mkdir()
|
script.venv_path.join("build").mkdir()
|
||||||
script.venv_path.join("build", "somefile.txt").write("I am not empty!")
|
script.venv_path.join("build", "somefile.txt").write("I am not empty!")
|
||||||
script.pip('install', '--no-install', 'INITools==0.2', '-d', '.')
|
script.pip(
|
||||||
|
'install', '--no-install', 'INITools==0.2', '-d', '.',
|
||||||
|
expect_stderr=True,
|
||||||
|
)
|
||||||
with open(script.venv_path / 'build' / 'somefile.txt') as fp:
|
with open(script.venv_path / 'build' / 'somefile.txt') as fp:
|
||||||
content = fp.read()
|
content = fp.read()
|
||||||
assert os.path.exists(script.venv_path / 'build'), (
|
assert os.path.exists(script.venv_path / 'build'), (
|
||||||
|
@ -175,5 +180,5 @@ def test_cleanup_prevented_upon_build_dir_exception(script, data):
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result.returncode == PREVIOUS_BUILD_DIR_ERROR
|
assert result.returncode == PREVIOUS_BUILD_DIR_ERROR
|
||||||
assert "pip can't proceed" in result.stdout, result.stdout
|
assert "pip can't proceed" in result.stderr
|
||||||
assert exists(build_simple)
|
assert exists(build_simple)
|
||||||
|
|
|
@ -67,7 +67,7 @@ def test_nonexistent_extra_warns_user_no_wheel(script, data):
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
"simple 3.0 does not provide the extra 'nonexistent'"
|
"simple 3.0 does not provide the extra 'nonexistent'"
|
||||||
in result.stdout
|
in result.stderr
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ def test_nonexistent_extra_warns_user_with_wheel(script, data):
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
"simplewheel 2.0 does not provide the extra 'nonexistent'"
|
"simplewheel 2.0 does not provide the extra 'nonexistent'"
|
||||||
in result.stdout
|
in result.stderr
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,4 +102,4 @@ def test_nonexistent_options_listed_in_order(script, data):
|
||||||
" simplewheel 2.0 does not provide the extra 'nonexistent'\n"
|
" simplewheel 2.0 does not provide the extra 'nonexistent'\n"
|
||||||
" simplewheel 2.0 does not provide the extra 'nope'"
|
" simplewheel 2.0 does not provide the extra 'nope'"
|
||||||
)
|
)
|
||||||
assert msg in result.stdout
|
assert msg in result.stderr
|
||||||
|
|
|
@ -137,6 +137,7 @@ def test_install_local_editable_with_extras(script, data):
|
||||||
res = script.pip(
|
res = script.pip(
|
||||||
'install', '-e', to_install + '[bar]', '--process-dependency-links',
|
'install', '-e', to_install + '[bar]', '--process-dependency-links',
|
||||||
expect_error=False,
|
expect_error=False,
|
||||||
|
expect_stderr=True,
|
||||||
)
|
)
|
||||||
assert script.site_packages / 'easy-install.pth' in res.files_updated, (
|
assert script.site_packages / 'easy-install.pth' in res.files_updated, (
|
||||||
str(res)
|
str(res)
|
||||||
|
|
|
@ -293,8 +293,8 @@ def test_upgrade_vcs_req_with_dist_found(script):
|
||||||
"743aad47656b27"
|
"743aad47656b27"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
script.pip("install", req)
|
script.pip("install", req, expect_stderr=True)
|
||||||
result = script.pip("install", "-U", req)
|
result = script.pip("install", "-U", req, expect_stderr=True)
|
||||||
assert "pypi.python.org" not in result.stdout, result.stdout
|
assert "pypi.python.org" not in result.stdout, result.stdout
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ class Tests_UserSite:
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
"Can not perform a '--user' install. User site-packages are not "
|
"Can not perform a '--user' install. User site-packages are not "
|
||||||
"visible in this virtualenv." in result.stdout
|
"visible in this virtualenv." in result.stderr
|
||||||
)
|
)
|
||||||
|
|
||||||
@pytest.mark.network
|
@pytest.mark.network
|
||||||
|
@ -288,5 +288,5 @@ class Tests_UserSite:
|
||||||
assert (
|
assert (
|
||||||
"Will not install to the user site because it will lack sys.path "
|
"Will not install to the user site because it will lack sys.path "
|
||||||
"precedence to %s in %s" %
|
"precedence to %s in %s" %
|
||||||
('INITools', dist_location) in result2.stdout
|
('INITools', dist_location) in result2.stderr
|
||||||
), result2.stdout
|
)
|
||||||
|
|
|
@ -56,7 +56,8 @@ def test_git_with_sha1_revisions(script):
|
||||||
script.pip(
|
script.pip(
|
||||||
'install', '-e',
|
'install', '-e',
|
||||||
'%s@%s#egg=version_pkg' %
|
'%s@%s#egg=version_pkg' %
|
||||||
('git+file://' + version_pkg_path.abspath.replace('\\', '/'), sha1)
|
('git+file://' + version_pkg_path.abspath.replace('\\', '/'), sha1),
|
||||||
|
expect_stderr=True
|
||||||
)
|
)
|
||||||
version = script.run('version_pkg')
|
version = script.run('version_pkg')
|
||||||
assert '0.1' in version.stdout, version.stdout
|
assert '0.1' in version.stdout, version.stdout
|
||||||
|
|
|
@ -17,7 +17,10 @@ def test_install_from_future_wheel_version(script, data):
|
||||||
editable=False)
|
editable=False)
|
||||||
|
|
||||||
package = data.packages.join("futurewheel-1.9-py2.py3-none-any.whl")
|
package = data.packages.join("futurewheel-1.9-py2.py3-none-any.whl")
|
||||||
result = script.pip('install', package, '--no-index', expect_error=False)
|
result = script.pip(
|
||||||
|
'install', package, '--no-index', expect_error=False,
|
||||||
|
expect_stderr=True,
|
||||||
|
)
|
||||||
result.assert_installed('futurewheel', without_egg_link=True,
|
result.assert_installed('futurewheel', without_egg_link=True,
|
||||||
editable=False)
|
editable=False)
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,8 @@ def test_uptodate_flag(script, data):
|
||||||
'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package'
|
'git+https://github.com/pypa/pip-test-package.git#egg=pip-test-package'
|
||||||
)
|
)
|
||||||
result = script.pip(
|
result = script.pip(
|
||||||
'list', '-f', data.find_links, '--no-index', '--uptodate'
|
'list', '-f', data.find_links, '--no-index', '--uptodate',
|
||||||
|
expect_stderr=True,
|
||||||
)
|
)
|
||||||
assert 'simple (1.0)' not in result.stdout # 3.0 is latest
|
assert 'simple (1.0)' not in result.stdout # 3.0 is latest
|
||||||
assert 'pip-test-package' not in result.stdout # editables excluded
|
assert 'pip-test-package' not in result.stdout # editables excluded
|
||||||
|
@ -78,6 +79,7 @@ def test_outdated_flag(script, data):
|
||||||
)
|
)
|
||||||
result = script.pip(
|
result = script.pip(
|
||||||
'list', '-f', data.find_links, '--no-index', '--outdated',
|
'list', '-f', data.find_links, '--no-index', '--outdated',
|
||||||
|
expect_stderr=True,
|
||||||
)
|
)
|
||||||
assert 'simple (Current: 1.0 Latest: 3.0 [sdist])' in result.stdout
|
assert 'simple (Current: 1.0 Latest: 3.0 [sdist])' in result.stdout
|
||||||
assert 'simplewheel (Current: 1.0 Latest: 2.0 [wheel])' in result.stdout
|
assert 'simplewheel (Current: 1.0 Latest: 2.0 [wheel])' in result.stdout
|
||||||
|
|
|
@ -129,7 +129,7 @@ def test_search_missing_argument(script):
|
||||||
Test missing required argument for search
|
Test missing required argument for search
|
||||||
"""
|
"""
|
||||||
result = script.pip('search', expect_error=True)
|
result = script.pip('search', expect_error=True)
|
||||||
assert 'ERROR: Missing required argument (search query).' in result.stdout
|
assert 'ERROR: Missing required argument (search query).' in result.stderr
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.network
|
@pytest.mark.network
|
||||||
|
|
|
@ -67,7 +67,7 @@ def test_missing_argument(script):
|
||||||
Test show command with no arguments.
|
Test show command with no arguments.
|
||||||
"""
|
"""
|
||||||
result = script.pip('show', expect_error=True)
|
result = script.pip('show', expect_error=True)
|
||||||
assert 'ERROR: Please provide a package name or names.' in result.stdout
|
assert 'ERROR: Please provide a package name or names.' in result.stderr
|
||||||
|
|
||||||
|
|
||||||
def test_find_package_not_found():
|
def test_find_package_not_found():
|
||||||
|
|
|
@ -47,7 +47,7 @@ def test_simple_uninstall_distutils(script):
|
||||||
result = script.run('python', pkg_path / 'setup.py', 'install')
|
result = script.run('python', pkg_path / 'setup.py', 'install')
|
||||||
result = script.pip('list')
|
result = script.pip('list')
|
||||||
assert "distutils-install (0.1)" in result.stdout
|
assert "distutils-install (0.1)" in result.stdout
|
||||||
script.pip('uninstall', 'distutils_install', '-y')
|
script.pip('uninstall', 'distutils_install', '-y', expect_stderr=True)
|
||||||
result2 = script.pip('list')
|
result2 = script.pip('list')
|
||||||
assert "distutils-install (0.1)" not in result2.stdout
|
assert "distutils-install (0.1)" not in result2.stdout
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ def test_pip_wheel_fails_without_wheel(script, data):
|
||||||
'wheel', '--no-index', '-f', data.find_links, 'simple==3.0',
|
'wheel', '--no-index', '-f', data.find_links, 'simple==3.0',
|
||||||
expect_error=True,
|
expect_error=True,
|
||||||
)
|
)
|
||||||
assert "'pip wheel' requires the 'wheel' package" in result.stdout
|
assert "'pip wheel' requires the 'wheel' package" in result.stderr
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.network
|
@pytest.mark.network
|
||||||
|
|
Loading…
Reference in New Issue