From a99bcecd4bb690271b5f0c92b22d3b2c8c872ec7 Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Thu, 2 Jun 2016 12:41:11 -0700 Subject: Never use 'l' (lowercase letter el) as a variable name --- pycodestyle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pycodestyle.py b/pycodestyle.py index 7026396..92fe12a 100755 --- a/pycodestyle.py +++ b/pycodestyle.py @@ -1219,7 +1219,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: -- cgit v1.2.1 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 From 4c8152c7da74d7f7e20d3ae98b52581ef1b0f16b Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Thu, 2 Jun 2016 16:27:33 -0700 Subject: Add more doctests for E741 --- pycodestyle.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pycodestyle.py b/pycodestyle.py index ad1b463..38648a3 100755 --- a/pycodestyle.py +++ b/pycodestyle.py @@ -1157,7 +1157,19 @@ def ambiguous_identifier(logical_line, tokens): 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 other contexts, so identifiers appearing after + the 'as' keyword are also reported: + + Okay: except AttributeError as o: + Okay: with lock as L: + E741: except AttributeError as O: + E741: with lock as l: """ idents_to_avoid = ('l', 'O', 'I') prev_type, prev_text, prev_start, prev_end, __ = tokens[0] -- cgit v1.2.1 From 017d3b5da0c37bd48df3778752bfa98b4eed6d5e Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Fri, 3 Jun 2016 10:02:08 -0700 Subject: Also report E741 on 'global' and 'nonlocal' statements --- pycodestyle.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pycodestyle.py b/pycodestyle.py index 38648a3..f92d860 100755 --- a/pycodestyle.py +++ b/pycodestyle.py @@ -1180,8 +1180,8 @@ def ambiguous_identifier(logical_line, tokens): if prev_text in idents_to_avoid: ident = prev_text pos = prev_start - # identifiers after 'as' - if prev_text == 'as': + # 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 -- cgit v1.2.1 From fdf3e6a2655c8ddd465781e1c2693886a8aa762f Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Fri, 3 Jun 2016 10:03:24 -0700 Subject: Report E742 and E743 for badly named functions and classes --- docs/intro.rst | 4 ++++ pycodestyle.py | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/intro.rst b/docs/intro.rst index bfa6786..11b0e0c 100644 --- a/docs/intro.rst +++ b/docs/intro.rst @@ -360,6 +360,10 @@ This is the current list of error and warning codes: +------------+----------------------------------------------------------------------+ | 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 f92d860..11cb879 100755 --- a/pycodestyle.py +++ b/pycodestyle.py @@ -1163,13 +1163,18 @@ def ambiguous_identifier(logical_line, tokens): E741: O = 123 E741: I = 42 - Variables can be bound in other contexts, so identifiers appearing after - the 'as' keyword are also reported: + 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] @@ -1185,6 +1190,12 @@ def ambiguous_identifier(logical_line, tokens): 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 -- cgit v1.2.1