Skip to content

Enable ruff's flake8-pytest-style (PT) rules #2899

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 9 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 8 additions & 7 deletions pygmt/tests/test_clib.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,12 @@ def test_call_module_error_message():
Check is the GMT error message was captured.
"""
with clib.Session() as lib:
try:
with pytest.raises(GMTCLibError) as exc_info:
lib.call_module("info", "bogus-data.bla")
except GMTCLibError as error:
assert "Module 'info' failed with status code" in str(error)
assert "gmtinfo [ERROR]: Cannot find file bogus-data.bla" in str(error)
assert "Module 'info' failed with status code" in exc_info.value.args[0]
assert (
"gmtinfo [ERROR]: Cannot find file bogus-data.bla" in exc_info.value.args[0]
)


def test_method_no_session():
Expand Down Expand Up @@ -316,9 +317,9 @@ def test_create_data_fails():
)

# If the data pointer returned is None (NULL pointer)
with pytest.raises(GMTCLibError):
with clib.Session() as lib:
with mock(lib, "GMT_Create_Data", returns=None):
with clib.Session() as lib:
with mock(lib, "GMT_Create_Data", returns=None):
with pytest.raises(GMTCLibError):
lib.create_data(
family="GMT_IS_DATASET",
geometry="GMT_IS_SURFACE",
Expand Down
22 changes: 14 additions & 8 deletions pygmt/tests/test_clib_loading.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,15 @@ def _mock_ctypes_cdll_return(self, libname):
# libname is a loaded GMT library
return self.loaded_libgmt

@pytest.fixture
def mock_ctypes(self, monkeypatch):
@pytest.fixture()
def _mock_ctypes(self, monkeypatch):
"""
Patch the ctypes.CDLL function.
"""
monkeypatch.setattr(ctypes, "CDLL", self._mock_ctypes_cdll_return)

def test_two_broken_libraries(self, mock_ctypes):
@pytest.mark.usefixtures("_mock_ctypes")
def test_two_broken_libraries(self):
"""
Case 1: two broken libraries.

Expand All @@ -154,7 +155,8 @@ def test_two_broken_libraries(self, mock_ctypes):
with pytest.raises(GMTCLibNotFoundError, match=msg_regex):
load_libgmt(lib_fullnames=lib_fullnames)

def test_load_brokenlib_invalidpath(self, mock_ctypes):
@pytest.mark.usefixtures("_mock_ctypes")
def test_load_brokenlib_invalidpath(self):
"""
Case 2: broken library + invalid path.

Expand All @@ -171,28 +173,32 @@ def test_load_brokenlib_invalidpath(self, mock_ctypes):
with pytest.raises(GMTCLibNotFoundError, match=msg_regex):
load_libgmt(lib_fullnames=lib_fullnames)

def test_brokenlib_invalidpath_workinglib(self, mock_ctypes):
@pytest.mark.usefixtures("_mock_ctypes")
def test_brokenlib_invalidpath_workinglib(self):
"""
Case 3: broken library + invalid path + working library.
"""
lib_fullnames = [self.faked_libgmt1, self.invalid_path, self.loaded_libgmt]
assert check_libgmt(load_libgmt(lib_fullnames=lib_fullnames)) is None

def test_invalidpath_brokenlib_workinglib(self, mock_ctypes):
@pytest.mark.usefixtures("_mock_ctypes")
def test_invalidpath_brokenlib_workinglib(self):
"""
Case 4: invalid path + broken library + working library.
"""
lib_fullnames = [self.invalid_path, self.faked_libgmt1, self.loaded_libgmt]
assert check_libgmt(load_libgmt(lib_fullnames=lib_fullnames)) is None

def test_workinglib_brokenlib_invalidpath(self, mock_ctypes):
@pytest.mark.usefixtures("_mock_ctypes")
def test_workinglib_brokenlib_invalidpath(self):
"""
Case 5: working library + broken library + invalid path.
"""
lib_fullnames = [self.loaded_libgmt, self.faked_libgmt1, self.invalid_path]
assert check_libgmt(load_libgmt(lib_fullnames=lib_fullnames)) is None

def test_brokenlib_brokenlib_workinglib(self, mock_ctypes):
@pytest.mark.usefixtures("_mock_ctypes")
def test_brokenlib_brokenlib_workinglib(self):
"""
Case 6: repeating broken libraries + working library.
"""
Expand Down
2 changes: 1 addition & 1 deletion pygmt/tests/test_clib_virtualfiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def test_virtual_file_bad_direction():


@pytest.mark.parametrize(
"array_func,kind",
("array_func", "kind"),
[(np.array, "matrix"), (pd.DataFrame, "vector"), (xr.Dataset, "vector")],
)
def test_virtualfile_from_data_required_z_matrix(array_func, kind):
Expand Down
2 changes: 1 addition & 1 deletion pygmt/tests/test_geopandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def test_geopandas_info_geodataframe(gdf):


@pytest.mark.parametrize(
"geomtype,desired",
("geomtype", "desired"),
[
("multipolygon", [0.0, 35.0, 0.0, 20.0]),
("polygon", [20.0, 23.0, 10.0, 14.0]),
Expand Down
2 changes: 1 addition & 1 deletion pygmt/tests/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def test_load_static_earth_relief():


@pytest.mark.parametrize(
"data,x,y",
("data", "x", "y"),
[
(None, None, None),
("data.txt", np.array([1, 2]), np.array([4, 5])),
Expand Down
12 changes: 6 additions & 6 deletions pygmt/tests/test_meca.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,9 @@ def test_meca_spec_ndarray_no_convention():
"""
Raise an exception if convention is not given for an ndarray input.
"""
fig = Figure()
fig.basemap(region=[-125, -122, 47, 49], projection="M6c", frame=True)
with pytest.raises(GMTInvalidInput):
fig = Figure()
fig.basemap(region=[-125, -122, 47, 49], projection="M6c", frame=True)
fig.meca(spec=np.array([[-124, 48, 12.0, 330, 30, 90, 3]]), scale="1c")


Expand All @@ -316,16 +316,16 @@ def test_meca_spec_ndarray_mismatched_columns():
Raise an exception if the ndarray input doesn't have the expected number of
columns.
"""
fig = Figure()
fig.basemap(region=[-125, -122, 47, 49], projection="M6c", frame=True)
with pytest.raises(GMTInvalidInput):
fig = Figure()
fig.basemap(region=[-125, -122, 47, 49], projection="M6c", frame=True)
fig.meca(
spec=np.array([[-124, 48, 12.0, 330, 30, 90]]), convention="aki", scale="1c"
)

fig = Figure()
fig.basemap(region=[-125, -122, 47, 49], projection="M6c", frame=True)
with pytest.raises(GMTInvalidInput):
fig = Figure()
fig.basemap(region=[-125, -122, 47, 49], projection="M6c", frame=True)
fig.meca(
spec=np.array([[-124, 48, 12.0, 330, 30, 90, 3, -124.5, 47.5, 30.0, 50.0]]),
convention="aki",
Expand Down
26 changes: 17 additions & 9 deletions pygmt/tests/test_x2sys_cross.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@


@pytest.fixture(name="mock_x2sys_home")
def fixture_mock_x2sys_home(monkeypatch):
def _fixture_mock_x2sys_home(monkeypatch):
"""
Set the X2SYS_HOME environment variable to the current working directory
for the test session.
Expand All @@ -34,7 +34,8 @@ def fixture_tracks():
return [dataframe.query(expr="z > -20")] # reduce size of dataset


def test_x2sys_cross_input_file_output_file(mock_x2sys_home):
@pytest.mark.usefixtures("mock_x2sys_home")
def test_x2sys_cross_input_file_output_file():
"""
Run x2sys_cross by passing in a filename, and output internal crossovers to
an ASCII txt file.
Expand All @@ -52,7 +53,8 @@ def test_x2sys_cross_input_file_output_file(mock_x2sys_home):
_ = pd.read_csv(outfile, sep="\t", header=2) # ensure ASCII text file loads ok


def test_x2sys_cross_input_file_output_dataframe(mock_x2sys_home):
@pytest.mark.usefixtures("mock_x2sys_home")
def test_x2sys_cross_input_file_output_dataframe():
"""
Run x2sys_cross by passing in a filename, and output internal crossovers to
a pandas.DataFrame.
Expand All @@ -69,7 +71,8 @@ def test_x2sys_cross_input_file_output_dataframe(mock_x2sys_home):
assert columns[6:] == ["head_1", "head_2", "vel_1", "vel_2", "z_X", "z_M"]


def test_x2sys_cross_input_dataframe_output_dataframe(mock_x2sys_home, tracks):
@pytest.mark.usefixtures("mock_x2sys_home")
def test_x2sys_cross_input_dataframe_output_dataframe(tracks):
"""
Run x2sys_cross by passing in one dataframe, and output internal crossovers
to a pandas.DataFrame.
Expand All @@ -89,7 +92,8 @@ def test_x2sys_cross_input_dataframe_output_dataframe(mock_x2sys_home, tracks):
assert output.dtypes["i_2"].type == np.object_


def test_x2sys_cross_input_two_dataframes(mock_x2sys_home):
@pytest.mark.usefixtures("mock_x2sys_home")
def test_x2sys_cross_input_two_dataframes():
"""
Run x2sys_cross by passing in two pandas.DataFrame tables with a time
column, and output external crossovers to a pandas.DataFrame.
Expand Down Expand Up @@ -125,7 +129,8 @@ def test_x2sys_cross_input_two_dataframes(mock_x2sys_home):
assert output.dtypes["t_2"].type == np.datetime64


def test_x2sys_cross_input_dataframe_with_nan(mock_x2sys_home, tracks):
@pytest.mark.usefixtures("mock_x2sys_home")
def test_x2sys_cross_input_dataframe_with_nan(tracks):
"""
Run x2sys_cross by passing in one dataframe with NaN values, and output
internal crossovers to a pandas.DataFrame.
Expand All @@ -148,7 +153,8 @@ def test_x2sys_cross_input_dataframe_with_nan(mock_x2sys_home, tracks):
assert output.dtypes["i_2"].type == np.object_


def test_x2sys_cross_input_two_filenames(mock_x2sys_home):
@pytest.mark.usefixtures("mock_x2sys_home")
def test_x2sys_cross_input_two_filenames():
"""
Run x2sys_cross by passing in two filenames, and output external crossovers
to a pandas.DataFrame.
Expand Down Expand Up @@ -186,7 +192,8 @@ def test_x2sys_cross_invalid_tracks_input_type(tracks):
x2sys_cross(tracks=[invalid_tracks])


def test_x2sys_cross_region_interpolation_numpoints(mock_x2sys_home):
@pytest.mark.usefixtures("mock_x2sys_home")
def test_x2sys_cross_region_interpolation_numpoints():
"""
Test that x2sys_cross's region (R), interpolation (l) and numpoints (W)
arguments work.
Expand All @@ -210,7 +217,8 @@ def test_x2sys_cross_region_interpolation_numpoints(mock_x2sys_home):
npt.assert_allclose(output.z_M.mean(), -2890.465813)


def test_x2sys_cross_trackvalues(mock_x2sys_home):
@pytest.mark.usefixtures("mock_x2sys_home")
def test_x2sys_cross_trackvalues():
"""
Test that x2sys_cross's trackvalues (Z) argument work.
"""
Expand Down
8 changes: 5 additions & 3 deletions pygmt/tests/test_x2sys_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@


@pytest.fixture(name="mock_x2sys_home")
def fixture_mock_x2sys_home(monkeypatch):
def _fixture_mock_x2sys_home(monkeypatch):
"""
Set the X2SYS_HOME environment variable to the current working directory
for the test session.
"""
monkeypatch.setenv("X2SYS_HOME", os.getcwd())


def test_x2sys_init_region_spacing(mock_x2sys_home):
@pytest.mark.usefixtures("mock_x2sys_home")
def test_x2sys_init_region_spacing():
"""
Test that x2sys_init's region (R) and spacing (I) sequence arguments accept
a list properly.
Expand All @@ -34,7 +35,8 @@ def test_x2sys_init_region_spacing(mock_x2sys_home):
assert "-I5/5" in tail_line


def test_x2sys_init_units_gap(mock_x2sys_home):
@pytest.mark.usefixtures("mock_x2sys_home")
def test_x2sys_init_units_gap():
"""
Test that x2sys_init's units (N) and gap (W) arguments accept a list
properly.
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ select = [
"PGH", # pygrep-hooks
"PIE", # flake8-pie
"PL", # pylint
"PT", # flake8-pytest-style
"RET", # flake8-return
"RSE", # flake8-raise
"S", # flake8-bandit
Expand All @@ -133,6 +134,7 @@ ignore = [
"E501", # Avoid enforcing line-length violations
"ISC001", # Single-line-implicit-string-concatenation, conflict with formatter
"PD901", # Allow using the generic variable name `df` for DataFrames
"PT023", # Allow using pytest marker without parentheses
"PLR2004", # Allow any magic values
"RET504", # Allow variable assignment and return immediately for readability
"S603", # Allow method calls that initiate a subprocess without a shell
Expand Down