diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index c2b092f..d88ad1b 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -13,16 +13,16 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11"] + python-version: ["3.10", "3.11", "3.12"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: # Need to clone everything for the git tags. fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: "pip" @@ -31,25 +31,28 @@ jobs: run: sudo apt-get install libyaml-dev - name: Install prereqs for setuptools - run: pip install wheel + run: | + pip install uv + uv pip install --system wheel - name: Install dependencies - run: pip install -r requirements.txt + run: uv pip install --system -r requirements.txt # We have two cores so we can speed up the testing with xdist - name: Install support package for pytest - run: pip install pytest-xdist pytest-openfiles pytest-cov + run: uv pip install --system pytest pytest-xdist pytest-cov - name: Build and install - run: pip install --no-deps -v . + run: uv pip install --system --no-deps -v . - name: Run tests - run: pytest -r a -v -n 3 --open-files --cov=tests --cov=lsst.pex.config --cov-report=xml --cov-report=term + run: pytest -r a -v -n 3 --cov=tests --cov=lsst.pex.config --cov-report=xml --cov-report=term - name: Upload coverage to codecov - uses: codecov/codecov-action@v2 + uses: codecov/codecov-action@v4 with: - file: ./coverage.xml + files: ./coverage.xml + token: ${{ secrets.CODECOV_TOKEN }} pypi: @@ -58,13 +61,13 @@ jobs: if: startsWith(github.ref, 'refs/tags/') steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: # Need to clone everything to embed the version. fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.10" cache: "pip" diff --git a/.github/workflows/build_docs.yaml b/.github/workflows/build_docs.yaml index 5a4d715..30d4188 100644 --- a/.github/workflows/build_docs.yaml +++ b/.github/workflows/build_docs.yaml @@ -10,13 +10,13 @@ jobs: build_sphinx_docs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: # Need to clone everything to determine version from git. fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.10" cache: "pip" diff --git a/.github/workflows/docstyle.yaml b/.github/workflows/docstyle.yaml index 2f22ba9..3dd8da8 100644 --- a/.github/workflows/docstyle.yaml +++ b/.github/workflows/docstyle.yaml @@ -14,10 +14,10 @@ jobs: numpydoc: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 - name: Install numpydoc run: | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 291a075..e26e71f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,12 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/psf/black - rev: 23.12.0 + rev: 24.4.2 hooks: - id: black # It is recommended to specify the latest version of Python @@ -20,15 +20,15 @@ repos: - id: isort name: isort (python) - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 + rev: 7.0.0 hooks: - id: flake8 - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.1.8 + rev: v0.4.6 hooks: - id: ruff - repo: https://github.com/numpy/numpydoc - rev: "v1.6.0" + rev: "v1.7.0" hooks: - id: numpydoc-validation diff --git a/doc/lsst.pex.config/CHANGES.rst b/doc/lsst.pex.config/CHANGES.rst index ed4998c..4611fdd 100644 --- a/doc/lsst.pex.config/CHANGES.rst +++ b/doc/lsst.pex.config/CHANGES.rst @@ -1,23 +1,29 @@ +lsst-pex-config v27.0.0 (2024-05-29) +==================================== + +- Improved all docstrings to make them compliant with Numpydoc. +- Minor code cleanups driven by Ruff linting. (`DM-42116 `_) + lsst-pex-config v26.0.0 (2023-09-22) ==================================== New Features ------------ -- Added a dynamic-default callback argument to ``RegistryField``. (`DM-31924 `_) -- Introduced ``ConfigurableActions``. These are ``pex_config`` fields and config types which function as a functor, state is set at config time, but the ``ConfigurableActions`` are callable at runtime to produce an action. (`DM-36649 `_) +- Added a dynamic-default callback argument to ``RegistryField``. (`DM-31924 `_) +- Introduced ``ConfigurableActions``. These are ``pex_config`` fields and config types which function as a functor, state is set at config time, but the ``ConfigurableActions`` are callable at runtime to produce an action. (`DM-36649 `_) API Changes ----------- -- The ``loadFromStream`` and ``loadFromString`` methods now take a dictionary as an optional argument which allows specifying additional variables to use in local scope when reading configs. (`DM-40198 `_) +- The ``loadFromStream`` and ``loadFromString`` methods now take a dictionary as an optional argument which allows specifying additional variables to use in local scope when reading configs. (`DM-40198 `_) Other Changes and Additions --------------------------- -- There is now a requirement for configuration parameters to have a non-empty docstring. (`DM-4037 `_) +- There is now a requirement for configuration parameters to have a non-empty docstring. (`DM-4037 `_) lsst-pex-config v25.0.0 (2023-02-28) @@ -26,7 +32,7 @@ lsst-pex-config v25.0.0 (2023-02-28) Other Changes and Additions --------------------------- -- Some sorting now happens when saving config files (via DM-33027). (`DM-35060 `_) +- Some sorting now happens when saving config files (via DM-33027). (`DM-35060 `_) lsst-pex-config v24.0.0 (2022-08-30) diff --git a/pyproject.toml b/pyproject.toml index 7c47cc2..dfeb149 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,6 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "lsst-pex-config" +requires-python = ">=3.10.0" description = "A flexible configuration system using Python files." license = {text = "BSD 3-Clause License, GPLv3+"} readme = "README.rst" @@ -18,6 +19,7 @@ classifiers = [ "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Scientific/Engineering :: Astronomy", ] keywords = ["lsst"] @@ -63,7 +65,7 @@ line_length = 110 filename = "doc/lsst.pex.config/CHANGES.rst" directory = "doc/changes" title_format = "lsst-pex-config {version} ({project_date})" - issue_format = "`{issue} `_" + issue_format = "`{issue} `_" [[tool.towncrier.type]] directory = "feature" diff --git a/python/lsst/pex/config/config.py b/python/lsst/pex/config/config.py index 7fcdb47..a2800f3 100644 --- a/python/lsst/pex/config/config.py +++ b/python/lsst/pex/config/config.py @@ -716,14 +716,12 @@ def toDict(self, instance): @overload def __get__( self, instance: None, owner: Any = None, at: Any = None, label: str = "default" - ) -> Field[FieldTypeVar]: - ... + ) -> Field[FieldTypeVar]: ... @overload def __get__( self, instance: Config, owner: Any = None, at: Any = None, label: str = "default" - ) -> FieldTypeVar: - ... + ) -> FieldTypeVar: ... def __get__(self, instance, owner=None, at=None, label="default"): """Define how attribute access should occur on the Config instance diff --git a/python/lsst/pex/config/configChoiceField.py b/python/lsst/pex/config/configChoiceField.py index 54d3bff..07ea6c6 100644 --- a/python/lsst/pex/config/configChoiceField.py +++ b/python/lsst/pex/config/configChoiceField.py @@ -519,14 +519,12 @@ def _getOrMake(self, instance, label="default"): @overload def __get__( self, instance: None, owner: Any = None, at: Any = None, label: str = "default" - ) -> ConfigChoiceField: - ... + ) -> ConfigChoiceField: ... @overload def __get__( self, instance: Config, owner: Any = None, at: Any = None, label: str = "default" - ) -> ConfigInstanceDict: - ... + ) -> ConfigInstanceDict: ... def __get__(self, instance, owner=None, at=None, label="default"): if instance is None or not isinstance(instance, Config): diff --git a/python/lsst/pex/config/configField.py b/python/lsst/pex/config/configField.py index 9fecfea..b5cc8ac 100644 --- a/python/lsst/pex/config/configField.py +++ b/python/lsst/pex/config/configField.py @@ -99,14 +99,12 @@ def __init__(self, doc, dtype=None, default=None, check=None, deprecated=None): @overload def __get__( self, instance: None, owner: Any = None, at: Any = None, label: str = "default" - ) -> "ConfigField[FieldTypeVar]": - ... + ) -> "ConfigField[FieldTypeVar]": ... @overload def __get__( self, instance: Config, owner: Any = None, at: Any = None, label: str = "default" - ) -> FieldTypeVar: - ... + ) -> FieldTypeVar: ... def __get__(self, instance, owner=None, at=None, label="default"): if instance is None or not isinstance(instance, Config): diff --git a/python/lsst/pex/config/configurableActions/_configurableActionField.py b/python/lsst/pex/config/configurableActions/_configurableActionField.py index 3fb9c8d..2a72c03 100644 --- a/python/lsst/pex/config/configurableActions/_configurableActionField.py +++ b/python/lsst/pex/config/configurableActions/_configurableActionField.py @@ -93,12 +93,10 @@ def __set__( @overload def __get__( self, instance: None, owner: Any = None, at: Any = None, label: str = "default" - ) -> ConfigurableActionField[ActionTypeVar]: - ... + ) -> ConfigurableActionField[ActionTypeVar]: ... @overload - def __get__(self, instance: Config, owner: Any = None, at: Any = None, label: str = "default") -> Any: - ... + def __get__(self, instance: Config, owner: Any = None, at: Any = None, label: str = "default") -> Any: ... def __get__(self, instance, owner=None, at=None, label="default"): result = super().__get__(instance, owner) diff --git a/python/lsst/pex/config/configurableActions/_configurableActionStructField.py b/python/lsst/pex/config/configurableActions/_configurableActionStructField.py index cb0515a..73b8f04 100644 --- a/python/lsst/pex/config/configurableActions/_configurableActionStructField.py +++ b/python/lsst/pex/config/configurableActions/_configurableActionStructField.py @@ -354,14 +354,12 @@ def __set__( @overload def __get__( self, instance: None, owner: Any = None, at: Any = None, label: str = "default" - ) -> ConfigurableActionStruct[ActionTypeVar]: - ... + ) -> ConfigurableActionStruct[ActionTypeVar]: ... @overload def __get__( self, instance: Config, owner: Any = None, at: Any = None, label: str = "default" - ) -> ConfigurableActionStruct[ActionTypeVar]: - ... + ) -> ConfigurableActionStruct[ActionTypeVar]: ... def __get__(self, instance, owner=None, at=None, label="default"): if instance is None or not isinstance(instance, Config): diff --git a/python/lsst/pex/config/configurableField.py b/python/lsst/pex/config/configurableField.py index 51d5959..95e2179 100644 --- a/python/lsst/pex/config/configurableField.py +++ b/python/lsst/pex/config/configurableField.py @@ -360,14 +360,12 @@ def __getOrMake(self, instance, at=None, label="default"): @overload def __get__( self, instance: None, owner: Any = None, at: Any = None, label: str = "default" - ) -> ConfigurableField: - ... + ) -> ConfigurableField: ... @overload def __get__( self, instance: Config, owner: Any = None, at: Any = None, label: str = "default" - ) -> ConfigurableInstance[FieldTypeVar]: - ... + ) -> ConfigurableInstance[FieldTypeVar]: ... def __get__(self, instance, owner=None, at=None, label="default"): if instance is None or not isinstance(instance, Config): diff --git a/python/lsst/pex/config/listField.py b/python/lsst/pex/config/listField.py index c7ed4e3..d7fdd9b 100644 --- a/python/lsst/pex/config/listField.py +++ b/python/lsst/pex/config/listField.py @@ -144,8 +144,7 @@ def __len__(self): @overload def __setitem__( self, i: int, x: FieldTypeVar, at: Any = None, label: str = "setitem", setHistory: bool = True - ) -> None: - ... + ) -> None: ... @overload def __setitem__( @@ -155,8 +154,7 @@ def __setitem__( at: Any = None, label: str = "setitem", setHistory: bool = True, - ) -> None: - ... + ) -> None: ... def __setitem__(self, i, x, at=None, label="setitem", setHistory=True): if self._config._frozen: @@ -179,12 +177,10 @@ def __setitem__(self, i, x, at=None, label="setitem", setHistory=True): self.history.append((list(self._list), at, label)) @overload - def __getitem__(self, i: int) -> FieldTypeVar: - ... + def __getitem__(self, i: int) -> FieldTypeVar: ... @overload - def __getitem__(self, i: slice) -> MutableSequence[FieldTypeVar]: - ... + def __getitem__(self, i: slice) -> MutableSequence[FieldTypeVar]: ... def __getitem__(self, i): return self._list[i] diff --git a/setup.cfg b/setup.cfg index 3a680b9..b82bfc6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,7 +1,7 @@ [flake8] max-line-length = 110 max-doc-length = 79 -ignore = W503, E203, E228, N802, N803, N806, N812, N815, N816 +ignore = W503, E203, E704, N802, N803, N806, N812, N815, N816 exclude = bin, doc,