Skip to content

Commit f612503

Browse files
authored
Remove uses of utcnow in non-vendored code (#12006)
* Remove reference to utcnow This cleans up some of the datetime handling in the self check. Note that this changes the format of the state file, since the datetime now uses ``.isoformat()`` instead of ``.strftime``. Reading an outdated state file will still work on Python 3.11+, but not on earlier versions. * Use aware datetime object in x509.CertificateBuilder
1 parent b91cbd1 commit f612503

File tree

4 files changed

+18
-15
lines changed

4 files changed

+18
-15
lines changed

news/12005.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Removed uses of ``datetime.datetime.utcnow`` from non-vendored code.

src/pip/_internal/self_outdated_check.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828
from pip._internal.utils.filesystem import adjacent_tmp_file, check_path_owner, replace
2929
from pip._internal.utils.misc import ensure_dir
3030

31-
_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ"
32-
31+
_WEEK = datetime.timedelta(days=7)
3332

3433
logger = logging.getLogger(__name__)
3534

@@ -73,12 +72,10 @@ def get(self, current_time: datetime.datetime) -> Optional[str]:
7372
if "pypi_version" not in self._state:
7473
return None
7574

76-
seven_days_in_seconds = 7 * 24 * 60 * 60
77-
7875
# Determine if we need to refresh the state
79-
last_check = datetime.datetime.strptime(self._state["last_check"], _DATE_FMT)
80-
seconds_since_last_check = (current_time - last_check).total_seconds()
81-
if seconds_since_last_check > seven_days_in_seconds:
76+
last_check = datetime.datetime.fromisoformat(self._state["last_check"])
77+
time_since_last_check = current_time - last_check
78+
if time_since_last_check > _WEEK:
8279
return None
8380

8481
return self._state["pypi_version"]
@@ -100,7 +97,7 @@ def set(self, pypi_version: str, current_time: datetime.datetime) -> None:
10097
# Include the key so it's easy to tell which pip wrote the
10198
# file.
10299
"key": self.key,
103-
"last_check": current_time.strftime(_DATE_FMT),
100+
"last_check": current_time.isoformat(),
104101
"pypi_version": pypi_version,
105102
}
106103

@@ -229,7 +226,7 @@ def pip_self_version_check(session: PipSession, options: optparse.Values) -> Non
229226
try:
230227
upgrade_prompt = _self_version_check_logic(
231228
state=SelfCheckState(cache_dir=options.cache_dir),
232-
current_time=datetime.datetime.utcnow(),
229+
current_time=datetime.datetime.now(datetime.timezone.utc),
233230
local_version=installed_dist.version,
234231
get_remote_version=functools.partial(
235232
_get_current_remote_pip_version, session, options

tests/lib/certs.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from datetime import datetime, timedelta
1+
from datetime import datetime, timedelta, timezone
22
from typing import Tuple
33

44
from cryptography import x509
@@ -23,8 +23,8 @@ def make_tls_cert(hostname: str) -> Tuple[x509.Certificate, rsa.RSAPrivateKey]:
2323
.issuer_name(issuer)
2424
.public_key(key.public_key())
2525
.serial_number(x509.random_serial_number())
26-
.not_valid_before(datetime.utcnow())
27-
.not_valid_after(datetime.utcnow() + timedelta(days=10))
26+
.not_valid_before(datetime.now(timezone.utc))
27+
.not_valid_after(datetime.now(timezone.utc) + timedelta(days=10))
2828
.add_extension(
2929
x509.SubjectAlternativeName([x509.DNSName(hostname)]),
3030
critical=False,

tests/unit/test_self_check_outdated.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ def test_pip_self_version_check_calls_underlying_implementation(
4949
mocked_state.assert_called_once_with(cache_dir=str(tmpdir))
5050
mocked_function.assert_called_once_with(
5151
state=mocked_state(cache_dir=str(tmpdir)),
52-
current_time=datetime.datetime(1970, 1, 2, 11, 0, 0),
52+
current_time=datetime.datetime(
53+
1970, 1, 2, 11, 0, 0, tzinfo=datetime.timezone.utc
54+
),
5355
local_version=ANY,
5456
get_remote_version=ANY,
5557
)
@@ -167,14 +169,17 @@ def test_writes_expected_statefile(self, tmpdir: Path) -> None:
167169

168170
# WHEN
169171
state = self_outdated_check.SelfCheckState(cache_dir=str(cache_dir))
170-
state.set("1.0.0", datetime.datetime(2000, 1, 1, 0, 0, 0))
172+
state.set(
173+
"1.0.0",
174+
datetime.datetime(2000, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc),
175+
)
171176

172177
# THEN
173178
assert state._statefile_path == os.fspath(expected_path)
174179

175180
contents = expected_path.read_text()
176181
assert json.loads(contents) == {
177182
"key": sys.prefix,
178-
"last_check": "2000-01-01T00:00:00Z",
183+
"last_check": "2000-01-01T00:00:00+00:00",
179184
"pypi_version": "1.0.0",
180185
}

0 commit comments

Comments
 (0)