Skip to content

Commit 8a43a8d

Browse files
Jaap Roesnedbat
Jaap Roes
authored andcommitted
fix: raise a Coverage-handlable exception if a file can't be read. #78
1 parent 7b1628b commit 8a43a8d

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

README.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,17 @@ To run the tests::
130130
History
131131
~~~~~~~
132132

133+
Unreleased
134+
----------
135+
136+
If a non-UTF8 file was found when looking for templates, it would fail when
137+
reading during the reporting phase, ending execution. This failure is now
138+
raised in a way that can be ignored with a .coveragerc setting of ``[report]
139+
ignore_errors=True`` (`issue 78`_).
140+
141+
.. _issue 78: https://github.com/nedbat/django_coverage_plugin/issues/78
142+
143+
133144
v2.0.1 --- 2021-10-06
134145
---------------------
135146

django_coverage_plugin/plugin.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
import os.path
99
import re
1010

11+
try:
12+
from coverage.exceptions import NoSource
13+
except ImportError:
14+
# for coverage 5.x
15+
from coverage.misc import NoSource
1116
import coverage.plugin
1217
import django
1318
import django.template
@@ -303,7 +308,10 @@ def __init__(self, filename):
303308

304309
def source(self):
305310
if self._source is None:
306-
self._source = read_template_source(self.filename)
311+
try:
312+
self._source = read_template_source(self.filename)
313+
except (IOError, UnicodeError) as exc:
314+
raise NoSource("Couldn't read {}: {}".format(self.filename, exc))
307315
return self._source
308316

309317
def lines(self):

tests/test_source.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33

44
"""Tests of template inheritance for django_coverage_plugin."""
55

6+
import os
7+
8+
try:
9+
from coverage.exceptions import NoSource
10+
except ImportError:
11+
# for coverage 5.x
12+
from coverage.misc import NoSource
13+
614
from .plugin_test import DjangoPluginTestCase
715

816

@@ -64,3 +72,65 @@ def test_customized_extensions(self):
6472
self.assert_analysis([1], name="phd.tex", missing=[1])
6573
# The editor leave-behinds are not in the measured files.
6674
self.assert_measured_files("main.html", "unused.html", "phd.tex")
75+
76+
def test_non_utf8_error(self):
77+
# A non-UTF8 text file will raise an error.
78+
self.make_file(".coveragerc", """\
79+
[run]
80+
plugins = django_coverage_plugin
81+
source = .
82+
""")
83+
# This is a template that is rendered.
84+
self.make_template(name="main.html", text="Hello")
85+
# Extra file containing a word encoded in CP-1252
86+
self.make_file(self._path("static/changelog.txt"), bytes=b"sh\xf6n")
87+
88+
text = self.run_django_coverage(name="main.html")
89+
self.assertEqual(text, "Hello")
90+
91+
self.assert_measured_files("main.html", "static{}changelog.txt".format(os.sep))
92+
self.assert_analysis([1], name="main.html")
93+
with self.assertRaisesRegexp(NoSource, r"changelog.txt.*invalid start byte"):
94+
self.cov.html_report()
95+
96+
def test_non_utf8_omitted(self):
97+
# If we omit the directory with the non-UTF8 file, all is well.
98+
self.make_file(".coveragerc", """\
99+
[run]
100+
plugins = django_coverage_plugin
101+
source = .
102+
[report]
103+
omit = */static/*
104+
""")
105+
# This is a template that is rendered.
106+
self.make_template(name="main.html", text="Hello")
107+
# Extra file containing a word encoded in CP-1252
108+
self.make_file(self._path("static/changelog.txt"), bytes=b"sh\xf6n")
109+
110+
text = self.run_django_coverage(name="main.html")
111+
self.assertEqual(text, "Hello")
112+
113+
self.assert_measured_files("main.html", "static{}changelog.txt".format(os.sep))
114+
self.assert_analysis([1], name="main.html")
115+
self.cov.html_report()
116+
117+
def test_non_utf8_ignored(self):
118+
# If we ignore reporting errors, a non-UTF8 text file is fine.
119+
self.make_file(".coveragerc", """\
120+
[run]
121+
plugins = django_coverage_plugin
122+
source = .
123+
[report]
124+
ignore_errors = True
125+
""")
126+
# This is a template that is rendered.
127+
self.make_template(name="main.html", text="Hello")
128+
# Extra file containing a word encoded in CP-1252
129+
self.make_file(self._path("static/changelog.txt"), bytes=b"sh\xf6n")
130+
131+
text = self.run_django_coverage(name="main.html")
132+
self.assertEqual(text, "Hello")
133+
134+
self.assert_measured_files("main.html", "static{}changelog.txt".format(os.sep))
135+
self.assert_analysis([1], name="main.html")
136+
self.cov.html_report()

0 commit comments

Comments
 (0)