diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f96923a1..677b1272 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: uses: OpenAstronomy/github-actions-workflows/.github/workflows/tox.yml@v1 with: envs: | - - linux: py39-oldestdeps-cov-xdist + - linux: py310-oldestdeps-cov-xdist - linux: py310-xdist - macos: py311-xdist - linux: py311-cov-xdist diff --git a/.github/workflows/ci_cron.yml b/.github/workflows/ci_cron.yml index 08ba3f68..ccc55a79 100644 --- a/.github/workflows/ci_cron.yml +++ b/.github/workflows/ci_cron.yml @@ -24,7 +24,6 @@ jobs: if: (github.repository == 'spacetelescope/stpipe' && (github.event_name == 'schedule' || github.event_name == 'push' || github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, 'Weekly CI'))) with: envs: | - - macos: py39-xdist - macos: py310-xdist - windows: py311-xdist - linux: py3-devdeps-xdist diff --git a/pyproject.toml b/pyproject.toml index 35dcbe8c..ec08d03b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,56 +1,62 @@ [project] -name = 'stpipe' -description = 'Framework for calibration pipeline software' -readme = 'README.md' -requires-python = '>=3.9' -license = { file = 'LICENSE' } -authors = [{ name = 'STScI', email = 'help@stsci.edu' }] +name = "stpipe" +description = "Framework for calibration pipeline software" +readme = "README.md" +requires-python = ">=3.10" +authors = [ + { name = "STScI", email = "help@stsci.edu" }, +] classifiers = [ - 'Intended Audience :: Science/Research', - 'Topic :: Scientific/Engineering :: Astronomy', - 'License :: OSI Approved :: BSD License', - 'Programming Language :: Python :: 3', + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering :: Astronomy", + "License :: OSI Approved :: BSD License", + "Programming Language :: Python :: 3", ] dependencies = [ - 'asdf>=2.13', - 'crds>=7.4.1.3', - 'astropy>=5.0.4', - 'importlib_metadata>=4.11.4', - 'pyyaml>=5', + "asdf>=2.13", + "crds>=7.4.1.3", + "astropy>=5.0.4", + "importlib_metadata>=4.11.4", + "pyyaml>=5", +] +dynamic = [ + "version", ] -dynamic = ['version'] + +[project.license] +file = "LICENSE" [project.optional-dependencies] docs = [ - 'numpydoc', - 'sphinx', - 'sphinx-automodapi', - 'sphinx-rtd-theme', - 'stsci-rtd-theme', - 'tomli; python_version <"3.11"', + "numpydoc", + "sphinx", + "sphinx-automodapi", + "sphinx-rtd-theme", + "stsci-rtd-theme", + "tomli; python_version <\"3.11\"", ] test = [ - 'pytest >=7.0.0', - 'pytest-doctestplus >=0.10.0', + "pytest >=7.0.0", + "pytest-doctestplus >=0.10.0", ] [project.urls] -'repository' = 'https://github.com/spacetelescope/stpipe' -'tracker' = 'https://github.com/spacetelescope/stpipe/issues' +repository = "https://github.com/spacetelescope/stpipe" +tracker = "https://github.com/spacetelescope/stpipe/issues" -[project.entry-points] -'asdf.resource_mappings' = {stpipe = 'stpipe.integration:get_resource_mappings'} +[project.entry-points."asdf.resource_mappings"] +stpipe = "stpipe.integration:get_resource_mappings" [project.scripts] -stpipe = 'stpipe.cli.main:main' -strun = 'stpipe.cli.strun:main' +stpipe = "stpipe.cli.main:main" +strun = "stpipe.cli.strun:main" [build-system] requires = [ - 'setuptools >=61', - 'setuptools_scm[toml] >=3.4', + "setuptools >=61", + "setuptools_scm[toml] >=3.4", ] -build-backend = 'setuptools.build_meta' +build-backend = "setuptools.build_meta" [tool.setuptools_scm] write_to = "src/stpipe/_version.py" @@ -59,7 +65,9 @@ write_to = "src/stpipe/_version.py" zip-safe = true [tool.setuptools.packages.find] -where = ['src'] +where = [ + "src", +] [tool.pytest.ini_options] minversion = 6 @@ -67,15 +75,15 @@ log_cli_level = "INFO" xfail_strict = true doctest_plus = true doctest_rst = true -text_file_format = 'rst' +text_file_format = "rst" addopts = [ "--strict-config", "--strict-markers", "-ra", - "--color=yes" + "--color=yes", ] testpaths = [ - 'tests', + "tests", ] filterwarnings = [ "error::ResourceWarning", @@ -93,75 +101,74 @@ src = [ ] line-length = 88 extend-exclude = [ - 'docs', - 'scripts/strun', + "docs", + "scripts/strun", ] [tool.ruff.lint] extend-select = [ - 'F', # Pyflakes - 'W', 'E', # pycodestyle - 'I', # isort - 'N', # pep8-naming - 'UP', # pyupgrade - 'S', # flake8-bandit - # 'BLE', # flake8-blind-except - 'B', # flake8-bugbear - 'A', # flake8-builtins (prevent shadowing of builtins) - 'C4', # flake8-comprehensions (best practices for comprehensions) - 'T10', # flake8-debugger (prevent debugger statements in code) - 'ISC', # flake8-implicit-str-concat (prevent implicit string concat) - 'ICN', # flake8-import-conventions (enforce import conventions) - 'INP', # flake8-no-pep420 (prevent use of PEP420, i.e. implicit name spaces) - 'G', # flake8-logging-format (best practices for logging) - 'PIE', # flake8-pie (misc suggested improvement linting) - 'T20', # flake8-print (prevent print statements in code) - 'PT', # flake8-pytest-style (best practices for pytest) - 'Q', # flake8-quotes (best practices for quotes) - 'RSE', # flake8-raise (best practices for raising exceptions) - 'RET', # flake8-return (best practices for return statements) - # 'SLF', # flake8-self (prevent private member access) - 'TID', # flake8-tidy-imports (prevent banned api and best import practices) - 'INT', # flake8-gettext (when to use printf style strings) - 'ARG', # flake8-unused-arguments (prevent unused arguments) - # 'PTH', # flake8-use-pathlib (prefer pathlib over os.path) - 'ERA', # eradicate (remove commented out code) - 'PGH', # pygrep (simple grep checks) - # 'PL', # pylint (general linting, flake8 alternative) - 'FLY', # flynt (f-string conversion where possible) - 'NPY', # NumPy-specific checks (recommendations from NumPy) - 'PERF', # Perflint (performance linting) - 'RUF', # ruff specific checks + "F", # Pyflakes + "W", "E", # pycodestyle + "I", # isort + "N", # pep8-naming + "UP", # pyupgrade + "S", # flake8-bandit + # "BLE", # flake8-blind-except + "B", # flake8-bugbear + "A", # flake8-builtins (prevent shadowing of builtins) + "C4", # flake8-comprehensions (best practices for comprehensions) + "T10", # flake8-debugger (prevent debugger statements in code) + "ISC", # flake8-implicit-str-concat (prevent implicit string concat) + "ICN", # flake8-import-conventions (enforce import conventions) + "INP", # flake8-no-pep420 (prevent use of PEP420, i.e. implicit name spaces) + "G", # flake8-logging-format (best practices for logging) + "PIE", # flake8-pie (misc suggested improvement linting) + "T20", # flake8-print (prevent print statements in code) + "PT", # flake8-pytest-style (best practices for pytest) + "Q", # flake8-quotes (best practices for quotes) + "RSE", # flake8-raise (best practices for raising exceptions) + "RET", # flake8-return (best practices for return statements) + # "SLF", # flake8-self (prevent private member access) + "TID", # flake8-tidy-imports (prevent banned api and best import practices) + "INT", # flake8-gettext (when to use printf style strings) + "ARG", # flake8-unused-arguments (prevent unused arguments) + # "PTH", # flake8-use-pathlib (prefer pathlib over os.path) + "ERA", # eradicate (remove commented out code) + "PGH", # pygrep (simple grep checks) + # "PL", # pylint (general linting, flake8 alternative) + "FLY", # flynt (f-string conversion where possible) + "NPY", # NumPy-specific checks (recommendations from NumPy) + "PERF", # Perflint (performance linting) + "RUF", # ruff specific checks ] ignore = [ "ISC001", # conflicts with ruff formatter ] [tool.ruff.lint.extend-per-file-ignores] -"tests/*.py" = ["S101", "S603", "S607", "INP001", "ARG001"] -"src/stpipe/tests/*.py" = ["S101"] -"src/stpipe/cli/*.py" = ["T201"] -"src/stpipe/cmdline.py" = ["T201"] - +"tests/*.py" = [ + "S101", + "S603", + "S607", + "INP001", + "ARG001", +] +"src/stpipe/tests/*.py" = [ + "S101", +] +"src/stpipe/cli/*.py" = [ + "T201", +] +"src/stpipe/cmdline.py" = [ + "T201", +] [tool.black] line-length = 88 -force-exclude = ''' -^/( - ( - \.eggs - | \.git - | \.pytest_cache - | \.tox - )/ -) -''' +force-exclude = "^/(\n (\n \\.eggs\n | \\.git\n | \\.pytest_cache\n | \\.tox\n )/\n)\n" [tool.codespell] -skip="*.pdf,*.fits,*.asdf,.tox,build,./tags,.git,docs/_build" -# ignore-words-list=""" -# """ - +skip = "*.pdf,*.fits,*.asdf,.tox,build,./tags,.git,docs/_build" [tool.repo-review] ignore = [ diff --git a/src/stpipe/step.py b/src/stpipe/step.py index c493bf5a..fff9aea6 100644 --- a/src/stpipe/step.py +++ b/src/stpipe/step.py @@ -540,7 +540,7 @@ def run(self, *args): # Save the output file if one was specified if not self.skip and self.save_results: # Setup the save list. - if not isinstance(step_result, (list, tuple)): + if not isinstance(step_result, list | tuple): results_to_save = [step_result] else: results_to_save = step_result @@ -939,7 +939,7 @@ def set_primary_input(self, obj, exclusive=True): err_message = f"Cannot set master input file name from object {obj}" parent_input_filename = self.search_attr("_input_filename") if not exclusive or parent_input_filename is None: - if isinstance(obj, (str, Path)): + if isinstance(obj, str | Path): self._input_filename = str(obj) elif isinstance(obj, AbstractDataModel): try: