From 8394dac14440c47eb6ea8634e7ae09d5b2f34e2a Mon Sep 17 00:00:00 2001 From: mferrera Date: Thu, 12 Dec 2024 07:46:11 +0100 Subject: [PATCH] DEP: Drop Python 3.8 support --- .github/workflows/mypy.yml | 2 +- .github/workflows/publish.yml | 3 - .github/workflows/test.yml | 16 +--- README.md | 2 +- pyproject.toml | 32 +++---- tests/test_grid3d/test_grdecl_format.py | 114 ++++++++++++++---------- tests/test_grid3d/test_grid_grdecl.py | 68 ++++++++------ tests/test_grid3d/test_grid_roff.py | 15 ++-- tests/test_xyz/test_points_poly.py | 2 - 9 files changed, 136 insertions(+), 118 deletions(-) diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 7750e59cf..c51d5004e 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -16,7 +16,7 @@ jobs: mypy: strategy: matrix: - python-version: ["3.8", "3.11"] + python-version: ["3.9", "3.11", "3.12"] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index bf8d841e6..023b9f462 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,7 +15,6 @@ jobs: fail-fast: false matrix: python: - - ['3.8', cp38] - ['3.9', cp39] - ['3.10', cp310] - ['3.11', cp311] @@ -26,8 +25,6 @@ jobs: - [macos-13, macosx_x86_64] # macos-13 is the last x86-64 runner - [macos-latest, macosx_arm64] # macos-latest is always arm64 going forward exclude: - - os_arch: [macos-latest, macosx_arm64] - python: ['3.8', cp38] - os_arch: [macos-latest, macosx_arm64] python: ['3.9', cp39] env: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5cdb65e58..5afb0f869 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,15 +18,13 @@ jobs: timeout-minutes: 15 strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.9", "3.10", "3.11", "3.12"] os: [ubuntu-latest] include: - os: macos-latest python-version: "3.10" - os: macos-latest python-version: 3.12 - - os: windows-latest - python-version: 3.8 - os: windows-latest python-version: 3.12 @@ -86,18 +84,6 @@ jobs: fail-fast: false matrix: config: - - { - name: "RMS 12.1.4, 13.0.3, 13.1.0, 14.1.1", - os: ubuntu-20.04, - python: 3.8.6, - pip: 23.2.1, - wheel: 0.37.1, - setuptools: 63.4.3, - matplotlib: 3.3.2, - numpy: 1.19.2, - pandas: 1.1.3, - scipy: 1.5.3, - } - { name: "RMS 14.2", os: ubuntu-latest, diff --git a/README.md b/README.md index cfd60a953..66c001e7f 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Detailed documentation for [XTGeo at Read _the_ Docs](https://xtgeo.readthedocs. ## Feature summary -- Python 3.8+ support +- Python 3.9+ support - Focus on high speed, using numpy and pandas with C backend - Regular surfaces, i.e. 2D maps with regular sampling and rotation - 3D grids (corner-point), supporting several formats such as diff --git a/pyproject.toml b/pyproject.toml index 08f1cc5b2..da22187c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,6 @@ requires = [ "pybind11", "scikit-build-core[pyproject]>=0.10", "swig<4.3.0", - "numpy==1.19.2; python_version == '3.8'", "numpy==1.19.5; python_version == '3.9'", "numpy==1.21.6; python_version == '3.10'", "numpy==1.23.5; python_version == '3.11'", @@ -22,7 +21,7 @@ wheel.install-dir = "xtgeo" name = "xtgeo" description = "XTGeo is a Python library for 3D grids, surfaces, wells, etc" readme = "README.md" -requires-python = ">=3.8" +requires-python = ">=3.9" license = { text = "LGPL-3.0" } authors = [{ name = "Equinor", email = "fg_fmu-atlas@equinor.com" }] keywords = ["grids", "surfaces", "wells", "cubes"] @@ -36,7 +35,6 @@ classifiers = [ "Operating System :: MacOS", "Natural Language :: English", "Programming Language :: Python", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -120,7 +118,6 @@ match = '(?!(test_|_)).*\.py' [tool.pytest.ini_options] minversion = "6.0" -addopts = "--verbose" log_cli = "False" log_cli_format = "%(levelname)8s (%(relativeCreated)6.0fms) %(filename)44s [%(funcName)40s()] %(lineno)4d >> %(message)s" log_cli_level = "INFO" @@ -143,18 +140,21 @@ ignore = [ "C901", ] select = [ - "C", - "E", - "F", - "I", - "PIE", - "Q", - "RET", - "RSE", - "SIM", - "TCH", - "TID", - "W", + # "B", # flake-8-bugbear + "C", # pylint-convention + "E", # pycodestyle-error + "F", # pyflakes + "I", # isort + # "NPY", # numpy + "PIE", # flake8-pie + "Q", # flake8-quotes + "RET", # flake8-return + "RSE", # flake8-raise + "SIM", # flake8-simplify + "TC", # flake8-type-checking + "TID", # flake8-tidy-imports + # "UP", # pyupgrade + "W", # pylint-warnings ] [tool.ruff.lint.isort] diff --git a/tests/test_grid3d/test_grdecl_format.py b/tests/test_grid3d/test_grdecl_format.py index 008bb1daf..7b848ecf8 100644 --- a/tests/test_grid3d/test_grdecl_format.py +++ b/tests/test_grid3d/test_grdecl_format.py @@ -21,13 +21,16 @@ ], ) def test_read_simple_property(file_data): - with patch( - "builtins.open", - mock_open(read_data=file_data), - ) as mock_file, open_grdecl( - mock_file, - keywords=["PROP"], - ) as kw: + with ( + patch( + "builtins.open", + mock_open(read_data=file_data), + ) as mock_file, + open_grdecl( + mock_file, + keywords=["PROP"], + ) as kw, + ): assert list(kw) == [("PROP", ["1", "2", "3", "4"])] @@ -37,34 +40,43 @@ def test_read_simple_property(file_data): ) def test_read_repeated_property(repeats, value): inp_str = f"PROP\n {repeats}*{value} /\n" - with patch( - "builtins.open", - mock_open(read_data=inp_str), - ) as mock_file, open_grdecl(mock_file, keywords=["PROP"]) as kw: + with ( + patch( + "builtins.open", + mock_open(read_data=inp_str), + ) as mock_file, + open_grdecl(mock_file, keywords=["PROP"]) as kw, + ): assert list(kw) == [("PROP", [str(value)] * repeats)] def test_read_repeated_string_literal(): inp_str = "PROP\n 3*'INP ' /\n" - with patch( - "builtins.open", - mock_open(read_data=inp_str), - ) as mock_file, open_grdecl( - mock_file, - keywords=["PROP"], - ) as kw: + with ( + patch( + "builtins.open", + mock_open(read_data=inp_str), + ) as mock_file, + open_grdecl( + mock_file, + keywords=["PROP"], + ) as kw, + ): assert list(kw) == [("PROP", ["INP "] * 3)] def test_read_string(): inp_str = "PROP\n 'FOO BAR' FOO /\n" - with patch( - "builtins.open", - mock_open(read_data=inp_str), - ) as mock_file, open_grdecl( - mock_file, - keywords=["PROP"], - ) as kw: + with ( + patch( + "builtins.open", + mock_open(read_data=inp_str), + ) as mock_file, + open_grdecl( + mock_file, + keywords=["PROP"], + ) as kw, + ): assert list(kw) == [("PROP", ["FOO BAR", "FOO"])] @@ -73,13 +85,16 @@ def test_read_extra_keyword_characters(): "LONGPROP Eclipse comment\n" "1 2 3 4 / More Eclipse comment\nOTHERPROP\n 5 6 7 8 /\n" ) - with patch( - "builtins.open", - mock_open(read_data=file_data), - ) as mock_file, open_grdecl( - mock_file, - keywords=["LONGPROP", "OTHERPROP"], - ) as kw: + with ( + patch( + "builtins.open", + mock_open(read_data=file_data), + ) as mock_file, + open_grdecl( + mock_file, + keywords=["LONGPROP", "OTHERPROP"], + ) as kw, + ): assert list(kw) == [ ("LONGPROP", ["1", "2", "3", "4"]), ("OTHERPROP", ["5", "6", "7", "8"]), @@ -89,13 +104,16 @@ def test_read_extra_keyword_characters(): def test_read_long_keyword(): very_long_keyword = "a" * 200 file_data = f"{very_long_keyword} Eclipse comment\n" "1 2 3 4 /" - with patch( - "builtins.open", - mock_open(read_data=file_data), - ) as mock_file, open_grdecl( - mock_file, - keywords=[very_long_keyword], - ) as kw: + with ( + patch( + "builtins.open", + mock_open(read_data=file_data), + ) as mock_file, + open_grdecl( + mock_file, + keywords=[very_long_keyword], + ) as kw, + ): assert list(kw) == [ (very_long_keyword, ["1", "2", "3", "4"]), ] @@ -112,11 +130,15 @@ def test_read_long_keyword(): ], ) def test_read_prop_raises_error_when_no_forwardslash(undelimited_file_data): - with patch( - "builtins.open", - mock_open(read_data=undelimited_file_data), - ) as mock_file, open_grdecl( - mock_file, - keywords=["PROP"], - ) as kw, pytest.raises(ValueError): + with ( + patch( + "builtins.open", + mock_open(read_data=undelimited_file_data), + ) as mock_file, + open_grdecl( + mock_file, + keywords=["PROP"], + ) as kw, + pytest.raises(ValueError), + ): list(kw) diff --git a/tests/test_grid3d/test_grid_grdecl.py b/tests/test_grid3d/test_grid_grdecl.py index 20fc3f800..8a013d2b0 100644 --- a/tests/test_grid3d/test_grid_grdecl.py +++ b/tests/test_grid3d/test_grid_grdecl.py @@ -40,13 +40,16 @@ def test_grid_relative(): ], ) def test_mapaxes(inp_str, values): - with patch( - "builtins.open", - mock_open(read_data=inp_str), - ) as mock_file, open_grdecl( - mock_file, - keywords=["MAPAXES"], - ) as kw: + with ( + patch( + "builtins.open", + mock_open(read_data=inp_str), + ) as mock_file, + open_grdecl( + mock_file, + keywords=["MAPAXES"], + ) as kw, + ): keyword, values = next(kw) assert keyword == "MAPAXES" mapaxes = ggrid.MapAxes.from_grdecl(values) @@ -59,13 +62,16 @@ def test_mapaxes(inp_str, values): def test_gdorient(): inp_str = "GDORIENT\n INC INC INC DOWN LEFT /" - with patch( - "builtins.open", - mock_open(read_data=inp_str), - ) as mock_file, open_grdecl( - mock_file, - keywords=["GDORIENT"], - ) as kw: + with ( + patch( + "builtins.open", + mock_open(read_data=inp_str), + ) as mock_file, + open_grdecl( + mock_file, + keywords=["GDORIENT"], + ) as kw, + ): keyword, values = next(kw) assert keyword == "GDORIENT" gdorient = ecl_grid.GdOrient.from_grdecl(values) @@ -81,13 +87,16 @@ def test_gdorient(): def test_specgrid(): inp_str = "SPECGRID\n 64 118 263 1 F /" - with patch( - "builtins.open", - mock_open(read_data=inp_str), - ) as mock_file, open_grdecl( - mock_file, - keywords=["SPECGRID"], - ) as kw: + with ( + patch( + "builtins.open", + mock_open(read_data=inp_str), + ) as mock_file, + open_grdecl( + mock_file, + keywords=["SPECGRID"], + ) as kw, + ): keyword, values = next(kw) assert keyword == "SPECGRID" specgrid = ggrid.SpecGrid.from_grdecl(values) @@ -113,13 +122,16 @@ def test_specgrid(): ], ) def test_gridunit(inp_str, expected_unit, expected_relative): - with patch( - "builtins.open", - mock_open(read_data=inp_str), - ) as mock_file, open_grdecl( - mock_file, - keywords=["GRIDUNIT"], - ) as kw: + with ( + patch( + "builtins.open", + mock_open(read_data=inp_str), + ) as mock_file, + open_grdecl( + mock_file, + keywords=["GRIDUNIT"], + ) as kw, + ): keyword, values = next(kw) assert keyword == "GRIDUNIT" gridunit = ggrid.GridUnit.from_grdecl(values) diff --git a/tests/test_grid3d/test_grid_roff.py b/tests/test_grid3d/test_grid_roff.py index 428c0d4cd..b2f2f128d 100644 --- a/tests/test_grid3d/test_grid_roff.py +++ b/tests/test_grid3d/test_grid_roff.py @@ -337,12 +337,15 @@ def test_deprecated_fileread(roff_grid): ) ) - with pytest.warns( - UserWarning, - match="nonstandard but harmless roff", - ), handle_deprecated_xtgeo_roff_file( - new_buff, - ) as converted_buff: + with ( + pytest.warns( + UserWarning, + match="nonstandard but harmless roff", + ), + handle_deprecated_xtgeo_roff_file( + new_buff, + ) as converted_buff, + ): new_grid = RoffGrid.from_file(converted_buff) assert new_grid == roff_grid diff --git a/tests/test_xyz/test_points_poly.py b/tests/test_xyz/test_points_poly.py index bd4580f68..9b14b4ba6 100644 --- a/tests/test_xyz/test_points_poly.py +++ b/tests/test_xyz/test_points_poly.py @@ -1,5 +1,4 @@ import pathlib -import sys import pytest @@ -436,7 +435,6 @@ def test_add_inside_polygons_etc(): assert list(poi.get_dataframe()[poi.zname].values) == [10.0, 10.0, 10.0] -@pytest.mark.skipif(sys.version_info < (3, 8), reason="Different order in python 3.7") def test_boundary_from_points_simple(): """Test deriving a boundary around points (classmethod)."""