From 26893dafe4562caefeb200c990972bc6262842d9 Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Thu, 2 Jun 2016 12:44:23 -0700 Subject: Report E741 for prohibited single-letter variables Check for prohibited identifiers occuring to the lhs of an assignment operator or after the 'as' keyword. Closes #341 --- CHANGES.txt | 1 + docs/intro.rst | 2 ++ pycodestyle.py | 31 +++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index e129dc8..f2ac1de 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -16,6 +16,7 @@ Changes: * Added check E275 for whitespace on `from ... import ...` lines; #489 / #491 * Added W503 to the list of codes ignored by default ignore list; #498 * Removed use of project level `.pep8` configuration file; #364 +* Added check E741 for using variables named 'l', 'O', or 'I'; #341 Bugs: diff --git a/docs/intro.rst b/docs/intro.rst index 12f67d7..bfa6786 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -358,6 +358,8 @@ This is the current list of error and warning codes: +------------+----------------------------------------------------------------------+ | E731 | do not assign a lambda expression, use a def | +------------+----------------------------------------------------------------------+ +| E741 | do not use variables named 'l', 'O', or 'I' | ++------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | **E9** | *Runtime* | +------------+----------------------------------------------------------------------+ diff --git a/pycodestyle.py b/pycodestyle.py index 92fe12a..ad1b463 100755 --- a/pycodestyle.py +++ b/pycodestyle.py @@ -1150,6 +1150,37 @@ def comparison_type(logical_line, noqa): yield match.start(), "E721 do not compare types, use 'isinstance()'" +def ambiguous_identifier(logical_line, tokens): + r"""Never use the characters 'l', 'O', or 'I' as variable names. + + In some fonts, these characters are indistinguishable from the numerals + one and zero. When tempted to use 'l', use 'L' instead. + + Okay: L = 0 + E741: l = 0 + """ + idents_to_avoid = ('l', 'O', 'I') + prev_type, prev_text, prev_start, prev_end, __ = tokens[0] + for token_type, text, start, end, line in tokens[1:]: + ident = pos = None + # identifiers on the lhs of an assignment operator + if token_type == tokenize.OP and '=' in text: + if prev_text in idents_to_avoid: + ident = prev_text + pos = prev_start + # identifiers after 'as' + if prev_text == 'as': + if text in idents_to_avoid: + ident = text + pos = start + if ident: + yield pos, "E741 ambiguous variable name '%s'" % ident + prev_type = token_type + prev_text = text + prev_start = start + prev_end = end + + def python_3000_has_key(logical_line, noqa): r"""The {}.has_key() method is removed in Python 3: use the 'in' operator. -- cgit v1.2.1