File: test_environment.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 (154 lines) | stat: -rw-r--r-- 5,219 bytes parent folder | download | duplicates (3)
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
import os
import sys

import pytest

import jedi
from jedi.api.environment import get_default_environment, find_virtualenvs, \
    InvalidPythonEnvironment, find_system_environments, \
    get_system_environment, create_environment, InterpreterEnvironment, \
    get_cached_default_environment


def test_sys_path():
    assert get_default_environment().get_sys_path()


def test_find_system_environments():
    envs = list(find_system_environments())
    assert len(envs)
    for env in envs:
        assert env.version_info
        assert env.get_sys_path()
        parser_version = env.get_grammar().version_info
        assert parser_version[:2] == env.version_info[:2]


@pytest.mark.parametrize(
    'version',
    ['3.6', '3.7', '3.8', '3.9']
)
def test_versions(version):
    try:
        env = get_system_environment(version)
    except InvalidPythonEnvironment:
        if int(version.replace('.', '')) == str(sys.version_info[0]) + str(sys.version_info[1]):
            # At least the current version has to work
            raise
        pytest.skip()

    assert version == str(env.version_info[0]) + '.' + str(env.version_info[1])
    assert env.get_sys_path()


def test_load_module(inference_state):
    access_path = inference_state.compiled_subprocess.load_module(
        dotted_name='math',
        sys_path=inference_state.get_sys_path()
    )
    name, access_handle = access_path.accesses[0]

    assert access_handle.py__bool__() is True
    assert access_handle.get_api_type() == 'module'
    with pytest.raises(AttributeError):
        access_handle.py__mro__()


def test_error_in_environment(inference_state, Script, environment):
    if isinstance(environment, InterpreterEnvironment):
        pytest.skip("We don't catch these errors at the moment.")

    # Provoke an error to show how Jedi can recover from it.
    with pytest.raises(jedi.InternalError):
        inference_state.compiled_subprocess._test_raise_error(KeyboardInterrupt)
    # The second time it should raise an InternalError again.
    with pytest.raises(jedi.InternalError):
        inference_state.compiled_subprocess._test_raise_error(KeyboardInterrupt)
    # Jedi should still work.
    def_, = Script('str').infer()
    assert def_.name == 'str'


def test_stdout_in_subprocess(inference_state, Script):
    inference_state.compiled_subprocess._test_print(stdout='.')
    Script('1').infer()


def test_killed_subprocess(inference_state, Script, environment):
    if isinstance(environment, InterpreterEnvironment):
        pytest.skip("We cannot kill our own process")
    # Just kill the subprocess.
    inference_state.compiled_subprocess._compiled_subprocess._get_process().kill()
    # Since the process was terminated (and nobody knows about it) the first
    # Jedi call fails.
    with pytest.raises(jedi.InternalError):
        Script('str').infer()

    def_, = Script('str').infer()
    # Jedi should now work again.
    assert def_.name == 'str'


def test_not_existing_virtualenv(monkeypatch):
    """Should not match the path that was given"""
    path = '/foo/bar/jedi_baz'
    monkeypatch.setenv('VIRTUAL_ENV', path)
    assert get_default_environment().executable != path


def test_working_venv(venv_path, monkeypatch):
    monkeypatch.setenv('VIRTUAL_ENV', venv_path)
    assert get_default_environment().path == venv_path


def test_scanning_venvs(venv_path):
    parent_dir = os.path.dirname(venv_path)
    assert any(venv.path == venv_path
               for venv in find_virtualenvs([parent_dir]))


def test_create_environment_venv_path(venv_path):
    environment = create_environment(venv_path)
    assert environment.path == venv_path


def test_create_environment_executable():
    environment = create_environment(sys.executable)
    assert environment.executable == sys.executable


def test_get_default_environment_from_env_does_not_use_safe(tmpdir, monkeypatch):
    fake_python = os.path.join(str(tmpdir), 'fake_python')
    with open(fake_python, 'w', newline='') as f:
        f.write('')

    def _get_subprocess(self):
        if self._start_executable != fake_python:
            raise RuntimeError('Should not get called!')
        self.executable = fake_python
        self.path = 'fake'

    monkeypatch.setattr('jedi.api.environment.Environment._get_subprocess',
                        _get_subprocess)

    monkeypatch.setenv('VIRTUAL_ENV', fake_python)
    env = get_default_environment()
    assert env.path == 'fake'


@pytest.mark.parametrize('virtualenv', ['', 'fufuuuuu', sys.prefix])
def test_get_default_environment_when_embedded(monkeypatch, virtualenv):
    # When using Python embedded, sometimes the executable is not a Python
    # executable.
    executable_name = 'RANDOM_EXE'
    monkeypatch.setattr(sys, 'executable', executable_name)
    monkeypatch.setenv('VIRTUAL_ENV', virtualenv)
    env = get_default_environment()
    assert env.executable != executable_name


def test_changing_venv(venv_path, monkeypatch):
    monkeypatch.setitem(os.environ, 'VIRTUAL_ENV', venv_path)
    get_cached_default_environment()
    monkeypatch.setitem(os.environ, 'VIRTUAL_ENV', sys.executable)
    assert get_cached_default_environment().executable == sys.executable