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

Drop python 3.9 #2526

Merged
merged 1 commit into from
Mar 27, 2024
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
14 changes: 7 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: "3.9"
python-version: "3.10"
- name: Check README syntax
run: |
pip install restructuredtext-lint
Expand All @@ -39,7 +39,7 @@ jobs:
matrix:
include:
- os: ubuntu-latest
python-version: "3.9"
python-version: "3.10"
install-method: mamba

- os: ubuntu-latest
Expand All @@ -60,12 +60,12 @@ jobs:
install-method: pip

- os: macos-latest
python-version: "3.12"
install-method: mamba
python-version: "3.10"
install-method: pip

- os: macos-latest
python-version: "3.9"
install-method: pip
python-version: "3.12"
install-method: mamba

defaults:
run:
Expand Down Expand Up @@ -164,7 +164,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.9"
python-version: "3.10"

- name: Install doc dependencies
run: |
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ build:
- ffmpeg
- graphviz
tools:
python: "3.9"
python: "3.10"

python:
install:
Expand Down
1 change: 1 addition & 0 deletions docs/changes/2526.maintenance.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Drop support for python 3.9.
4 changes: 1 addition & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# ctapipe documentation build configuration file, created by
# sphinx-quickstart on Fri Jan 6 10:22:58 2017.
#
Expand Down Expand Up @@ -390,7 +388,7 @@ def setup(app):

# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
"python": ("https://docs.python.org/3.9", None),
"python": ("https://docs.python.org/3.10", None),
"numpy": ("https://numpy.org/doc/stable/", None),
"scipy": ("https://docs.scipy.org/doc/scipy/", None),
"astropy": ("https://docs.astropy.org/en/latest/", None),
Expand Down
2 changes: 1 addition & 1 deletion examples/algorithms/nd_interpolation.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@
plt.pcolormesh(
energy_table.bin_centers(0), energy_table.bin_centers(1), energy_table.hist.T
)
plt.title("Raw table, uninterpolated {0}".format(energy_table.hist.T.shape))
plt.title(f"Raw table, uninterpolated {energy_table.hist.T.shape}")
cb = plt.colorbar()
cb.set_label(r"$\log_{10}(E/\mathrm{TeV})$")

Expand Down
6 changes: 2 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ classifiers = [
"Intended Audience :: Science/Research",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand All @@ -28,15 +27,14 @@ classifiers = [
]

dynamic = ["version"]
requires-python = ">=3.9"
requires-python = ">=3.10"

dependencies = [
"astropy >=5.3,<7.0.0a0",
"bokeh ~=2.0",
"docutils",
"eventio >=1.9.1, <2.0.0a0",
"iminuit >=2",
"importlib_metadata; python_version < '3.10'",
"joblib",
"matplotlib ~=3.0",
"numba >=0.56",
Expand Down Expand Up @@ -193,7 +191,7 @@ relative_files = true


[tool.ruff]
target-version = "py39"
target-version = "py310"
line-length = 88

[tool.ruff.lint]
Expand Down
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
sonar.projectKey=cta-observatory_ctapipe_AY52EYhuvuGcMFidNyUs
sonar.language=python
sonar.python.coverage.reportPaths=coverage.xml
sonar.python.version=3.9
sonar.python.version=3.10

# ignore examples for coverage and issues, these are sphinx-gallery notebook scripts
# which aren't really supported by sonarqube and lead to a lot of false positives
Expand Down
3 changes: 1 addition & 2 deletions src/ctapipe/atmosphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import abc
from dataclasses import dataclass
from functools import partial
from typing import Dict

import numpy as np
from astropy import units as u
Expand Down Expand Up @@ -342,7 +341,7 @@ def __init__(self, table: Table):
]

@classmethod
def from_array(cls, array: np.ndarray, metadata: Dict = None):
def from_array(cls, array: np.ndarray, metadata: dict = None):
"""construct from a 5x5 array as provided by eventio"""

if metadata is None:
Expand Down
6 changes: 1 addition & 5 deletions src/ctapipe/coordinates/impact_distance.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
#!/usr/bin/env python3
"""
Functions to compute the impact distance from a simulated or reconstructed
shower axis (Defined by the line from the impact point on the ground in the
reconstructed sky direction) to each telescope's ground position.
"""

from typing import Union

import numpy as np
from astropy import units as u
from astropy.coordinates import SkyCoord
Expand Down Expand Up @@ -37,7 +33,7 @@ def impact_distance(point: np.ndarray, direction: np.ndarray, test_points: np.nd


def shower_impact_distance(
shower_geom: Union[ReconstructedGeometryContainer, SimulatedShowerContainer],
shower_geom: ReconstructedGeometryContainer | SimulatedShowerContainer,
subarray,
):
"""computes the impact distance of the shower axis to the telescope positions
Expand Down
2 changes: 1 addition & 1 deletion src/ctapipe/core/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ def as_dict(self, recursive=False, flatten=False, add_prefix=False, add_key=Fals

d = dict()
for key, val in self.items(add_prefix=add_prefix):
if isinstance(val, (Container, Map)):
if isinstance(val, Container | Map):
if flatten:
d.update(val.as_dict(**kwargs))
else:
Expand Down
8 changes: 1 addition & 7 deletions src/ctapipe/core/plugins.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
"""ctapipe plugin system"""
import logging
import sys

if sys.version_info < (3, 10):
from importlib_metadata import entry_points
else:
from importlib.metadata import entry_points

from importlib.metadata import entry_points

log = logging.getLogger(__name__)
installed_entry_points = entry_points()
Expand Down
9 changes: 4 additions & 5 deletions src/ctapipe/core/telescope_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import logging
from collections import UserList
from fnmatch import fnmatch
from typing import Optional, Union

import numpy as np
from traitlets import List, TraitError, TraitType, Undefined
Expand Down Expand Up @@ -197,7 +196,7 @@ def attach_subarray(self, subarray):
else:
raise ValueError(f"Unrecognized command: {command}")

def __getitem__(self, tel: Optional[Union[int, str]]):
def __getitem__(self, tel: int | str | None):
"""
Returns the resolved parameter for the given telescope id
"""
Expand All @@ -213,7 +212,7 @@ def __getitem__(self, tel: Optional[Union[int, str]]):
"`attach_subarray` first before trying to access a value by tel_id"
)

if isinstance(tel, (int, np.integer)):
if isinstance(tel, int | np.integer):
try:
return self._value_for_tel_id[tel]
except KeyError:
Expand Down Expand Up @@ -331,7 +330,7 @@ def _validate_entry(self, obj, value):

def validate(self, obj, value):
# Support a single value for all (check and convert into a default value)
if not isinstance(value, (list, List, UserList, TelescopePatternList)):
if not isinstance(value, list | List | UserList | TelescopePatternList):
value = [("type", "*", self._validate_entry(obj, value))]

# Check each value of list
Expand Down Expand Up @@ -374,7 +373,7 @@ def validate(self, obj, value):

def set(self, obj, value):
# Support a single value for all (check and convert into a default value)
if not isinstance(value, (list, List, UserList, TelescopePatternList)):
if not isinstance(value, list | List | UserList | TelescopePatternList):
value = [("type", "*", self._validate_entry(obj, value))]

# Retain existing subarray description
Expand Down
5 changes: 2 additions & 3 deletions src/ctapipe/core/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from inspect import cleandoc
from subprocess import CalledProcessError
from tempfile import mkdtemp
from typing import Union

import yaml
from docutils.core import publish_parts
Expand Down Expand Up @@ -258,7 +257,7 @@ def initialize(self, argv=None):

self.log.info(f"ctapipe version {self.version_string}")

def load_config_file(self, path: Union[str, pathlib.Path]) -> None:
def load_config_file(self, path: str | pathlib.Path) -> None:
"""
Load a configuration file in one of the supported formats, and merge it with
the current config if it exists.
Expand All @@ -272,7 +271,7 @@ def load_config_file(self, path: Union[str, pathlib.Path]) -> None:

if path.suffix in [".yaml", ".yml"]:
# do our own YAML loading
with open(path, "r") as infile:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels a bit scary, prefer the more explicit version.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"r" is the default and python won't ever change that, it would break everyone

with open(path) as infile:
config = Config(yaml.safe_load(infile))
self.update_config(config)
elif path.suffix == ".toml" and HAS_TOML:
Expand Down
2 changes: 1 addition & 1 deletion src/ctapipe/core/traits.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def validate(self, obj, value):
else:
self.error(obj, value)

if not isinstance(value, (str, pathlib.Path)):
if not isinstance(value, str | pathlib.Path):
return self.error(obj, value)

# expand any environment variables in the path:
Expand Down
10 changes: 5 additions & 5 deletions src/ctapipe/image/extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@


from abc import abstractmethod
from collections.abc import Callable
from functools import lru_cache
from typing import Callable, List, Optional, Tuple

import astropy.units as u
import numpy as np
Expand Down Expand Up @@ -937,7 +937,7 @@ def _calculate_correction(self, tel_id, width, shift):

def _apply_first_pass(
self, waveforms, tel_id
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
"""
Execute step 1.

Expand Down Expand Up @@ -1015,7 +1015,7 @@ def _apply_second_pass(
pulse_time_1stpass,
correction,
broken_pixels,
) -> Tuple[np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray]:
"""
Follow steps from 2 to 7.

Expand Down Expand Up @@ -1299,8 +1299,8 @@ def deconvolution_parameters(
window_shift: int,
leading_edge_timing: bool,
leading_edge_rel_descend_limit: float,
time_profile_pdf: Optional[Callable[[npt.ArrayLike], npt.ArrayLike]] = None,
) -> Tuple[List[float], List[float], List[float]]:
time_profile_pdf: None | Callable[[npt.ArrayLike], npt.ArrayLike] = None,
) -> tuple[list[float], list[float], list[float]]:
"""
Estimates deconvolution and recalibration parameters from the camera's reference
single-p.e. pulse shape for the given configuration of FlashCamExtractor.
Expand Down
3 changes: 1 addition & 2 deletions src/ctapipe/image/invalid_pixels.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
Methods to interpolate broken pixels
"""
from abc import ABCMeta, abstractmethod
from typing import Tuple

import numpy as np

Expand All @@ -22,7 +21,7 @@ class InvalidPixelHandler(TelescopeComponent, metaclass=ABCMeta):
@abstractmethod
def __call__(
self, tel_id, image, peak_time, pixel_mask
) -> Tuple[np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray]:
"""
Handle invalid (broken, high noise, ...) pixels.

Expand Down
2 changes: 1 addition & 1 deletion src/ctapipe/instrument/camera/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@

version = tab.meta.get("TAB_VER")
if version not in cls.SUPPORTED_TAB_VERSIONS:
raise IOError(f"Unsupported camera geometry table version: {version}")
raise OSError(f"Unsupported camera geometry table version: {version}")

Check warning on line 675 in src/ctapipe/instrument/camera/geometry.py

View check run for this annotation

Codecov / codecov/patch

src/ctapipe/instrument/camera/geometry.py#L675

Added line #L675 was not covered by tests
maxnoe marked this conversation as resolved.
Show resolved Hide resolved

return cls(
name=tab.meta.get("CAM_ID", "Unknown"),
Expand Down
2 changes: 1 addition & 1 deletion src/ctapipe/instrument/camera/readout.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@

version = tab.meta.get("TAB_VER", "")
if version not in cls.SUPPORTED_TAB_VERSIONS:
raise IOError(
raise OSError(

Check warning on line 212 in src/ctapipe/instrument/camera/readout.py

View check run for this annotation

Codecov / codecov/patch

src/ctapipe/instrument/camera/readout.py#L212

Added line #L212 was not covered by tests
f"CameraReadout table has unsupported version: {version},"
f" supported are: {cls.SUPPORTED_TAB_VERSIONS}."
)
Expand Down
Loading