File: test_names.py

package info (click to toggle)
python-jedi 0.19.1%2Bds1-1
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,680 kB
  • sloc: python: 28,783; makefile: 172; ansic: 13
file content (197 lines) | stat: -rw-r--r-- 5,218 bytes parent folder | download | duplicates (2)
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
"""
Tests for `api.names`.
"""

from textwrap import dedent

import pytest


def _assert_definition_names(definitions, names):
    assert [d.name for d in definitions] == names


def _check_names(get_names, source, names):
    definitions = get_names(dedent(source))
    _assert_definition_names(definitions, names)
    return definitions


def test_get_definitions_flat(get_names):
    _check_names(get_names, """
        import module
        class Class:
            pass
        def func():
            pass
        data = None
        """, ['module', 'Class', 'func', 'data'])


def test_dotted_assignment(get_names):
    _check_names(get_names, """
    x = Class()
    x.y.z = None
    """, ['x', 'z'])  # TODO is this behavior what we want?


def test_multiple_assignment(get_names):
    _check_names(get_names, "x = y = None", ['x', 'y'])


def test_multiple_imports(get_names):
    _check_names(get_names, """
    from module import a, b
    from another_module import *
    """, ['a', 'b'])


def test_nested_definitions(get_names):
    definitions = _check_names(get_names, """
    class Class:
        def f():
            pass
        def g():
            pass
    """, ['Class'])
    subdefinitions = definitions[0].defined_names()
    _assert_definition_names(subdefinitions, ['f', 'g'])
    assert [d.full_name for d in subdefinitions] == ['__main__.Class.f', '__main__.Class.g']


def test_nested_class(get_names):
    definitions = _check_names(get_names, """
    class L1:
        class L2:
            class L3:
                def f(): pass
            def f(): pass
        def f(): pass
    def f(): pass
    """, ['L1', 'f'])
    subdefs = definitions[0].defined_names()
    subsubdefs = subdefs[0].defined_names()
    _assert_definition_names(subdefs, ['L2', 'f'])
    _assert_definition_names(subsubdefs, ['L3', 'f'])
    _assert_definition_names(subsubdefs[0].defined_names(), ['f'])


def test_class_fields_with_all_scopes_false(get_names):
    definitions = _check_names(get_names, """
    from module import f
    g = f(f)
    class C:
        h = g

    def foo(x=a):
       bar = x
       return bar
    """, ['f', 'g', 'C', 'foo'])
    C_subdefs = definitions[-2].defined_names()
    foo_subdefs = definitions[-1].defined_names()
    _assert_definition_names(C_subdefs, ['h'])
    _assert_definition_names(foo_subdefs, ['x', 'bar'])


def test_async_stmt_with_all_scopes_false(get_names):
    definitions = _check_names(get_names, """
    from module import f
    import asyncio

    g = f(f)
    class C:
        h = g
        def __init__(self):
            pass

        async def __aenter__(self):
            pass

    def foo(x=a):
       bar = x
       return bar

    async def async_foo(duration):
        async def wait():
            await asyncio.sleep(100)
        for i in range(duration//100):
            await wait()
        return duration//100*100

    async with C() as cinst:
        d = cinst
    """, ['f', 'asyncio', 'g', 'C', 'foo', 'async_foo', 'cinst', 'd'])
    C_subdefs = definitions[3].defined_names()
    foo_subdefs = definitions[4].defined_names()
    async_foo_subdefs = definitions[5].defined_names()
    cinst_subdefs = definitions[6].defined_names()
    _assert_definition_names(C_subdefs, ['h', '__init__', '__aenter__'])
    _assert_definition_names(foo_subdefs, ['x', 'bar'])
    _assert_definition_names(async_foo_subdefs, ['duration', 'wait', 'i'])
    # We treat d as a name outside `async with` block
    _assert_definition_names(cinst_subdefs, [])


def test_follow_imports(get_names):
    # github issue #344
    imp = get_names('import datetime')[0]
    assert imp.name == 'datetime'
    datetime_names = [str(d.name) for d in imp.defined_names()]
    assert 'timedelta' in datetime_names


def test_names_twice(get_names):
    code = dedent('''
    def lol():
        pass
    ''')

    defs = get_names(code)
    assert defs[0].defined_names() == []


def test_simple_name(get_names):
    defs = get_names('foo', references=True)
    assert not defs[0]._name.infer()


def test_no_error(get_names):
    code = dedent("""
        def foo(a, b):
            if a == 10:
                if b is None:
                    print("foo")
                a = 20
        """)
    func_name, = get_names(code)
    a, b, a20 = func_name.defined_names()
    assert a.name == 'a'
    assert b.name == 'b'
    assert a20.name == 'a'
    assert a20.goto() == [a20]


@pytest.mark.parametrize(
    'code, index, is_side_effect', [
        ('x', 0, False),
        ('x.x', 0, False),
        ('x.x', 1, False),
        ('x.x = 3', 0, False),
        ('x.x = 3', 1, True),
        ('def x(x): x.x = 3', 1, False),
        ('def x(x): x.x = 3', 3, True),
        ('import sys; sys.path', 0, False),
        ('import sys; sys.path', 1, False),
        ('import sys; sys.path', 2, False),
        ('import sys; sys.path = []', 2, True),
    ]
)
def test_is_side_effect(get_names, code, index, is_side_effect):
    names = get_names(code, references=True, all_scopes=True)
    assert names[index].is_side_effect() == is_side_effect


def test_no_defined_names(get_names):
    definition, = get_names("x = (1, 2)")

    assert not definition.defined_names()