summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcpopa <devnull@localhost>2014-01-22 20:55:21 +0200
committercpopa <devnull@localhost>2014-01-22 20:55:21 +0200
commitc16dcb5dc0e6ac28c3b242d67b1d7e761db1c23a (patch)
tree62794c54fcc8e496ea48cff25b251d1ab246a914
parent89132cbec80eeea0976f4ab4e8c10d44019bd934 (diff)
parent68829be83c2a6951350ef3a91f74c4bc052fcb40 (diff)
downloadpylint-c16dcb5dc0e6ac28c3b242d67b1d7e761db1c23a.tar.gz
Merge with default.
-rw-r--r--ChangeLog3
-rw-r--r--checkers/variables.py6
-rw-r--r--test/input/func_used_before_assignment_py30.py28
-rw-r--r--test/messages/func_used_before_assignment_py30.txt2
4 files changed, 39 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 868ad60..e18fa04 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -17,6 +17,9 @@ ChangeLog for Pylint
that `raise ... from ...` uses a proper exception context
(None or an exception).
+ * Enhance the check for 'used-before-assignment' to look
+ for 'nonlocal' uses.
+
2013-12-22 -- 1.1.0
* Add new check for use of deprecated pragma directives "pylint:disable-msg"
diff --git a/checkers/variables.py b/checkers/variables.py
index 90b7fe7..f461319 100644
--- a/checkers/variables.py
+++ b/checkers/variables.py
@@ -507,6 +507,12 @@ builtins. Remember that you should avoid to define new builtins when possible.'
# defined in global or builtin scope
if defframe.root().lookup(name)[1]:
maybee0601 = False
+ else:
+ # check if we have a nonlocal
+ if name in defframe.locals:
+ maybee0601 = not any(isinstance(child, astroid.Nonlocal)
+ and name in child.names
+ for child in defframe.get_children())
if (maybee0601
and stmt.fromlineno <= defstmt.fromlineno
and not is_defined_before(node)
diff --git a/test/input/func_used_before_assignment_py30.py b/test/input/func_used_before_assignment_py30.py
new file mode 100644
index 0000000..b5d0bf3
--- /dev/null
+++ b/test/input/func_used_before_assignment_py30.py
@@ -0,0 +1,28 @@
+"""Check for nonlocal and used-before-assignment"""
+# pylint: disable=missing-docstring, unused-variable
+
+__revision__ = 0
+
+def test_ok():
+ """ uses nonlocal """
+ cnt = 1
+ def wrap():
+ nonlocal cnt
+ cnt = cnt + 1
+ wrap()
+
+def test_fail():
+ """ doesn't use nonlocal """
+ cnt = 1
+ def wrap():
+ cnt = cnt + 1
+ wrap()
+
+def test_fail2():
+ """ use nonlocal, but for other variable """
+ cnt = 1
+ count = 1
+ def wrap():
+ nonlocal count
+ cnt = cnt + 1
+ wrap()
diff --git a/test/messages/func_used_before_assignment_py30.txt b/test/messages/func_used_before_assignment_py30.txt
new file mode 100644
index 0000000..5b6080f
--- /dev/null
+++ b/test/messages/func_used_before_assignment_py30.txt
@@ -0,0 +1,2 @@
+E: 18:test_fail.wrap: Using variable 'cnt' before assignment
+E: 27:test_fail2.wrap: Using variable 'cnt' before assignment \ No newline at end of file