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

Docs: API for pytest_collect_file #2493

Closed
pkch opened this Issue Jun 12, 2017 · 9 comments

Comments

Projects
None yet
3 participants
@pkch
Copy link
Contributor

pkch commented Jun 12, 2017

I'm not sure from reading the docs whether there is public API for pytest_collect_file that allows to fall back to the default collector. Would it be possible to clarify that?

Specifically, I need to use custom code to process certain (non-python) test files; I can recognize them by their path pattern. However, any other files should be processed using normal pytest rules. This would be very easy if I could (under custom-defined conditions) return the default collector from pytest_collect_file.

@RonnyPfannschmidt

This comment has been minimized.

Copy link
Member

RonnyPfannschmidt commented Jun 12, 2017

as far as i can tell all non-none results will be used,

while some hooks use the furst result, this one ises all results

@pkch

This comment has been minimized.

Copy link
Contributor Author

pkch commented Jun 12, 2017

Just to clarify this is the use case I'm talking about:

import _pytest
def pytest_collect_file(path, parent):
  ext = path.ext
  if ext == '.yaml':
    return YamlCollector(path=path, parent=parent)
  if ext == '.py':
    # here it's a regular .py file that should be handled by pytest the normal way
    return _pytest.python.pytest_collect_file(path, parent)

This works perfectly, but it uses non-public API by importing _pytest. It would be nice to show in the docs the proper way to do that, if it's available.

@pkch

This comment has been minimized.

Copy link
Contributor Author

pkch commented Jun 12, 2017

Oh wait... This works if I just to return None instead of _pytest.python.pytest_collect_file(path, parent). But how?

(The code snippet I posted above actually processes the .py files twice.)

@nicoddemus

This comment has been minimized.

Copy link
Member

nicoddemus commented Jun 12, 2017

As @RonnyPfannschmidt mentioned, pytest will call pytest_collect_file for all plugins and use all collectors returned by them (ignoring None of course). So what happens is that you will return a collector for .yaml files and pytest's own builtin python plugin will return its own collector and things just work.

So in summary you really should only check for .yaml files and return your collector in that case:

def pytest_collect_file(path, parent):
  if path.ext == '.yaml':
    return YamlCollector(path=path, parent=parent)

Pytest will gather all collectors returned by all plugins because even a .py file might have tests depending on the plugin: doctests inside docstrings (doctest plugin) and test functions (python plugin).

That's what the example in https://docs.pytest.org/en/latest/example/nonpython.html does, btw.

@pkch

This comment has been minimized.

Copy link
Contributor Author

pkch commented Jun 12, 2017

I misunderstood @RonnyPfannschmidt comment, now it makes sense!

@pkch

This comment has been minimized.

Copy link
Contributor Author

pkch commented Jun 12, 2017

Should I make a PR to add basically your explanation to the docs, or is it good enough to have it here in this issue? And thanks =)

@nicoddemus

This comment has been minimized.

Copy link
Member

nicoddemus commented Jun 12, 2017

A PR would be very welcome! 👍

@pkch

This comment has been minimized.

Copy link
Contributor Author

pkch commented Jun 12, 2017

Upon reading the docs more carefully, I realized that there's a very clear explanation here. The only thing I could add perhaps is to show the decorator firstresult=True above hooks that have that, do you think it would be useful?

@nicoddemus

This comment has been minimized.

Copy link
Member

nicoddemus commented Jun 12, 2017

The only thing I could add perhaps is to show the decorator firstresult=True above hooks that have that, do you think it would be useful?

Definitely, thanks! You will need to add that information in the docstring of each hook in hookspec.py.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.