From 6a739b6531ab894eeab68cdb3b60b2b0217d512a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=87a=C4=9Ftay=20Fabry?= Date: Sat, 16 Sep 2023 12:56:51 +0200 Subject: [PATCH] apply pyupgrade --py39-plus (#893) * apply pyupgrade py39+ * Update media_file.py --- .pre-commit-config.yaml | 5 +++ devtools/scripts/clean_notebooks.py | 3 +- weldx/asdf/cli/welding_schema.py | 5 ++- weldx/asdf/file.py | 31 ++++++++++--------- weldx/asdf/types.py | 5 ++- weldx/asdf/util.py | 26 +++++++--------- weldx/asdf/validators.py | 6 ++-- weldx/config.py | 9 +++--- weldx/core/generic_series.py | 36 +++++++++++----------- weldx/core/math_expression.py | 10 +++--- weldx/core/spatial_series.py | 18 +++++------ weldx/core/time_series.py | 26 ++++++++-------- weldx/geometry.py | 46 ++++++++++++++-------------- weldx/measurement.py | 10 +++--- weldx/tags/core/common_types.py | 4 +-- weldx/tests/test_geometry.py | 5 ++- weldx/tests/test_time.py | 12 +++----- weldx/tests/transformations/_util.py | 6 ++-- weldx/time.py | 34 ++++++++++---------- weldx/transformations/cs_manager.py | 20 ++++++------ weldx/transformations/local_cs.py | 22 ++++++------- weldx/transformations/rotation.py | 4 +-- weldx/util/media_file.py | 13 ++++---- weldx/util/util.py | 4 +-- weldx/util/xarray.py | 12 ++++---- weldx/visualization/__init__.py | 2 +- weldx/welding/groove/iso_9692_1.py | 6 ++-- 27 files changed, 185 insertions(+), 195 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 72aff5104..58a5ae918 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,6 +28,11 @@ repos: - mdformat-black - mdformat-config # ----- Python formatting ----- + - repo: https://github.com/asottile/pyupgrade + rev: v3.10.1 + hooks: + - id: pyupgrade + args: [--py39-plus] - repo: https://github.com/psf/black rev: 23.7.0 hooks: diff --git a/devtools/scripts/clean_notebooks.py b/devtools/scripts/clean_notebooks.py index b382d0b12..2e6bcb02f 100644 --- a/devtools/scripts/clean_notebooks.py +++ b/devtools/scripts/clean_notebooks.py @@ -2,10 +2,9 @@ from __future__ import annotations import json -from typing import Union -def _clean_notebook(file: Union[str, Path]): # pragma: no cover +def _clean_notebook(file: str | Path): # pragma: no cover """Clean ID metadata, output and execution count from jupyter notebook cells. This function overrides the existing notebook file, use with caution! diff --git a/weldx/asdf/cli/welding_schema.py b/weldx/asdf/cli/welding_schema.py index a48f47eda..7e1ad814e 100644 --- a/weldx/asdf/cli/welding_schema.py +++ b/weldx/asdf/cli/welding_schema.py @@ -3,12 +3,11 @@ import sys from io import BytesIO -from typing import Optional, Union def single_pass_weld_example( - out_file: Optional[Union[str, BytesIO]] = "single_pass_weld_example.asdf", -) -> Optional[tuple[BytesIO, dict]]: + out_file: str | BytesIO | None = "single_pass_weld_example.asdf", +) -> tuple[BytesIO, dict] | None: """Create ASDF file containing all required fields of the single_pass_weld schema. Parameters diff --git a/weldx/asdf/file.py b/weldx/asdf/file.py index 4721d3ce0..93e1b1efc 100644 --- a/weldx/asdf/file.py +++ b/weldx/asdf/file.py @@ -5,10 +5,10 @@ import io import pathlib import warnings -from collections.abc import Iterable, Mapping, MutableMapping, Set, ValuesView +from collections.abc import Hashable, Iterable, Mapping, MutableMapping, Set, ValuesView from contextlib import contextmanager from io import BytesIO, IOBase -from typing import IO, Any, Dict, Hashable, Optional, Union, get_args +from typing import IO, Any, get_args import asdf import numpy as np @@ -208,16 +208,17 @@ class WeldxFile(_ProtectedViewDict): def __init__( self, - filename_or_file_like: Optional[Union[types_path_like, types_file_like]] = None, + filename_or_file_like: types_path_like | types_file_like | None = None, mode: str = "r", asdffile_kwargs: Mapping = None, write_kwargs: Mapping = None, tree: Mapping = None, sync: bool = True, - custom_schema: Optional[ + custom_schema: None + | ( types_path_like, tuple[None, types_path_like], - ] = None, + ) = None, software_history_entry: Mapping = None, compression: str = DEFAULT_ARRAY_COMPRESSION, copy_arrays: bool = DEFAULT_ARRAY_COPYING, @@ -486,7 +487,7 @@ def software_history_entry(self, value: dict): "version": version, } else: - if not isinstance(value, Dict): + if not isinstance(value, dict): raise ValueError("expected a dictionary type") try: test = AsdfFile(tree=dict(software=Software(value))) @@ -519,7 +520,7 @@ def sync( self, all_array_storage: str = None, all_array_compression: str = "input", - pad_blocks: Union[float, bool] = False, + pad_blocks: float | bool = False, include_block_index: bool = True, version: str = None, **kwargs, @@ -595,7 +596,7 @@ def get(self, key, default=None): """ return super().get(key, default=default) - def update(self, mapping: Union[Mapping, Iterable] = (), **kwargs: Any): + def update(self, mapping: Mapping | Iterable = (), **kwargs: Any): """Update this file from mapping or iterable mapping and kwargs. Parameters @@ -734,7 +735,7 @@ def asdf_library(self) -> dict: return self._asdf_handle["asdf_library"].copy() @property - def custom_schema(self) -> Optional[str, tuple[Optional[str]]]: + def custom_schema(self) -> str | tuple[str | None] | None: """Return schema used to validate the structure and types of the tree.""" if self._schema_on_read == self._schema_on_write: return self._schema_on_read @@ -752,7 +753,7 @@ def file_handle(self) -> IOBase: def copy( self, - filename_or_file_like: Optional[types_path_and_file_like] = None, + filename_or_file_like: types_path_and_file_like | None = None, overwrite: bool = False, ) -> WeldxFile: """Take a copy of this file. @@ -834,10 +835,10 @@ def __init__(self, iterable, **kwargs): def write_to( self, - fd: Optional[types_path_and_file_like] = None, + fd: types_path_and_file_like | None = None, array_inline_threshold=None, **write_args, - ) -> Optional[types_path_and_file_like]: + ) -> types_path_and_file_like | None: """Write current contents to given file name or file type. Parameters @@ -885,7 +886,7 @@ def header( self, use_widgets: bool = None, path: tuple = None, - _interactive: Optional[bool] = None, + _interactive: bool | None = None, ): """Show the header of the ASDF serialization. @@ -970,7 +971,7 @@ def _fake_copy(x, _): # take a copy of the handle to avoid side effects! def show( self, use_widgets=None, path=None, _interactive=None - ) -> Union[None, IPython.display.HTML, IPython.display.JSON]: # noqa: F821 + ) -> None | IPython.display.HTML | IPython.display.JSON: # noqa: F821 if _interactive is None: _interactive = is_interactive_session() if use_widgets is None: @@ -995,7 +996,7 @@ def show( @staticmethod def _show_interactive( use_widgets: bool, buff: BytesIO, path: tuple = None - ) -> Union[IPython.display.HTML, IPython.display.JSON]: # noqa: F821 + ) -> IPython.display.HTML | IPython.display.JSON: # noqa: F821 from weldx.asdf.util import notebook_fileprinter if use_widgets: diff --git a/weldx/asdf/types.py b/weldx/asdf/types.py index bf344342b..82a131515 100644 --- a/weldx/asdf/types.py +++ b/weldx/asdf/types.py @@ -2,7 +2,6 @@ import functools import re -from typing import Union from asdf.asdf import SerializationContext from asdf.extension import Converter @@ -51,7 +50,7 @@ def from_yaml_tree_metadata(func): """Wrapper that will add reading metadata and userdata during form_tree methods.""" @functools.wraps(func) - def from_yaml_tree_wrapped(self, tree: Union[dict, list, str], tag, ctx): + def from_yaml_tree_wrapped(self, tree: dict | list | str, tag, ctx): """Call default from_yaml_tree method and add metadata attributes.""" meta_dict = {} if isinstance(tree, dict): # only valid if we serialize a dict @@ -89,7 +88,7 @@ class WeldxConverter(Converter, metaclass=WeldxConverterMeta): """Base class to inherit from for custom converter classes.""" tags: tuple[str] = None # note: this will be updated by WeldxConverterMeta. - types: tuple[Union[type, str]] = () + types: tuple[type | str] = () def to_yaml_tree(self, obj, tag: str, ctx: SerializationContext): raise NotImplementedError diff --git a/weldx/asdf/util.py b/weldx/asdf/util.py index 80eb8a62f..52e420a69 100644 --- a/weldx/asdf/util.py +++ b/weldx/asdf/util.py @@ -1,11 +1,11 @@ """Utilities for asdf files.""" from __future__ import annotations -from collections.abc import Callable, Mapping, Set +from collections.abc import Callable, Hashable, Mapping, MutableMapping, Set from contextlib import contextmanager from io import BytesIO, TextIOBase from pathlib import Path -from typing import Any, Hashable, MutableMapping, Union +from typing import Any from warnings import warn import asdf @@ -261,7 +261,7 @@ def write_read_buffer( return data -def get_yaml_header(file: types_path_and_file_like, parse=False) -> Union[str, dict]: +def get_yaml_header(file: types_path_and_file_like, parse=False) -> str | dict: """Read the YAML header part (excluding binary sections) of an ASDF file. Parameters @@ -492,7 +492,7 @@ def from_yaml_tree( return _SerializationClass -def get_weldx_extension(ctx: Union[SerializationContext, AsdfConfig]) -> Extension: +def get_weldx_extension(ctx: SerializationContext | AsdfConfig) -> Extension: """Grab the weldx extension from list of current active extensions.""" if isinstance(ctx, asdf.asdf.SerializationContext): extensions = ctx.extension_manager.extensions @@ -508,7 +508,7 @@ def get_weldx_extension(ctx: Union[SerializationContext, AsdfConfig]) -> Extensi return extensions[0] -def uri_match(patterns: Union[str, list[str]], uri: str) -> bool: +def uri_match(patterns: str | list[str], uri: str) -> bool: """Returns `True` if the ASDF URI matches any of the listed patterns. See Also @@ -521,7 +521,7 @@ def uri_match(patterns: Union[str, list[str]], uri: str) -> bool: return any(asdf_uri_match(p, uri) for p in patterns) -def get_converter_for_tag(tag: str) -> Union[WeldxConverter, None]: +def get_converter_for_tag(tag: str) -> WeldxConverter | None: """Get the converter class that handles a given tag.""" converters = [s for s in WeldxConverter.__subclasses__() if uri_match(s.tags, tag)] if len(converters) > 1: @@ -534,8 +534,8 @@ def get_converter_for_tag(tag: str) -> Union[WeldxConverter, None]: def get_highest_tag_version( - pattern: Union[str, list[str]], ctx: Union[SerializationContext, AsdfConfig] = None -) -> Union[str, None]: + pattern: str | list[str], ctx: SerializationContext | AsdfConfig = None +) -> str | None: """Get the highest available weldx extension tag version matching a pattern. Parameters @@ -580,9 +580,7 @@ def get_highest_tag_version( return tags[-1] -def _get_instance_shape( - instance_dict: Union[TaggedDict, dict[str, Any]] -) -> Union[list[int], None]: +def _get_instance_shape(instance_dict: TaggedDict | dict[str, Any]) -> list[int] | None: """Get the shape of an ASDF instance from its tagged dict form. Parameters @@ -607,9 +605,7 @@ def _get_instance_shape( return None -def _get_instance_units( - instance_dict: Union[TaggedDict, dict[str, Any]] -) -> Union[pint.Unit, None]: +def _get_instance_units(instance_dict: TaggedDict | dict[str, Any]) -> pint.Unit | None: """Get the units of an ASDF instance from its tagged dict form. Parameters @@ -715,7 +711,7 @@ def _warn_protected_keys(self, stacklevel=3): def get_schema_tree( # noqa: C901, MC0001, RUF100, codacy:ignore - schemafile: Union[str, Path], *, drop: set = None + schemafile: str | Path, *, drop: set = None ) -> dict: """Get a dictionary representation of a weldx schema file with custom formatting. diff --git a/weldx/asdf/validators.py b/weldx/asdf/validators.py index df00d6dd2..18d63cf77 100644 --- a/weldx/asdf/validators.py +++ b/weldx/asdf/validators.py @@ -4,7 +4,7 @@ import re from collections import OrderedDict from collections.abc import Callable, Iterator, Mapping -from typing import Any, Union +from typing import Any from asdf.exceptions import ValidationError from asdf.extension import Validator @@ -306,7 +306,7 @@ def _validate_expected_list(list_expected): ) -def _compare_lists(_list, list_expected) -> Union[bool, dict]: +def _compare_lists(_list, list_expected) -> bool | dict: """Compare two lists. The two lists are interpreted as a list of dimensions. We compare the dimensions of @@ -425,7 +425,7 @@ def _validate_instance_shape( def _custom_shape_validator( dict_test: dict[str, Any], - dict_expected: Union[dict[str, Any], list], + dict_expected: dict[str, Any] | list, optional: bool = False, ): """Validate dimensions which are stored in two dictionaries dict_test and diff --git a/weldx/config.py b/weldx/config.py index bcf23a1f1..400f0d6af 100644 --- a/weldx/config.py +++ b/weldx/config.py @@ -2,7 +2,6 @@ from __future__ import annotations from pathlib import Path -from typing import List, Union import asdf import pkg_resources @@ -102,7 +101,7 @@ def name(self) -> str: """Get the quality standards name.""" return self._name - def get_mappings(self, version: Union[AsdfVersion, str] = None): + def get_mappings(self, version: AsdfVersion | str = None): """Get the manifest and schema mapping for the specified version. Parameters @@ -152,7 +151,7 @@ def add_quality_standard(standard: QualityStandard): Config._standards[standard.name] = standard @staticmethod - def enable_quality_standard(name: str, version: Union[AsdfVersion, str] = None): + def enable_quality_standard(name: str, version: AsdfVersion | str = None): """Enable a quality standard. All corresponding schemas will be used for validation during serialization and @@ -177,7 +176,7 @@ def load_installed_standards(): """Load all standards that are installed to the active virtual environment.""" for entry_point in pkg_resources.iter_entry_points("weldx.standard"): standards = entry_point.load()() - if not isinstance(standards, List): + if not isinstance(standards, list): standards = [standards] for standard in standards: if not isinstance(standard, QualityStandard): @@ -197,7 +196,7 @@ def add_quality_standard(standard: QualityStandard): Config.add_quality_standard(standard) -def enable_quality_standard(name: str, version: Union[AsdfVersion, str] = None): +def enable_quality_standard(name: str, version: AsdfVersion | str = None): """Enable a quality standard. All corresponding schemas will be used for validation during serialization and diff --git a/weldx/core/generic_series.py b/weldx/core/generic_series.py index 20c78bef2..83849c00d 100644 --- a/weldx/core/generic_series.py +++ b/weldx/core/generic_series.py @@ -4,7 +4,7 @@ from collections.abc import Callable, Mapping from copy import deepcopy from dataclasses import dataclass -from typing import Any, Union +from typing import Any import numpy as np import pint @@ -95,12 +95,12 @@ class GenericSeries: def __init__( self, - obj: Union[pint.Quantity, xr.DataArray, str, MathematicalExpression], - dims: Union[list[str], dict[str, str]] = None, - coords: dict[str, Union[list, pint.Quantity]] = None, - units: dict[str, Union[str, pint.Unit]] = None, + obj: pint.Quantity | xr.DataArray | str | MathematicalExpression, + dims: list[str] | dict[str, str] = None, + coords: dict[str, list | pint.Quantity] = None, + units: dict[str, str | pint.Unit] = None, interpolation: str = None, - parameters: dict[str, Union[str, pint.Quantity, xr.DataArray]] = None, + parameters: dict[str, str | pint.Quantity | xr.DataArray] = None, ): """Create a generic series. @@ -218,7 +218,7 @@ def __init__( if units is None: units = {} - self._obj: Union[xr.DataArray, MathematicalExpression] = None + self._obj: xr.DataArray | MathematicalExpression = None self._variable_units: dict[str, pint.Unit] = None self._symbol_dims: bidict = bidict({}) self._units: pint.Unit = None @@ -265,9 +265,9 @@ def __hash__(self): def _init_discrete( self, - data: Union[pint.Quantity, xr.DataArray], + data: pint.Quantity | xr.DataArray, dims: list[str], - coords: dict[str, Union[list, pint.Quantity]], + coords: dict[str, list | pint.Quantity], ): """Initialize the internal data with discrete values.""" if not isinstance(data, xr.DataArray): @@ -318,9 +318,9 @@ def _init_get_updated_units( def _init_expression( self, - expr: Union[str, MathematicalExpression, sympy.Expr], + expr: str | MathematicalExpression | sympy.Expr, dims: dict[str, str], - parameters: dict[str, Union[str, pint.Quantity, xr.DataArray]], + parameters: dict[str, str | pint.Quantity | xr.DataArray], units: dict[str, pint.Unit], ): """Initialize the internal data with a mathematical expression.""" @@ -402,8 +402,8 @@ def _test_expr(expr, dims, units: dict[str, pint.Unit]) -> pint.Unit: @staticmethod def _format_expression_params( - parameters: dict[str, Union[pint.Quantity, xr.DataArray]] - ) -> dict[str, Union[pint.Quantity, xr.DataArray]]: + parameters: dict[str, pint.Quantity | xr.DataArray] + ) -> dict[str, pint.Quantity | xr.DataArray]: """Create expression parameters as a valid internal type. Valid types are all input types for the `MathematicalExpression`, with the @@ -549,7 +549,7 @@ def __call__(self, **kwargs) -> GenericSeries: # properties etc. --------------------------------------------- @property - def coordinates(self) -> Union[DataArrayCoordinates, None]: + def coordinates(self) -> DataArrayCoordinates | None: """Get the coordinates of the generic series.""" if self.is_discrete: return self.data_array.coords @@ -561,14 +561,14 @@ def coordinate_names(self) -> list[str]: return NotImplemented @property - def data(self) -> Union[pint.Quantity, MathematicalExpression]: + def data(self) -> pint.Quantity | MathematicalExpression: """Get the internal data.""" if self.is_discrete: return self.data_array.data return self._obj @property - def data_array(self) -> Union[xr.DataArray, None]: + def data_array(self) -> xr.DataArray | None: """Get the internal data as `xarray.DataArray`.""" if self.is_discrete: return self._obj @@ -634,7 +634,7 @@ def ndims(self) -> int: return len(self.dims) @property - def variable_names(self) -> Union[list[str], None]: + def variable_names(self) -> list[str] | None: """Get the names of all variables.""" if self.is_expression: return list(self._variable_units.keys()) @@ -823,7 +823,7 @@ class SeriesParameter: The stored value can be converted to different formats available as properties. """ - values: Union[xr.DataArray, pint.Quantity] + values: xr.DataArray | pint.Quantity """The values of the parameter are stored as quantities or DataArrays""" dim: str = None """The xarray dimension associated with the parameter.""" diff --git a/weldx/core/math_expression.py b/weldx/core/math_expression.py index bc83cfe58..9c3e19458 100644 --- a/weldx/core/math_expression.py +++ b/weldx/core/math_expression.py @@ -1,7 +1,7 @@ """Contains the MathematicalExpression class.""" from __future__ import annotations -from typing import Any, Tuple, Union +from typing import Any, Union import pint import sympy @@ -10,7 +10,7 @@ from weldx import Q_ ExpressionParameterTypes = Union[ - pint.Quantity, str, Tuple[pint.Quantity, str], xr.DataArray + pint.Quantity, str, tuple[pint.Quantity, str], xr.DataArray ] __all__ = ["MathematicalExpression", "ExpressionParameterTypes"] @@ -21,7 +21,7 @@ class MathematicalExpression: def __init__( self, - expression: Union[sympy.Expr, str], + expression: sympy.Expr | str, parameters: ExpressionParameterTypes = None, ): """Construct a MathematicalExpression. @@ -45,7 +45,7 @@ def __init__( tuple(self._expression.free_symbols), self._expression, ("numpy", "scipy") ) - self._parameters: dict[str, Union[pint.Quantity, xr.DataArray]] = {} + self._parameters: dict[str, pint.Quantity | xr.DataArray] = {} if parameters is not None: self.set_parameters(parameters) @@ -214,7 +214,7 @@ def expression(self): return self._expression @property - def parameters(self) -> dict[str, Union[pint.Quantity, xr.DataArray]]: + def parameters(self) -> dict[str, pint.Quantity | xr.DataArray]: """Return the internal parameters dictionary. Returns diff --git a/weldx/core/spatial_series.py b/weldx/core/spatial_series.py index 05bff8050..a3660b693 100644 --- a/weldx/core/spatial_series.py +++ b/weldx/core/spatial_series.py @@ -1,8 +1,6 @@ """Contains the SpatialSeries class.""" from __future__ import annotations -from typing import Union - import pint import xarray as xr @@ -31,12 +29,12 @@ class SpatialSeries(GenericSeries): def __init__( self, - obj: Union[pint.Quantity, xr.DataArray, str, MathematicalExpression], - dims: Union[list[str], dict[str, str]] = None, - coords: dict[str, Union[list, pint.Quantity]] = None, - units: dict[str, Union[str, pint.Unit]] = None, + obj: pint.Quantity | xr.DataArray | str | MathematicalExpression, + dims: list[str] | dict[str, str] = None, + coords: dict[str, list | pint.Quantity] = None, + units: dict[str, str | pint.Unit] = None, interpolation: str = None, - parameters: dict[str, Union[str, pint.Quantity, xr.DataArray]] = None, + parameters: dict[str, str | pint.Quantity | xr.DataArray] = None, ): if isinstance(obj, Q_): obj = self._process_quantity(obj, dims, coords) @@ -49,9 +47,9 @@ def __init__( @classmethod def _process_quantity( cls, - obj: Union[pint.Quantity, xr.DataArray, str, MathematicalExpression], - dims: Union[list[str], dict[str, str]], - coords: dict[str, Union[list, pint.Quantity]], + obj: pint.Quantity | xr.DataArray | str | MathematicalExpression, + dims: list[str] | dict[str, str], + coords: dict[str, list | pint.Quantity], ) -> xr.DataArray: """Turn a quantity into a a correctly formatted data array.""" if isinstance(coords, dict): diff --git a/weldx/core/time_series.py b/weldx/core/time_series.py index ea00361e1..acfd434fb 100644 --- a/weldx/core/time_series.py +++ b/weldx/core/time_series.py @@ -1,7 +1,7 @@ """Contains TimeSeries class.""" from __future__ import annotations -from typing import TYPE_CHECKING, Any, Optional, Union +from typing import TYPE_CHECKING, Any import numpy as np import pandas as pd @@ -41,7 +41,7 @@ class TimeSeries(TimeDependent): def __init__( self, - data: Union[pint.Quantity, MathematicalExpression], + data: pint.Quantity | MathematicalExpression, time: types_time_like = None, interpolation: str = None, reference_time: types_timestamp_like = None, @@ -63,8 +63,8 @@ def __init__( 'step', 'linear'. """ - self._data: Union[MathematicalExpression, xr.DataArray] = None - self._time_var_name: Optional[str] = None + self._data: MathematicalExpression | xr.DataArray = None + self._time_var_name: str | None = None self._shape = None self._units = None self._interp_counter = 0 @@ -141,7 +141,7 @@ def _check_data_array(data_array: xr.DataArray): @staticmethod def _create_data_array( - data: Union[pint.Quantity, xr.DataArray], time: Time + data: pint.Quantity | xr.DataArray, time: Time ) -> xr.DataArray: return ( xr.DataArray(data=data) @@ -151,7 +151,7 @@ def _create_data_array( def _initialize_discrete( self, - data: Union[pint.Quantity, xr.DataArray], + data: pint.Quantity | xr.DataArray, time: types_time_like = None, interpolation: str = None, reference_time=None, @@ -249,7 +249,7 @@ def _interp_time_expression(self, time: Time, time_unit: str) -> xr.DataArray: return data.assign_coords({"time": time.as_data_array()}) @property - def data(self) -> Union[pint.Quantity, MathematicalExpression]: + def data(self) -> pint.Quantity | MathematicalExpression: """Return the data of the TimeSeries. This is either a set of discrete values/quantities or a mathematical expression. @@ -267,7 +267,7 @@ def data(self) -> Union[pint.Quantity, MathematicalExpression]: return self._data @property - def data_array(self) -> Union[xr.DataArray, None]: + def data_array(self) -> xr.DataArray | None: """Return the internal data as 'xarray.DataArray'. If the TimeSeries contains an expression, 'None' is returned. @@ -283,7 +283,7 @@ def data_array(self) -> Union[xr.DataArray, None]: return None @property - def interpolation(self) -> Union[str, None]: + def interpolation(self) -> str | None: """Return the interpolation. Returns @@ -320,7 +320,7 @@ def is_expression(self) -> bool: return isinstance(self.data, MathematicalExpression) @property - def time(self) -> Union[None, Time]: + def time(self) -> None | Time: """Return the data's timestamps. Returns @@ -334,14 +334,14 @@ def time(self) -> Union[None, Time]: return None @property - def reference_time(self) -> Union[pd.Timestamp, None]: + def reference_time(self) -> pd.Timestamp | None: """Get the reference time.""" if self.is_discrete: return self._data.weldx.time_ref # type: ignore[union-attr] return self._reference_time def interp_time( - self, time: Union[pd.TimedeltaIndex, pint.Quantity, Time], time_unit: str = "s" + self, time: pd.TimedeltaIndex | pint.Quantity | Time, time_unit: str = "s" ) -> TimeSeries: """Interpolate the TimeSeries in time. @@ -390,7 +390,7 @@ def interp_time( @check_matplotlib_available def plot( self, - time: Union[pd.TimedeltaIndex, pint.Quantity] = None, + time: pd.TimedeltaIndex | pint.Quantity = None, axes: matplotlib.axes.Axes = None, data_name: str = "values", time_unit: UnitLike = None, diff --git a/weldx/geometry.py b/weldx/geometry.py index 59a3ec063..b7f9818be 100644 --- a/weldx/geometry.py +++ b/weldx/geometry.py @@ -109,9 +109,9 @@ class DynamicBaseSegment: def __init__( self, - series: Union[ - SpatialSeries, pint.Quantity, DataArray, str, MathematicalExpression - ], + series: ( + SpatialSeries | pint.Quantity | DataArray | str | MathematicalExpression + ), max_coord: float = 1, **kwargs, ): @@ -891,7 +891,7 @@ def apply_translation(self, vector): class Shape: """Defines a shape in 2 dimensions.""" - def __init__(self, segments: Union[segment_types, list[segment_types]] = None): + def __init__(self, segments: segment_types | list[segment_types] = None): """Construct a shape. Parameters @@ -918,7 +918,7 @@ def __str__(self): return f"{shape_str}" @staticmethod - def _check_segments_connected(segments: Union[segment_types, list[segment_types]]): + def _check_segments_connected(segments: segment_types | list[segment_types]): """Check if all segments are connected to each other. The start point of a segment must be identical to the end point of @@ -1071,7 +1071,7 @@ def add_line_segments(self, points: pint.Quantity): return self - def add_segments(self, segments: Union[segment_types, list[segment_types]]): + def add_segments(self, segments: segment_types | list[segment_types]): """Add segments to the shape. Parameters @@ -1303,7 +1303,7 @@ def translate(self, vector: pint.Quantity) -> Shape: class Profile: """Defines a 2d profile.""" - def __init__(self, shapes: Union[Shape, list[Shape]], units: pint.Unit = None): + def __init__(self, shapes: Shape | list[Shape], units: pint.Unit = None): """Construct profile class. Parameters @@ -1352,7 +1352,7 @@ def num_shapes(self) -> int: """ return len(self._shapes) - def add_shapes(self, shapes: Union[Shape, list[Shape]]): + def add_shapes(self, shapes: Shape | list[Shape]): """Add shapes to the profile. Parameters @@ -1372,7 +1372,7 @@ def add_shapes(self, shapes: Union[Shape, list[Shape]]): @UREG.wraps(None, (None, _DEFAULT_LEN_UNIT, None), strict=True) def rasterize( self, raster_width: pint.Quantity, stack: bool = True - ) -> Union[pint.Quantity, list[pint.Quantity]]: + ) -> pint.Quantity | list[pint.Quantity]: """Rasterize the profile. Parameters @@ -1478,9 +1478,9 @@ class DynamicTraceSegment(DynamicBaseSegment): def __init__( self, - series: Union[ - SpatialSeries, pint.Quantity, DataArray, str, MathematicalExpression - ], + series: ( + SpatialSeries | pint.Quantity | DataArray | str | MathematicalExpression + ), max_coord: float = 1, limit_orientation_to_xy: bool = False, **kwargs, @@ -1723,7 +1723,7 @@ class Trace: def __init__( self, - segments: Union[trace_segment_types, list[trace_segment_types]], + segments: trace_segment_types | list[trace_segment_types], coordinate_system: tf.LocalCoordinateSystem = None, ): """Construct trace. @@ -2225,8 +2225,8 @@ class Geometry: def __init__( self, - profile: Union[Profile, VariableProfile, iso.IsoBaseGroove], - trace_or_length: Union[Trace, pint.Quantity], + profile: Profile | VariableProfile | iso.IsoBaseGroove, + trace_or_length: Trace | pint.Quantity, width: QuantityLike = "10mm", ): """Construct a geometry. @@ -2265,7 +2265,7 @@ def __repr__(self): return f"Geometry('profile': {self._profile!r}, 'trace': {self._trace!r})" @staticmethod - def _check_inputs(profile: Union[Profile, VariableProfile], trace: Trace): + def _check_inputs(profile: Profile | VariableProfile, trace: Trace): """Check the inputs to the constructor. Parameters @@ -2453,7 +2453,7 @@ def _rasterize_variable_profile(self, profile_raster_width, trace_raster_width): return raster_data @property - def profile(self) -> Union[Profile, VariableProfile]: + def profile(self) -> Profile | VariableProfile: """Get the geometry's profile. Returns @@ -2513,7 +2513,7 @@ def plot( profile_raster_width: QuantityLike = "1mm", trace_raster_width: QuantityLike = "50mm", axes: matplotlib.axes.Axes = None, - color: Union[int, tuple[int, int, int], tuple[float, float, float]] = None, + color: int | tuple[int, int, int] | tuple[float, float, float] = None, label: str = None, limits: weldx.visualization.types.types_limits = None, show_wireframe: bool = True, @@ -2657,7 +2657,7 @@ def to_file( class SpatialData: """Represent 3D point cloud data with optional triangulation.""" - coordinates: Union[DataArray, npt.ArrayLike] + coordinates: DataArray | npt.ArrayLike """3D array of point data. The expected array dimension order is [("time"), "n", "c"].""" triangles: npt.ArrayLike = None @@ -2700,7 +2700,7 @@ def __post_init__(self, time): raise ValueError("SpatialData triangulation must be a 2d array") @staticmethod - def from_file(file_name: Union[str, Path], units: str = "mm") -> SpatialData: + def from_file(file_name: str | Path, units: str = "mm") -> SpatialData: """Create an instance from a file. Parameters @@ -2723,7 +2723,7 @@ def from_file(file_name: Union[str, Path], units: str = "mm") -> SpatialData: @staticmethod def _shape_raster_points( - shape_raster_data: Union[np.ndarray, pint.Quantity] + shape_raster_data: np.ndarray | pint.Quantity, ) -> list[list[int]]: """Extract all points from a shapes raster data.""" if isinstance(shape_raster_data, Q_): @@ -2876,7 +2876,7 @@ def limits(self) -> np.ndarray: def plot( self, axes: matplotlib.axes.Axes = None, - color: Union[int, tuple[int, int, int], tuple[float, float, float]] = None, + color: int | tuple[int, int, int] | tuple[float, float, float] = None, label: str = None, show_wireframe: bool = True, limits: weldx.visualization.types.types_limits = None, @@ -2946,7 +2946,7 @@ def plot( show_wireframe=show_wireframe, ) - def to_file(self, file_name: Union[str, Path], units: str = "mm"): + def to_file(self, file_name: str | Path, units: str = "mm"): """Write spatial data into a file. The extension prescribes the output format. diff --git a/weldx/measurement.py b/weldx/measurement.py index 8fe9155a1..9ebc6dd17 100644 --- a/weldx/measurement.py +++ b/weldx/measurement.py @@ -3,7 +3,7 @@ from __future__ import annotations from dataclasses import dataclass, field -from typing import TYPE_CHECKING, Union +from typing import TYPE_CHECKING from warnings import warn import pint @@ -47,10 +47,10 @@ def __post_init__(self): def plot( self, - time: Union[TimedeltaIndex, Quantity] = None, + time: TimedeltaIndex | Quantity = None, axes: matplotlib.axes.Axes = None, data_name: str = "values", - time_unit: Union[str, Unit] = None, + time_unit: str | Unit = None, **mpl_kwargs, ) -> matplotlib.axes.Axes: """Plot the time dependent data of the `Signal`. @@ -375,7 +375,7 @@ def from_parameters( source_name: str, source_error: Error, output_signal_type: str, - output_signal_unit: Union[str, Unit], + output_signal_unit: str | Unit, signal_data: TimeSeries = None, ) -> MeasurementChain: """Create a new measurement chain without providing a `SignalSource` instance. @@ -757,7 +757,7 @@ def create_transformation( name: str, error: Error, output_signal_type: str = None, - output_signal_unit: Union[str, Unit] = None, + output_signal_unit: str | Unit = None, func: MathematicalExpression = None, data: TimeSeries = None, input_signal_source: str = None, diff --git a/weldx/tags/core/common_types.py b/weldx/tags/core/common_types.py index 35129ecd2..541f70127 100644 --- a/weldx/tags/core/common_types.py +++ b/weldx/tags/core/common_types.py @@ -1,9 +1,9 @@ from __future__ import annotations import dataclasses -from collections.abc import Mapping +from collections.abc import Hashable, Mapping from dataclasses import dataclass -from typing import Any, Hashable +from typing import Any import numpy as np import pint diff --git a/weldx/tests/test_geometry.py b/weldx/tests/test_geometry.py index 6275d4f62..f1a41c8bd 100644 --- a/weldx/tests/test_geometry.py +++ b/weldx/tests/test_geometry.py @@ -5,7 +5,6 @@ import math from pathlib import Path from tempfile import TemporaryDirectory -from typing import Union import numpy as np import pint @@ -234,7 +233,7 @@ def is_row_in_matrix(row, matrix) -> bool: def default_segment_rasterization_tests( - segment: Union[geo.ArcSegment, geo.LineSegment], raster_width + segment: geo.ArcSegment | geo.LineSegment, raster_width ): """Perform some default checks for a passed segment's rasterization method. @@ -3136,7 +3135,7 @@ def test_comparison(kwargs_mod: dict, expected_result: bool): "filename", ["test.ply", "test.stl", "test.vtk", Path("test.stl")], ) - def test_read_write_file(filename: Union[str, Path]): + def test_read_write_file(filename: str | Path): """Test the `from_file` and `write_to_file` functions. The test simply creates a `SpatialData` instance, writes it to a file and reads diff --git a/weldx/tests/test_time.py b/weldx/tests/test_time.py index e064171b0..8e979fdad 100644 --- a/weldx/tests/test_time.py +++ b/weldx/tests/test_time.py @@ -1,8 +1,6 @@ """Test the `Time` class.""" from __future__ import annotations -from typing import List, Union - import numpy as np import pandas as pd import pytest @@ -21,13 +19,13 @@ def _initialize_delta_type(cls_type, values, unit): """Initialize the passed time type.""" if cls_type is np.timedelta64: - if isinstance(values, List): + if isinstance(values, list): return np.array(values, dtype=f"timedelta64[{unit}]") return np.timedelta64(values, unit) if cls_type is Time: return Time(Q_(values, unit)) if cls_type is str: - if not isinstance(values, List): + if not isinstance(values, list): return f"{values}{unit}" return [f"{v}{unit}" for v in values] return cls_type(values, unit) @@ -36,7 +34,7 @@ def _initialize_delta_type(cls_type, values, unit): def _initialize_datetime_type(cls_type, values): """Initialize the passed datetime type.""" if cls_type is np.datetime64: - if isinstance(values, List): + if isinstance(values, list): return np.array(values, dtype="datetime64") return np.datetime64(values) if cls_type is str: @@ -97,7 +95,7 @@ class TestTime: @staticmethod def _parse_time_type_test_input( type_input, - ) -> tuple[Union[types_time_like, Time], bool]: + ) -> tuple[types_time_like | Time, bool]: """Return the time type and a bool that defines if the returned type is a delta. This is mainly used in generalized tests where a type like `Time` itself can @@ -183,7 +181,7 @@ def _get_init_exp_values( ) def test_init( self, - input_vals: Union[type, tuple[type, str]], + input_vals: type | tuple[type, str], set_time_ref: bool, scl: bool, arr: bool, diff --git a/weldx/tests/transformations/_util.py b/weldx/tests/transformations/_util.py index a520e0732..86f99a239 100644 --- a/weldx/tests/transformations/_util.py +++ b/weldx/tests/transformations/_util.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, Union +from typing import Any import numpy as np from pkg_resources import get_distribution @@ -42,8 +42,8 @@ def check_coordinate_system_orientation( def check_coordinate_system( lcs: tf.LocalCoordinateSystem, - orientation_expected: Union[np.ndarray, list[list[Any]], DataArray], - coordinates_expected: Union[np.ndarray, list[Any], DataArray], + orientation_expected: np.ndarray | list[list[Any]] | DataArray, + coordinates_expected: np.ndarray | list[Any] | DataArray, positive_orientation_expected: bool = True, time=None, time_ref=None, diff --git a/weldx/time.py b/weldx/time.py index cb878c179..5095f9d91 100644 --- a/weldx/time.py +++ b/weldx/time.py @@ -4,7 +4,7 @@ from abc import ABC, abstractmethod from collections.abc import Sequence from functools import reduce -from typing import List, Union +from typing import Union import numpy as np import pandas as pd @@ -37,7 +37,7 @@ def time(self) -> Time: @property @abstractmethod - def reference_time(self) -> Union[Timestamp, None]: + def reference_time(self) -> Timestamp | None: """Return the reference timestamp if the time data is absolute.""" @@ -295,7 +295,7 @@ def __init__( if isinstance(time, pd.Index) and not time.is_monotonic_increasing: raise ValueError("The time values passed are not monotonic increasing.") - self._time: Union[pd.TimedeltaIndex, pd.DatetimeIndex] = time + self._time: pd.TimedeltaIndex | pd.DatetimeIndex = time self._time_ref: pd.Timestamp = time_ref @staticmethod @@ -342,7 +342,7 @@ def __rsub__(self, other: types_time_like) -> Time: time_ref = None if self.is_absolute else other.reference_time return Time(other.as_pandas() - self._time, time_ref) - def __eq__(self, other: types_time_like) -> Union[bool, list[bool]]: # type: ignore + def __eq__(self, other: types_time_like) -> bool | list[bool]: # type: ignore """Element-wise comparisons between time object and compatible types. See Also @@ -455,7 +455,7 @@ def as_quantity(self, unit: str = "s") -> pint.Quantity: q.time_ref = self.reference_time # type: ignore[attr-defined] return q # type: ignore[return-value] - def as_timedelta(self) -> Union[Timedelta, TimedeltaIndex]: + def as_timedelta(self) -> Timedelta | TimedeltaIndex: """Return the data as `pandas.TimedeltaIndex` or `pandas.Timedelta`.""" if self.is_absolute: return self._time - self.reference_time @@ -474,7 +474,7 @@ def as_timestamp(self) -> Timestamp: raise TypeError("Time object does not represent a timestamp.") return self._time - def as_datetime(self) -> Union[Timestamp, DatetimeIndex]: + def as_datetime(self) -> Timestamp | DatetimeIndex: """Return the data as `pandas.DatetimeIndex`.""" if not self.is_absolute: raise TypeError("Cannot convert non absolute Time object to datetime") @@ -482,11 +482,11 @@ def as_datetime(self) -> Union[Timestamp, DatetimeIndex]: def as_pandas( self, - ) -> Union[pd.Timedelta, pd.TimedeltaIndex, pd.Timestamp, pd.DatetimeIndex]: + ) -> pd.Timedelta | pd.TimedeltaIndex | pd.Timestamp | pd.DatetimeIndex: """Return the underlying pandas time datatype.""" return self._time - def as_pandas_index(self) -> Union[pd.TimedeltaIndex, pd.DatetimeIndex]: + def as_pandas_index(self) -> pd.TimedeltaIndex | pd.DatetimeIndex: """Return a pandas index type regardless of length. This is useful when using time as coordinate in xarray types. @@ -520,7 +520,7 @@ def as_data_array(self, timedelta_base: bool = True) -> DataArray: return da @property - def reference_time(self) -> Union[Timestamp, None]: + def reference_time(self) -> Timestamp | None: """Get the reference time.""" if isinstance(self._time, DatetimeIndex): return self._time_ref if self._time_ref is not None else self._time[0] @@ -544,7 +544,7 @@ def is_timestamp(self) -> bool: return isinstance(self._time, pd.Timestamp) @property - def index(self) -> Union[pd.TimedeltaIndex, pd.DatetimeIndex]: + def index(self) -> pd.TimedeltaIndex | pd.DatetimeIndex: """Return a pandas index type regardless of length. See Also @@ -581,7 +581,7 @@ def duration(self) -> Time: """Get the covered time span.""" return Time(self.max() - self.min()) - def resample(self, number_or_interval: Union[int, types_timedelta_like]): + def resample(self, number_or_interval: int | types_timedelta_like): """Resample the covered duration. Parameters @@ -659,7 +659,7 @@ def resample(self, number_or_interval: Union[int, types_timedelta_like]): @staticmethod def _convert_quantity( time: pint.Quantity, - ) -> Union[pd.TimedeltaIndex, pd.DatetimeIndex]: + ) -> pd.TimedeltaIndex | pd.DatetimeIndex: """Build a time-like pandas.Index from pint.Quantity.""" time_ref = getattr(time, "time_ref", None) base = "s" # using low base unit could cause rounding errors @@ -677,8 +677,8 @@ def _convert_quantity( @staticmethod def _convert_xarray( - time: Union[xr.DataArray, xr.Dataset] - ) -> Union[pd.TimedeltaIndex, pd.DatetimeIndex]: + time: xr.DataArray | xr.Dataset, + ) -> pd.TimedeltaIndex | pd.DatetimeIndex: """Build a time-like pandas.Index from xarray objects.""" if "time" in time.coords: time = time.time @@ -692,7 +692,7 @@ def _convert_xarray( return time_index @staticmethod - def _convert_other(time) -> Union[pd.TimedeltaIndex, pd.DatetimeIndex]: + def _convert_other(time) -> pd.TimedeltaIndex | pd.DatetimeIndex: """Try autocasting input to time-like pandas index.""" _input_type = type(time) @@ -784,14 +784,14 @@ def _union_instance(self, times: Sequence[types_time_like]) -> Time: # list of types that are supported to be stored in Time._time _data_base_types = (pd.Timedelta, pd.Timestamp, pd.DatetimeIndex, pd.TimedeltaIndex) -types_datetime_like = Union[DatetimeIndex, np.datetime64, List[str], Time] +types_datetime_like = Union[DatetimeIndex, np.datetime64, list[str], Time] """types that define ascending arrays of time stamps.""" types_timestamp_like = Union[Timestamp, str, Time] """types that define timestamps.""" types_timedelta_like = Union[ - TimedeltaIndex, pint.Quantity, np.timedelta64, List[str], Time + TimedeltaIndex, pint.Quantity, np.timedelta64, list[str], Time ] """types that define ascending time delta arrays.""" diff --git a/weldx/transformations/cs_manager.py b/weldx/transformations/cs_manager.py index 8ccd02f69..2d0219b3e 100644 --- a/weldx/transformations/cs_manager.py +++ b/weldx/transformations/cs_manager.py @@ -5,7 +5,7 @@ import warnings from copy import deepcopy from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any import numpy as np import pandas as pd @@ -560,7 +560,7 @@ def relabel(self, mapping: dict[str, str]): def assign_data( self, - data: Union[xr.DataArray, SpatialData], + data: xr.DataArray | SpatialData, data_name: str, reference_system: str, target_system: str = None, @@ -947,9 +947,7 @@ def data_names(self) -> list[str]: data_names += list(self._graph.nodes[node]["data"].keys()) return data_names - def _find_data( - self, data_name: str - ) -> tuple[str, Union[xr.DataArray, SpatialData]]: + def _find_data(self, data_name: str) -> tuple[str, xr.DataArray | SpatialData]: """Get the data and its owning systems name.""" for cs in self._graph.nodes: for name, data in self._graph.nodes[cs]["data"].items(): @@ -959,7 +957,7 @@ def _find_data( def get_data( self, data_name, target_coordinate_system_name=None - ) -> Union[np.ndarray, SpatialData]: + ) -> np.ndarray | SpatialData: """Get the specified data, optionally transformed into any coordinate system. Parameters @@ -1231,7 +1229,7 @@ def get_cs( lcs_result += self._get_cs_on_edge(edge, time, time_ref) return lcs_result - def get_parent_system_name(self, coordinate_system_name) -> Union[str, None]: + def get_parent_system_name(self, coordinate_system_name) -> str | None: """Get the name of a coordinate systems parent system. The parent is the next system on the path towards the root node. @@ -1297,7 +1295,7 @@ def interp_time( self, time: types_time_like = None, time_ref: types_timestamp_like = None, - affected_coordinate_systems: Union[str, list[str]] = None, + affected_coordinate_systems: str | list[str] = None, in_place: bool = False, ) -> CoordinateSystemManager: """Interpolates the coordinate systems in time. @@ -1520,13 +1518,13 @@ def plot( reference_system: str = None, coordinate_systems: list[str] = None, data_sets: list[str] = None, - colors: dict[str, Union[int, tuple[int, int, int]]] = None, + colors: dict[str, int | tuple[int, int, int]] = None, title: str = None, limits: list[tuple[float, float]] = None, time: types_time_like = None, time_ref: types_timestamp_like = None, axes_equal: bool = False, - scale_vectors: Union[float, list, np.ndarray] = None, + scale_vectors: float | list | np.ndarray = None, show_data_labels: bool = True, show_labels: bool = True, show_origins: bool = True, @@ -1697,7 +1695,7 @@ def transform_data( data: types_coordinates, source_coordinate_system_name: str, target_coordinate_system_name: str, - ) -> Union[SpatialData, xr.DataArray]: + ) -> SpatialData | xr.DataArray: """Transform spatial data from one coordinate system to another. Parameters diff --git a/weldx/transformations/local_cs.py b/weldx/transformations/local_cs.py index e1f766bb6..ac976d776 100644 --- a/weldx/transformations/local_cs.py +++ b/weldx/transformations/local_cs.py @@ -5,7 +5,7 @@ import typing import warnings from copy import deepcopy -from typing import Any, Union +from typing import Any import numpy as np import pandas as pd @@ -40,7 +40,7 @@ class LocalCoordinateSystem(TimeDependent): def __init__( self, orientation: types_orientation = None, - coordinates: Union[types_coordinates, TimeSeries] = None, + coordinates: types_coordinates | TimeSeries = None, time: types_time_like = None, time_ref: types_timestamp_like = None, construction_checks: bool = True, @@ -290,7 +290,7 @@ def _build_orientation( @classmethod def _build_coordinates( cls, coordinates, time: Time = None - ) -> Union[xr.DataArray, TimeSeries]: + ) -> xr.DataArray | TimeSeries: """Create xarray coordinates from different formats and time-inputs.""" if isinstance(coordinates, TimeSeries): if coordinates.is_expression: @@ -331,10 +331,10 @@ def _build_coordinates( @staticmethod def _build_time( - coordinates: Union[types_coordinates, TimeSeries], + coordinates: types_coordinates | TimeSeries, time: types_time_like, time_ref: types_timestamp_like, - ) -> Union[Time, None]: + ) -> Time | None: if time is None: if isinstance(coordinates, TimeSeries) and coordinates.is_discrete: time = coordinates.time @@ -371,7 +371,7 @@ def _check_and_normalize_orientation(orientation: xr.DataArray) -> xr.DataArray: return orientation @staticmethod - def _check_coordinates(coordinates: Union[xr.DataArray, TimeSeries]): + def _check_coordinates(coordinates: xr.DataArray | TimeSeries): """Check if the coordinates have the correct format.""" if isinstance(coordinates, xr.DataArray): ut.xr_check_coords( @@ -402,7 +402,7 @@ def _coords_from_discrete_time_series(time_series): @staticmethod def _unify_time_axis( - orientation: xr.DataArray, coordinates: Union[xr.DataArray, TimeSeries] + orientation: xr.DataArray, coordinates: xr.DataArray | TimeSeries ) -> tuple: """Unify time axis of orientation and coordinates if both are DataArrays.""" if ( @@ -553,7 +553,7 @@ def orientation(self) -> xr.DataArray: return self.dataset.orientation @property - def coordinates(self) -> Union[xr.DataArray, TimeSeries]: + def coordinates(self) -> xr.DataArray | TimeSeries: """Get the coordinate systems coordinates. Returns @@ -598,7 +598,7 @@ def has_reference_time(self) -> bool: return self.reference_time is not None @property - def reference_time(self) -> Union[pd.Timestamp, None]: + def reference_time(self) -> pd.Timestamp | None: """Get the coordinate systems reference time. Returns @@ -612,7 +612,7 @@ def reference_time(self) -> Union[pd.Timestamp, None]: return self._dataset.weldx.time_ref @property - def time(self) -> Union[Time, None]: + def time(self) -> Time | None: """Get the time union of the local coordinate system (None if system is static). Returns @@ -808,7 +808,7 @@ def plot( time: types_time_like = None, time_ref: types_timestamp_like = None, time_index: int = None, - scale_vectors: Union[float, list, np.ndarray] = None, + scale_vectors: float | list | np.ndarray = None, show_origin: bool = True, show_trace: bool = True, show_vectors: bool = True, diff --git a/weldx/transformations/rotation.py b/weldx/transformations/rotation.py index da86d8633..9b30a1d97 100644 --- a/weldx/transformations/rotation.py +++ b/weldx/transformations/rotation.py @@ -1,7 +1,7 @@ """Contains tools to handle rotations.""" from __future__ import annotations -from typing import TYPE_CHECKING, Union +from typing import TYPE_CHECKING import pint from scipy.spatial.transform import Rotation as _Rotation @@ -59,7 +59,7 @@ def from_rotvec(cls, rotvec: npt.ArrayLike) -> WXRotation: def from_euler( cls, seq: str, - angles: Union[pint.Quantity, npt.ArrayLike], + angles: pint.Quantity | npt.ArrayLike, degrees: bool = False, ) -> WXRotation: """Initialize from euler angles. diff --git a/weldx/util/media_file.py b/weldx/util/media_file.py index 8451e2c27..cba0e0436 100644 --- a/weldx/util/media_file.py +++ b/weldx/util/media_file.py @@ -2,7 +2,7 @@ from __future__ import annotations from pathlib import Path -from typing import Optional, Union, get_args, get_type_hints +from typing import Union, get_args import numpy as np import pandas as pd @@ -85,8 +85,8 @@ class MediaFile: def __init__( self, path_or_array: types_media_input, - reference_time: Optional[pd.Timestamp] = None, - fps: Optional[float] = None, + reference_time: pd.Timestamp | None = None, + fps: float | None = None, ): if isinstance(path_or_array, get_args(types_path_like)): self._init_from_path(path_or_array, reference_time) # type: ignore @@ -136,8 +136,7 @@ def _init_from_sequence( resolution=(image.width, image.height), nframes=len(path_or_array), ) - _ref_time_types = get_type_hints(MediaFile.__init__)["reference_time"] - if not isinstance(reference_time, get_args(_ref_time_types)): + if reference_time is not None and not isinstance(reference_time, pd.Timestamp): raise ValueError( f"unsupported type for reference_time {type(reference_time)}" ) @@ -189,7 +188,7 @@ def _get_video_metadata(fn: str) -> dict: return metadata @property - def reference_time(self) -> Optional[pd.Timestamp]: + def reference_time(self) -> pd.Timestamp | None: """Time of recording of this media (if known).""" return self._reference_time @@ -211,7 +210,7 @@ def fps(self) -> pint.Quantity: return Q_(self._metadata["fps"], "1/s") @property - def duration(self) -> Optional[pint.Quantity]: + def duration(self) -> pint.Quantity | None: """In case of time-dynamic data, return its duration.""" return len(self._handle) / self.fps diff --git a/weldx/util/util.py b/weldx/util/util.py index 2d71d1f7e..14a792d0e 100644 --- a/weldx/util/util.py +++ b/weldx/util/util.py @@ -4,11 +4,11 @@ import functools import sys import warnings -from collections.abc import Callable, Sequence, Set +from collections.abc import Callable, Collection, Hashable, Mapping, Sequence, Set from functools import wraps from importlib.util import find_spec from inspect import getmembers, isfunction -from typing import ClassVar, Collection, Hashable, Mapping, Union +from typing import ClassVar, Union import numpy as np import pandas as pd diff --git a/weldx/util/xarray.py b/weldx/util/xarray.py index ec51055b0..e8f6ec436 100644 --- a/weldx/util/xarray.py +++ b/weldx/util/xarray.py @@ -3,7 +3,7 @@ from __future__ import annotations from collections.abc import Iterable, Mapping -from typing import TYPE_CHECKING, Any, Union +from typing import TYPE_CHECKING, Any import numpy as np import pandas as pd @@ -275,7 +275,7 @@ def _add_coord_edges(da1: xr.DataArray, da2: xr.DataArray, assume_sorted: bool): def xr_interp_like( da1: xr.DataArray, - da2: Union[xr.DataArray, dict[str, Any]], + da2: xr.DataArray | dict[str, Any], interp_coords: list[str] = None, broadcast_missing: bool = False, fillna: bool = True, @@ -425,7 +425,7 @@ def _check_dtype(var_dtype, ref_dtype: str) -> bool: return True -def xr_check_coords(coords: Union[xr.DataArray, Mapping[str, Any]], ref: dict) -> bool: +def xr_check_coords(coords: xr.DataArray | Mapping[str, Any], ref: dict) -> bool: """Validate the coordinates of the DataArray against a reference dictionary. The reference dictionary should have the dimensions as keys and those contain @@ -541,7 +541,7 @@ def xr_check_coords(coords: Union[xr.DataArray, Mapping[str, Any]], ref: dict) - return True -def xr_check_dimensionality(da: xr.DataArray, units_ref: Union[str, pint.Unit]): +def xr_check_dimensionality(da: xr.DataArray, units_ref: str | pint.Unit): """Check if the dimensionality of a ``DataArray`` is compatible with reference unit. Parameters @@ -817,7 +817,7 @@ def reset_reference_time(self, time_ref_new: pd.Timestamp) -> xr.DataArray: return da @property - def time_ref(self) -> Union[pd.Timestamp, None]: + def time_ref(self) -> pd.Timestamp | None: """Get the time_ref value or `None` if not set.""" da = self._obj if "time" in da.coords and "time_ref" in da.time.attrs: @@ -894,7 +894,7 @@ def dequantify_coords(self): return da @property - def units(self) -> Union[pint.Unit, None]: + def units(self) -> pint.Unit | None: """Get the unit of the data array values. Other than the pint-xarray accessor ``.pint.units`` this will also return units diff --git a/weldx/visualization/__init__.py b/weldx/visualization/__init__.py index 6509c7cda..94cfd60e4 100644 --- a/weldx/visualization/__init__.py +++ b/weldx/visualization/__init__.py @@ -38,7 +38,7 @@ def _warn(stacklevel=2): class _Hint(_MagickMock): # warn again, if actual features are requested. def __init__(self, *args, **kwargs): - super(_Hint, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) _warn(stacklevel=3) CoordinateSystemManagerVisualizerK3D = _Hint diff --git a/weldx/welding/groove/iso_9692_1.py b/weldx/welding/groove/iso_9692_1.py index b91b7dd46..89e1962e4 100644 --- a/weldx/welding/groove/iso_9692_1.py +++ b/weldx/welding/groove/iso_9692_1.py @@ -5,7 +5,7 @@ import abc from abc import abstractmethod from dataclasses import dataclass, field -from typing import TYPE_CHECKING, Union +from typing import TYPE_CHECKING import numpy as np import pint @@ -54,7 +54,7 @@ def _get_bounds(points): def _compute_cross_sect_shape_points( - points: list[list[Union[Point2D, tuple]]] + points: list[list[Point2D | tuple]], ) -> pint.Quantity: # Assumes that we have two separate shapes for each workpiece # 1. compute the total area of all workpieces @@ -1621,7 +1621,7 @@ def _helperfunction(segment: list[str], array: np.ndarray) -> geo.Shape: geo.Shape """ - segment_list: list[Union[geo.LineSegment, geo.ArcSegment]] = [] + segment_list: list[geo.LineSegment | geo.ArcSegment] = [] counter = 0 for elem in segment: if elem == "line":