Skip to content

Commit

Permalink
Add Python 3.13 support, drop 3.9
Browse files Browse the repository at this point in the history
Remove the upper bound of the supported Python version, since that
makes it tedious to add new versions: PyDPF Composites needs to
be released before we can update PyACP, for example.

Add Python 3.13 to the explicitly supported versions in the
trove classifiers, and add it to the test matrix.

Drop support for Python 3.9.

Run pyupgrade with the '--py310-plus' flag, and remove the now
unused imports.
  • Loading branch information
greschd committed Nov 27, 2024
1 parent 9ff7e3d commit 3d25da0
Show file tree
Hide file tree
Showing 30 changed files with 1,480 additions and 1,399 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
inputs:

env:
MAIN_PYTHON_VERSION: '3.12'
MAIN_PYTHON_VERSION: '3.13'
CONTAINER_TAG: 'latest'
PACKAGE_NAME: 'ansys-dpf-composites'
DOCUMENTATION_CNAME: 'composites.dpf.docs.pyansys.com'
Expand Down Expand Up @@ -58,7 +58,7 @@ jobs:
# docker images on the windows agents. See the issue
# https://github.com/actions/runner-images/issues/1143
os: [ubuntu-latest]
python-version: ['3.9', '3.10', '3.11', '3.12']
python-version: ['3.10', '3.11', '3.12', '3.13']
fail-fast: false
steps:
- name: "Login in Github Container registry"
Expand Down Expand Up @@ -134,7 +134,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.9
python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install --upgrade pip tox tox-gh-actions
Expand Down Expand Up @@ -223,7 +223,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ['3.9', '3.10', '3.11', '3.12']
python-version: ['3.10', '3.11', '3.12', '3.13']
steps:
- name: "Build a wheelhouse of the Python library"
uses: ansys/actions/build-wheelhouse@v8
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ repos:
rev: v3.15.2
hooks:
- id: pyupgrade
args: [--py39-plus]
args: [--py310-plus]

- repo: https://github.com/PyCQA/flake8
rev: 7.0.0
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ PyDPF Composites
:target: https://docs.pyansys.com/
:alt: PyAnsys

.. |python| image:: https://img.shields.io/badge/Python-%3E%3D3.9-blue
.. |python| image:: https://img.shields.io/badge/Python-%3E%3D3.10-blue
:target: https://pypi.org/project/ansys-dpf-composites/
:alt: Python

Expand Down
2,537 changes: 1,312 additions & 1,225 deletions poetry.lock

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ documentation = "https://composites.dpf.docs.pyansys.com"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]
Expand All @@ -25,9 +29,7 @@ packages = [
]

[tool.poetry.dependencies]
# Note we cannot remove the upper bound for python, because
# (at least ) dpf core specifies an upper bound.
python = ">=3.9,<3.13"
python = ">=3.10,<4"
packaging = "*"
numpy = ">=1.22"
build = {version = ">=0.8.0", optional = true}
Expand Down Expand Up @@ -127,6 +129,6 @@ ignored-classes = [
]

[tool.mypy]
python_version = 3.12
python_version = 3.10
mypy_path = "$MYPY_CONFIG_FILE_DIR/src:$MYPY_CONFIG_FILE_DIR/tests"
ignore_missing_imports = true
3 changes: 2 additions & 1 deletion src/ansys/dpf/composites/_composite_model_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
# SOFTWARE.

"""Composite Model Interface Factory."""
from typing import Callable, Optional, Union
from collections.abc import Callable
from typing import Optional, Union

from ansys.dpf.core import UnitSystem
from ansys.dpf.core.server_types import BaseServer
Expand Down
36 changes: 18 additions & 18 deletions src/ansys/dpf/composites/_composite_model_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"""Composite Model Interface."""
# New interface after 2023 R2
from collections.abc import Collection, Sequence
from typing import Optional, cast
from typing import cast
from warnings import warn

import ansys.dpf.core as dpf
Expand Down Expand Up @@ -102,7 +102,7 @@ def __init__(
self,
composite_files: ContinuousFiberCompositesFiles,
server: BaseServer,
default_unit_system: Optional[UnitSystem] = None,
default_unit_system: UnitSystem | None = None,
):
"""Initialize data providers and add composite information to meshed region."""
self._composite_files = upload_continuous_fiber_composite_files_to_server(
Expand Down Expand Up @@ -263,15 +263,15 @@ def material_metadata(self) -> dict[int, MaterialMetadata]:
return metadata

@_deprecated_composite_definition_label
def get_mesh(self, composite_definition_label: Optional[str] = None) -> MeshedRegion:
def get_mesh(self, composite_definition_label: str | None = None) -> MeshedRegion:
"""Get the underlying DPF meshed region.
The meshed region contains the lay-up information.
"""
return self._core_model.metadata.meshed_region

@_deprecated_composite_definition_label
def get_layup_operator(self, composite_definition_label: Optional[str] = None) -> Operator:
def get_layup_operator(self, composite_definition_label: str | None = None) -> Operator:
"""Get the lay-up operator.
Parameters
Expand All @@ -297,7 +297,7 @@ def layup_model_type(self) -> LayupModelContextType:
def evaluate_failure_criteria(
self,
combined_criterion: CombinedFailureCriterion,
composite_scope: Optional[CompositeScope] = None,
composite_scope: CompositeScope | None = None,
measure: FailureMeasureEnum = FailureMeasureEnum.INVERSE_RESERVE_FACTOR,
write_data_for_full_element_scope: bool = True,
max_chunk_size: int = 50000,
Expand Down Expand Up @@ -525,8 +525,8 @@ def get_sampling_point(
self,
combined_criterion: CombinedFailureCriterion,
element_id: int,
time: Optional[float] = None,
composite_definition_label: Optional[str] = None,
time: float | None = None,
composite_definition_label: str | None = None,
) -> SamplingPointNew:
"""Get a sampling point for an element ID and failure criteria.
Expand Down Expand Up @@ -563,8 +563,8 @@ def get_sampling_point(

@_deprecated_composite_definition_label
def get_element_info(
self, element_id: int, composite_definition_label: Optional[str] = None
) -> Optional[ElementInfo]:
self, element_id: int, composite_definition_label: str | None = None
) -> ElementInfo | None:
"""Get element information for an element ID.
This method returns ``None`` if the element type is not supported.
Expand All @@ -586,8 +586,8 @@ def get_property_for_all_layers(
self,
layup_property: LayerProperty,
element_id: int,
composite_definition_label: Optional[str] = None,
) -> Optional[NDArray[np.double]]:
composite_definition_label: str | None = None,
) -> NDArray[np.double] | None:
"""Get a layer property for an element ID.
This method returns a numpy array with the values of the property for all the layers.
Expand Down Expand Up @@ -617,8 +617,8 @@ def get_property_for_all_layers(

@_deprecated_composite_definition_label
def get_analysis_plies(
self, element_id: int, composite_definition_label: Optional[str] = None
) -> Optional[Sequence[str]]:
self, element_id: int, composite_definition_label: str | None = None
) -> Sequence[str] | None:
"""Get analysis ply names.
This method returns ``None`` if the element is not layered.
Expand All @@ -639,8 +639,8 @@ def get_analysis_plies(

@_deprecated_composite_definition_label
def get_element_laminate_offset(
self, element_id: int, composite_definition_label: Optional[str] = None
) -> Optional[np.double]:
self, element_id: int, composite_definition_label: str | None = None
) -> np.double | None:
"""Get the laminate offset of an element.
This method returns ``None`` if the element is not layered.
Expand All @@ -661,7 +661,7 @@ def get_element_laminate_offset(
def get_constant_property_dict(
self,
material_properties: Collection[MaterialProperty],
composite_definition_label: Optional[str] = None,
composite_definition_label: str | None = None,
) -> dict[np.int64, dict[MaterialProperty, float]]:
"""Get a dictionary with constant properties.
Expand Down Expand Up @@ -703,7 +703,7 @@ def add_interlaminar_normal_stresses(
self,
stresses: FieldsContainer,
strains: FieldsContainer,
composite_definition_label: Optional[str] = None,
composite_definition_label: str | None = None,
) -> None:
"""Add interlaminar normal stresses to the stresses fields container.
Expand Down Expand Up @@ -749,7 +749,7 @@ def get_all_layered_element_ids(self) -> Sequence[int]:
)

def get_all_layered_element_ids_for_composite_definition_label(
self, composite_definition_label: Optional[str] = None
self, composite_definition_label: str | None = None
) -> Sequence[int]:
"""Get all layered element IDs that belong to a composite definition label.
Expand Down
36 changes: 18 additions & 18 deletions src/ansys/dpf/composites/_composite_model_impl_2023r2.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

"""Composite Model Interface 2023R2."""
from collections.abc import Collection, Sequence
from typing import Optional, cast
from typing import cast
from warnings import warn

import ansys.dpf.core as dpf
Expand Down Expand Up @@ -138,7 +138,7 @@ def __init__(
self,
composite_files: ContinuousFiberCompositesFiles,
server: BaseServer,
default_unit_system: Optional[UnitSystem] = None,
default_unit_system: UnitSystem | None = None,
):
"""Initialize data providers and add composite information to meshed region."""
self._composite_files = upload_continuous_fiber_composite_files_to_server(
Expand Down Expand Up @@ -189,7 +189,7 @@ def composite_files(self) -> ContinuousFiberCompositesFiles:
"""Get the composite file paths on the server."""
return self._composite_files

def get_mesh(self, composite_definition_label: Optional[str] = None) -> MeshedRegion:
def get_mesh(self, composite_definition_label: str | None = None) -> MeshedRegion:
"""Get the underlying DPF meshed region.
The meshed region contains the lay-up information.
Expand Down Expand Up @@ -239,7 +239,7 @@ def material_metadata(self) -> dict[int, MaterialMetadata]:
" or later should be used instead."
)

def get_layup_operator(self, composite_definition_label: Optional[str] = None) -> Operator:
def get_layup_operator(self, composite_definition_label: str | None = None) -> Operator:
"""Get the lay-up operator.
Parameters
Expand Down Expand Up @@ -267,7 +267,7 @@ def layup_model_type(self) -> LayupModelContextType:
def evaluate_failure_criteria(
self,
combined_criterion: CombinedFailureCriterion,
composite_scope: Optional[CompositeScope] = None,
composite_scope: CompositeScope | None = None,
measure: FailureMeasureEnum = FailureMeasureEnum.INVERSE_RESERVE_FACTOR,
write_data_for_full_element_scope: bool = True,
max_chunk_size: int = 50000,
Expand Down Expand Up @@ -355,8 +355,8 @@ def get_sampling_point(
self,
combined_criterion: CombinedFailureCriterion,
element_id: int,
time: Optional[float] = None,
composite_definition_label: Optional[str] = None,
time: float | None = None,
composite_definition_label: str | None = None,
) -> SamplingPoint:
"""Get a sampling point for an element ID and failure criteria.
Expand Down Expand Up @@ -408,8 +408,8 @@ def get_sampling_point(
return SamplingPoint2023R2("Sampling Point", rd, self._unit_system, server=self._server)

def get_element_info(
self, element_id: int, composite_definition_label: Optional[str] = None
) -> Optional[ElementInfo]:
self, element_id: int, composite_definition_label: str | None = None
) -> ElementInfo | None:
"""Get element information for an element ID.
This method returns ``None`` if the element type is not supported.
Expand All @@ -434,8 +434,8 @@ def get_property_for_all_layers(
self,
layup_property: LayerProperty,
element_id: int,
composite_definition_label: Optional[str] = None,
) -> Optional[NDArray[np.double]]:
composite_definition_label: str | None = None,
) -> NDArray[np.double] | None:
"""Get a layer property for an element ID.
Returns a numpy array with the values of the property for all the layers.
Expand Down Expand Up @@ -469,8 +469,8 @@ def get_property_for_all_layers(
raise RuntimeError(f"Invalid property {layup_property}")

def get_analysis_plies(
self, element_id: int, composite_definition_label: Optional[str] = None
) -> Optional[Sequence[str]]:
self, element_id: int, composite_definition_label: str | None = None
) -> Sequence[str] | None:
"""Get analysis ply names.
This method returns ``None`` if the element is not layered.
Expand All @@ -495,8 +495,8 @@ def get_analysis_plies(
return layup_properties_provider.get_analysis_plies(element_id)

def get_element_laminate_offset(
self, element_id: int, composite_definition_label: Optional[str] = None
) -> Optional[np.double]:
self, element_id: int, composite_definition_label: str | None = None
) -> np.double | None:
"""Get the laminate offset of an element.
THis method returns ``None`` if the element is not layered.
Expand All @@ -521,7 +521,7 @@ def get_element_laminate_offset(
def get_constant_property_dict(
self,
material_properties: Collection[MaterialProperty],
composite_definition_label: Optional[str] = None,
composite_definition_label: str | None = None,
) -> dict[np.int64, dict[MaterialProperty, float]]:
"""Get a dictionary with constant properties.
Expand Down Expand Up @@ -564,7 +564,7 @@ def add_interlaminar_normal_stresses(
self,
stresses: FieldsContainer,
strains: FieldsContainer,
composite_definition_label: Optional[str] = None,
composite_definition_label: str | None = None,
) -> None:
"""Add interlaminar normal stresses to the stresses fields container.
Expand Down Expand Up @@ -612,7 +612,7 @@ def get_all_layered_element_ids(self) -> Sequence[int]:
)

def get_all_layered_element_ids_for_composite_definition_label(
self, composite_definition_label: Optional[str]
self, composite_definition_label: str | None
) -> Sequence[int]:
"""Get all layered element IDs that belong to a composite definition label.
Expand Down
4 changes: 2 additions & 2 deletions src/ansys/dpf/composites/_composite_model_impl_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@

"""Composite Model Interface."""
# New interface after 2023 R2
from collections.abc import Sequence
from typing import Any, Callable
from collections.abc import Callable, Sequence
from typing import Any
from warnings import warn

import ansys.dpf.core as dpf
Expand Down
Loading

0 comments on commit 3d25da0

Please sign in to comment.