◐ Shell
clean mode source ↗

gh-86298: Ensure that __loader__ and __spec__.loader agree in warnings.warn_explicit() by warsaw · Pull Request #97803 · python/cpython

In _warnings.c, in the C equivalent of warnings.warn_explicit(), if the module
globals are given (and not None), the warning will attempt to get the source
line for the issued warning.  To do this, it needs the module's loader.

Previously, it would only look up `__loader__` in the module globals.  In
python#86298 we want to defer to the
`__spec__.loader` if available.

The first step on this journey is to check that `loader` == `__spec__.loader`
and issue another warning if it is not.  This commit does that.

Since this is a PoC, only manual testing for now.

```python
import warnings

import bar

warnings.warn_explicit(
    'warning!',
    RuntimeWarning,
    'bar.py', 2,
    module='bar knee',
    module_globals=bar.__dict__,
    )
```

```python
import sys
import os
import pathlib

```

Then running this: `./python.exe -Wdefault /tmp/foo.py`

Produces:

```
bar.py:2: RuntimeWarning: warning!
  import os
```

Uncomment the `__loader__ = ` line in `bar.py` and try it again:

```
sys:1: ImportWarning: Module bar; __loader__ != __spec__.loader (<_frozen_importlib_external.SourceFileLoader object at 0x109f7dfa0> != PosixPath('.'))
bar.py:2: RuntimeWarning: warning!
  import os
```

@warsaw warsaw changed the title PoC for checking both __loader__ and __spec__.loader issue-86298: PoC for checking both __loader__ and __spec__.loader

Oct 3, 2022

@warsaw warsaw changed the title issue-86298: PoC for checking both __loader__ and __spec__.loader #86298: PoC for checking both __loader__ and __spec__.loader

Oct 3, 2022

@warsaw warsaw changed the title #86298: PoC for checking both __loader__ and __spec__.loader gh-86298: PoC for checking both __loader__ and __spec__.loader

Oct 3, 2022

@warsaw warsaw marked this pull request as draft

October 3, 2022 22:33

@warsaw warsaw marked this pull request as ready for review

October 4, 2022 00:03

@warsaw

@warsaw warsaw changed the title gh-86298: PoC for checking both __loader__ and __spec__.loader gh-86298: Ensure that __loader__ and __spec__.loader agree in warnings.warn_explicit()

Oct 4, 2022

brettcannon

Note however that the semantics of the helper has changed, and can't be full
on loader blessing... yet.

brettcannon

Co-authored-by: Brett Cannon <brett@python.org>
Co-authored-by: Brett Cannon <brett@python.org>
Co-authored-by: Brett Cannon <brett@python.org>

carljm added a commit to carljm/cpython that referenced this pull request

Oct 8, 2022

mpage pushed a commit to mpage/cpython that referenced this pull request

Oct 11, 2022
…arnings.warn_explicit() (pythonGH-97803)

In `_warnings.c`, in the C equivalent of `warnings.warn_explicit()`, if the module globals are given (and not None), the warning will attempt to get the source line for the issued warning.  To do this, it needs the module's loader.

Previously, it would only look up `__loader__` in the module globals.  In python#86298 we want to defer to the `__spec__.loader` if available.

The first step on this journey is to check that `loader == __spec__.loader` and issue another warning if it is not.  This commit does that.

Since this is a PoC, only manual testing for now.

```python
# /tmp/foo.py
import warnings

import bar

warnings.warn_explicit(
    'warning!',
    RuntimeWarning,
    'bar.py', 2,
    module='bar knee',
    module_globals=bar.__dict__,
    )
```

```python
# /tmp/bar.py
import sys
import os
import pathlib

# __loader__ = pathlib.Path()
```

Then running this: `./python.exe -Wdefault /tmp/foo.py`

Produces:

```
bar.py:2: RuntimeWarning: warning!
  import os
```

Uncomment the `__loader__ = ` line in `bar.py` and try it again:

```
sys:1: ImportWarning: Module bar; __loader__ != __spec__.loader (<_frozen_importlib_external.SourceFileLoader object at 0x109f7dfa0> != PosixPath('.'))
bar.py:2: RuntimeWarning: warning!
  import os
```

Automerge-Triggered-By: GH:warsaw