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

Don't hardcode 'std' for captured stdout/stderr. #1052

Merged
merged 1 commit into from
Sep 29, 2015
Merged

Don't hardcode 'std' for captured stdout/stderr. #1052

merged 1 commit into from
Sep 29, 2015

Conversation

The-Compiler
Copy link
Member

This will make Item.add_report_sect more usable for plugins.
See eisensheng/pytest-catchlog#7

This will make Item.add_report_sect more usable for plugins.
See eisensheng/pytest-catchlog#7
@hpk42
Copy link
Contributor

hpk42 commented Sep 22, 2015

Is there a chance you could add a test for add_report_section? (If it's too bothersome to write even a superficial test then i am probably fine).

Also if we start to consider this method as an external API it should grow a docstring so that doc/en/writing_plugins.rst "Item" docs pick it up.

@The-Compiler
Copy link
Member Author

I haven't actually taken a closer look at eisensheng/pytest-catchlog#7 yet - I wonder what's the right way to proceed.

Should add_report_section be public API, or should the PR not use add_report_section in pytest_runtest_* and instead save stuff in item and use pytest_runtest_makereport?

@nicoddemus what's your take on this? It seems pytest-qt does something quite similar with Qt logging messages.

/cc @abusalimov

@nicoddemus
Copy link
Member

FWIW on pytest-qt I use longrepr.addsection, on pytest_runtest_makereport:

@pytest.mark.hookwrapper
def pytest_runtest_makereport(self, item, call):    
    outcome = yield   
    report = outcome.result
    ...
    if not report.passed:
        long_repr = getattr(report, 'longrepr', None)
        if hasattr(long_repr, 'addsection'):  
            ...
            if lines:
                long_repr.addsection('Captured Qt messages', '\n'.join(lines))

(full code here)

I didn't know about Item.add_report_section, otherwise I think I would have used it myself as it seems easier to use. 😁

I could replace all the above by simply calling item.add_report_section and let pytest do all the handling of displaying it if the test fails. Seems nice and general to me.

I think we should make it part of the public API, along with adding a get_report_sections() for completeness with it.

Nevertheless, this PR should be merged as solves a small wart. 👍

@hpk42
Copy link
Contributor

hpk42 commented Sep 24, 2015

i agree it should be merged but at least there should be docs (see my previous comment). Also, shouldn't the PR target features instead of master?

@The-Compiler
Copy link
Member Author

agree it should be merged but at least there should be docs (see my previous comment)

I hope I can add docs today or tomorrow. As for tests, the functionality is already tested by test_capture.py but I can check if there's a good place to add some more fine-grained tests.

Also, shouldn't the PR target features instead of master?

I'm not sure. I didn't think of this PR as making item.add_report_section public (after all, it is already "public" in the sense of not being prefixed by _), but merely of fixing a wart (the std being hardcoded).

If you consider this as a new added feature, maybe that'd be better?

@nicoddemus
Copy link
Member

I'm not sure. I didn't think of this PR as making item.add_report_section public (after all, it is already "public" in the sense of not being prefixed by _), but merely of fixing a wart (the std being hardcoded).

I agree. if it was becoming public then it would be different, but here an existing feature is being documented better. Even if someone makes use of it by looking at the docs for 2.8.1, the same code will still work in 2.8.0. 😄

@RonnyPfannschmidt
Copy link
Member

we should note that the api of that method is completely wrong

the assumption is that the added section has something to do with capture
it ignores any semantics of when

we should ensure to deprecate that one quickly and think about a better way to add sections to reports

@abusalimov
Copy link

abusalimov commented Sep 26, 2015 via email

@RonnyPfannschmidt
Copy link
Member

@abusalimov however the sections are accumulated over all when actions, so a call report also adds the items of a setup, and a teardown report also adds the sections of call and setup

when in that part of the code is purely cosmetic, its not considered for semantics

@abusalimov
Copy link

@RonnyPfannschmidt I guess, you're right. Probably a better place for storing sections would be an instance of CallInfo created for each setup/call/teardown invocation. It already holds when attribute, exception info, if any, so I guess, it could also hold report sections as well.

BTW, what is the rationale for pytest_runtest_xxx hooks accepting an item, but not a call? Backward compatibility? Or do I just misunderstand the semantics?

@RonnyPfannschmidt
Copy link
Member

@abusalimov a call is directly evaluated and then has the result information of that call, thus making it a parameter to the other hooks is semantically wrong

if it was not directly evaluated, we would have a huge semantic missmatch

@abusalimov
Copy link

@RonnyPfannschmidt Is it that wrong to pass call=self to a hook from the CallInfo.__init__()? The only drawback is that the call instance would be incomplete during execution of the hook.

@nicoddemus
Copy link
Member

we should ensure to deprecate that one quickly and think about a better way to add sections to reports

Then we should hold on adding docs for it as it would elevate it even more to "public" status. Can we merge this PR then? The "wart removal" is worth it, and it seems add_report_section warrants more discussion (which is out of scope for this PR).

@RonnyPfannschmidt
Copy link
Member

@abusalimov it would completely change the scope of callinfo - i'm strictly opposed unless someone presents a good reason

@RonnyPfannschmidt
Copy link
Member

@The-Compiler please add to the doc-string that this function is accidentally under a public name and scheduled for removal/replacement, once we have the replacement we can add in a pytest-warning and schedule it for complete removal in 3.0

hpk42 added a commit that referenced this pull request Sep 29, 2015
Don't hardcode 'std' for captured stdout/stderr.
@hpk42 hpk42 merged commit f61f39e into pytest-dev:master Sep 29, 2015
abusalimov added a commit to abusalimov/pytest-catchlog that referenced this pull request Oct 1, 2015
Take advantage of `@pytest.mark.hookwrapper` facility and use more
idiomatic pytest_runtest_call(item) hook for performing capturing (in
fact, the same is used by the core 'pytest.capture' module).

Instead of messing around `report.longrepr` internals and since we
don't have a `report` instance at the moment of executing
pytest_runtest_call() anyway (it used to be created within a more late
pytest_runtest_makereport() hook), use a higher-level
item.add_report_section() method to attach log output to a report.

However, there is a drawback that now reports show sections named like
'Captured stdlog ...' ('std' is hardcoded). This is an issue of the
pytest itself addressed in pytest-dev/pytest#1052. That PR also
contains a discussion on deprecating Item.add_report_section(),
however the same approach is still used by 'pytest.capture', so it
should be fine to use it here as well.

This change also removes the use of the deprecated '__multicall__', so
that fixes eisensheng#3.
abusalimov added a commit to abusalimov/pytest-catchlog that referenced this pull request Oct 1, 2015
Take advantage of `@pytest.mark.hookwrapper` facility and use more
idiomatic pytest_runtest_call(item) hook for performing capturing (in
fact, the same is used by the core 'pytest.capture' module).

Instead of messing around `report.longrepr` internals and since we
don't have a `report` instance at the moment of executing
pytest_runtest_call() anyway (it used to be created within a more late
pytest_runtest_makereport() hook), use a higher-level
item.add_report_section() method to attach log output to a report.

However, there is a drawback that now reports show sections named like
'Captured stdlog ...' ('std' is hardcoded). This is an issue of the
pytest itself addressed in pytest-dev/pytest#1052. That PR also
contains a discussion on deprecating Item.add_report_section(),
however the same approach is still used by 'pytest.capture', so it
should be fine to use it here as well.

This change also removes the use of the deprecated '__multicall__', so
that fixes eisensheng#3.
abusalimov added a commit to abusalimov/pytest-catchlog that referenced this pull request Nov 16, 2015
Take advantage of `@pytest.mark.hookwrapper` facility and use more
idiomatic pytest_runtest_call(item) hook for performing capturing (in
fact, the same is used by the core 'pytest.capture' module).

Instead of messing around `report.longrepr` internals and since we
don't have a `report` instance at the moment of executing
pytest_runtest_call() anyway (it used to be created within
pytest_runtest_makereport() hook), use a higher-level
item.add_report_section() method to attach log output to a report.

However, there is a drawback that now reports show sections named like
'Captured stdlog ...' ('std' is hardcoded). Nevertheless this is likely
to be an issue of the pytest itself. It is addressed in
pytest-dev/pytest#1052, and that PR also contains a discussion on
deprecating Item.add_report_section(). However, the same approach is
still used by 'pytest.capture', so it should be fine to use it here as
well.

This change also removes the use of the deprecated '__multicall__', so
that fixes eisensheng#3.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants