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

Expand warnings output for ResourceWarning #9682

Merged
merged 3 commits into from Feb 15, 2022

Conversation

nicoddemus
Copy link
Member

Fix #9644

cc @fschulze

@nicoddemus
Copy link
Member Author

Here's the output for the test in the suite:

============================== warnings summary ===============================
test_resource_warning.py::test_resource_warning
  E:\.tmp\pytest-of-Pichau\pytest-1285\test_resource_warning0\test_resource_warning.py:8: ResourceWarning: unclosed file <_io.TextIOWrapper name='E:\\.tmp\\pytest-of-Pichau\\pytest-1285\\tmp-test_resource_warning0\\pytest-of-Pichau\\pytest-1\\test_resource_warning0\\foo.txt' mode='r' encoding='cp1252'>
    open_file(p)
  
  Object allocated at (most recent call first):
    File "E:\projects\pytest\src\_pytest\main.py", line 347
      item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
    File "E:\projects\pytest\.env39\lib\site-packages\pluggy\_hooks.py", line 265
      return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
    File "E:\projects\pytest\.env39\lib\site-packages\pluggy\_manager.py", line 80
      return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
    File "E:\projects\pytest\.env39\lib\site-packages\pluggy\_callers.py", line 39
      res = hook_impl.function(*args)
    File "E:\projects\pytest\src\_pytest\runner.py", line 113
      runtestprotocol(item, nextitem=nextitem)
    File "E:\projects\pytest\src\_pytest\runner.py", line 132
      reports.append(call_and_report(item, "call", log))
    File "E:\projects\pytest\src\_pytest\runner.py", line 221
      call = call_runtest_hook(item, when, **kwds)
    File "E:\projects\pytest\src\_pytest\runner.py", line 260
      return CallInfo.from_call(
    File "E:\projects\pytest\src\_pytest\runner.py", line 340
      result: Optional[TResult] = func()
    File "E:\projects\pytest\src\_pytest\runner.py", line 261
      lambda: ihook(item=item, **kwds), when=when, reraise=reraise
    File "E:\projects\pytest\.env39\lib\site-packages\pluggy\_hooks.py", line 265
      return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
    File "E:\projects\pytest\.env39\lib\site-packages\pluggy\_manager.py", line 80
      return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
    File "E:\projects\pytest\.env39\lib\site-packages\pluggy\_callers.py", line 39
      res = hook_impl.function(*args)
    File "E:\projects\pytest\src\_pytest\runner.py", line 168
      item.runtest()
    File "E:\projects\pytest\src\_pytest\python.py", line 1756
      self.ihook.pytest_pyfunc_call(pyfuncitem=self)
    File "E:\projects\pytest\.env39\lib\site-packages\pluggy\_hooks.py", line 265
      return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
    File "E:\projects\pytest\.env39\lib\site-packages\pluggy\_manager.py", line 80
      return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
    File "E:\projects\pytest\.env39\lib\site-packages\pluggy\_callers.py", line 39
      res = hook_impl.function(*args)
    File "E:\projects\pytest\src\_pytest\python.py", line 192
      result = testfunction(**testargs)
    File "E:\.tmp\pytest-of-Pichau\pytest-1285\test_resource_warning0\test_resource_warning.py", line 8
      open_file(p)

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

Copy link
Contributor

@fschulze fschulze left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thanks for the PR, you beat me to it 😉

# Use a leading new line to better separate the (large) output
# from the traceback to the previous warning text.
msg += (
f"\nObject allocated at (most recent call first):\n{formatted_tb}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure most recent call first is correct here, maybe just remove it?

@@ -81,6 +81,25 @@ def warning_record_to_str(warning_message: warnings.WarningMessage) -> str:
warning_message.lineno,
warning_message.line,
)
if warning_message.source is not None:
try:
import tracemalloc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there platforms which don't have tracemalloc available?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pypy3 CI failed with ImportError: cannot import _tracemalloc, so I went ahead and assumed that was the case, but didn't look into official sources TBH.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is likely that PyPy doesn't support it at all due to differing memory management.

Copy link
Member

@bluetech bluetech left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great to me! I left one comment.

except ImportError:
has_tracemalloc = False

pytester.makepyfile(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this test (tracemalloc not enabled) will fail if the person running the pytest test suite enables tracemalloc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm why do you say that? And do you mean running in CPython?

I tried it here:

python -X tracemalloc=20 -m pytest testing\test_warnings.py

And it passes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note the try/except is checking if tracemalloc is available at all, which is not on PyPy for example, not if tracemalloc is enabled or not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess python -X tracemalloc=20 doesn't transfer, but an envvar does, so try this:

PYTHONTRACEMALLOC=100 pytest testing/test_warnings.py -k resource

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh got it, good catch. 😁

Updated the test, thanks.

@nicoddemus nicoddemus enabled auto-merge (squash) February 15, 2022 12:42
@nicoddemus nicoddemus merged commit 9af3e23 into pytest-dev:main Feb 15, 2022
@nicoddemus nicoddemus deleted the 9644-resource-warning branch February 15, 2022 13:12
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.

Expand warnings output for ResourceWarning
3 participants