Skip to content

CI/TST: Error on PytestUnraisableExceptionWarning instead of using psutil to check open resources #51443

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

Merged
merged 19 commits into from
Feb 20, 2023

Conversation

mroeschke
Copy link
Member

Using psutil to check for open resources in tests has been a false positive for a while, picking up unrelated connections such as the database services.

Erroring on ResourceWarnings, captured by PytestUnraisableExceptionWarning, should be sufficient for validating that resources are not left open as a result of a test. pytest-dev/pytest#9825

@mroeschke mroeschke added CI Continuous Integration Unreliable Test Unit tests that occasionally fail labels Feb 16, 2023
@jbrockmendel
Copy link
Member

there have been times in the past where we did leave files open incorrectly, which I think the check this removes would catch. does the check this adds still catch those?

@mroeschke
Copy link
Member Author

Correct for example

 % git diff
diff --git a/pandas/tests/frame/test_api.py b/pandas/tests/frame/test_api.py
index e5787a7f16..c280fb9748 100644
--- a/pandas/tests/frame/test_api.py
+++ b/pandas/tests/frame/test_api.py
@@ -379,3 +379,7 @@ class TestDataFrameMisc:
         df = DataFrame()
         with tm.assert_produces_warning(None):
             inspect.getmembers(df)
+
+
+def test_open():
+    open("/dev/null")

% pytest pandas/tests/frame/test_api.py

...

pandas/tests/frame/test_api.py .................................F

...
    def unraisable_exception_runtest_hook() -> Generator[None, None, None]:
        with catch_unraisable_exception() as cm:
            yield
            if cm.unraisable:
                if cm.unraisable.err_msg is not None:
                    err_msg = cm.unraisable.err_msg
                else:
                    err_msg = "Exception ignored in"
                msg = f"{err_msg}: {cm.unraisable.object!r}\n\n"
                msg += "".join(
                    traceback.format_exception(
                        cm.unraisable.exc_type,
                        cm.unraisable.exc_value,
                        cm.unraisable.exc_traceback,
                    )
                )
>               warnings.warn(pytest.PytestUnraisableExceptionWarning(msg))
E               pytest.PytestUnraisableExceptionWarning: Exception ignored in: <_io.FileIO [closed]>
E
E               Traceback (most recent call last):
E                 File "...pandas/tests/frame/test_api.py", line 385, in test_open
E                   open("/dev/null")
E               ResourceWarning: unclosed file <_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>

../opt/miniconda3/envs/pandas-dev/lib/python3.8/site-packages/_pytest/unraisableexception.py:78: PytestUnraisableExceptionWarnin

@jbrockmendel
Copy link
Member

awesome, thanks for explaining

@mroeschke
Copy link
Member Author

Looks like this caught actual issues with open files in ExcelWriter

@mroeschke mroeschke added this to the 2.0 milestone Feb 19, 2023
# https://github.com/dateutil/dateutil/issues/197
pytest.skip(
"tzlocal() on a 32 bit platform causes internal overflow errors"
)
Copy link
Member

Choose a reason for hiding this comment

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

are we giving incorrect results in these cases?

Copy link
Member Author

@mroeschke mroeschke Feb 19, 2023

Choose a reason for hiding this comment

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

Running the 32 bit container locally it appears this still returns the correct result but hits the traceback in the dateutil issue

>>> from pandas import Timestamp
>>> import dateutil.tz
>>> dt = Timestamp("2100-01-01 00:00:00", tz=dateutil.tz.tzlocal())
Traceback (most recent call last):
  File "pandas/_libs/tslibs/tzconversion.pyx", line 125, in pandas._libs.tslibs.tzconversion.Localizer.utc_val_to_local_val
    return utc_val + _tz_localize_using_tzinfo_api(
  File "pandas/_libs/tslibs/tzconversion.pyx", line 736, in pandas._libs.tslibs.tzconversion._tz_localize_using_tzinfo_api
    dt = _astimezone(dts, tz)
  File "pandas/_libs/tslibs/tzconversion.pyx", line 768, in pandas._libs.tslibs.tzconversion._astimezone
    return tz.fromutc(result)
  File "/root/virtualenvs/pandas-dev/lib/python3.8/site-packages/dateutil/tz/_common.py", line 144, in fromutc
    return f(self, dt)
  File "/root/virtualenvs/pandas-dev/lib/python3.8/site-packages/dateutil/tz/_common.py", line 261, in fromutc
    _fold = self._fold_status(dt, dt_wall)
  File "/root/virtualenvs/pandas-dev/lib/python3.8/site-packages/dateutil/tz/_common.py", line 196, in _fold_status
    if self.is_ambiguous(dt_wall):
  File "/root/virtualenvs/pandas-dev/lib/python3.8/site-packages/dateutil/tz/tz.py", line 254, in is_ambiguous
    naive_dst = self._naive_is_dst(dt)
  File "/root/virtualenvs/pandas-dev/lib/python3.8/site-packages/dateutil/tz/tz.py", line 260, in _naive_is_dst
    return time.localtime(timestamp + time.timezone).tm_isdst
OverflowError: timestamp out of range for platform time_t
Exception ignored in: 'pandas._libs.tslibs.conversion._localize_tso'
Traceback (most recent call last):
  File "pandas/_libs/tslibs/tzconversion.pyx", line 125, in pandas._libs.tslibs.tzconversion.Localizer.utc_val_to_local_val
    return utc_val + _tz_localize_using_tzinfo_api(
  File "pandas/_libs/tslibs/tzconversion.pyx", line 736, in pandas._libs.tslibs.tzconversion._tz_localize_using_tzinfo_api
    dt = _astimezone(dts, tz)
  File "pandas/_libs/tslibs/tzconversion.pyx", line 768, in pandas._libs.tslibs.tzconversion._astimezone
    return tz.fromutc(result)
  File "/root/virtualenvs/pandas-dev/lib/python3.8/site-packages/dateutil/tz/_common.py", line 144, in fromutc
    return f(self, dt)
  File "/root/virtualenvs/pandas-dev/lib/python3.8/site-packages/dateutil/tz/_common.py", line 261, in fromutc
    _fold = self._fold_status(dt, dt_wall)
  File "/root/virtualenvs/pandas-dev/lib/python3.8/site-packages/dateutil/tz/_common.py", line 196, in _fold_status
    if self.is_ambiguous(dt_wall):
  File "/root/virtualenvs/pandas-dev/lib/python3.8/site-packages/dateutil/tz/tz.py", line 254, in is_ambiguous
    naive_dst = self._naive_is_dst(dt)
  File "/root/virtualenvs/pandas-dev/lib/python3.8/site-packages/dateutil/tz/tz.py", line 260, in _naive_is_dst
    return time.localtime(timestamp + time.timezone).tm_isdst
OverflowError: timestamp out of range for platform time_t
>>> dt.is_leap_year
False

proc = psutil.Process()
flist = proc.open_files()
yield
flist2 = proc.open_files()
Copy link
Member

Choose a reason for hiding this comment

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

documenting in case we wind up keeping this: looks like all of the flaky failures have raddr.port of either 5432 or 3306 (mostly 5432), which correspond to postgres and mysql defaults, respectively. We could filter those out here

Copy link
Member Author

Choose a reason for hiding this comment

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

FWIW I have seen the port 443 show up a few times too

@phofl phofl mentioned this pull request Feb 20, 2023
1 task
@phofl
Copy link
Member

phofl commented Feb 20, 2023

merging, I guess we should backport to get rid of these on the 2.0.x branch?

@phofl phofl merged commit cbad73a into pandas-dev:main Feb 20, 2023
@phofl
Copy link
Member

phofl commented Feb 20, 2023

thx @mroeschke

@jbrockmendel
Copy link
Member

nice!

@mroeschke mroeschke deleted the ci/open_files_rework branch February 20, 2023 22:03
phofl added a commit that referenced this pull request Feb 21, 2023
…ExceptionWarning instead of using psutil to check open resources) (#51507)

Backport PR #51443: CI/TST: Error on PytestUnraisableExceptionWarning instead of using psutil to check open resources

Co-authored-by: Matthew Roeschke <[email protected]>
Co-authored-by: Patrick Hoefler <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI Continuous Integration Unreliable Test Unit tests that occasionally fail
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants