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
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8df59ed
CI/TST: Check for PytestUnraisableExceptionWarning instead of psutil …
mroeschke Feb 16, 2023
f903f62
Make ResourceWarning also error
mroeschke Feb 16, 2023
72b70cc
Merge remote-tracking branch 'upstream/main' into ci/open_files_rework
mroeschke Feb 17, 2023
5c24bdd
Fix ExcelWriter not clossing files during instantiation
mroeschke Feb 17, 2023
a046267
Ignore asyncio ResourceWarnings
mroeschke Feb 17, 2023
844f277
Merge remote-tracking branch 'upstream/main' into ci/open_files_rework
mroeschke Feb 17, 2023
cfdd50f
Merge remote-tracking branch 'upstream/main' into ci/open_files_rework
mroeschke Feb 17, 2023
edaf9db
Forgot comma
mroeschke Feb 17, 2023
648e83c
Merge remote-tracking branch 'upstream/main' into ci/open_files_rework
mroeschke Feb 17, 2023
d5d269b
Ignore socketwarnings
mroeschke Feb 17, 2023
bd490be
Merge remote-tracking branch 'upstream/main' into ci/open_files_rework
mroeschke Feb 18, 2023
8401c79
More permissive mesage match
mroeschke Feb 18, 2023
bae2fc0
Ignore tzlocal specific 32 bit error
mroeschke Feb 18, 2023
6b80a8e
Merge remote-tracking branch 'upstream/main' into ci/open_files_rework
mroeschke Feb 18, 2023
4c2ef83
Merge remote-tracking branch 'upstream/main' into ci/open_files_rework
mroeschke Feb 19, 2023
b99158c
Try these changes
mroeschke Feb 19, 2023
8c9cf4e
Merge remote-tracking branch 'upstream/main' into ci/open_files_rework
mroeschke Feb 19, 2023
efb667b
Try the whole file?
mroeschke Feb 19, 2023
1daf6d7
Just skip under condidition
mroeschke Feb 19, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion ci/deps/actions-310.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ dependencies:
- pytest>=7.0.0
- pytest-cov
- pytest-xdist>=2.2.0
- psutil
- pytest-asyncio>=0.17
- boto3

Expand Down
1 change: 0 additions & 1 deletion ci/deps/actions-311.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ dependencies:
- pytest>=7.0
- pytest-cov
- pytest-xdist>=2.2.0
- psutil
- pytest-asyncio>=0.17
- boto3

Expand Down
1 change: 0 additions & 1 deletion ci/deps/actions-38-downstream_compat.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ dependencies:
- pytest>=7.0.0
- pytest-cov
- pytest-xdist>=2.2.0
- psutil
- pytest-asyncio>=0.17
- boto3

Expand Down
1 change: 0 additions & 1 deletion ci/deps/actions-38-minimum_versions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ dependencies:
- pytest>=7.0.0
- pytest-cov
- pytest-xdist>=2.2.0
- psutil
- pytest-asyncio>=0.17
- boto3

Expand Down
1 change: 0 additions & 1 deletion ci/deps/actions-38.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ dependencies:
- pytest>=7.0.0
- pytest-cov
- pytest-xdist>=2.2.0
- psutil
- pytest-asyncio>=0.17
- boto3

Expand Down
1 change: 0 additions & 1 deletion ci/deps/actions-39.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ dependencies:
- pytest>=7.0.0
- pytest-cov
- pytest-xdist>=2.2.0
- psutil
- pytest-asyncio>=0.17
- boto3

Expand Down
1 change: 0 additions & 1 deletion ci/deps/circle-38-arm64.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ dependencies:
- pytest>=7.0.0
- pytest-cov
- pytest-xdist>=2.2.0
- psutil
- pytest-asyncio>=0.17
- boto3

Expand Down
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1330,6 +1330,7 @@ I/O
- Bug in :meth:`DataFrame.to_html` with ``na_rep`` set when the :class:`DataFrame` contains non-scalar data (:issue:`47103`)
- Bug in :func:`read_xml` where file-like objects failed when iterparse is used (:issue:`50641`)
- Bug in :func:`read_xml` ignored repeated elements when iterparse is used (:issue:`51183`)
- Bug in :class:`ExcelWriter` leaving file handles open if an exception occurred during instantiation (:issue:`51443`)

Period
^^^^^^
Expand Down
1 change: 0 additions & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ dependencies:
- pytest>=7.0.0
- pytest-cov
- pytest-xdist>=2.2.0
- psutil
- pytest-asyncio>=0.17
- coverage

Expand Down
30 changes: 11 additions & 19 deletions pandas/io/excel/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,17 @@ def __init__(
# the excel backend first read the existing file and then write any data to it
mode = mode.replace("a", "r+")

if if_sheet_exists not in (None, "error", "new", "replace", "overlay"):
raise ValueError(
f"'{if_sheet_exists}' is not valid for if_sheet_exists. "
"Valid options are 'error', 'new', 'replace' and 'overlay'."
)
if if_sheet_exists and "r+" not in mode:
raise ValueError("if_sheet_exists is only valid in append mode (mode='a')")
if if_sheet_exists is None:
if_sheet_exists = "error"
self._if_sheet_exists = if_sheet_exists

# cast ExcelWriter to avoid adding 'if self._handles is not None'
self._handles = IOHandles(
cast(IO[bytes], path), compression={"compression": None}
Expand All @@ -1244,17 +1255,6 @@ def __init__(

self._mode = mode

if if_sheet_exists not in (None, "error", "new", "replace", "overlay"):
raise ValueError(
f"'{if_sheet_exists}' is not valid for if_sheet_exists. "
"Valid options are 'error', 'new', 'replace' and 'overlay'."
)
if if_sheet_exists and "r+" not in mode:
raise ValueError("if_sheet_exists is only valid in append mode (mode='a')")
if if_sheet_exists is None:
if_sheet_exists = "error"
self._if_sheet_exists = if_sheet_exists

@property
def date_format(self) -> str:
"""
Expand Down Expand Up @@ -1617,11 +1617,3 @@ def __exit__(
traceback: TracebackType | None,
) -> None:
self.close()

def __del__(self) -> None:
# Ensure we don't leak file descriptors, but put in try/except in case
# attributes are already deleted
try:
self.close()
except AttributeError:
pass
6 changes: 3 additions & 3 deletions pandas/io/excel/_odswriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ def __init__(
if mode == "a":
raise ValueError("Append mode is not supported with odf!")

engine_kwargs = combine_kwargs(engine_kwargs, kwargs)
self._book = OpenDocumentSpreadsheet(**engine_kwargs)

super().__init__(
path,
mode=mode,
Expand All @@ -56,9 +59,6 @@ def __init__(
engine_kwargs=engine_kwargs,
)

engine_kwargs = combine_kwargs(engine_kwargs, kwargs)

self._book = OpenDocumentSpreadsheet(**engine_kwargs)
self._style_dict: dict[str, str] = {}

@property
Expand Down
12 changes: 10 additions & 2 deletions pandas/io/excel/_openpyxl.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,19 @@ def __init__(
if "r+" in self._mode: # Load from existing workbook
from openpyxl import load_workbook

self._book = load_workbook(self._handles.handle, **engine_kwargs)
try:
self._book = load_workbook(self._handles.handle, **engine_kwargs)
except TypeError:
self._handles.handle.close()
raise
self._handles.handle.seek(0)
else:
# Create workbook object with default optimized_write=True.
self._book = Workbook(**engine_kwargs)
try:
self._book = Workbook(**engine_kwargs)
except TypeError:
self._handles.handle.close()
raise

if self.book.worksheets:
self.book.remove(self.book.worksheets[0])
Expand Down
2 changes: 0 additions & 2 deletions pandas/tests/frame/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

from pandas._config.config import option_context

import pandas.util._test_decorators as td
from pandas.util._test_decorators import (
async_mark,
skip_if_no,
Expand Down Expand Up @@ -293,7 +292,6 @@ def _check_f(base, f):
_check_f(d.copy(), f)

@async_mark()
@td.check_file_leaks
async def test_tab_complete_warning(self, ip, frame_or_series):
# GH 16409
pytest.importorskip("IPython", minversion="6.0.0")
Expand Down
26 changes: 0 additions & 26 deletions pandas/tests/io/excel/conftest.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import pytest

from pandas.compat import is_platform_windows
import pandas.util._test_decorators as td

import pandas._testing as tm

from pandas.io.parsers import read_csv
Expand Down Expand Up @@ -42,26 +39,3 @@ def read_ext(request):
Valid extensions for reading Excel files.
"""
return request.param


# Checking for file leaks can hang on Windows CI
@pytest.fixture(autouse=not is_platform_windows())
def check_for_file_leaks():
"""
Fixture to run around every test to ensure that we are not leaking files.

See also
--------
_test_decorators.check_file_leaks
"""
# GH#30162
psutil = td.safe_import("psutil")
if not psutil:
yield

else:
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

assert flist == flist2
2 changes: 0 additions & 2 deletions pandas/tests/io/excel/test_readers.py
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,6 @@ def test_read_from_pathlib_path(self, read_ext):
tm.assert_frame_equal(expected, actual)

@td.skip_if_no("py.path")
@td.check_file_leaks
def test_read_from_py_localpath(self, read_ext):
# GH12655
from py.path import local as LocalPath
Expand All @@ -922,7 +921,6 @@ def test_read_from_py_localpath(self, read_ext):

tm.assert_frame_equal(expected, actual)

@td.check_file_leaks
def test_close_from_py_localpath(self, read_ext):
# GH31467
str_path = os.path.join("test1" + read_ext)
Expand Down
2 changes: 0 additions & 2 deletions pandas/tests/io/formats/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
IS64,
is_platform_windows,
)
import pandas.util._test_decorators as td

import pandas as pd
from pandas import (
Expand Down Expand Up @@ -3400,7 +3399,6 @@ def test_format_percentiles_integer_idx():
assert result == expected


@td.check_file_leaks
def test_repr_html_ipython_config(ip):
code = textwrap.dedent(
"""\
Expand Down
18 changes: 3 additions & 15 deletions pandas/tests/io/parser/common/test_file_buffer_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

import pytest

from pandas.compat import is_ci_environment
from pandas.errors import (
EmptyDataError,
ParserError,
Expand Down Expand Up @@ -404,25 +403,14 @@ def test_context_manageri_user_provided(all_parsers, datapath):
assert not reader.handles.handle.closed


def test_file_descriptor_leak(all_parsers, using_copy_on_write, request):
def test_file_descriptor_leak(all_parsers, using_copy_on_write):
# GH 31488
if using_copy_on_write and is_ci_environment():
mark = pytest.mark.xfail(
reason="2023-02-12 frequent-but-flaky failures", strict=False
)
request.node.add_marker(mark)

parser = all_parsers
with tm.ensure_clean() as path:

def test():
with pytest.raises(EmptyDataError, match="No columns to parse from file"):
parser.read_csv(path)

td.check_file_leaks(test)()
with pytest.raises(EmptyDataError, match="No columns to parse from file"):
parser.read_csv(path)


@td.check_file_leaks
def test_memory_map(all_parsers, csv_dir_path):
mmap_file = os.path.join(csv_dir_path, "test_mmap.csv")
parser = all_parsers
Expand Down
2 changes: 0 additions & 2 deletions pandas/tests/io/parser/common/test_read_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
EmptyDataError,
ParserError,
)
import pandas.util._test_decorators as td

from pandas import DataFrame
import pandas._testing as tm
Expand Down Expand Up @@ -204,7 +203,6 @@ def test_null_byte_char(request, all_parsers):
parser.read_csv(StringIO(data), names=names)


@td.check_file_leaks
def test_open_file(request, all_parsers):
# GH 39024
parser = all_parsers
Expand Down
14 changes: 3 additions & 11 deletions pandas/tests/io/sas/test_xport.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import numpy as np
import pytest

import pandas.util._test_decorators as td

import pandas as pd
import pandas._testing as tm

Expand All @@ -21,11 +19,6 @@ def numeric_as_float(data):


class TestXport:
@pytest.fixture(autouse=True)
def setup_method(self):
with td.file_leak_context():
yield

@pytest.fixture
def file01(self, datapath):
return datapath("io", "sas", "data", "DEMO_G.xpt")
Expand Down Expand Up @@ -138,10 +131,9 @@ def test2_binary(self, file02):
numeric_as_float(data_csv)

with open(file02, "rb") as fd:
with td.file_leak_context():
# GH#35693 ensure that if we pass an open file, we
# dont incorrectly close it in read_sas
data = read_sas(fd, format="xport")
# GH#35693 ensure that if we pass an open file, we
# dont incorrectly close it in read_sas
data = read_sas(fd, format="xport")

tm.assert_frame_equal(data, data_csv)

Expand Down
2 changes: 0 additions & 2 deletions pandas/tests/resample/test_resampler_grouper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import numpy as np
import pytest

import pandas.util._test_decorators as td
from pandas.util._test_decorators import async_mark

import pandas as pd
Expand All @@ -24,7 +23,6 @@


@async_mark()
@td.check_file_leaks
async def test_tab_complete_ipython6_warning(ip):
from IPython.core.completer import provisionalcompleter

Expand Down
Loading