question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Docs on warnings filters should note that `ResourceWarning` is often delayed

See original GitHub issue

Some of my tests need to ensure open files are closed. Let’s use the simplest example:

# test_example.py
import pytest

@pytest.mark.filterwarnings('error::ResourceWarning')
def test_resourcewarning():
    open('/dev/null')

When I run pytest, the warning is thrown and even printed in the test output, but the test still passes:

$ pytest
======================================== test session starts =========================================
platform darwin -- Python 3.10.2, pytest-7.1.1, pluggy-1.0.0
rootdir: /path/to/project
collected 1 item

test_example.py .                                                                              [100%]

========================================== warnings summary ==========================================
test_example.py::test_resourcewarning
  /path/to/python/site-packages/_pytest/unraisableexception.py:78: PytestUnraisableExceptionWarning: 
Exception ignored in: <_io.FileIO [closed]>

  Traceback (most recent call last):
    File "/path/to/project/test_example.py", line 5, in test_resourcewarning
      open('/dev/null')
  ResourceWarning: unclosed file <_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>

    warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
==================================== 1 passed, 1 warning in 0.01s ====================================

Removing @pytest.mark.filterwarnings or changing the warning type to something unrelated (like DeprecationWarning) results in the test passing without printing any warnings at all. That tells me pytest is picking up the warning, but it’s being subsequently caught by pytest.PytestUnraisableExceptionWarning, and my tests still pass because I wasn’t filtering for that. If I filter for pytest.PytestUnraisableExceptionWarning instead the test also passes, because it isn’t looking for the original ResourceWarning.

The only solution I can think of is to filter for both:

@pytest.mark.filterwarnings('error::ResourceWarning')
@pytest.mark.filterwarnings('error::pytest.PytestUnraisableExceptionWarning')

Unless I’m missing something this seems to be a bug for ResourceWarning in particular, since I can’t reproduce this with other warning types. I think failing the test case without requiring the 2nd generic warning filter is the reasonable expected behaviour here.

Note: this test example was run on a vanilla virtual env:

$ pip freeze
attrs==21.4.0
iniconfig==1.1.1
packaging==21.3
pluggy==1.0.0
py==1.11.0
pyparsing==3.0.7
pytest==7.1.1
tomli==2.0.1

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
dchevellcommented, Apr 19, 2022

Your explanation of expected behaviour is precisely what I was looking for, without that the change to docs wasn’t very clear.

Agreed on the explanatory section, perhaps the solution of filtering in combination with 'error::pytest.PytestUnraisableExceptionWarning' would fit there as well.

1reaction
Zac-HDcommented, Apr 19, 2022

It’s not behaving how you expect, but it is behaving how I expect it to - and IMO that means it’s a docs issue. And yes, unfortunately it’s not feasible to change this, because the ResourceWarning literally doesn’t exist in the scope that we want to handle it; the warning is only raised much later during garbage collection. In fact the language doesn’t guarantee that you’ll ever get a ResourceWarning, and so sometimes (often, on PyPy) you simply won’t!

So I think an explanatory section much like the “DeprecationWarning and PendingDeprecationWarning” section, and located just below it", would be useful here 🙂

Read more comments on GitHub >

github_iconTop Results From Across the Web

Python warnings come after thing trying to warn user about
in theory, filterwarnings should help shake out repeat warnings if used with right arguments # * note how our loop causes the content...
Read more >
warnings — Warning control — Python 3.11.1 documentation
The determination whether to issue a warning message is controlled by the warning filter, which is a sequence of matching rules and actions....
Read more >
How to create custom template tags and filters
You can extend the template engine by defining custom tags and filters using Python, and then make them available to your templates using...
Read more >
Hypothesis Documentation - Read the Docs
Note that as we saw in the above example you can pass arguments to @given either as ... register_random(r) # Hypothesis will emit...
Read more >
Full Changelog — Astropy v5.2
An Astropy table can now be converted to a scalar NumPy object array. ... This was always noted as allowed in an exception...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found