From e10e6bbcd00d49daa99ff8d2df84df0b8bf42570 Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Tue, 26 Nov 2024 18:21:35 +0100 Subject: [PATCH] fix: handle deprecations in third-party libraries (#963) ### Summary of Changes Migrate our code, so it no longer uses deprecated API elements of third-party libraries. --------- Co-authored-by: megalinter-bot <129584137+megalinter-bot@users.noreply.github.com> --- src/safeds/data/tabular/containers/_table.py | 15 ++++++++++----- .../data/tabular/plotting/_table_plotter.py | 6 +++--- .../tabular/transformation/_label_encoder.py | 6 ++++-- tests/safeds/data/image/containers/test_image.py | 16 ---------------- .../tabular/containers/_row/test_column_count.py | 5 +++-- .../tabular/containers/_row/test_column_names.py | 5 +++-- .../tabular/containers/_row/test_contains.py | 5 +++-- .../data/tabular/containers/_row/test_eq.py | 11 ++++++----- .../containers/_row/test_get_column_type.py | 5 +++-- .../data/tabular/containers/_row/test_getitem.py | 6 +++--- .../tabular/containers/_row/test_has_column.py | 5 +++-- .../data/tabular/containers/_row/test_hash.py | 7 ++++--- .../data/tabular/containers/_row/test_iter.py | 5 +++-- .../data/tabular/containers/_row/test_len.py | 5 +++-- .../data/tabular/containers/_row/test_schema.py | 5 +++-- .../data/tabular/containers/_row/test_sizeof.py | 7 ++----- .../data/tabular/containers/_table/test_join.py | 11 ++++++++++- 17 files changed, 66 insertions(+), 59 deletions(-) diff --git a/src/safeds/data/tabular/containers/_table.py b/src/safeds/data/tabular/containers/_table.py index d53f314af..df9c8d4ff 100644 --- a/src/safeds/data/tabular/containers/_table.py +++ b/src/safeds/data/tabular/containers/_table.py @@ -472,7 +472,7 @@ def add_columns( | 3 | 6 | +-----+-----+ """ - import polars as pl + from polars.exceptions import DuplicateError if isinstance(columns, Column): columns = [columns] @@ -484,7 +484,7 @@ def add_columns( return Table._from_polars_data_frame( self._data_frame.hstack([column._series for column in columns]), ) - except pl.DuplicateError: + except DuplicateError: # polars already validates this, so we don't need to do it again upfront (performance) _check_columns_dont_exist(self, [column.name for column in columns]) return Table() # pragma: no cover @@ -1706,7 +1706,7 @@ def join( left_names: str | list[str], right_names: str | list[str], *, - mode: Literal["inner", "left", "outer"] = "inner", + mode: Literal["inner", "left", "right", "outer"] = "inner", ) -> Table: """ Join a table with the current table and return the result. @@ -1720,7 +1720,7 @@ def join( right_names: Name or list of names of columns from right_table on which to join the current table. mode: - Specify which type of join you want to use. Options include 'inner', 'outer', 'left', 'right'. + Specify which type of join you want to use. Returns ------- @@ -1750,12 +1750,17 @@ def join( raise ValueError("The number of columns to join on must be the same in both tables.") # Implementation + if mode == "outer": + polars_mode = "full" + else: + polars_mode = mode + return self._from_polars_lazy_frame( self._lazy_frame.join( right_table._lazy_frame, left_on=left_names, right_on=right_names, - how=mode, + how=polars_mode, ), ) diff --git a/src/safeds/data/tabular/plotting/_table_plotter.py b/src/safeds/data/tabular/plotting/_table_plotter.py index fe7aa3fd2..cd0a4ad03 100644 --- a/src/safeds/data/tabular/plotting/_table_plotter.py +++ b/src/safeds/data/tabular/plotting/_table_plotter.py @@ -94,7 +94,7 @@ def box_plots(self, *, theme: Literal["dark", "light"] = "light") -> Image: axs.boxplot( column, patch_artist=True, - labels=[numerical_table.column_names[i]], + tick_labels=[numerical_table.column_names[i]], ) break @@ -102,14 +102,14 @@ def box_plots(self, *, theme: Literal["dark", "light"] = "light") -> Image: axs[i].boxplot( column, patch_artist=True, - labels=[numerical_table.column_names[i]], + tick_labels=[numerical_table.column_names[i]], ) else: axs[line, i % number_of_columns].boxplot( column, patch_artist=True, - labels=[numerical_table.column_names[i]], + tick_labels=[numerical_table.column_names[i]], ) # removes unused ax indices, so there wont be empty plots diff --git a/src/safeds/data/tabular/transformation/_label_encoder.py b/src/safeds/data/tabular/transformation/_label_encoder.py index 78545f088..30b7ff85f 100644 --- a/src/safeds/data/tabular/transformation/_label_encoder.py +++ b/src/safeds/data/tabular/transformation/_label_encoder.py @@ -162,7 +162,7 @@ def transform(self, table: Table) -> Table: _check_columns_exist(table, self._column_names) columns = [ - pl.col(name).replace(self._mapping[name], default=None, return_dtype=pl.UInt32) + pl.col(name).replace_strict(self._mapping[name], default=None, return_dtype=pl.UInt32) for name in self._column_names ] @@ -208,7 +208,9 @@ def inverse_transform(self, transformed_table: Table) -> Table: operation="inverse-transform with a LabelEncoder", ) - columns = [pl.col(name).replace(self._inverse_mapping[name], default=None) for name in self._column_names] + columns = [ + pl.col(name).replace_strict(self._inverse_mapping[name], default=None) for name in self._column_names + ] return Table._from_polars_lazy_frame( transformed_table._lazy_frame.with_columns(columns), diff --git a/tests/safeds/data/image/containers/test_image.py b/tests/safeds/data/image/containers/test_image.py index a3d1ef472..3959a5ab3 100644 --- a/tests/safeds/data/image/containers/test_image.py +++ b/tests/safeds/data/image/containers/test_image.py @@ -3,8 +3,6 @@ from pathlib import Path from tempfile import NamedTemporaryFile -import numpy as np -import PIL.Image import pytest import torch from syrupy import SnapshotAssertion @@ -107,20 +105,6 @@ def test_should_write_and_load_bytes_png(self, resource_path: str | Path, device assert image == image_copy -@pytest.mark.parametrize("device", get_devices(), ids=get_devices_ids()) -class TestToNumpyArray: - @pytest.mark.parametrize( - "resource_path", - images_all(), - ids=images_all_ids(), - ) - def test_should_return_numpy_array(self, resource_path: str | Path, device: Device) -> None: - configure_test_with_device(device) - image_safeds = Image.from_file(resolve_resource_path(resource_path)) - image_np = np.array(PIL.Image.open(resolve_resource_path(resource_path))) - assert np.all(np.array(image_safeds).squeeze() == image_np) - - @pytest.mark.parametrize("device", get_devices(), ids=get_devices_ids()) class TestReprJpeg: @pytest.mark.parametrize( diff --git a/tests/safeds/data/tabular/containers/_row/test_column_count.py b/tests/safeds/data/tabular/containers/_row/test_column_count.py index dacf2dbf8..fb6dc98bb 100644 --- a/tests/safeds/data/tabular/containers/_row/test_column_count.py +++ b/tests/safeds/data/tabular/containers/_row/test_column_count.py @@ -1,5 +1,6 @@ import pytest -from safeds.data.tabular.containers import Row, Table + +from safeds.data.tabular.containers import Table from safeds.data.tabular.containers._lazy_vectorized_row import _LazyVectorizedRow @@ -15,5 +16,5 @@ ], ) def test_should_return_the_number_of_columns(table: Table, expected: int) -> None: - row: Row[any] = _LazyVectorizedRow(table=table) + row = _LazyVectorizedRow(table=table) assert row.column_count == expected diff --git a/tests/safeds/data/tabular/containers/_row/test_column_names.py b/tests/safeds/data/tabular/containers/_row/test_column_names.py index c5f55b6e2..09b32bbf7 100644 --- a/tests/safeds/data/tabular/containers/_row/test_column_names.py +++ b/tests/safeds/data/tabular/containers/_row/test_column_names.py @@ -1,5 +1,6 @@ import pytest -from safeds.data.tabular.containers import Row, Table + +from safeds.data.tabular.containers import Table from safeds.data.tabular.containers._lazy_vectorized_row import _LazyVectorizedRow @@ -20,5 +21,5 @@ ], ) def test_should_return_the_column_names(table: Table, expected: list[str]) -> None: - row: Row[any] = _LazyVectorizedRow(table=table) + row = _LazyVectorizedRow(table=table) assert row.column_names == expected diff --git a/tests/safeds/data/tabular/containers/_row/test_contains.py b/tests/safeds/data/tabular/containers/_row/test_contains.py index 216cbbcde..fc9cda260 100644 --- a/tests/safeds/data/tabular/containers/_row/test_contains.py +++ b/tests/safeds/data/tabular/containers/_row/test_contains.py @@ -1,5 +1,6 @@ import pytest -from safeds.data.tabular.containers import Row, Table + +from safeds.data.tabular.containers import Table from safeds.data.tabular.containers._lazy_vectorized_row import _LazyVectorizedRow @@ -19,5 +20,5 @@ ], ) def test_should_return_whether_the_row_has_the_column(table: Table, column_name: str, expected: bool) -> None: - row: Row[any] = _LazyVectorizedRow(table=table) + row = _LazyVectorizedRow(table=table) assert (column_name in row) == expected diff --git a/tests/safeds/data/tabular/containers/_row/test_eq.py b/tests/safeds/data/tabular/containers/_row/test_eq.py index 1bcfb3470..5e57cbc56 100644 --- a/tests/safeds/data/tabular/containers/_row/test_eq.py +++ b/tests/safeds/data/tabular/containers/_row/test_eq.py @@ -1,5 +1,6 @@ import pytest -from safeds.data.tabular.containers import Row, Table + +from safeds.data.tabular.containers import Table from safeds.data.tabular.containers._lazy_vectorized_row import _LazyVectorizedRow @@ -21,8 +22,8 @@ ], ) def test_should_return_whether_two_rows_are_equal(table1: Table, table2: Table, expected: bool) -> None: - row1: Row[any] = _LazyVectorizedRow(table=table1) - row2: Row[any] = _LazyVectorizedRow(table=table2) + row1 = _LazyVectorizedRow(table=table1) + row2 = _LazyVectorizedRow(table=table2) assert (row1.__eq__(row2)) == expected @@ -38,7 +39,7 @@ def test_should_return_whether_two_rows_are_equal(table1: Table, table2: Table, ], ) def test_should_return_true_if_rows_are_strict_equal(table: Table, expected: bool) -> None: - row1: Row[any] = _LazyVectorizedRow(table=table) + row1 = _LazyVectorizedRow(table=table) assert (row1.__eq__(row1)) == expected @@ -54,5 +55,5 @@ def test_should_return_true_if_rows_are_strict_equal(table: Table, expected: boo ], ) def test_should_return_false_if_object_is_other_type(table1: Table, table2: Table) -> None: - row1: Row[any] = _LazyVectorizedRow(table=table1) + row1 = _LazyVectorizedRow(table=table1) assert (row1.__eq__(table2)) == NotImplemented diff --git a/tests/safeds/data/tabular/containers/_row/test_get_column_type.py b/tests/safeds/data/tabular/containers/_row/test_get_column_type.py index f5cd78a25..c0af9aeaf 100644 --- a/tests/safeds/data/tabular/containers/_row/test_get_column_type.py +++ b/tests/safeds/data/tabular/containers/_row/test_get_column_type.py @@ -1,5 +1,6 @@ import pytest -from safeds.data.tabular.containers import Row, Table + +from safeds.data.tabular.containers import Table from safeds.data.tabular.containers._lazy_vectorized_row import _LazyVectorizedRow from safeds.data.tabular.typing import DataType @@ -16,5 +17,5 @@ ], ) def test_should_return_the_type_of_the_column(table: Table, column_name: str, expected: DataType) -> None: - row: Row[any] = _LazyVectorizedRow(table=table) + row = _LazyVectorizedRow(table=table) assert str(row.get_column_type(column_name)) == expected diff --git a/tests/safeds/data/tabular/containers/_row/test_getitem.py b/tests/safeds/data/tabular/containers/_row/test_getitem.py index 93f668ad8..0ad8eb349 100644 --- a/tests/safeds/data/tabular/containers/_row/test_getitem.py +++ b/tests/safeds/data/tabular/containers/_row/test_getitem.py @@ -1,10 +1,10 @@ import re import pytest -from safeds.data.tabular.containers import Row, Table + +from safeds.data.tabular.containers import Table from safeds.data.tabular.containers._lazy_vectorized_row import _LazyVectorizedRow from safeds.exceptions import ColumnNotFoundError - from tests.helpers import assert_row_operation_works @@ -41,6 +41,6 @@ def test_should_get_correct_item(table_data: dict, column_name: str, target: int ], ) def test_should_raise_column_not_found_error(table: Table, column_name: str) -> None: - row: Row[any] = _LazyVectorizedRow(table=table) + row = _LazyVectorizedRow(table=table) with pytest.raises(ColumnNotFoundError, match=re.escape(f"Could not find column(s):\n - '{column_name}'")): row[column_name] diff --git a/tests/safeds/data/tabular/containers/_row/test_has_column.py b/tests/safeds/data/tabular/containers/_row/test_has_column.py index 3d496ceda..f96c5a0d1 100644 --- a/tests/safeds/data/tabular/containers/_row/test_has_column.py +++ b/tests/safeds/data/tabular/containers/_row/test_has_column.py @@ -1,5 +1,6 @@ import pytest -from safeds.data.tabular.containers import Row, Table + +from safeds.data.tabular.containers import Table from safeds.data.tabular.containers._lazy_vectorized_row import _LazyVectorizedRow @@ -17,5 +18,5 @@ ], ) def test_should_have_column_name(table: Table, column_name: str, expected: bool) -> None: - row: Row[any] = _LazyVectorizedRow(table=table) + row = _LazyVectorizedRow(table=table) assert row.has_column(column_name) == expected diff --git a/tests/safeds/data/tabular/containers/_row/test_hash.py b/tests/safeds/data/tabular/containers/_row/test_hash.py index 9ec756db3..638d201f3 100644 --- a/tests/safeds/data/tabular/containers/_row/test_hash.py +++ b/tests/safeds/data/tabular/containers/_row/test_hash.py @@ -1,5 +1,6 @@ import pytest -from safeds.data.tabular.containers import Row, Table + +from safeds.data.tabular.containers import Table from safeds.data.tabular.containers._lazy_vectorized_row import _LazyVectorizedRow @@ -19,6 +20,6 @@ ], ) def test_should_return_consistent_hashes(table1: Table, table2: Table, expected: bool) -> None: - row1: Row[any] = _LazyVectorizedRow(table=table1) - row2: Row[any] = _LazyVectorizedRow(table=table2) + row1 = _LazyVectorizedRow(table=table1) + row2 = _LazyVectorizedRow(table=table2) assert (hash(row1) == hash(row2)) == expected diff --git a/tests/safeds/data/tabular/containers/_row/test_iter.py b/tests/safeds/data/tabular/containers/_row/test_iter.py index e68aefea9..a629e3d7e 100644 --- a/tests/safeds/data/tabular/containers/_row/test_iter.py +++ b/tests/safeds/data/tabular/containers/_row/test_iter.py @@ -1,5 +1,6 @@ import pytest -from safeds.data.tabular.containers import Row, Table + +from safeds.data.tabular.containers import Table from safeds.data.tabular.containers._lazy_vectorized_row import _LazyVectorizedRow @@ -17,6 +18,6 @@ ], ) def test_should_return_same_list_of_column_name_with_iter(table: Table, expected: list) -> None: - row: Row[any] = _LazyVectorizedRow(table=table) + row = _LazyVectorizedRow(table=table) iterable = iter(row) assert list(iterable) == expected diff --git a/tests/safeds/data/tabular/containers/_row/test_len.py b/tests/safeds/data/tabular/containers/_row/test_len.py index 6a9f9f0db..d03cfcc01 100644 --- a/tests/safeds/data/tabular/containers/_row/test_len.py +++ b/tests/safeds/data/tabular/containers/_row/test_len.py @@ -1,5 +1,6 @@ import pytest -from safeds.data.tabular.containers import Row, Table + +from safeds.data.tabular.containers import Table from safeds.data.tabular.containers._lazy_vectorized_row import _LazyVectorizedRow @@ -17,5 +18,5 @@ ], ) def test_should_have_same_length_as_number_of_columns(table: Table, expected: int) -> None: - row: Row[any] = _LazyVectorizedRow(table=table) + row = _LazyVectorizedRow(table=table) assert len(row) == expected diff --git a/tests/safeds/data/tabular/containers/_row/test_schema.py b/tests/safeds/data/tabular/containers/_row/test_schema.py index 4ebdc68f2..e4a0956fb 100644 --- a/tests/safeds/data/tabular/containers/_row/test_schema.py +++ b/tests/safeds/data/tabular/containers/_row/test_schema.py @@ -1,5 +1,6 @@ import pytest -from safeds.data.tabular.containers import Row, Table + +from safeds.data.tabular.containers import Table from safeds.data.tabular.containers._lazy_vectorized_row import _LazyVectorizedRow @@ -17,5 +18,5 @@ ], ) def test_should_return_same_schema(table: Table) -> None: - row: Row[any] = _LazyVectorizedRow(table=table) + row = _LazyVectorizedRow(table=table) assert table.schema == row.schema diff --git a/tests/safeds/data/tabular/containers/_row/test_sizeof.py b/tests/safeds/data/tabular/containers/_row/test_sizeof.py index d252a310a..808e0882b 100644 --- a/tests/safeds/data/tabular/containers/_row/test_sizeof.py +++ b/tests/safeds/data/tabular/containers/_row/test_sizeof.py @@ -1,13 +1,10 @@ import sys -from typing import TYPE_CHECKING, Any import polars as pl -from safeds.data.tabular.containers._lazy_vectorized_row import _LazyVectorizedRow -if TYPE_CHECKING: - from safeds.data.tabular.containers import Row +from safeds.data.tabular.containers._lazy_vectorized_row import _LazyVectorizedRow def test_should_return_size_greater_than_normal_object() -> None: - cell: Row[Any] = _LazyVectorizedRow(pl.col("a")) + cell = _LazyVectorizedRow(pl.col("a")) assert sys.getsizeof(cell) > sys.getsizeof(object()) diff --git a/tests/safeds/data/tabular/containers/_table/test_join.py b/tests/safeds/data/tabular/containers/_table/test_join.py index 1a1aec200..455360404 100644 --- a/tests/safeds/data/tabular/containers/_table/test_join.py +++ b/tests/safeds/data/tabular/containers/_table/test_join.py @@ -1,6 +1,7 @@ from typing import Literal import pytest + from safeds.data.tabular.containers import Table from safeds.exceptions import ColumnNotFoundError @@ -24,6 +25,14 @@ "left", Table({"a": [1, 2], "b": [3, 4], "e": [5, None]}), ), + ( + Table({"a": [1, 2], "b": [3, 4]}), + Table({"d": [1, 5], "e": [5, 6]}), + ["a"], + ["d"], + "right", + Table({"b": [3, None], "d": [1, 5], "e": [5, 6]}), + ), ( Table({"a": [1, 2], "b": [3, 4]}), Table({"d": [1, 5], "e": [5, 6]}), @@ -55,7 +64,7 @@ def test_should_join_two_tables( table_right: Table, left_names: list[str], right_names: list[str], - mode: Literal["inner", "left", "outer"], + mode: Literal["inner", "left", "right", "outer"], table_expected: Table, ) -> None: assert table_left.join(table_right, left_names, right_names, mode=mode) == table_expected