Skip to content

Commit 7fb846e

Browse files
askhlnedbat
andauthored
fix: runpy.run_path(path) crashes with pathlib.Path (#1819)
* fix: runpy.run_path(path) crashes with pathlib.Path * Revert "fix: runpy.run_path(path) crashes with pathlib.Path" This reverts commit 2d1eabd. * fix: runpy.run_path(path) crashes with pathlib.Path * test: runpy.run_path(path) with being pathlib.Path * finish up #1819 * test both str and Path --------- Co-authored-by: Ned Batchelder <ned@nedbatchelder.com>
1 parent 1da3ee1 commit 7fb846e

File tree

4 files changed

+29
-2
lines changed

4 files changed

+29
-2
lines changed

CHANGES.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ upgrading your version of coverage.py.
2323
Unreleased
2424
----------
2525

26-
Nothing yet.
26+
- Fix: coverage used to fail when measuring code using :func:`runpy.run_path
27+
<python:runpy.run_path>` with a :class:`Path <python:pathlib.Path>` argument.
28+
This is now fixed, thanks to `Ask Hjorth Larsen <pull 1819_>`_.
29+
30+
.. _pull 1819: https://github.com/nedbat/coveragepy/pull/1819/files
2731

2832

2933
.. scriv-start-here

CONTRIBUTORS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Artem Dayneko
2525
Arthur Deygin
2626
Arthur Rio
2727
Asher Foa
28+
Ask Hjorth Larsen
2829
Ben Carlsson
2930
Ben Finney
3031
Benjamin Parzella

coverage/inorout.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,8 @@ def nope(disp: TFileDisposition, reason: str) -> TFileDisposition:
321321
# co_filename value.
322322
dunder_file = frame.f_globals and frame.f_globals.get("__file__")
323323
if dunder_file:
324-
filename = source_for_file(dunder_file)
324+
# Danger: __file__ can (rarely?) be of type Path.
325+
filename = source_for_file(str(dunder_file))
325326
if original_filename and not original_filename.startswith("<"):
326327
orig = os.path.basename(original_filename)
327328
if orig != os.path.basename(filename):

tests/test_python.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,24 @@ def test_source_for_file_windows(tmp_path: pathlib.Path) -> None:
6363
# If both pyw and py exist, py is preferred
6464
a_py.write_text("")
6565
assert source_for_file(src + 'c') == src
66+
67+
68+
class RunpyTest(CoverageTest):
69+
"""Tests using runpy."""
70+
71+
@pytest.mark.parametrize("convert_to", ["str", "Path"])
72+
def test_runpy_path(self, convert_to: str) -> None:
73+
# Ensure runpy.run_path(path) works when path is pathlib.Path or str.
74+
#
75+
# runpy.run_path(pathlib.Path(...)) causes __file__ to be a Path,
76+
# which may make source_for_file() stumble (#1819) with:
77+
#
78+
# AttributeError: 'PosixPath' object has no attribute 'endswith'
79+
80+
self.check_coverage(f"""\
81+
import runpy
82+
from pathlib import Path
83+
pyfile = Path('script.py')
84+
pyfile.write_text('')
85+
runpy.run_path({convert_to}(pyfile))
86+
""")

0 commit comments

Comments
 (0)