Skip to content

Commit 7f2a54d

Browse files
author
Chad Smith
authored
suppress pip version warning and auto-update shared libraries (#318)
1 parent 72bd386 commit 7f2a54d

File tree

8 files changed

+62
-16
lines changed

8 files changed

+62
-16
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ See Contributing for how to update this file.
2121
<a href="https://travis-ci.org/pipxproject/pipx"><img src="https://travis-ci.org/pipxproject/pipx.svg?branch=master" /></a>
2222

2323
<a href="https://pypi.python.org/pypi/pipx/">
24-
<img src="https://img.shields.io/badge/pypi-0.15.0.1-blue.svg" /></a>
24+
<img src="https://img.shields.io/badge/pypi-0.15.1.0-blue.svg" /></a>
2525
<a href="https://github.com/ambv/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
2626
</p>
2727

docs/changelog.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
0.15.0.1
1+
0.15.1.0
22

3-
- [bugfix] pass pip arguments to pip when determining package name
3+
- Add Python 3.8 to PyPI classifier and travis test matrix
4+
- [feature] auto-upgrade shared libraries, including pip, if older than one month. Hide all pip warnings that a new version is available. (#264)
5+
- [bugfix] pass pip arguments to pip when determining package name (#320)
46

57
0.15.0.0
68

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ See Contributing for how to update this file.
2121
<a href="https://travis-ci.org/pipxproject/pipx"><img src="https://travis-ci.org/pipxproject/pipx.svg?branch=master" /></a>
2222

2323
<a href="https://pypi.python.org/pypi/pipx/">
24-
<img src="https://img.shields.io/badge/pypi-0.15.0.1-blue.svg" /></a>
24+
<img src="https://img.shields.io/badge/pypi-0.15.1.0-blue.svg" /></a>
2525
<a href="https://github.com/ambv/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
2626
</p>
2727

src/pipx/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from .util import PipxError, mkdir
2222
from .venv import VenvContainer
2323

24-
__version__ = "0.15.0.1"
24+
__version__ = "0.15.1.0"
2525

2626

2727
def simple_parse_version(s, segments=4) -> Tuple[Union[int, str], ...]:

src/pipx/shared_libs.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
import logging
22
from pathlib import Path
33
from typing import List
4+
import time
5+
import datetime
46

57
from pipx.animate import animate
68
from pipx.constants import DEFAULT_PYTHON, PIPX_SHARED_LIBS, WINDOWS
79
from pipx.util import get_site_packages, get_venv_paths, run
810

11+
SHARED_LIBS_MAX_AGE_SEC = datetime.timedelta(days=30).total_seconds()
12+
913

1014
class _SharedLibs:
1115
def __init__(self):
1216
self.root = PIPX_SHARED_LIBS
1317
self.bin_path, self.python_path = get_venv_paths(self.root)
18+
self.pip_path = self.bin_path / ("pip" if not WINDOWS else "pip.exe")
1419
# i.e. bin_path is ~/.local/pipx/shared/bin
1520
# i.e. python_path is ~/.local/pipx/shared/python
1621
self._site_packages = None
@@ -31,10 +36,23 @@ def create(self, pip_args: List[str], verbose: bool = False):
3136

3237
@property
3338
def is_valid(self):
34-
return (
35-
self.python_path.is_file()
36-
and (self.bin_path / ("pip" if not WINDOWS else "pip.exe")).is_file()
39+
return self.python_path.is_file() and self.pip_path.is_file()
40+
41+
@property
42+
def needs_upgrade(self):
43+
if self.has_been_updated_this_run:
44+
return False
45+
46+
if not self.pip_path.is_file():
47+
return True
48+
49+
now = time.time()
50+
time_since_last_update_sec = now - self.pip_path.stat().st_mtime
51+
logging.info(
52+
f"Time since last upgrade of shared libs, in seconds: {time_since_last_update_sec}. "
53+
f"Upgrade will be run by pipx if greater than {SHARED_LIBS_MAX_AGE_SEC}."
3754
)
55+
return time_since_last_update_sec > SHARED_LIBS_MAX_AGE_SEC
3856

3957
def upgrade(self, pip_args: List[str], verbose: bool = False):
4058
# Don't try to upgrade multiple times per run
@@ -64,6 +82,8 @@ def upgrade(self, pip_args: List[str], verbose: bool = False):
6482
]
6583
)
6684
self.has_been_updated_this_run = True
85+
self.pip_path.touch()
86+
6787
except Exception:
6888
logging.error("Failed to upgrade shared libraries", exc_info=True)
6989

src/pipx/util.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ def run_subprocess(
103103
# pipx directories to it, and can make it appear to venvs as though
104104
# pipx dependencies are in the venv path (#233)
105105
env = {k: v for k, v in os.environ.items() if k.upper() != "PYTHONPATH"}
106+
env["PIP_DISABLE_PIP_VERSION_CHECK"] = "1"
106107
cmd_str = " ".join(str(c) for c in cmd)
107108
logging.info(f"running {cmd_str}")
108109
# windows cannot take Path objects, only strings

src/pipx/venv.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,16 @@ def __init__(
8888
except StopIteration:
8989
self._existing = False
9090

91-
if self._existing and self.uses_shared_libs and not shared_libs.is_valid:
92-
logging.warning(
93-
f"Shared libraries not found, but are required for package {self.root.name}. "
94-
"Attempting to install now."
95-
)
96-
shared_libs.create([])
91+
if self._existing and self.uses_shared_libs:
9792
if shared_libs.is_valid:
98-
logging.info("Successfully created shared libraries")
93+
if shared_libs.needs_upgrade:
94+
shared_libs.upgrade([], verbose)
9995
else:
96+
shared_libs.create([], verbose)
97+
98+
if not shared_libs.is_valid:
10099
raise PipxError(
101-
f"Error: pipx's shared venv is invalid and "
100+
f"Error: pipx's shared venv {shared_libs.root} is invalid and "
102101
"needs re-installation. To fix this, install or reinstall a "
103102
"package. For example,\n"
104103
f" pipx install {self.root.name} --force"

tests/test_shared_libs.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import os
2+
import time
3+
import pytest # type: ignore
4+
from pipx import shared_libs
5+
6+
7+
now = time.time()
8+
9+
10+
@pytest.mark.parametrize(
11+
"mtime,needs_upgrade",
12+
[
13+
(now - shared_libs.SHARED_LIBS_MAX_AGE_SEC - 600, True),
14+
(now - shared_libs.SHARED_LIBS_MAX_AGE_SEC + 600, False),
15+
],
16+
)
17+
def test_auto_update_shared_libs(capsys, pipx_temp_env, mtime, needs_upgrade):
18+
shared_libs.shared_libs.create([], verbose=True)
19+
shared_libs.shared_libs.has_been_updated_this_run = False
20+
21+
access_time = now # this can be anything
22+
os.utime(shared_libs.shared_libs.pip_path, (access_time, mtime))
23+
24+
assert shared_libs.shared_libs.needs_upgrade is needs_upgrade

0 commit comments

Comments
 (0)