-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Test pytables refactor #28746
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
Test pytables refactor #28746
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
b7450c7
added a conftest.py to pytables subdir
tolaa001 480184d
added common.py file to migrate the functions which all 3 test classe…
tolaa001 31d6836
moved TestTimezone class to test_timezones.py and relevant imports
tolaa001 e3242f4
moved HDFComplexvalues class to test_hdf_complex_values.py and releva…
tolaa001 1985c96
updated common.py, updated imports in test_hdf_complex_values and cre…
tolaa001 e93f3df
removed tables variable as not required for Timezone class
tolaa001 80d6aaf
cleaned up unused imports
tolaa001 7f0842b
updated import for ensure_clean_path to reference common.py instead
tolaa001 882ba8e
deleted test_pytables.py after splitting contents across 4 python files
tolaa001 54483fb
created test_hdf_store module to move class TestHDFStore
tolaa001 cd6a2c9
Ran black formatting
tolaa001 eb14b23
amended scope for setup_mode to module as the future state of test mo…
tolaa001 7b640fc
running isort to import in the right order
tolaa001 44c56f1
moving tables from common.py to the modules requiring this
tolaa001 595670e
renaming test files to make them sexier
tolaa001 515825a
copied pytest.importorskip to timezone
tolaa001 6106a24
removed test_timezone class and kept module functional
tolaa001 8f540a7
removed test_hdfcomplexvalues class and kept module functional
tolaa001 cfdd437
convert test_store back to class to make git diff easier for review
tolaa001 6375977
Merge remote-tracking branch 'upstream/master' into test_pytables_ref…
tolaa001 aa97d78
moved xfail_non_writeable into _test_decorators
tolaa001 9931352
removed numpy from safe import
tolaa001 27d62e4
importing numpy instead of using safe import
tolaa001 2e83dfd
Merge remote-tracking branch 'upstream/master' into test_pytables_ref…
tolaa001 eeac6ce
removing unused imports
tolaa001 78c710b
added tables to xfail decorator
tolaa001 a38bc5e
changed import for decorator
tolaa001 6d97676
reverted accidentally changes to test_operator.py
tolaa001 64ec41d
Merge remote-tracking branch 'upstream/master' into test_pytables_ref…
tolaa001 49e9d31
moved tables to common.py
tolaa001 e5cecce
fixed import
tolaa001 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
from contextlib import contextmanager | ||
import os | ||
import tempfile | ||
|
||
import pytest | ||
|
||
from pandas.io.pytables import HDFStore | ||
|
||
tables = pytest.importorskip("tables") | ||
# set these parameters so we don't have file sharing | ||
tables.parameters.MAX_NUMEXPR_THREADS = 1 | ||
tables.parameters.MAX_BLOSC_THREADS = 1 | ||
tables.parameters.MAX_THREADS = 1 | ||
|
||
|
||
def safe_remove(path): | ||
if path is not None: | ||
try: | ||
os.remove(path) | ||
except OSError: | ||
pass | ||
|
||
|
||
def safe_close(store): | ||
try: | ||
if store is not None: | ||
store.close() | ||
except IOError: | ||
pass | ||
|
||
|
||
def create_tempfile(path): | ||
""" create an unopened named temporary file """ | ||
return os.path.join(tempfile.gettempdir(), path) | ||
|
||
|
||
# contextmanager to ensure the file cleanup | ||
@contextmanager | ||
def ensure_clean_store(path, mode="a", complevel=None, complib=None, fletcher32=False): | ||
|
||
try: | ||
|
||
# put in the temporary path if we don't have one already | ||
if not len(os.path.dirname(path)): | ||
path = create_tempfile(path) | ||
|
||
store = HDFStore( | ||
path, mode=mode, complevel=complevel, complib=complib, fletcher32=False | ||
) | ||
yield store | ||
finally: | ||
safe_close(store) | ||
if mode == "w" or mode == "a": | ||
safe_remove(path) | ||
|
||
|
||
@contextmanager | ||
def ensure_clean_path(path): | ||
""" | ||
return essentially a named temporary file that is not opened | ||
and deleted on exiting; if path is a list, then create and | ||
return list of filenames | ||
""" | ||
try: | ||
if isinstance(path, list): | ||
filenames = [create_tempfile(p) for p in path] | ||
yield filenames | ||
else: | ||
filenames = [create_tempfile(path)] | ||
yield filenames[0] | ||
finally: | ||
for f in filenames: | ||
safe_remove(f) | ||
|
||
|
||
def _maybe_remove(store, key): | ||
"""For tests using tables, try removing the table to be sure there is | ||
no content from previous tests using the same table name.""" | ||
try: | ||
store.remove(key) | ||
except (ValueError, KeyError): | ||
pass |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import pytest | ||
|
||
import pandas.util.testing as tm | ||
|
||
|
||
@pytest.fixture | ||
def setup_path(): | ||
"""Fixture for setup path""" | ||
return "tmp.__{}__.h5".format(tm.rands(10)) | ||
|
||
|
||
@pytest.fixture(scope="module", autouse=True) | ||
def setup_mode(): | ||
""" Reset testing mode fixture""" | ||
tm.reset_testing_mode() | ||
yield | ||
tm.set_testing_mode() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
from warnings import catch_warnings | ||
|
||
import numpy as np | ||
import pytest | ||
|
||
import pandas.util._test_decorators as td | ||
|
||
import pandas as pd | ||
from pandas import DataFrame, Series | ||
from pandas.tests.io.pytables.common import ensure_clean_path, ensure_clean_store | ||
import pandas.util.testing as tm | ||
from pandas.util.testing import assert_frame_equal | ||
|
||
from pandas.io.pytables import read_hdf | ||
|
||
# GH10447 | ||
|
||
|
||
def test_complex_fixed(setup_path): | ||
df = DataFrame( | ||
np.random.rand(4, 5).astype(np.complex64), | ||
index=list("abcd"), | ||
columns=list("ABCDE"), | ||
) | ||
|
||
with ensure_clean_path(setup_path) as path: | ||
df.to_hdf(path, "df") | ||
reread = read_hdf(path, "df") | ||
assert_frame_equal(df, reread) | ||
|
||
df = DataFrame( | ||
np.random.rand(4, 5).astype(np.complex128), | ||
index=list("abcd"), | ||
columns=list("ABCDE"), | ||
) | ||
with ensure_clean_path(setup_path) as path: | ||
df.to_hdf(path, "df") | ||
reread = read_hdf(path, "df") | ||
assert_frame_equal(df, reread) | ||
|
||
|
||
def test_complex_table(setup_path): | ||
df = DataFrame( | ||
np.random.rand(4, 5).astype(np.complex64), | ||
index=list("abcd"), | ||
columns=list("ABCDE"), | ||
) | ||
|
||
with ensure_clean_path(setup_path) as path: | ||
df.to_hdf(path, "df", format="table") | ||
reread = read_hdf(path, "df") | ||
assert_frame_equal(df, reread) | ||
|
||
df = DataFrame( | ||
np.random.rand(4, 5).astype(np.complex128), | ||
index=list("abcd"), | ||
columns=list("ABCDE"), | ||
) | ||
|
||
with ensure_clean_path(setup_path) as path: | ||
df.to_hdf(path, "df", format="table", mode="w") | ||
reread = read_hdf(path, "df") | ||
assert_frame_equal(df, reread) | ||
|
||
|
||
@td.xfail_non_writeable | ||
def test_complex_mixed_fixed(setup_path): | ||
complex64 = np.array( | ||
[1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j], dtype=np.complex64 | ||
) | ||
complex128 = np.array( | ||
[1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j], dtype=np.complex128 | ||
) | ||
df = DataFrame( | ||
{ | ||
"A": [1, 2, 3, 4], | ||
"B": ["a", "b", "c", "d"], | ||
"C": complex64, | ||
"D": complex128, | ||
"E": [1.0, 2.0, 3.0, 4.0], | ||
}, | ||
index=list("abcd"), | ||
) | ||
with ensure_clean_path(setup_path) as path: | ||
df.to_hdf(path, "df") | ||
reread = read_hdf(path, "df") | ||
assert_frame_equal(df, reread) | ||
|
||
|
||
def test_complex_mixed_table(setup_path): | ||
complex64 = np.array( | ||
[1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j], dtype=np.complex64 | ||
) | ||
complex128 = np.array( | ||
[1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j], dtype=np.complex128 | ||
) | ||
df = DataFrame( | ||
{ | ||
"A": [1, 2, 3, 4], | ||
"B": ["a", "b", "c", "d"], | ||
"C": complex64, | ||
"D": complex128, | ||
"E": [1.0, 2.0, 3.0, 4.0], | ||
}, | ||
index=list("abcd"), | ||
) | ||
|
||
with ensure_clean_store(setup_path) as store: | ||
store.append("df", df, data_columns=["A", "B"]) | ||
result = store.select("df", where="A>2") | ||
assert_frame_equal(df.loc[df.A > 2], result) | ||
|
||
with ensure_clean_path(setup_path) as path: | ||
df.to_hdf(path, "df", format="table") | ||
reread = read_hdf(path, "df") | ||
assert_frame_equal(df, reread) | ||
|
||
|
||
def test_complex_across_dimensions_fixed(setup_path): | ||
with catch_warnings(record=True): | ||
complex128 = np.array([1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j]) | ||
s = Series(complex128, index=list("abcd")) | ||
df = DataFrame({"A": s, "B": s}) | ||
|
||
objs = [s, df] | ||
comps = [tm.assert_series_equal, tm.assert_frame_equal] | ||
for obj, comp in zip(objs, comps): | ||
with ensure_clean_path(setup_path) as path: | ||
obj.to_hdf(path, "obj", format="fixed") | ||
reread = read_hdf(path, "obj") | ||
comp(obj, reread) | ||
|
||
|
||
def test_complex_across_dimensions(setup_path): | ||
complex128 = np.array([1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j]) | ||
s = Series(complex128, index=list("abcd")) | ||
df = DataFrame({"A": s, "B": s}) | ||
|
||
with catch_warnings(record=True): | ||
|
||
objs = [df] | ||
comps = [tm.assert_frame_equal] | ||
for obj, comp in zip(objs, comps): | ||
with ensure_clean_path(setup_path) as path: | ||
obj.to_hdf(path, "obj", format="table") | ||
reread = read_hdf(path, "obj") | ||
comp(obj, reread) | ||
|
||
|
||
def test_complex_indexing_error(setup_path): | ||
complex128 = np.array( | ||
[1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j], dtype=np.complex128 | ||
) | ||
df = DataFrame( | ||
{"A": [1, 2, 3, 4], "B": ["a", "b", "c", "d"], "C": complex128}, | ||
index=list("abcd"), | ||
) | ||
with ensure_clean_store(setup_path) as store: | ||
with pytest.raises(TypeError): | ||
store.append("df", df, data_columns=["C"]) | ||
|
||
|
||
def test_complex_series_error(setup_path): | ||
complex128 = np.array([1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j, 1.0 + 1.0j]) | ||
s = Series(complex128, index=list("abcd")) | ||
|
||
with ensure_clean_path(setup_path) as path: | ||
with pytest.raises(TypeError): | ||
s.to_hdf(path, "obj", format="t") | ||
|
||
with ensure_clean_path(setup_path) as path: | ||
s.to_hdf(path, "obj", format="t", index=False) | ||
reread = read_hdf(path, "obj") | ||
tm.assert_series_equal(s, reread) | ||
|
||
|
||
def test_complex_append(setup_path): | ||
df = DataFrame( | ||
{"a": np.random.randn(100).astype(np.complex128), "b": np.random.randn(100)} | ||
) | ||
|
||
with ensure_clean_store(setup_path) as store: | ||
store.append("df", df, data_columns=["b"]) | ||
store.append("df", df) | ||
result = store.select("df") | ||
assert_frame_equal(pd.concat([df, df], 0), result) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in a future PR, we want to have doc-strings & typing for these
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type errors in tests directories are not reported by mypy
pandas/setup.cfg
Lines 133 to 134 in 75c9783
so should typing be added? does help grok functions but equally if not correct (since not checked) could be confusing.