gh-103857: Update deprecation stacktrace to point to calling line by hugovk · Pull Request #104431 · python/cpython

Conversation

@hugovk

Set up

# From CPython repo:
git clone https://github.com/hugovk/pepotron ../pepotron
./python.exe -m pip install "../pepotron[tests]"

Before

Warnings don't point to the actual lines of code that calls the deprecated utcfromtimestamp and utcnow:

$ ./python.exe -m pytest ../pepotron
...
==================================================================== warnings summary =====================================================================
../../.local/lib/python3.12/site-packages/dateutil/tz/__init__.py:2
  /Users/hugo/.local/lib/python3.12/site-packages/dateutil/tz/__init__.py:2: DeprecationWarning: datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.now(datetime.UTC).
    from .tz import *

tests/test_pepotron.py::test_url[dead batteries-https://peps.python.org/pep-0594/]
tests/test_pepotron.py::test_url_base_url[dead batteries-https://hugovk.github.io/peps-https://hugovk.github.io/peps/pep-0594/]
  /Users/hugo/.local/lib/python3.12/site-packages/pepotron/__init__.py:54: DeprecationWarning: datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.now(datetime.UTC).
    cache_file = _cache.filename(json_url)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
...

After

Now points to the actual lines of code directly calling utcfromtimestamp and utcnow:

$ $ ./python.exe -m pytest ../pepotron
...
==================================================================== warnings summary =====================================================================
../../.local/lib/python3.12/site-packages/dateutil/tz/tz.py:37
  /Users/hugo/.local/lib/python3.12/site-packages/dateutil/tz/tz.py:37: DeprecationWarning: datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.now(datetime.UTC).
    EPOCH = datetime.datetime.utcfromtimestamp(0)

tests/test_pepotron.py::test_url[dead batteries-https://peps.python.org/pep-0594/]
tests/test_pepotron.py::test_url_base_url[dead batteries-https://hugovk.github.io/peps-https://hugovk.github.io/peps/pep-0594/]
  /Users/hugo/.local/lib/python3.12/site-packages/pepotron/_cache.py:30: DeprecationWarning: datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.now(datetime.UTC).
    today = dt.datetime.utcnow().strftime("%Y-%m-%d")

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
...

@pganssle

I think _pydatetime.py presumably needs to be updated as well.

abalkin

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks right.

@abalkin

I think _pydatetime.py presumably needs to be updated as well.

The stacklevel setting in the pure python implementation is actually correct because warning is generated inside a python,rather than a C function in this case:

    def utcfromtimestamp(cls, t):
        """Construct a naive UTC datetime from a POSIX timestamp."""
        import warnings
        warnings.warn("datetime.utcfromtimestamp() is deprecated and scheduled "
                      "for removal in a future version. Use timezone-aware "
                      "objects to represent datetimes in UTC: "
                      "datetime.fromtimestamp(t, datetime.UTC).",
                      DeprecationWarning,
                      stacklevel=2)
        return cls._fromtimestamp(t, True, None)

To test, create the following file:

cat > test_103857.py
import sys
sys.modules['_datetime'] = None
from datetime import datetime

def f():
    return datetime.utcfromtimestamp(0)

f()

and run

% ./python.exe -W always test_103857.py
/Users/a/Work/abalkin/cpython-1/test_103857.py:6: DeprecationWarning: datetime.utcfromtimestamp() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.fromtimestamp(t, datetime.UTC).
  return datetime.utcfromtimestamp(0)

@hugovk hugovk deleted the datetime-deprecations-stacktrace branch

May 13, 2023 14:27