pytest-dev / pytest-dev/pytest

Making rewrite and import of custom DSL play nice

Open
#3,477 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: help wanted topic: rewrite
Dominant language
Python
Stars
14.5k
Forks
3.4k
Avg merge
2d 9h
Merged PRs (30d)
35

Description

I am currently writing a custom importer for a Domain Specific Language.

Lets call calc the module written in a simple DSL. Meaning that I do:

with my_custom_importer():  # installs the loader in the path hooks
    from . import calc

The import works fine, the DSL is parsed with the Loader, which override the get_source method, transforming the DSL into python source and importing it.

The problem arises when I use pytest in some test modules:

with my_custom_importer():  # installs the loader in the path hooks
    from . import calc

def test_calc():
    assert calc.works_fine()

if __name__ == '__main__':
    pytest.main(['-s'])

and when pytest attempts to rewrite the asserts in there :

tests/test_lark/calc/tests/test_parse.py:None (tests/test_lark/calc/tests/test_parse.py)
/home/alexv/.virtualenvs/replator/lib/python3.5/site-packages/_pytest/python.py:412: in _importtestmodule
    mod = self.fspath.pyimport(ensuresyspath=importmode)
/home/alexv/.virtualenvs/replator/lib/python3.5/site-packages/py/_path/local.py:668: in pyimport
    __import__(modname)
<frozen importlib._bootstrap>:969: in _find_and_load
    ???
<frozen importlib._bootstrap>:958: in _find_and_load_unlocked
    ???
<frozen importlib._bootstrap>:664: in _load_unlocked
    ???
<frozen importlib._bootstrap>:634: in _load_backward_compatible
    ???
/home/alexv/.virtualenvs/replator/lib/python3.5/site-packages/_pytest/assertion/rewrite.py:213: in load_module
    py.builtin.exec_(co, mod.__dict__)
calc/tests/test_parse.py:5: in <module>
    from .. import calc
E     File "/home/alexv/Projects/palimport/tests/test_lark/calc/calc.lark", line 1
E       //
E        ^
E   SyntaxError: invalid syntax

It breaks on the DSL syntax in that module.
It seems it doesn't use the custom loader for that module...

Any idea how to investigate this and get it right ?
Any example of pytest running with custom importers (and non-python syntax in module) ?
Or is there any way to disable the rewrite, in cases like this where it might get us into trouble ?

my pytest setup:

(replator) alexv@alexv-XPS-Tablet:~/Projects/palimport$ pytest --version
This is pytest version 3.5.1, imported from /home/alexv/.virtualenvs/replator/lib/python3.5/site-packages/pytest.py
setuptools registered plugins:
  pytest-xdist-1.22.2 at /home/alexv/.virtualenvs/replator/lib/python3.5/site-packages/xdist/plugin.py
  pytest-xdist-1.22.2 at /home/alexv/.virtualenvs/replator/lib/python3.5/site-packages/xdist/looponfail.py
  pytest-forked-0.2 at /home/alexv/.virtualenvs/replator/lib/python3.5/site-packages/pytest_forked/__init__.py

I ll try to get a minimal reproducible example, but that might be tricky, given the machinery involved...

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with pytest's assertion-rewriting path, especially _pytest/assertion/rewrite.py and _pytest/python.py named in the traceback, and compare it with the custom importer's Loader.get_source behavior. Build the promised minimal reproducible example around the Python 3.5 setup and a non-Python DSL module. Done means the custom-imported DSL test module no longer fails on DSL syntax during collection, or the supported way to disable rewriting for it is documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.