summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Abou-Samra <jean@abou-samra.fr>2022-05-12 08:35:59 +0200
committerGitHub <noreply@github.com>2022-05-12 08:35:59 +0200
commit49c757cab5e4ca80af109581b83a3527df02d29c (patch)
treec6153eb458cc0289f5e538881a6fdbbb60cf688e
parent4d2a285bd14f4dc153360e171bebdc52d1921089 (diff)
downloadpygments-git-49c757cab5e4ca80af109581b83a3527df02d29c.tar.gz
Improve heuristic to warn about passing lexer/formatter class (#2123)
Don't rely on the error message since 'missing 1 required positional argument' can give false positives. Instead, use issubclass().
-rw-r--r--pygments/__init__.py13
-rw-r--r--tests/test_basic_api.py22
2 files changed, 28 insertions, 7 deletions
diff --git a/pygments/__init__.py b/pygments/__init__.py
index 52ff035d..1c107f33 100644
--- a/pygments/__init__.py
+++ b/pygments/__init__.py
@@ -39,9 +39,9 @@ def lex(code, lexer):
try:
return lexer.get_tokens(code)
except TypeError as err:
- if (isinstance(err.args[0], str) and
- ('unbound method get_tokens' in err.args[0] or
- 'missing 1 required positional argument' in err.args[0])):
+ # Heuristic to catch a common mistake.
+ from pygments.lexer import RegexLexer
+ if isinstance(lexer, type) and issubclass(lexer, RegexLexer):
raise TypeError('lex() argument must be a lexer instance, '
'not a class')
raise
@@ -63,9 +63,9 @@ def format(tokens, formatter, outfile=None): # pylint: disable=redefined-builti
else:
formatter.format(tokens, outfile)
except TypeError as err:
- if (isinstance(err.args[0], str) and
- ('unbound method format' in err.args[0] or
- 'missing 1 required positional argument' in err.args[0])):
+ # Heuristic to catch a common mistake.
+ from pygments.formatter import Formatter
+ if isinstance(formatter, type) and issubclass(formatter, Formatter):
raise TypeError('format() argument must be a formatter instance, '
'not a class')
raise
@@ -80,4 +80,3 @@ def highlight(code, lexer, formatter, outfile=None):
it is returned as a string.
"""
return format(lex(code, lexer), formatter, outfile)
-
diff --git a/tests/test_basic_api.py b/tests/test_basic_api.py
index 1767572f..62ea4895 100644
--- a/tests/test_basic_api.py
+++ b/tests/test_basic_api.py
@@ -15,6 +15,7 @@ import pytest
from pygments import lexers, formatters, lex, format
from pygments.token import _TokenType, Text
from pygments.lexer import RegexLexer
+from pygments.formatter import Formatter
from pygments.formatters.img import FontNotFound
from pygments.util import ClassNotFound
@@ -250,6 +251,27 @@ def test_bare_class_handler():
else:
assert False, 'nothing raised'
+ # These cases should not trigger this heuristic.
+ class BuggyLexer(RegexLexer):
+ def get_tokens(self, text, extra_argument):
+ pass
+ tokens = {'root': []}
+ try:
+ list(lex('dummy', BuggyLexer()))
+ except TypeError as e:
+ assert 'lex() argument must be a lexer instance' not in str(e)
+ else:
+ assert False, 'no error raised by buggy lexer?'
+
+ class BuggyFormatter(Formatter):
+ def format(self, tokensource, outfile, extra_argument):
+ pass
+ try:
+ format([], BuggyFormatter())
+ except TypeError as e:
+ assert 'format() argument must be a formatter instance' not in str(e)
+ else:
+ assert False, 'no error raised by buggy formatter?'
class TestFilters: