Skip to content
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

Making rewrite and import of custom DSL play nice #3477

Open
asmodehn opened this issue May 15, 2018 · 4 comments
Open

Making rewrite and import of custom DSL play nice #3477

asmodehn opened this issue May 15, 2018 · 4 comments
Labels
status: help wanted developers would like help from experts on this topic topic: rewrite related to the assertion rewrite mechanism

Comments

@asmodehn
Copy link

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...

@pytestbot
Copy link
Contributor

GitMate.io thinks possibly related issues are #1871 (No assertion rewriting in files imported from conftest), #1840 (register_assert_rewrite warns for already imported and rewritten modules), #2435 (f), #295 (lazy import of doctest in pdb breaks debugging if the environment makes doctest unimportable), and #296 (lazy import of doctest in pdb breaks debugging if the environment makes doctest unimportable).

@Sup3rGeo
Copy link
Member

Sup3rGeo commented May 21, 2018

@asmodehn , I'm no core developer but probably you want to look at the find_module and load_module methods in the AssertionRewritingHook class and see what it does:
https://github.com/pytest-dev/pytest/blob/master/_pytest/assertion/rewrite.py

The import hook is installed in the install_importhook function in the init module:
https://github.com/pytest-dev/pytest/blob/master/_pytest/assertion/__init__.py

@nicoddemus
Copy link
Member

nicoddemus commented May 24, 2018

@Sup3rGeo's tips are on point! 👍

I don't have time to check right now, but it might the order of the hooks because we install the assertion rewriter hook with:

config._assertstate.hook = hook = rewrite.AssertionRewritingHook(config)
sys.meta_path.insert(0, hook)

Your my_custom_importer context manager might be installing your hook using sys.meta_path.append, which would explain why pytest's hook runs first and fails to parse the file.

@nicoddemus nicoddemus added type: question general question, might be closed after 2 weeks of inactivity topic: rewrite related to the assertion rewrite mechanism labels May 24, 2018
@asmodehn
Copy link
Author

asmodehn commented May 25, 2018 via email

@Zac-HD Zac-HD added status: help wanted developers would like help from experts on this topic and removed type: question general question, might be closed after 2 weeks of inactivity labels Dec 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: help wanted developers would like help from experts on this topic topic: rewrite related to the assertion rewrite mechanism
Projects
None yet
Development

No branches or pull requests

5 participants