diff options
author | Ian Lee <IanLee1521@gmail.com> | 2016-06-06 17:21:36 -0700 |
---|---|---|
committer | Ian Lee <IanLee1521@gmail.com> | 2016-06-06 17:21:36 -0700 |
commit | 4ccdc55324ccdb848fb41e33b346405acd6c2114 (patch) | |
tree | 411fcdaeba6c70309e94baea81a797dcda28790f | |
parent | 60859d6408d1479ec40d80f73f37d34d914704f1 (diff) | |
parent | fdf3e6a2655c8ddd465781e1c2693886a8aa762f (diff) | |
download | pep8-4ccdc55324ccdb848fb41e33b346405acd6c2114.tar.gz |
Merge pull request #525 from mtmiller/issue341
Detect single letter variable names enumerated in PEP-0008
-rw-r--r-- | CHANGES.txt | 1 | ||||
-rw-r--r-- | docs/intro.rst | 6 | ||||
-rwxr-xr-x | pycodestyle.py | 56 |
3 files changed, 62 insertions, 1 deletions
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 ce71692..982b786 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -359,6 +359,12 @@ 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' | ++------------+----------------------------------------------------------------------+ +| E742 | do not define classes named 'l', 'O', or 'I' | ++------------+----------------------------------------------------------------------+ +| E743 | do not define functions named 'l', 'O', or 'I' | ++------------+----------------------------------------------------------------------+ +------------+----------------------------------------------------------------------+ | **E9** | *Runtime* | +------------+----------------------------------------------------------------------+ diff --git a/pycodestyle.py b/pycodestyle.py index f2f4284..a5141f2 100755 --- a/pycodestyle.py +++ b/pycodestyle.py @@ -1155,6 +1155,60 @@ 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 + Okay: o = 123 + Okay: i = 42 + E741: l = 0 + E741: O = 123 + E741: I = 42 + + Variables can be bound in several other contexts, including class and + function definitions, 'global' and 'nonlocal' statements, exception + handlers, and 'with' statements. + + Okay: except AttributeError as o: + Okay: with lock as L: + E741: except AttributeError as O: + E741: with lock as l: + E741: global I + E741: nonlocal l + E742: class I(object): + E743: def l(x): + """ + 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 bound to a value with 'as', 'global', or 'nonlocal' + if prev_text in ('as', 'global', 'nonlocal'): + if text in idents_to_avoid: + ident = text + pos = start + if prev_text == 'class': + if text in idents_to_avoid: + yield start, "E742 ambiguous class definition '%s'" % text + if prev_text == 'def': + if text in idents_to_avoid: + yield start, "E743 ambiguous function definition '%s'" % text + 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. @@ -1224,7 +1278,7 @@ else: with open(filename, 'rb') as f: (coding, lines) = tokenize.detect_encoding(f.readline) f = TextIOWrapper(f, coding, line_buffering=True) - return [l.decode(coding) for l in lines] + f.readlines() + return [line.decode(coding) for line in lines] + f.readlines() except (LookupError, SyntaxError, UnicodeError): # Fall back if file encoding is improperly declared with open(filename, encoding='latin-1') as f: |