Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Drop python 39 #5620

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 1 addition & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,18 @@ classifiers = [
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Scientific/Engineering",
]
license = {text = "MIT"}
requires-python = ">=3.9"
requires-python = ">=3.10"
dependencies = [
"broadbean>=0.9.1",
"h5netcdf>=0.10.0,!=0.14.0",
# see https://github.com/h5netcdf/h5netcdf/issues/154
"h5py>=3.0.0",
"importlib-metadata>=4.4; python_version < '3.10'",
"ipywidgets>=8.0.0,<9.0.0",
"ipykernel>=6.6.0", # implicitly required by ipywidgets >=8.0.5
"jsonschema>=4.9.0",
Expand Down
4 changes: 2 additions & 2 deletions src/qcodes/dataset/data_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ def _snapshot_raw(self) -> str | None:
snapshot_raw = select_one_where(
self.conn, "runs", "snapshot", "run_id", self.run_id
)
assert isinstance(snapshot_raw, (str, type(None)))
assert isinstance(snapshot_raw, str | type(None))
return snapshot_raw

@property
Expand Down Expand Up @@ -424,7 +424,7 @@ def _parameters(self) -> str | None:
parameters = select_one_where(
self.conn, "runs", "parameters", "run_id", self.run_id
)
assert isinstance(parameters, (str, type(None)))
assert isinstance(parameters, str | type(None))
return parameters

@property
Expand Down
4 changes: 2 additions & 2 deletions src/qcodes/dataset/data_set_in_memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import time
import warnings
from pathlib import Path
from typing import TYPE_CHECKING, Any, Callable, Literal
from typing import TYPE_CHECKING, Any, Literal

import numpy as np

Expand Down Expand Up @@ -49,7 +49,7 @@
from .linked_datasets.links import str_to_links

if TYPE_CHECKING:
from collections.abc import Mapping, Sequence
from collections.abc import Callable, Mapping, Sequence

import pandas as pd
import xarray as xr
Expand Down
25 changes: 9 additions & 16 deletions src/qcodes/dataset/data_set_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@

import logging
import os
import sys
import warnings
from collections.abc import Mapping, Sequence
from collections.abc import Callable, Mapping, Sequence
from enum import Enum
from importlib.metadata import entry_points
from pathlib import Path
from typing import (
TYPE_CHECKING,
Any,
Callable,
Literal,
Protocol,
Union,
Expand All @@ -34,17 +33,11 @@
from .exporters.export_to_xarray import xarray_to_h5netcdf_with_complex_numbers
from .sqlite.queries import raw_time_to_str_time

if sys.version_info >= (3, 10):
# new entrypoints api was added in 3.10
from importlib.metadata import entry_points
else:
# 3.9 and earlier
from importlib_metadata import entry_points

if TYPE_CHECKING:
from typing import TypeAlias

import pandas as pd
import xarray as xr
from typing_extensions import TypeAlias

from qcodes.dataset.descriptions.rundescriber import RunDescriber
from qcodes.dataset.descriptions.versioning.rundescribertypes import Shapes
Expand All @@ -61,17 +54,17 @@
# even with from __future__ import annotations
# type aliases must use the old format until we drop 3.8/3.9
array_like_types = (tuple, list, np.ndarray)
scalar_res_types: TypeAlias = Union[
str, complex, np.integer, np.floating, np.complexfloating
]
values_type: TypeAlias = Union[scalar_res_types, np.ndarray, Sequence[scalar_res_types]]
scalar_res_types: TypeAlias = (
str | complex | np.integer | np.floating | np.complexfloating
)
values_type: TypeAlias = scalar_res_types | np.ndarray | Sequence[scalar_res_types]
res_type: TypeAlias = tuple[Union["ParameterBase", str], values_type]
setpoints_type: TypeAlias = Sequence[Union[str, "ParameterBase"]]
SPECS: TypeAlias = list[ParamSpec]
# Transition period type: SpecsOrInterDeps. We will allow both as input to
# the DataSet constructor for a while, then deprecate SPECS and finally remove
# the ParamSpec class
SpecsOrInterDeps: TypeAlias = Union[SPECS, InterDependencies_]
SpecsOrInterDeps: TypeAlias = SPECS | InterDependencies_
ParameterData: TypeAlias = dict[str, dict[str, np.ndarray]]

LOG = logging.getLogger(__name__)
Expand Down
2 changes: 1 addition & 1 deletion src/qcodes/dataset/descriptions/detect_shapes.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def _get_shape_of_step(step: int | np.integer[Any] | Sized | np.ndarray) -> int:


def _param_is_array_like(meas_param: ParameterBase) -> bool:
if isinstance(meas_param, (ArrayParameter, ParameterWithSetpoints)):
if isinstance(meas_param, ArrayParameter | ParameterWithSetpoints):
return True
elif isinstance(meas_param.vals, Arrays):
return True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"""
from __future__ import annotations

from typing import TYPE_CHECKING, Union
from typing import TYPE_CHECKING

from typing_extensions import TypedDict

Expand Down Expand Up @@ -56,7 +56,6 @@ class RunDescriberV3Dict(RunDescriberV2Dict):
# dict from dependent to dict from depenency to num points in grid


RunDescriberDicts = Union[RunDescriberV0Dict,
RunDescriberV1Dict,
RunDescriberV2Dict,
RunDescriberV3Dict]
RunDescriberDicts = (
RunDescriberV0Dict | RunDescriberV1Dict | RunDescriberV2Dict | RunDescriberV3Dict
)
6 changes: 3 additions & 3 deletions src/qcodes/dataset/dond/do_nd.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import itertools
import logging
import time
from collections.abc import Mapping, Sequence
from collections.abc import Callable, Mapping, Sequence
from contextlib import ExitStack
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any, Callable, Union, cast
from typing import TYPE_CHECKING, Any, cast

import numpy as np
from opentelemetry import trace
Expand Down Expand Up @@ -88,7 +88,7 @@ def _make_setpoints_tuples(
) -> tuple[tuple[tuple[SweepVarType, ...] | SweepVarType, ...], ...]:
sweeps = tuple(sweep.get_setpoints() for sweep in self._sweeps)
return cast(
tuple[tuple[Union[tuple[SweepVarType, ...], SweepVarType], ...], ...],
tuple[tuple[tuple[SweepVarType, ...] | SweepVarType, ...], ...],
tuple(itertools.product(*sweeps)),
)

Expand Down
8 changes: 4 additions & 4 deletions src/qcodes/dataset/dond/do_nd_utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from __future__ import annotations

import logging
from collections.abc import Iterator, Sequence
from collections.abc import Callable, Iterator, Sequence
from contextlib import contextmanager
from typing import TYPE_CHECKING, Callable, Optional, Union
from typing import TYPE_CHECKING, Optional

if TYPE_CHECKING:
import matplotlib.axes
Expand All @@ -23,7 +23,7 @@
ActionsT = Sequence[Callable[[], None]]
BreakConditionT = Callable[[], bool]

ParamMeasT = Union[ParameterBase, Callable[[], None]]
ParamMeasT = ParameterBase | Callable[[], None]

AxesTuple = tuple["matplotlib.axes.Axes", "matplotlib.colorbar.Colorbar"]
AxesTupleList = tuple[
Expand All @@ -45,7 +45,7 @@ class BreakConditionInterrupt(Exception):
pass


MeasInterruptT = Union[KeyboardInterrupt, BreakConditionInterrupt, None]
MeasInterruptT = KeyboardInterrupt | BreakConditionInterrupt | None


def _register_parameters(
Expand Down
2 changes: 1 addition & 1 deletion src/qcodes/dataset/experiment_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def finished_at(self) -> float | None:
finish_time = select_one_where(
self.conn, "experiments", "end_time", "exp_id", self.exp_id
)
assert isinstance(finish_time, (float, type(None)))
assert isinstance(finish_time, float | type(None))
return finish_time

@property
Expand Down
2 changes: 1 addition & 1 deletion src/qcodes/dataset/guid_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def guids_from_list_str(s: str) -> tuple[str, ...] | None:
else:
return tuple()

if not isinstance(parsed, (ast.List, ast.Tuple, ast.Set)):
if not isinstance(parsed, ast.List | ast.Tuple | ast.Set):
return None

if not all(isinstance(e, ast.Constant) for e in parsed.elts):
Expand Down
8 changes: 4 additions & 4 deletions src/qcodes/dataset/measurements.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
import logging
import traceback as tb_module
import warnings
from collections.abc import Mapping, MutableMapping, MutableSequence, Sequence
from collections.abc import Callable, Mapping, MutableMapping, MutableSequence, Sequence
from contextlib import ExitStack
from copy import deepcopy
from inspect import signature
from numbers import Number
from time import perf_counter
from typing import TYPE_CHECKING, Any, Callable, TypeVar, Union, cast
from typing import TYPE_CHECKING, Any, TypeVar, cast

import numpy as np
from opentelemetry import trace
Expand Down Expand Up @@ -64,7 +64,7 @@

ActionType = tuple[Callable[..., Any], Sequence[Any]]
SubscriberType = tuple[
Callable[..., Any], Union[MutableSequence[Any], MutableMapping[Any, Any]]
Callable[..., Any], MutableSequence[Any] | MutableMapping[Any, Any]
]


Expand Down Expand Up @@ -341,7 +341,7 @@ def _unpack_multiparameter(
)
for i in range(len(parameter.shapes)):
# if this loop runs, then 'data' is a Sequence
data = cast(Sequence[Union[str, int, float, Any]], data)
data = cast(Sequence[str | int | float | Any], data)

shape = parameter.shapes[i]

Expand Down
12 changes: 6 additions & 6 deletions src/qcodes/dataset/sqlite/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ def get_completed_timestamp_from_run_id(
# sometimes it happens that the timestamp is written to DB as an int
if isinstance(ts, int):
ts = float(ts)
assert isinstance(ts, (float, type(None)))
assert isinstance(ts, float | type(None))
return ts


Expand Down Expand Up @@ -1750,7 +1750,7 @@ def get_parent_dataset_links(conn: ConnectionPlus, run_id: int) -> str:
maybe_mayby_link_str = select_one_where(
conn, "runs", "parent_datasets", "run_id", run_id
)
assert isinstance(maybe_mayby_link_str, (str, type(None)))
assert isinstance(maybe_mayby_link_str, str | type(None))
maybe_link_str = maybe_mayby_link_str

if maybe_link_str is None:
Expand Down Expand Up @@ -1909,7 +1909,7 @@ def get_experiment_name_from_experiment_id(conn: ConnectionPlus, exp_id: int) ->

def get_sample_name_from_experiment_id(conn: ConnectionPlus, exp_id: int) -> str:
sample_name = select_one_where(conn, "experiments", "sample_name", "exp_id", exp_id)
assert isinstance(sample_name, (str, type(None)))
assert isinstance(sample_name, str | type(None))
# there may be a few cases for very old db where None is returned as a sample name
# however, these probably do not exist in relaity outside that test so here we
# cast to str. See test_experiments_with_NULL_sample_name
Expand All @@ -1921,7 +1921,7 @@ def get_run_timestamp_from_run_id(conn: ConnectionPlus, run_id: int) -> float |
# sometimes it happens that the timestamp is saved as an integer in the database
if isinstance(time_stamp, int):
time_stamp = float(time_stamp)
assert isinstance(time_stamp, (float, type(None)))
assert isinstance(time_stamp, float | type(None))
return time_stamp


Expand Down Expand Up @@ -2096,7 +2096,7 @@ def get_experiment_attributes_by_exp_id(
start_time = temp_exp_attrs["start_time"]
assert isinstance(start_time, float)
end_time = temp_exp_attrs["end_time"]
assert isinstance(end_time, (float, type(None)))
assert isinstance(end_time, float | type(None))

exp_attrs: ExperimentAttributeDict = {
"name": str(temp_exp_attrs["name"]),
Expand Down Expand Up @@ -2206,7 +2206,7 @@ def get_raw_run_attributes(
assert isinstance(name, str)

rawsnapshot = select_one_where(conn, "runs", "snapshot", "guid", guid)
assert isinstance(rawsnapshot, (str, type(None)))
assert isinstance(rawsnapshot, str | type(None))
output: RawRunAttributesDict = {
"run_id": run_id,
"experiment": experiment,
Expand Down
4 changes: 2 additions & 2 deletions src/qcodes/dataset/sqlite/query_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import itertools
from collections.abc import Mapping, Sequence
from typing import TYPE_CHECKING, Any, Union
from typing import TYPE_CHECKING, Any

import numpy as np
from numpy import ndarray
Expand All @@ -24,7 +24,7 @@
import sqlite3

# represent the type of data we can/want map to sqlite column
VALUE = Union[str, complex, list, ndarray, bool, None]
VALUE = str | complex | list | ndarray | bool | None
VALUES = Sequence[VALUE]


Expand Down
4 changes: 2 additions & 2 deletions src/qcodes/dataset/subscriber.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
import time
from queue import Empty, Queue
from threading import Thread
from typing import TYPE_CHECKING, Any, Callable
from typing import TYPE_CHECKING, Any

from qcodes.dataset.sqlite.connection import atomic_transaction

if TYPE_CHECKING:
from collections.abc import Mapping
from collections.abc import Callable, Mapping

from qcodes.dataset.data_set import DataSet

Expand Down
3 changes: 2 additions & 1 deletion src/qcodes/dataset/threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
import itertools
import logging
from collections import defaultdict
from collections.abc import Callable
from functools import partial
from typing import TYPE_CHECKING, Callable, Protocol, TypeVar, Union
from typing import TYPE_CHECKING, Protocol, TypeVar, Union

from qcodes.utils import RespondingThread

Expand Down
4 changes: 2 additions & 2 deletions src/qcodes/instrument/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import sys
from collections.abc import Callable, Iterable, Iterator, MutableSequence, Sequence
from typing import TYPE_CHECKING, Any, TypeVar, Union, cast, overload
from typing import TYPE_CHECKING, Any, TypeVar, cast, overload

from qcodes.metadatable import MetadatableWithName
from qcodes.parameters import (
Expand Down Expand Up @@ -459,7 +459,7 @@ def _construct_multiparam(self, name: str) -> MultiChannelInstrumentParameter:
"Slicing is currently not supported for MultiParameters"
)
parameters = cast(
list[Union[Parameter, ArrayParameter]],
list[Parameter | ArrayParameter],
[chan.parameters[name] for chan in self._channels],
)
names = tuple(f"{chan.name}_{name}" for chan in self._channels)
Expand Down
11 changes: 7 additions & 4 deletions src/qcodes/instrument/mockers/simulated_ats_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


import ctypes
from typing import Any, Callable, ClassVar, Optional
from typing import TYPE_CHECKING, Any, ClassVar

import numpy as np

Expand All @@ -20,6 +20,9 @@
)
from qcodes.instrument_drivers.AlazarTech.dll_wrapper import _mark_params_as_updated

if TYPE_CHECKING:
from collections.abc import Callable


class SimulatedATS9360API(AlazarATSAPI):

Expand All @@ -29,9 +32,9 @@ class SimulatedATS9360API(AlazarATSAPI):
}

def __init__(
self,
dll_path: Optional[str] = None, # Need this for meta super class
buffer_generator: Optional[Callable[[np.ndarray], None]] = None,
self,
dll_path: str | None = None, # Need this for meta super class
buffer_generator: "Callable[[np.ndarray], None] | None" = None,
):
def _default_buffer_generator(buffer: np.ndarray) -> None:
upper = buffer.size // 2
Expand Down