diff --git a/.github/workflows/build_workflow.yml b/.github/workflows/build_workflow.yml index d0aa857a..bd158784 100644 --- a/.github/workflows/build_workflow.yml +++ b/.github/workflows/build_workflow.yml @@ -19,10 +19,10 @@ jobs: - name: Checkout Code Repository uses: actions/checkout@v3 - - name: Set up Python 3.13 + - name: Set up Python 3.14 uses: actions/setup-python@v4 with: - python-version: "3.13" + python-version: "3.14" # Run all pre-commit hooks on all the files. # Getting only staged files can be tricky in case a new PR is opened @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.11", "3.12", "3.13"] + python-version: ["3.11", "3.12", "3.13", "3.14"] defaults: run: shell: bash -l {0} @@ -72,11 +72,6 @@ jobs: conda list # Ensure we have the right Python version python --version - # Fix pip issues for Python 3.12+ - if [[ "${{ matrix.python-version }}" == "3.12" ]] || [[ "${{ matrix.python-version }}" == "3.13" ]]; then - python -m ensurepip --upgrade || true - python -m pip install --upgrade --force-reinstall pip setuptools wheel - fi - name: Install `zstash` Package run: | @@ -121,7 +116,7 @@ jobs: environment-file: conda/dev.yml channel-priority: flexible # Changed from strict to flexible auto-update-conda: true - python-version: "3.13" # Use stable Python version for docs + python-version: "3.14" # Use stable Python version for docs # sphinx-multiversion allows for version docs. - name: Build Sphinx Docs diff --git a/conda/dev.yml b/conda/dev.yml index 6ec8e1b9..85f64d32 100644 --- a/conda/dev.yml +++ b/conda/dev.yml @@ -5,7 +5,8 @@ dependencies: # Base # ================= - pip - - python >=3.11,<3.14 + - python >=3.11,<3.15 + - setuptools - sqlite - six >=1.16.0 - globus-sdk >=3.15.0,<4.0 diff --git a/setup.cfg b/setup.cfg index 4e6c6cb4..5a75b3ef 100644 --- a/setup.cfg +++ b/setup.cfg @@ -46,7 +46,7 @@ exclude = venv [mypy] -python_version = 3.13 +python_version = 3.14 check_untyped_defs = True ignore_missing_imports = True warn_unused_ignores = True diff --git a/setup.py b/setup.py index 292653e0..67df2e8e 100644 --- a/setup.py +++ b/setup.py @@ -7,6 +7,6 @@ author_email="forsyth2@llnl.gov, golaz1@llnl.gov, shaheen2@llnl.gov", description="Long term HPSS archiving software for E3SM", packages=find_packages(include=["zstash", "zstash.*"]), - python_requires=">=3.11,<3.14", + python_requires=">=3.11,<3.15", entry_points={"console_scripts": ["zstash=zstash.main:main"]}, ) diff --git a/zstash/extract.py b/zstash/extract.py index 64977aef..06faf40c 100644 --- a/zstash/extract.py +++ b/zstash/extract.py @@ -659,7 +659,12 @@ def extractFiles( # noqa: C901 logger.debug("Valid md5: {} {}".format(md5, fname)) elif extract_this_file: - tar.extract(tarinfo) + if sys.version_info >= (3, 12): + tar.extract( + tarinfo, filter="tar" + ) # "data" is too restrictive, "fully_trusted" is too permissive. + else: + tar.extract(tarinfo) # Note: tar.extract() will not restore time stamps of symbolic # links. Could not find a Python-way to restore it either, so # relying here on 'touch'. This is not the prettiest solution. diff --git a/zstash/main.py b/zstash/main.py index 6201834d..7d011d23 100755 --- a/zstash/main.py +++ b/zstash/main.py @@ -2,6 +2,7 @@ from __future__ import absolute_import, print_function import argparse +import multiprocessing import os import os.path import sys @@ -27,6 +28,12 @@ def handler(signal_received, frame): # ----------------------------------------------------------------------------- def main(): + # Force the use of 'fork' for multiprocessing to ensure consistent behavior + # across Python versions (Python 3.14+ changed the default to 'spawn'). + # 'fork' is only available on POSIX systems (Linux, macOS). + if sys.platform != "win32": + multiprocessing.set_start_method("fork", force=True) + # Run the handler() function when SIGINT is received signal(SIGINT, handler)