| /* |
| Copyright 2020 Google LLC |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| https://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| */ |
| |
| package warn |
| |
| import "testing" |
| |
| func TestMissingReturnValueWarning(t *testing.T) { |
| // empty return |
| checkFindings(t, "return-value", ` |
| def foo(): |
| if x: |
| return x |
| else: |
| return |
| `, []string{ |
| `:5: Some but not all execution paths of "foo" return a value.`, |
| }, scopeEverywhere) |
| |
| // empty return; implicit return in the end |
| checkFindings(t, "return-value", ` |
| def bar(): |
| if x: |
| pass |
| elif y: |
| return y |
| else: |
| for z in t: |
| return |
| `, []string{ |
| `:1: Some but not all execution paths of "bar" return a value. |
| The function may terminate by an implicit return in the end.`, |
| `:8: Some but not all execution paths of "bar" return a value.`, |
| }, scopeEverywhere) |
| |
| // implicit return in the end |
| checkFindings(t, "return-value", ` |
| def foo(): |
| if x: |
| return x |
| else: |
| bar() |
| `, []string{ |
| `:1: Some but not all execution paths of "foo" return a value. |
| The function may terminate by an implicit return in the end.`, |
| }, scopeEverywhere) |
| |
| // implicit return in the end |
| checkFindings(t, "return-value", ` |
| def bar(): |
| if x: |
| return x |
| elif y: |
| return y |
| else: |
| foo |
| if z: |
| return z |
| |
| if foo: |
| return not foo |
| `, []string{ |
| `:1: Some but not all execution paths of "bar" return a value. |
| The function may terminate by an implicit return in the end.`, |
| }, scopeEverywhere) |
| |
| // only returned values and fail() statements, ok |
| checkFindings(t, "return-value", ` |
| def bar(): |
| if x: |
| return x |
| elif y: |
| return y |
| else: |
| foo |
| if z: |
| return z |
| |
| if foo: |
| return not foo |
| else: |
| fail("unreachable") |
| `, []string{}, scopeEverywhere) |
| |
| // implicit return in the end because fail() is not a statement |
| checkFindings(t, "return-value", ` |
| def bar(): |
| if x: |
| return x |
| elif y: |
| return y |
| else: |
| foo |
| if z: |
| return z |
| |
| if foo: |
| return not foo |
| else: |
| foo() or fail("unreachable") |
| `, []string{ |
| `:1: Some but not all execution paths of "bar" return a value. |
| The function may terminate by an implicit return in the end.`, |
| }, scopeEverywhere) |
| |
| // only empty returns, ok |
| checkFindings(t, "return-value", ` |
| def bar(): |
| if x: |
| x() |
| elif y: |
| return |
| else: |
| foo |
| if z: |
| fail() |
| |
| if foo: |
| return |
| `, []string{}, scopeEverywhere) |
| |
| // no returns, ok |
| checkFindings(t, "return-value", ` |
| def foobar(): |
| pass |
| `, []string{}, scopeEverywhere) |
| |
| // only fails, ok |
| checkFindings(t, "return-value", ` |
| def foobar(): |
| if foo: |
| fail() |
| `, []string{}, scopeEverywhere) |
| |
| // nested functions, no errors |
| checkFindings(t, "return-value", ` |
| def foo(): |
| def bar(): |
| pass |
| |
| return bar |
| `, []string{}, scopeEverywhere) |
| |
| // nested functions, missing return value in the outer function |
| checkFindings(t, "return-value", ` |
| def foo(): |
| def bar(): |
| pass |
| |
| if bar(): |
| return 42 |
| `, []string{ |
| `:1: Some but not all execution paths of "foo" return a value. |
| The function may terminate by an implicit return in the end.`, |
| }, scopeEverywhere) |
| |
| // nested functions, missing return value in the inner function |
| checkFindings(t, "return-value", ` |
| def foo(): |
| def bar(): |
| if something: |
| return something |
| |
| if bar(): |
| return 42 |
| return 43 |
| `, []string{ |
| `:2: Some but not all execution paths of "bar" return a value. |
| The function may terminate by an implicit return in the end.`, |
| }, scopeEverywhere) |
| |
| // nested functions, missing return value in both |
| checkFindings(t, "return-value", ` |
| def foo(): |
| def bar(): |
| if something: |
| return something |
| |
| if bar(): |
| return 42 |
| `, []string{ |
| `:1: Some but not all execution paths of "foo" return a value. |
| The function may terminate by an implicit return in the end.`, |
| `:2: Some but not all execution paths of "bar" return a value. |
| The function may terminate by an implicit return in the end.`, |
| }, scopeEverywhere) |
| } |
| |
| func TestUnreachableStatementWarning(t *testing.T) { |
| // after return |
| checkFindings(t, "unreachable", ` |
| def foo(): |
| return |
| bar() |
| baz() |
| `, []string{ |
| `:3: The statement is unreachable.`, |
| }, scopeEverywhere) |
| |
| // two returns |
| checkFindings(t, "unreachable", ` |
| def foo(): |
| return 1 |
| return 2 |
| `, []string{ |
| `:3: The statement is unreachable.`, |
| }, scopeEverywhere) |
| |
| // after fail() |
| checkFindings(t, "unreachable", ` |
| def foo(): |
| fail("die") |
| bar() |
| baz() |
| `, []string{ |
| `:3: The statement is unreachable.`, |
| }, scopeEverywhere) |
| |
| // after break and continue |
| checkFindings(t, "unreachable", ` |
| def foo(): |
| for x in y: |
| if x: |
| break |
| bar() # unreachable |
| if y: |
| continue |
| bar() # unreachable |
| |
| def bar(): |
| for x in y: |
| if x: |
| break |
| elif y: |
| continue |
| else: |
| return x |
| |
| foo() # unreachable |
| foobar() # potentially reachable |
| `, []string{ |
| `:5: The statement is unreachable.`, |
| `:8: The statement is unreachable.`, |
| `:19: The statement is unreachable.`, |
| }, scopeEverywhere) |
| |
| // ok |
| checkFindings(t, "unreachable", ` |
| def foo(): |
| if x: |
| return |
| bar() |
| `, []string{}, scopeEverywhere) |
| |
| // ok |
| checkFindings(t, "unreachable", ` |
| def foo(): |
| x() or fail("maybe") |
| bar() |
| `, []string{}, scopeEverywhere) |
| |
| // unreacheable statement inside a nested function |
| checkFindings(t, "unreachable", ` |
| def foo(): |
| def bar(): |
| fail("die") |
| baz() |
| `, []string{ |
| `:4: The statement is unreachable.`, |
| }, scopeEverywhere) |
| |
| } |
| |
| func TestNoEffect(t *testing.T) { |
| checkFindings(t, "no-effect", ` |
| """Docstring.""" |
| def bar(): |
| """Other Docstring""" |
| fct() |
| pass |
| return 2 |
| |
| [f() for i in rang(3)] # top-level comprehension is okay |
| `, |
| []string{}, |
| scopeEverywhere) |
| |
| checkFindings(t, "no-effect", ` |
| def foo(): |
| [fct() for i in range(3)] |
| `, |
| []string{":2: Expression result is not used. Use a for-loop instead"}, |
| scopeEverywhere) |
| |
| checkFindings(t, "no-effect", `None`, |
| []string{":1: Expression result is not used."}, |
| scopeEverywhere) |
| |
| checkFindings(t, "no-effect", ` |
| foo # 1 |
| foo() |
| |
| def bar(): |
| [1, 2] # 5 |
| if True: |
| "string" # 7 |
| `, |
| []string{":1:", ":5:", ":7:"}, |
| scopeEverywhere) |
| |
| checkFindings(t, "no-effect", ` |
| # A comment |
| |
| """A docstring""" |
| |
| # Another comment |
| |
| """Not a docstring""" |
| |
| def bar(): |
| """A docstring""" |
| foo |
| """ Not a docstring""" |
| return foo |
| `, |
| []string{ |
| ":7: Expression result is not used. Docstrings should be the first statements of a file or a function (they may follow comment lines).", |
| ":11: Expression result is not used.", |
| ":12: Expression result is not used. Docstrings should be the first statements of a file or a function (they may follow comment lines).", |
| }, scopeEverywhere) |
| |
| checkFindings(t, "no-effect", ` |
| foo == bar |
| foo = bar |
| a + b |
| c // d |
| -e |
| foo != bar |
| |
| foo += bar |
| bar -= bar |
| bar *= bar |
| bar /= bar |
| bar //= bar |
| bar %= bar |
| bar &= bar |
| bar |= bar |
| bar ^= bar |
| bar <<= bar |
| bar >>= bar |
| `, |
| []string{":1:", ":3:", ":4:", ":5:", ":6:"}, |
| scopeEverywhere) |
| |
| checkFindings(t, "no-effect", ` |
| def foo(): |
| """Doc.""" |
| def bar(): |
| """Doc.""" |
| foo == bar |
| `, |
| []string{":5:"}, |
| scopeEverywhere) |
| } |
| |
| func TestWarnUnusedVariable(t *testing.T) { |
| checkFindings(t, "unused-variable", ` |
| load(":f.bzl", "x") |
| x = "unused" |
| y = "also unused" |
| z = "name" |
| t = "unused by design" # @unused |
| _foo, _bar = pair #@unused |
| cc_library(name = z) |
| |
| def f(): |
| pass |
| |
| def g(): |
| pass |
| |
| g() + 3 |
| `, |
| []string{":2: Variable \"x\" is unused.", |
| ":3: Variable \"y\" is unused.", |
| ":9: Function \"f\" is unused."}, |
| scopeDeclarative) |
| |
| checkFindings(t, "unused-variable", ` |
| a = 1 |
| b = 2 |
| c = 3 |
| d = (a if b else c) # only d is unused |
| `, |
| []string{":4: Variable \"d\" is unused."}, |
| scopeDeclarative) |
| |
| checkFindings(t, "unused-variable", ` |
| _a = 1 |
| _a += 2 |
| _b = 3 |
| print(_b) |
| |
| def _f(): pass |
| def _g(): pass |
| _g() |
| `, |
| []string{ |
| ":1: Variable \"_a\" is unused.", |
| ":6: Function \"_f\" is unused.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "unused-variable", ` |
| a = 1 |
| |
| def foo( |
| x, |
| y = 0, |
| z = 1): |
| b = 2 |
| c = 3 |
| d = (a if b else c) # only d is unused |
| e = 7 |
| f = 8 # @unused |
| # @unused |
| g = 9 |
| |
| return e + z |
| |
| foo() |
| `, |
| []string{ |
| ":4: Variable \"x\" is unused.", |
| ":5: Variable \"y\" is unused.", |
| ":9: Variable \"d\" is unused.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "unused-variable", ` |
| a = 1 |
| |
| def foo(a): |
| b = 2 |
| return a |
| |
| def foo(): |
| pass |
| |
| def bar(c, cc): |
| d = 3 |
| print(c) |
| |
| def baz(): |
| foo() |
| d = 4 |
| return a |
| |
| bar() |
| `, |
| []string{ |
| ":4: Variable \"b\" is unused.", |
| ":10: Variable \"cc\" is unused.", |
| ":11: Variable \"d\" is unused.", |
| ":14: Function \"baz\" is unused.", |
| ":16: Variable \"d\" is unused.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "unused-variable", ` |
| def foo(): |
| a = 1 |
| b = 2 |
| c = 3 |
| |
| def bar( |
| x = a + baz(c = 4), |
| y = b): |
| pass |
| |
| foo() |
| `, |
| []string{ |
| ":4: Variable \"c\" is unused.", |
| ":6: Function \"bar\" is unused.", |
| ":7: Variable \"x\" is unused.", |
| ":8: Variable \"y\" is unused.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "unused-variable", ` |
| def foo(): |
| a = 1 |
| b = 2 |
| c = [x for a in aa if a % b for x in a] |
| return c |
| |
| foo() |
| `, |
| []string{ |
| ":2: Variable \"a\" is unused.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "unused-variable", ` |
| def foo(): |
| a = 1 |
| b = 2 |
| c = [ |
| a + b |
| for a in [b for b in bb if b] |
| if a |
| ] |
| return c |
| |
| foo() |
| `, |
| []string{ |
| ":2: Variable \"a\" is unused.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "unused-variable", ` |
| def foo(): |
| a = 1 |
| b = 2 |
| |
| def bar(*args): |
| def baz(**kwargs): |
| def foobar(*a, |
| **kw): |
| return b |
| return foobar(**kwargs) |
| return baz(*args) |
| return bar() |
| |
| foo() |
| `, |
| []string{ |
| ":2: Variable \"a\" is unused.", |
| ":7: Variable \"a\" is unused.", |
| ":8: Variable \"kw\" is unused.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "unused-variable", ` |
| def foo(): |
| a = 1 |
| b = 2 |
| c = 3 |
| d = 4 |
| e, f = 5, 6 |
| |
| for x, yy in xx: |
| for (y, z, _, _t) in yy: |
| print(a + y) |
| |
| if bar: |
| print(c) |
| elif baz: |
| print(d) |
| else: |
| print(e) |
| |
| foo() |
| `, |
| []string{ |
| ":3: Variable \"b\" is unused.", |
| ":6: Variable \"f\" is unused.", |
| ":8: Variable \"x\" is unused.", |
| ":9: Variable \"z\" is unused.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "unused-variable", ` |
| def foo(): |
| |
| # @unused |
| def bar(): |
| pass |
| |
| def baz(): |
| pass |
| |
| foo() |
| `, |
| []string{ |
| ":7: Function \"baz\" is unused.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "unused-variable", ` |
| def foo(my_iterable, arg, _some_unused_argument, _also_unused = None, *_args, **_kwargs): |
| |
| a, b, _c = 1, 2, 3 # ok to not use _c |
| print(a) |
| |
| _d, _e = 4, 5 # all are underscored |
| print(_d) |
| |
| for f, g, _h, _ in my_iterable: # ok to not use any underscored |
| print(f) |
| |
| for _i, (_j, _k) in another_iterable: # ok to not use any of them |
| pass |
| |
| [1 for (_y, _z) in bar] |
| |
| foo() |
| `, |
| []string{ |
| ":1: Variable \"arg\" is unused.", |
| ":3: Variable \"b\" is unused.", |
| ":6: Variable \"_e\" is unused.", |
| ":9: Variable \"g\" is unused.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "unused-variable", ` |
| def foo( |
| x, |
| _y, |
| z, # @unused |
| t = 42, #@unused |
| *args, # @unused |
| **kwargs, ### also @unused |
| ): |
| pass |
| |
| foo() |
| `, |
| []string{ |
| ":2: Variable \"x\" is unused.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "unused-variable", ` |
| def foo( |
| name, |
| x): |
| pass |
| |
| |
| def bar( |
| name = "", |
| y = 3): |
| pass |
| |
| |
| foo() |
| bar() |
| `, |
| []string{ |
| ":3: Variable \"x\" is unused.", |
| ":9: Variable \"y\" is unused.", |
| }, |
| scopeEverywhere) |
| } |
| |
| func TestRedefinedVariable(t *testing.T) { |
| checkFindings(t, "redefined-variable", ` |
| x = "old_value" |
| x = "new_value" |
| x[1] = "new" |
| cc_library(name = x)`, |
| []string{":2: Variable \"x\" has already been defined."}, |
| scopeEverywhere) |
| |
| checkFindings(t, "redefined-variable", ` |
| x = "a" |
| |
| def foo(): |
| x = "b" |
| y = "c" |
| y = "d" |
| |
| def bar(): |
| x = "e" |
| y = "f" |
| y = "g"`, |
| []string{}, |
| scopeEverywhere) |
| |
| checkFindings(t, "redefined-variable", ` |
| x = [1, 2, 3] |
| y = [a for a in b] |
| z = list() |
| n = 43 |
| |
| x += something() |
| y += something() |
| z += something() |
| n += something() |
| x -= something()`, |
| []string{ |
| ":9: Variable \"n\" has already been defined.", |
| ":10: Variable \"x\" has already been defined.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "redefined-variable", ` |
| x = [1, 2, 3] |
| y = [a for a in b] |
| z = list() |
| |
| a = something() |
| b = something() |
| c = something() |
| d = something() |
| e = something() |
| |
| a += x |
| b += y |
| c += z |
| d += [42] |
| e += foo`, |
| []string{ |
| ":15: Variable \"e\" has already been defined.", |
| }, |
| scopeEverywhere) |
| } |
| |
| func TestWarnUnusedLoad(t *testing.T) { |
| checkFindingsAndFix(t, "load", ` |
| load(":f.bzl", "s1", "s2") |
| load(":bar.bzl", "s1") |
| foo(name = s1)`, ` |
| load(":f.bzl", "s1") |
| load(":bar.bzl", "s1") |
| foo(name = s1)`, |
| []string{ |
| ":1: Loaded symbol \"s2\" is unused.", |
| ":2: A different symbol \"s1\" has already been loaded on line 1.", |
| }, |
| scopeEverywhere) |
| |
| checkFindingsAndFix(t, "load", ` |
| load("foo", "b", "a", "c") |
| load("foo", "a", "d", "e") |
| |
| z = a + b + d`, ` |
| load("foo", "a", "b") |
| load("foo", "d") |
| |
| z = a + b + d`, |
| []string{ |
| ":1: Loaded symbol \"c\" is unused.", |
| ":2: Symbol \"a\" has already been loaded on line 1.", |
| ":2: Loaded symbol \"e\" is unused.", |
| }, |
| scopeEverywhere) |
| |
| checkFindingsAndFix(t, "load", ` |
| load("foo", "a") |
| a(1) |
| load("bar", "a") |
| a(2) |
| load("bar", a = "a") |
| a(3) |
| load("bar", a = "b") |
| a(4) |
| load("foo", "a") |
| a(5) |
| load("foo", "a") |
| a(6) |
| load("foo", a = "a") |
| a(7)`, ` |
| load("foo", "a") |
| a(1) |
| load("bar", "a") |
| a(2) |
| |
| a(3) |
| load("bar", a = "b") |
| a(4) |
| load("foo", "a") |
| a(5) |
| |
| a(6) |
| |
| a(7)`, |
| []string{ |
| ":3: A different symbol \"a\" has already been loaded on line 1.", |
| ":5: Symbol \"a\" has already been loaded on line 3.", |
| ":7: A different symbol \"a\" has already been loaded on line 5.", |
| ":9: A different symbol \"a\" has already been loaded on line 7.", |
| ":11: Symbol \"a\" has already been loaded on line 9.", |
| ":13: Symbol \"a\" has already been loaded on line 11.", |
| }, |
| scopeEverywhere) |
| |
| checkFindingsAndFix(t, "load", ` |
| load( |
| ":f.bzl", |
| "s1", |
| "s2", # @unused (s2) |
| ) |
| |
| # @unused - both s3 and s4 |
| load( |
| ":f.bzl", |
| "s3", |
| "s4", |
| )`, ` |
| load( |
| ":f.bzl", |
| "s2", # @unused (s2) |
| ) |
| |
| # @unused - both s3 and s4 |
| load( |
| ":f.bzl", |
| "s3", |
| "s4", |
| )`, |
| []string{":3: Loaded symbol \"s1\" is unused."}, |
| scopeEverywhere) |
| |
| checkFindingsAndFix(t, "load", ` |
| load(":f.bzl", "x") |
| x = "unused"`, ` |
| x = "unused"`, |
| []string{":1: Loaded symbol \"x\" is unused."}, |
| scopeEverywhere) |
| |
| checkFindings(t, "load", ` |
| load( |
| ":f.bzl", |
| "s1", |
| ) |
| |
| def test(x: s1): |
| pass |
| `, |
| []string{}, |
| scopeEverywhere) |
| checkFindings(t, "load", ` |
| load( |
| ":f.bzl", |
| "s1", |
| "s2", |
| ) |
| |
| def test(x: s1) -> List[s2]: |
| pass |
| `, |
| []string{}, |
| scopeEverywhere) |
| checkFindingsAndFix(t, "load", ` |
| load( |
| ":f.bzl", |
| "s1", |
| "s2", |
| ) |
| |
| load( |
| ":s.bzl", |
| "s3", |
| ) |
| |
| def test(x: s1) -> List[s2]: |
| pass |
| `, ` |
| load( |
| ":f.bzl", |
| "s1", |
| "s2", |
| ) |
| |
| def test(x: s1) -> List[s2]: |
| pass |
| `, |
| []string{ |
| ":9: Loaded symbol \"s3\" is unused.", |
| }, |
| scopeEverywhere) |
| } |
| |
| func TestUninitializedVariable(t *testing.T) { |
| checkFindings(t, "uninitialized", ` |
| def foo(x): |
| if bar: |
| x = 1 |
| y = 2 |
| |
| bar = True |
| print(x + y) |
| `, |
| []string{ |
| ":2: Variable \"bar\" may not have been initialized.", |
| ":7: Variable \"y\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(x): |
| for t in s: |
| x = 1 |
| y = 2 |
| |
| print(x + y) |
| `, |
| []string{ |
| ":6: Variable \"y\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(): |
| if bar: |
| x = 1 |
| y = 2 |
| else: |
| if foobar: |
| x = 3 |
| y = 4 |
| else: |
| x = 5 |
| |
| print(x + y) |
| `, |
| []string{ |
| ":12: Variable \"y\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(x): |
| if bar: |
| t = 1 |
| else: |
| for t in maybe_empty: |
| pass |
| |
| print(t) |
| `, |
| []string{ |
| ":8: Variable \"t\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(x): |
| if bar: |
| t = 1 |
| else: |
| for y in maybe_empty: |
| return |
| |
| print(t) |
| `, |
| []string{ |
| ":8: Variable \"t\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(x): |
| if bar: |
| for t in [2, 3]: |
| pass |
| |
| print(t) |
| `, |
| []string{ |
| ":6: Variable \"t\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(x): |
| print(t) # maybe global or loaded |
| `, |
| []string{}, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(x): |
| if bar: |
| y = 1 |
| |
| print(y) |
| x, y = y, x |
| print(y) |
| `, |
| []string{ |
| ":5: Variable \"y\" may not have been initialized.", |
| ":6: Variable \"y\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(): |
| if a: |
| x = 1 |
| y = 1 |
| z = 1 |
| elif b: |
| x = 2 |
| z = 2 |
| t = 2 |
| else: |
| x = 3 |
| y = 3 |
| t = 3 |
| |
| print(x + y + z + t) |
| `, |
| []string{ |
| ":15: Variable \"y\" may not have been initialized.", |
| ":15: Variable \"z\" may not have been initialized.", |
| ":15: Variable \"t\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(y): |
| if y < 0: |
| x = -1 |
| elif y > 0: |
| x = 1 |
| else: |
| fail() |
| |
| print(x) |
| `, |
| []string{}, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(y): |
| if y < 0: |
| x = -1 |
| elif y > 0: |
| x = 1 |
| else: |
| if z: |
| fail("z") |
| else: |
| fail("not z") |
| |
| print(x) |
| `, |
| []string{}, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(y): |
| if y < 0: |
| return |
| elif y > 0: |
| x = 1 |
| else: |
| return x # not initialized |
| |
| print(x) |
| `, |
| []string{ |
| ":7: Variable \"x\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(y): |
| if y < 0: |
| return |
| elif y > 0: |
| x = 1 |
| else: |
| pass |
| |
| print(x) # not initialized |
| `, |
| []string{ |
| ":9: Variable \"x\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(): |
| for x in y: |
| print(x) |
| print(x.attr) |
| |
| print(x) |
| print(x.attr) |
| `, |
| []string{ |
| ":6: Variable \"x\" may not have been initialized.", |
| ":7: Variable \"x\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(): |
| for x in y: |
| a = x |
| print(a) |
| |
| print(a) |
| `, |
| []string{ |
| ":6: Variable \"a\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def f(): |
| if foo: |
| x = foo |
| |
| f(x = y) |
| `, |
| []string{}, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def f(): |
| if foo: |
| x = foo |
| |
| f(x + y) |
| `, |
| []string{ |
| ":5: Variable \"x\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def f(): |
| if foo: |
| x = foo |
| |
| x, y = 1, x |
| `, |
| []string{ |
| ":5: Variable \"x\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def f(): |
| if foo: |
| x = foo |
| |
| x, y = 1, 2 |
| `, |
| []string{}, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def f(y): |
| return [x for x in y if x] |
| |
| x = 1 |
| `, |
| []string{}, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def f(): |
| if foo: |
| f(x = foo) |
| else: |
| x = 3 |
| |
| print(x) |
| `, |
| []string{ |
| ":7: Variable \"x\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(x): |
| for y in x: |
| if foo: |
| break |
| elif bar: |
| continue |
| elif baz: |
| return |
| else: |
| z = 3 |
| print(z) |
| `, |
| []string{}, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(x: int, y: int = 2): |
| if bar: |
| x = 1 |
| y = 2 |
| z = 3 |
| |
| print(x + y + z) |
| `, |
| []string{ |
| ":7: Variable \"z\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(x: int, y: int = 2): |
| def bar(y=x): |
| if baz: |
| x = 1 |
| y = 2 |
| z = 3 |
| |
| print(x + y + z) |
| |
| if something: |
| x = bar() |
| |
| return x |
| `, |
| []string{ |
| ":8: Variable \"x\" may not have been initialized.", |
| ":8: Variable \"z\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(x: int, y: int = 2): |
| if bar: |
| y, z, t = 2, 3, 4 |
| w, s = 5, 6 |
| r = 7 |
| |
| [t for t in range(5)] |
| [a for a in range(z + y)] |
| {b: c + s for b, c in [ |
| d * 2 for d in range(t) |
| if d != baz(r=w) |
| ]} |
| `, |
| []string{ |
| ":8: Variable \"z\" may not have been initialized.", |
| ":9: Variable \"s\" may not have been initialized.", |
| ":10: Variable \"t\" may not have been initialized.", |
| ":11: Variable \"w\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(): |
| x = 1 |
| for y, z in t: |
| print(y, z) |
| |
| def bar(x, y, s = z): |
| pass |
| `, |
| []string{ |
| ":6: Variable \"z\" may not have been initialized.", |
| }, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(): |
| for bar in baz: |
| pass |
| |
| y = [baz.get(bar) for bar in bars] |
| x = lambda bar: baz.get(bar) |
| `, |
| []string{}, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(): |
| def bar(x): |
| print(x) |
| |
| for x, y in z: |
| bar(x) |
| `, |
| []string{}, |
| scopeEverywhere) |
| |
| checkFindings(t, "uninitialized", ` |
| def foo(): |
| [x, y] = [1, 2] |
| x = 3 |
| print(x) |
| `, |
| []string{}, |
| scopeEverywhere) |
| } |