Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ body:
```
placeholder: |
`scio` version: 1.0.0
Python version: 3.13.5
Python version: 3.14.0
Platform: Linux (#67~22.04.1-Ubuntu ...)
Machine type: x86_64
validations:
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
matrix:
os: ["ubuntu-latest", "windows-latest"] # Remove MacOS (billing + github.com/ThalesGroup/scio/issues/2)
python-version: ["3.12", "3.13"]
python-version: ["3.12", "3.13", "3.14"]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
Expand All @@ -39,14 +39,14 @@ jobs:
uv -v pip install dist/scio_pypi-1.0.1.dev0-py3-none-any.whl

- name: Build docs (Posix)
if: matrix.os != 'windows-latest'
if: matrix.os != 'windows-latest' && matrix.python-version != '3.14' # github.com/ThalesGroup/scio/issues/38
env:
SPHINXOPTS: --fail-on-warning
run: |
uv -v run make -C docs

- name: Build docs (Windows)
if: matrix.os == 'windows-latest'
if: matrix.os == 'windows-latest' && matrix.python-version != '3.14' # github.com/ThalesGroup/scio/issues/38
env:
SPHINXOPTS: --fail-on-warning
run: |
Expand All @@ -71,7 +71,7 @@ jobs:
run: exit 1

- name: Upload coverage report to Codecov
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13'
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.14'
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
[os_img]: https://img.shields.io/badge/cross--platform-%E2%9C%93-blue "Tested on Ubuntu & Windows"
[os_target]: https://sciortd.readthedocs.io/stable/user_guide/installation_compatibility.html#os-compatibility

[python_img]: https://img.shields.io/badge/python-3.12%20|%203.13-blue "Compatible Python versions"
[python_img]: https://img.shields.io/badge/python-3.12%20|%203.13%20|%203.14-blue "Compatible Python versions"
[python_target]: https://devguide.python.org/versions

[pypi_img]: https://img.shields.io/pypi/v/scio-pypi "Latest PyPI release"
Expand Down
2 changes: 1 addition & 1 deletion docs/.readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ version: 2
build:
os: ubuntu-24.04
tools:
python: "3.13"
python: "3.13" # github.com/ThalesGroup/scio/issues/38
commands:
- pip install uv
# Clone the repo hub first to avoid log in sphinx-gallery tutorials
Expand Down
9 changes: 2 additions & 7 deletions docs/src/api_references/misc/enums.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@

In many place in this package, we use `Enum <https://docs.python.org/3/library/enum.html#enum.Enum>`_ classes in conjunction with ``Literal`` as follows::

@unique
class Arg(str, EnumWithExplicitSupport):
class Arg(str, Enum):
'''Enum for supported ``arg`` values.'''

__slots__ = ()
Expand All @@ -17,11 +16,7 @@ In many place in this package, we use `Enum <https://docs.python.org/3/library/e

This allows static type checkers to understand direct API calls such as ``func("value1")``, while also providing runtime sanitization for more complex uses such as ``func(Arg(kw[0]))``.

Furthermore, we derive such *enums* from the base :class:`~scio.utils.enums.EnumWithExplicitSupport`, which provides a more detailed error message for unexpected values::

>>> Arg("value3") # Also fails type check
<traceback>
ValueError: 'value3' is not a valid Arg. Supported: 'value1', 'value2'
In fact, we derive such *enums* from a custom base :class:`~scio.utils.enums.EnumWithExplicitSupport`, which adds nice little tweaks.

.. autosummary::
:toctree: autosummary
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
# .. hint:: We recommend reading
# :doc:`/auto_tutorials/inferring_with_confidence` first.
#
# .. attention:: This tutorial uses the `datasets
# <https://github.com/huggingface/datasets>`_ library, which may not
# yet be fully compatible with Python 3.14. If necessary, use older
# Python versions. For more information, see `this issue
# <https://github.com/ThalesGroup/scio/issues/38>`_.
#
# In this tutorial, we use the
# :doc:`/api_references/eval/classification` API from ``scio.eval`` to
# compare several confidence score algorithms in a classification setup,
Expand Down
8 changes: 5 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ maintainers = [
{name = "Élie Goudout", email = "elie.goudout@thalesgroup.com"},
{name = "Élie Goudout", email = "eliegoudout@hotmail.com"},
]
requires-python = ">=3.12, <3.14"
requires-python = ">=3.12, <3.15"
readme = "README.md"
license = {file = "LICENSE"}
keywords = [
Expand All @@ -26,6 +26,7 @@ classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Topic :: Scientific/Engineering :: Artificial Intelligence",
"Topic :: Software Development :: Libraries",
"Typing :: Typed",
Expand All @@ -39,15 +40,15 @@ dependencies = [
"pandas>=2.2.3",
"paramclasses>=0.4.0",
"rich>=13.9.4",
"scikit-learn>=1.6.1",
"scikit-learn>=1.7.2",
"scipy>=1.16",
"seaborn>=0.13.2",
"torch>=2.6",
"torchinfo>=1.8",
]
[dependency-groups]
dev = [
"datasets>=3",
"datasets>=4.3.0",
"mypy>=1.17",
"mypy-extensions>=1.1",
"myst-parser>=4.0.1",
Expand All @@ -70,6 +71,7 @@ dev = [
required-environments = [
"python_version >= '3.12' and python_version < '3.13'",
"python_version >= '3.13' and python_version < '3.14'",
"python_version >= '3.14' and python_version < '3.15'",
]
# Adjust indirect dependencies lower bound
constraint-dependencies = [
Expand Down
35 changes: 28 additions & 7 deletions scio/utils/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,34 @@
"ZAggrLike",
]

from enum import Enum, unique
from enum import Enum, EnumType, unique
from inspect import Parameter, Signature
from typing import Literal


class EnumWithExplicitSupport(Enum):
class SimplerSignatureEnumType(EnumType):
"""Adjust the default :class:`Enum` signature.

While enums may technically accept multiple arguments
(github.com/python/cpython/issues/132543), we assume only one is
expected in our case and override the signature for doc style.

This fix works for python>=3.14 and is useless before. For more
info, see https://github.com/python/cpython/pull/116234.
"""

__signature__ = Signature([Parameter("value", Parameter.POSITIONAL_OR_KEYWORD)])


class EnumWithExplicitSupport(Enum, metaclass=SimplerSignatureEnumType):
"""Base Enum for explicit error message.

In many place in this package, we use :class:`Enum` in conjunction
with ``Literal`` as follows::

from enum import unique


@unique
class Arg(str, EnumWithExplicitSupport):
'''Enum for supported ``arg`` values.'''
Expand All @@ -56,14 +73,18 @@ class Arg(str, EnumWithExplicitSupport):
<traceback>
ValueError: 'value3' is not a valid Arg. Supported: 'value1', 'value2'

Finally, it provides a `more sensible
<https://github.com/python/cpython/issues/132543>`_ signature::

>>> from inspect import signature
>>> signature(Arg)
<Signature (value)>

"""

__slots__ = ()
# While enums may technically accept multiple arguments
# (github.com/python/cpython/issues/132543), we assume only one is
# expected in our case and override the signature for doc style. If
# necessary, override again in subclasses.
__signature__ = Signature([Parameter("value", Parameter.POSITIONAL_OR_KEYWORD)]) # type: ignore[assignment] # github.com/python/cpython/issues/132543
# Remove following signature fix when python 3.13 is dropped
__signature__ = Signature([Parameter("value", Parameter.POSITIONAL_OR_KEYWORD)]) # type: ignore[assignment, unused-ignore]

@classmethod
def _missing_(cls, value: object) -> None:
Expand Down
Loading