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 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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 .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,8 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12"]
exclude:
- os: windows-latest
python-version: 3.9
- os: windows-latest
python-version: 3.10
- os: windows-latest
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/pytest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12"]
min-version: [false]
include:
- os: ubuntu-latest
python-version: "3.9"
python-version: "3.10"
min-version: true
exclude:
- os: ubuntu-latest
python-version: "3.9"
python-version: "3.10"
- os: windows-latest
python-version: "3.11"
- os: windows-latest
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ To get a feeling of QCoDeS read
and/or browse the Jupyter notebooks in `docs/examples
<https://github.com/QCoDeS/Qcodes/tree/main/docs/examples>`__ .

QCoDeS is compatible with Python 3.9+ (3.9 soon to be deprecated). It is
QCoDeS is compatible with Python 3.10+. It is
primarily intended for use from Jupyter notebooks, but can be used from
traditional terminal-based shells and in stand-alone scripts as well. The
features in `qcodes.utils.magic` are exclusively for Jupyter notebooks.
Expand Down
23 changes: 11 additions & 12 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,25 @@ 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'",
"h5py>=3.6.0",
"ipywidgets>=8.0.0,<9.0.0",
"ipykernel>=6.6.0", # implicitly required by ipywidgets >=8.0.5
"jsonschema>=4.9.0",
"matplotlib>=3.3.3",
"numpy>=1.21.0",
"matplotlib>=3.5.0",
"numpy>=1.22.0",
"packaging>=20.0",
"pandas>=1.2.0",
"pandas>=1.4.0",
"pyarrow>=11.0.0", # will become a requirement of pandas. Installing explicitly silences a warning
"pyvisa>=1.11.0, <1.15.0",
"ruamel.yaml>=0.16.0,!=0.16.6",
Expand All @@ -43,8 +41,8 @@ dependencies = [
"tqdm>=4.59.0",
"uncertainties>=3.1.4",
"versioningit>=2.2.1",
"websockets>=9.1",
"wrapt>=1.13.2; python_version < '3.12'",
"websockets>=11.0",
"wrapt>=1.14.0; python_version < '3.12'",
"wrapt>=1.16.0; python_version >= '3.12'",
"xarray>=2022.06.0",
"cf_xarray>=0.8.4",
Expand Down Expand Up @@ -78,7 +76,7 @@ test = [
"coverage[toml]>=6.0.0",
"deepdiff>=5.0.2",
"hypothesis>=6.85.0",
"lxml>=4.6.0",
"lxml>=4.8.0",
"lxml-stubs>=0.4.0",
"mypy>=0.971",
"pandas-stubs>=1.2.0.1",
Expand Down Expand Up @@ -112,7 +110,7 @@ docs = [
"sphinx-rtd-theme>=1.0.0",
"sphinxcontrib-towncrier>=0.3.0a0",
"towncrier>=22.8.0",
"scipy>=1.7.0", # examples using scipy
"scipy>=1.8.0", # examples using scipy
"qcodes_loop>=0.1.1", # legacy dataset import examples
"jinja2>=3.1.3", # transitive dependency pin due to cve in earlier version
]
Expand Down Expand Up @@ -263,7 +261,8 @@ select = ["E", "F", "PT025", "UP", "RUF010", "RUF012", "RUF200", "I", "G", "ISC"
# code.
# PLxxxx are pylint lints that generate a fair amount of warnings
# it may be worth fixing some or these in the future
ignore = ["E501", "G004", "NPY002", "PLR2004", "PLR0913", "PLR0911", "PLR0912", "PLR0915", "PLW0602", "PLW0603", "PLW2901"]
# UP038 this can result in slower code so we ignore it
ignore = ["E501", "G004", "NPY002", "PLR2004", "PLR0913", "PLR0911", "PLR0912", "PLR0915", "PLW0602", "PLW0603", "PLW2901", "UP038"]

[tool.ruff.lint.isort]

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
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 @@ -53,10 +53,9 @@ class RunDescriberV2Dict(RunDescriberV0Dict):

class RunDescriberV3Dict(RunDescriberV2Dict):
shapes: Shapes | None
# dict from dependent to dict from depenency to num points in grid
# dict from dependent to dict from dependency 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
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
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/extensions/_refactor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from glob import glob
from pathlib import Path
from textwrap import dedent
from typing import Union, cast
from typing import cast

try:
import libcst as cst
Expand Down Expand Up @@ -99,7 +99,7 @@ def visit_Arg(self, node: cst.Arg) -> None:
if arg_is_docstring:
self.annotations.docstring = str(
cast(
Union[cst.SimpleString, cst.ConcatenatedString], node.value
cst.SimpleString | cst.ConcatenatedString, node.value
).evaluated_value
)
if arg_is_docstring_dedent:
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 @@ -461,7 +461,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