Skip to content
Closed
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/workflows/check_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:

env:
POETRY_VERSION: 1.8.2
PYTHON_VERSION: 3.11.9
PYTHON_VERSION: 3.13.3

jobs:
check_docs:
Expand Down
110 changes: 101 additions & 9 deletions src/nitypes/_typing.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,133 @@
"""Single source for typing backports to avoid depending on typing_extensions at run time."""
"""Version-specific compatibility shims for the standard `typing` module.

For `typing` symbols that require Python 3.10 or later, this submodule redirects to the standard
`typing` module (when appropriate), the `typing_extensions` package, or provides a minimial stub
implementation for run time. This allows us to use new typing features without littering the rest of
our code with conditionals or making our Python packages depend on `typing_extenions` at run time.

For `typing` symbols that are supported in Python 3.9, you do not need this submodule. Import these
symbols directly from the standard `typing` module.

This submodule is vendored in multiple packages (nitypes, nipanel, etc.) to avoid compatibility
breakage when upgrading these packages.

Do not add project-specific types to this submodule.

Many of these symbosl are references to `None` at run time. Clients of this submodule should use
`from __future__ import annotations` to avoid parsing type hints at run time.
"""

from __future__ import annotations

import sys
from typing import TYPE_CHECKING

if sys.version_info >= (3, 10):
from typing import TypeAlias
from typing import (
Concatenate,
ParamSpec,
ParamSpecArgs,
ParamSpecKwargs,
TypeAlias,
TypeGuard,
)
elif TYPE_CHECKING:
from typing_extensions import TypeAlias
from typing_extensions import (
Concatenate,
ParamSpec,
ParamSpecArgs,
ParamSpecKwargs,
TypeAlias,
TypeGuard,
)
else:
TypeAlias = None
Concatenate = ParamSpecArgs = ParamSpecKwargs = TypeAlias = TypeGuard = None

def ParamSpec( # noqa: D103, N802 - Missing docstring, wrong case
name, *, bound=None, covariant=False, contravariant=False
):
return None


if sys.version_info >= (3, 11):
from typing import Self, assert_type
from typing import (
LiteralString,
Never,
NotRequired,
Required,
Self,
TypeVarTuple,
Unpack,
assert_never,
assert_type,
reveal_type,
)
elif TYPE_CHECKING:
from typing_extensions import Self, assert_type
from typing_extensions import (
LiteralString,
Never,
NotRequired,
Required,
Self,
TypeVarTuple,
Unpack,
assert_never,
assert_type,
reveal_type,
)
else:
Self = None
LiteralString = Never = NotRequired = Required = Self = Unpack = None

def assert_never(arg, /): # noqa: D103 - Missing docstring in public function
pass

def assert_type(val, typ, /): # noqa: D103 - Missing docstring in public function
pass

def reveal_type(obj, /): # noqa: D103 - Missing docstring in public function
pass

def TypeVarTuple(name): # noqa: D103, N802 - Missing docstring, wrong case
return None


if sys.version_info >= (3, 12):
from typing import override
from typing import TypeAliasType, override
elif TYPE_CHECKING:
from typing_extensions import override
from typing_extensions import TypeAliasType, override
else:
TypeAliasType = None

def override(arg, /): # noqa: D103 - Missing docstring in public function
return arg


if sys.version_info >= (3, 13):
from typing import ReadOnly, TypeIs
elif TYPE_CHECKING:
from typing_extensions import ReadOnly, TypeIs
else:
ReadOnly = TypeIs = None

__all__ = [
"assert_never",
"assert_type",
"Concatenate",
"LiteralString",
"Never",
"NotRequired",
"override",
"ParamSpec",
"ParamSpecArgs",
"ParamSpecKwargs",
"ReadOnly",
"Required",
"reveal_type",
"Self",
"TypeAlias",
"TypeAliasType",
"TypeGuard",
"TypeIs",
"TypeVarTuple",
"Unpack",
]
6 changes: 5 additions & 1 deletion src/nitypes/time/_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
import hightime as ht

from nitypes._exceptions import invalid_arg_type, invalid_requested_type
from nitypes._typing import TypeAlias

try:
from typing import TypeAlias
except ImportError:
from nitypes._typing import TypeAlias

_AnyDateTime: TypeAlias = Union[dt.datetime, ht.datetime]
_TDateTime = TypeVar("_TDateTime", dt.datetime, ht.datetime)
Expand Down
6 changes: 5 additions & 1 deletion src/nitypes/waveform/_analog_waveform.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

from nitypes._arguments import arg_to_uint, validate_dtype, validate_unsupported_arg
from nitypes._exceptions import invalid_arg_type, invalid_array_ndim
from nitypes._typing import Self, TypeAlias
from nitypes.waveform._exceptions import (
input_array_data_type_mismatch,
input_waveform_data_type_mismatch,
Expand All @@ -27,6 +26,11 @@
from nitypes.waveform._timing import BaseTiming, PrecisionTiming, Timing, convert_timing
from nitypes.waveform._warnings import scale_mode_mismatch

try:
from typing import Self, TypeAlias
except ImportError:
from nitypes._typing import Self, TypeAlias

if sys.version_info < (3, 10):
import array as std_array

Expand Down
5 changes: 4 additions & 1 deletion src/nitypes/waveform/_extended_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
from collections.abc import Mapping
from typing import Iterator, MutableMapping, Union

from nitypes._typing import TypeAlias
try:
from typing import TypeAlias
except ImportError:
from nitypes._typing import TypeAlias

# Extended property keys
CHANNEL_NAME = "NI_ChannelName"
Expand Down
7 changes: 6 additions & 1 deletion src/nitypes/waveform/_timing/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@
from typing import Any, Generic, SupportsIndex, TypeVar

from nitypes._exceptions import add_note
from nitypes._typing import Self
from nitypes.waveform._timing._sample_interval import (
SampleIntervalMode,
SampleIntervalStrategy,
create_sample_interval_strategy,
)

try:
from typing import Self
except ImportError:
from nitypes._typing import Self


_TDateTime = TypeVar("_TDateTime", bound=dt.datetime)
_TTimeDelta = TypeVar("_TTimeDelta", bound=dt.timedelta)

Expand Down
6 changes: 5 additions & 1 deletion src/nitypes/waveform/_timing/_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
import hightime as ht

from nitypes._exceptions import invalid_arg_type, invalid_requested_type
from nitypes._typing import TypeAlias
from nitypes.time._conversion import convert_datetime, convert_timedelta
from nitypes.waveform._timing._base import BaseTiming
from nitypes.waveform._timing._precision import PrecisionTiming
from nitypes.waveform._timing._standard import Timing

try:
from typing import TypeAlias
except ImportError:
from nitypes._typing import TypeAlias


_AnyTiming: TypeAlias = Union[BaseTiming[Any, Any], Timing, PrecisionTiming]
_TTiming = TypeVar("_TTiming", bound=BaseTiming[Any, Any])
Expand Down
6 changes: 5 additions & 1 deletion src/nitypes/waveform/_timing/_precision.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@

import hightime as ht

from nitypes._typing import override
from nitypes.waveform._timing._base import BaseTiming
from nitypes.waveform._timing._sample_interval import SampleIntervalMode

try:
from typing import override
except ImportError:
from nitypes._typing import override


class PrecisionTiming(BaseTiming[ht.datetime, ht.timedelta]):
"""High-precision waveform timing using the hightime package.
Expand Down
6 changes: 5 additions & 1 deletion src/nitypes/waveform/_timing/_standard.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
from collections.abc import Sequence
from typing import ClassVar

from nitypes._typing import override
from nitypes.waveform._timing._base import BaseTiming
from nitypes.waveform._timing._sample_interval import SampleIntervalMode

try:
from typing import override
except ImportError:
from nitypes._typing import override


class Timing(BaseTiming[dt.datetime, dt.timedelta]):
"""Waveform timing using the standard datetime module.
Expand Down
Loading