Skip to content

Commit

Permalink
Remove uses of utcnow in non-vendored code (pypa#12006)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
pganssle authored Aug 31, 2023
1 parent b91cbd1 commit f612503
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 15 deletions.
1 change: 1 addition & 0 deletions news/12005.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Removed uses of ``datetime.datetime.utcnow`` from non-vendored code.
15 changes: 6 additions & 9 deletions src/pip/_internal/self_outdated_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
from pip._internal.utils.filesystem import adjacent_tmp_file, check_path_owner, replace
from pip._internal.utils.misc import ensure_dir

_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ"

_WEEK = datetime.timedelta(days=7)

logger = logging.getLogger(__name__)

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

seven_days_in_seconds = 7 * 24 * 60 * 60

# Determine if we need to refresh the state
last_check = datetime.datetime.strptime(self._state["last_check"], _DATE_FMT)
seconds_since_last_check = (current_time - last_check).total_seconds()
if seconds_since_last_check > seven_days_in_seconds:
last_check = datetime.datetime.fromisoformat(self._state["last_check"])
time_since_last_check = current_time - last_check
if time_since_last_check > _WEEK:
return None

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

Expand Down Expand Up @@ -229,7 +226,7 @@ def pip_self_version_check(session: PipSession, options: optparse.Values) -> Non
try:
upgrade_prompt = _self_version_check_logic(
state=SelfCheckState(cache_dir=options.cache_dir),
current_time=datetime.datetime.utcnow(),
current_time=datetime.datetime.now(datetime.timezone.utc),
local_version=installed_dist.version,
get_remote_version=functools.partial(
_get_current_remote_pip_version, session, options
Expand Down
6 changes: 3 additions & 3 deletions tests/lib/certs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from datetime import datetime, timedelta
from datetime import datetime, timedelta, timezone
from typing import Tuple

from cryptography import x509
Expand All @@ -23,8 +23,8 @@ def make_tls_cert(hostname: str) -> Tuple[x509.Certificate, rsa.RSAPrivateKey]:
.issuer_name(issuer)
.public_key(key.public_key())
.serial_number(x509.random_serial_number())
.not_valid_before(datetime.utcnow())
.not_valid_after(datetime.utcnow() + timedelta(days=10))
.not_valid_before(datetime.now(timezone.utc))
.not_valid_after(datetime.now(timezone.utc) + timedelta(days=10))
.add_extension(
x509.SubjectAlternativeName([x509.DNSName(hostname)]),
critical=False,
Expand Down
11 changes: 8 additions & 3 deletions tests/unit/test_self_check_outdated.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ def test_pip_self_version_check_calls_underlying_implementation(
mocked_state.assert_called_once_with(cache_dir=str(tmpdir))
mocked_function.assert_called_once_with(
state=mocked_state(cache_dir=str(tmpdir)),
current_time=datetime.datetime(1970, 1, 2, 11, 0, 0),
current_time=datetime.datetime(
1970, 1, 2, 11, 0, 0, tzinfo=datetime.timezone.utc
),
local_version=ANY,
get_remote_version=ANY,
)
Expand Down Expand Up @@ -167,14 +169,17 @@ def test_writes_expected_statefile(self, tmpdir: Path) -> None:

# WHEN
state = self_outdated_check.SelfCheckState(cache_dir=str(cache_dir))
state.set("1.0.0", datetime.datetime(2000, 1, 1, 0, 0, 0))
state.set(
"1.0.0",
datetime.datetime(2000, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc),
)

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

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

0 comments on commit f612503

Please sign in to comment.