Skip to content

Tests from mypy/test/teststubtest.py fail without pytest-xdist or with v2.3.0 #11019

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sbraz opened this issue Aug 24, 2021 · 0 comments · Fixed by #12282
Closed

Tests from mypy/test/teststubtest.py fail without pytest-xdist or with v2.3.0 #11019

sbraz opened this issue Aug 24, 2021 · 0 comments · Fixed by #12282
Labels
bug mypy got something wrong topic-stubtest

Comments

@sbraz
Copy link
Contributor

sbraz commented Aug 24, 2021

Bug Report

Hi,
I have noticed that tests frommypy/test/teststubtest.py fail with pytest-xdist 2.3.0. This is the faulty commit:
pytest-dev/pytest-xdist@56e631b

It is especially problematic because they also fail without pytest-xdist, so I am not sure the bug is actually pytest-xdist's fault.

I understand that you have pinned an older version of pytest-xdist but some day you might still to have to deal with this issue.

To Reproduce

Here is an example Dockerfile which you can edit to test the faulty commit and its working parent. Getting rid of pytest-xdist does not fix the issue either.

FROM python:3.9
RUN git clone --depth 1 https://github.com/python/mypy
WORKDIR mypy
RUN pip install -r test-requirements.txt

# This commit is fine
#RUN pip install -U git+https://github.com/pytest-dev/pytest-xdist@7f2426b11d2c7890e5637fdaa3aa1c75b4f31758

# This one is broken
RUN pip install -U git+https://github.com/pytest-dev/pytest-xdist@56e631b4bbeedf7ef6da94d3c5eab00c20a07d12

# Disabling pytest-xdist makes tests fail too
#RUN pip uninstall -y pytest-xdist
#RUN pytest -o addopts= -vv mypy/test/teststubtest.py

RUN pytest -vv mypy/test/teststubtest.py

Expected Behavior

Tests should pass.

Actual Behavior

Tests fail because of a sys.path problem, e.g.:

_________________________ StubtestMiscUnit.test_output _________________________ 
[gw2] linux -- Python 3.9.6 /usr/local/bin/python                                                        
                                                    
self = <mypy.test.teststubtest.StubtestMiscUnit testMethod=test_output>
                                                    
    def test_output(self) -> None:
        output = run_stubtest(
            stub="def bad(number: int, text: str) -> None: ...",
            runtime="def bad(num, text): pass",
            options=[],
        )    
        expected = (
            'error: {0}.bad is inconsistent, stub argument "number" differs from runtime '
            'argument "num"\nStub: at line 1\ndef (number: builtins.int, text: builtins.str)\n'
            "Runtime: at line 1 in file {0}.py\ndef (num, text)\n\n".format(TEST_MODULE_NAME)
        )                                                                                                
>       assert remove_color_code(output) == expected                            
E       AssertionError: assert ("error: test_module failed to import: No module named 'test_module'\n"\n 'Stub: at line 1\n'\n 'MypyFile:1(\n'\n '  test_module.pyi)\n'\n 'Runtime:\n'\n 'MISSING\n'\n '\n') == ('e
rror: test_module.bad is inconsistent, stub argument "number" differs from '\n 'runtime argument "num"\n'\n 'Stub: at line 1\n'\n 'def (number: builtins.int, text: builtins.str)\n'\n 'Runtime: at line 1 in file 
test_module.py\n'\n 'def (num, text)\n'\n '\n')                                                          
E         - error: test_module.bad is inconsistent, stub argument "number" differs from runtime argument "num"
E         + error: test_module failed to import: No module named 'test_module'  
E           Stub: at line 1                                                                              
E         - def (number: builtins.int, text: builtins.str)                      
E         - Runtime: at line 1 in file test_module.py                           
E         - def (num, text)                                                                              
E         + MypyFile:1(                                                                                  
E         +   test_module.pyi)                                                                           
E         + Runtime:                                                                                     
E         + MISSING                                                                                      
                                                                                                         
mypy/test/teststubtest.py:754: AssertionError                                                            

Your Environment

  • Mypy version used: git master
  • Mypy command-line flags: N/A
  • Mypy configuration options from mypy.ini (and other config files): N/A
  • Python version used: 3.9.6
  • Operating system and version: Debian Bullseye
@sbraz sbraz added the bug mypy got something wrong label Aug 24, 2021
bmwiedemann pushed a commit to bmwiedemann/openSUSE that referenced this issue Jan 23, 2022
https://build.opensuse.org/request/show/948161
by user sebix + dimstar_suse
- Skip teststubtest because we use a pytest-xdist version which is
  not allowed by upstream -- gh#python/mypy#11019 (forwarded request 948145 from bnavigator)
stanislavlevin added a commit to stanislavlevin/mypy that referenced this issue Mar 3, 2022
Description:
`run_stubtest` creates temp directory and prepend `sys.path` with
relative path (dot `.`) wrongly assuming that the dot will be
resolved to absolute path on *every* import attempt.

But in Python dot(`.`) in sys.path is actually resolved by
PathFinder and cached in `sys.path_importer_cache` like:
```
sys.path_importer_cache['.']
FileFinder('/somepath/.')
```
later calls for `find_module` return None and import of
`test_module` fails.

This resulted in only the first test in stubtest's suite passed in
non-pytest-xdist environments.

This issue was hidden with bug or feature in pytest-xdist < 2.3.0:
pytest-dev/pytest-xdist#421

It was fixed in pytest-xdist 2.3.0:
pytest-dev/pytest-xdist#667

- sys.path for pytest-xdist < 2.3.0
  `'.', 'project_path', ''`

- sys.path for pytest-xdist >= 2.3.0 or without xdist
  `'.', 'project_path'`

Fix:
In Python for denoting cwd the empty path `''` can be used as a
special case, but for readability `sys.path` is prepended with
resolved absolute path of temp directory. Also it's essential to
restore back `sys.path` after a test to not break subsequent tests.

Fixes: python#11019
Signed-off-by: Stanislav Levin <[email protected]>
hauntsaninja pushed a commit that referenced this issue Mar 4, 2022
Fixes #11019

`run_stubtest` creates temp directory and prepend `sys.path` with relative path (dot `.`) wrongly assuming that the dot will be resolved to absolute path on *every* import attempt.

But in Python dot(`.`) in sys.path is actually resolved by PathFinder and cached in `sys.path_importer_cache` like:
```
sys.path_importer_cache['.']
FileFinder('/somepath/.')
```
later calls for `find_module` return None and import of `test_module` fails. This resulted in only the first test in stubtest's suite passed in non-pytest-xdist environments.

This issue was hidden with bug or feature in pytest-xdist < 2.3.0:
pytest-dev/pytest-xdist#421

It was fixed in pytest-xdist 2.3.0:
pytest-dev/pytest-xdist#667

- sys.path for pytest-xdist < 2.3.0
  `'.', 'project_path', ''`

- sys.path for pytest-xdist >= 2.3.0 or without xdist
  `'.', 'project_path'`

In Python for denoting cwd the empty path `''` can be used as a special case, but for readability `sys.path` is prepended with resolved absolute path of temp directory. Also it's essential to restore back `sys.path` after a test to not break subsequent tests.

Signed-off-by: Stanislav Levin <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-stubtest
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants