leopd / timebudget

Stupidly-simple speed measurements for Python.
Apache License 2.0
156 stars 13 forks source link

Doesn't work well with pytest - need ability to log to file instead. #13

Open vvasuki opened 4 years ago

vvasuki commented 4 years ago

The below illustrates the problem

Testing started at 8:26 AM ...
/usr/bin/python3.8 /home/vvasuki/.local/share/JetBrains/IntelliJIdea2020.2/python/helpers/pycharm/_jb_pytest_runner.py --target test_annual.py::test_panchanga_chennai_18 -- --log-cli-level 0 -k test_panchanga_chennai_18
Launching pytest with arguments --log-cli-level 0 -k test_panchanga_chennai_18 test_annual.py::test_panchanga_chennai_18 in /home/vvasuki/sanskrit-coders/jyotisha/tests/spatio_temporal

============================= test session starts ==============================
platform linux -- Python 3.8.5, pytest-6.1.0, py-1.9.0, pluggy-0.13.1 -- /usr/bin/python3.8
cachedir: .pytest_cache
rootdir: /home/vvasuki/sanskrit-coders/jyotisha, configfile: pyproject.toml
plugins: xonsh-0.9.22
collecting ... 
----------------------------- live log collection ------------------------------
DEBUG    root:common.py:928 {'DataSource': <class 'sanskrit_data.schema.common.DataSource'>, 'JsonObject': <class 'sanskrit_data.schema.common.JsonObject'>, 'JsonObjectNode': <class 'sanskrit_data.schema.common.JsonObjectNode'>, 'NamedEntity': <class 'sanskrit_data.schema.common.NamedEntity'>, 'SchemaError': <class 'jsonschema.exceptions.SchemaError'>, 'ScriptRendering': <class 'sanskrit_data.schema.common.ScriptRendering'>, 'Target': <class 'sanskrit_data.schema.common.Target'>, 'TargetValidationError': <class 'sanskrit_data.schema.common.TargetValidationError'>, 'Text': <class 'sanskrit_data.schema.common.Text'>, 'UllekhanamJsonObject': <class 'sanskrit_data.schema.common.UllekhanamJsonObject'>, 'ValidationError': <class 'jsonschema.exceptions.ValidationError'>}
DEBUG    matplotlib:__init__.py:241 CACHEDIR=/home/vvasuki/.cache/matplotlib
DEBUG    matplotlib.font_manager:font_manager.py:1436 Using fontManager instance from /home/vvasuki/.cache/matplotlib/fontlist-v330.json
collected 1 item

test_annual.py::test_panchanga_chennai_18 

============================== 1 passed in 24.22s ==============================
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/timebudget/timebudget.py", line 118, in report
    self._print("timebudget report...")
  File "/usr/lib/python3.8/site-packages/timebudget/timebudget.py", line 65, in _print
    self.out_stream.write(msg)
ValueError: I/O operation on closed file.

Process finished with exit code 0

-------------------------------- live log call ---------------------------------
INFO     root:annual.py:74 No precomputed data available. Computing panchaanga...

Settings used:


timebudget.set_quiet()  # don't show measurements as they happen
timebudget.report_at_exit()  # Generate report when the program exits
PranayAnchuri commented 3 years ago

I encountered the same issue. The following alternative works:

  1. Remove report_at_exit() during the setup
  2. Add timebudget.report() at the end of program.
leuchtum commented 1 year ago

Same problem, here is my alternative:

I use timebudget as a dev dependency, so the context manager has to default to a contextlib.nullcontext in production mode. While testing with pytest (also in the dev environment) I get the same ValueError: I/O operation on closed file. Error. Therefore I use sys.modules to check if pytest is running:

# File mylib.timing.py
try:
    import sys as __sys

    from timebudget import timebudget as timed

    timed.set_quiet()

    if "pytest" not in __sys.modules:
        timed.report_at_exit()
except ImportError:
    from contextlib import nullcontext as timed
# File mylib.foo.py
from mylib.timing import timed

@timed
def func_to_be_timed():
    ...