summaryrefslogtreecommitdiff
path: root/tests/functional/u/used/used_before_assignment_issue85.py
blob: 7ede436bb974978037e4f478247e189a77a4f14c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
"""https://github.com/pylint-dev/pylint/issues/85"""
def main():
    """When evaluating finally blocks, assume try statements fail."""
    try:
        res = 1 / 0
        res = 42
    finally:
        print(res)  # [used-before-assignment]
    print(res)


def try_except_finally():
    """When evaluating finally blocks, assume try statements fail."""
    try:
        res = 1 / 0
        res = 42
    except ZeroDivisionError:
        print()
    finally:
        print(res)  # [used-before-assignment]
    print(res)


def try_except_finally_assignment_in_final_block():
    """Assignment of the name in the final block does not warn."""
    try:
        res = 1 / 0
        res = 42
    except ZeroDivisionError:
        print()
    finally:
        res = 999
        print(res)
    print(res)


def try_except_finally_nested_try_finally_in_try():
    """Don't confuse assignments in different finally statements where
    one is nested inside a try.
    """
    try:
        try:
            res = 1 / 0
        finally:
            print(res)  # [used-before-assignment]
        print(1 / 0)
    except ZeroDivisionError:
        print()
    finally:
        res = 999  # this assignment could be confused for that above
        print(res)
    print(res)


def try_except_finally_nested_in_finally():
    """Until Pylint comes to a consensus on requiring all except handlers to
    define a name, raise, or return (https://github.com/pylint-dev/pylint/issues/5524),
    Pylint assumes statements in try blocks succeed when accessed *after*
    except or finally blocks and fail when accessed *in* except or finally
    blocks.)
    """
    try:
        outer_times = 1
    finally:
        try:
            inner_times = 1
        except TypeError:
            pass
        finally:
            print(outer_times)  # [used-before-assignment]
        print(inner_times)  # see docstring: might emit in a future version


def try_except_finally_nested_in_finally_2():
    """Neither name is accessed after a finally block."""
    try:
        outer_times = 1
    finally:
        try:
            inner_times = 1
        except TypeError:
            pass
        finally:
            print(inner_times)  # [used-before-assignment]
        print(outer_times)  # [used-before-assignment]


def try_except_finally_nested_in_finally_3():
    """One name is never accessed after a finally block, but just emit
    once per name.
    """
    try:
        outer_times = 1
    finally:
        try:
            inner_times = 1
        except TypeError:
            pass
        finally:
            print(inner_times)  # [used-before-assignment]
            print(outer_times)  # [used-before-assignment]
        print(inner_times)
        # used-before-assignment is only raised once per name
        print(outer_times)


def try_except_finally_nested_in_finally_4():
    """Triple nesting: don't assume direct parentages of outer try/finally
    and inner try/finally.
    """
    try:
        outer_times = 1
    finally:
        try:
            pass
        finally:
            try:
                inner_times = 1
            except TypeError:
                pass
            finally:
                print(inner_times)  # [used-before-assignment]
                print(outer_times)  # [used-before-assignment]
            print(inner_times)
            # used-before-assignment is only raised once per name
            print(outer_times)