Skip to content

Commit

Permalink
Merge pull request #2526 from cta-observatory/drop_py39
Browse files Browse the repository at this point in the history
Drop python 3.9
  • Loading branch information
maxnoe authored Mar 27, 2024
2 parents 01f4a99 + a61035d commit f8d1049
Show file tree
Hide file tree
Showing 40 changed files with 101 additions and 132 deletions.
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:
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 @@ def from_table(cls, url_or_table, **kwargs):

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}")

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 @@ def from_table(cls, url_or_table, **kwargs):

version = tab.meta.get("TAB_VER", "")
if version not in cls.SUPPORTED_TAB_VERSIONS:
raise IOError(
raise OSError(
f"CameraReadout table has unsupported version: {version},"
f" supported are: {cls.SUPPORTED_TAB_VERSIONS}."
)
Expand Down
Loading

0 comments on commit f8d1049

Please sign in to comment.