This is an automated email from the ASF dual-hosted git repository.

jorisvandenbossche pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new aa6ab95a12 GH-43518: [Python][Packaging][CI] Drop Python 3.8 support 
(#43970)
aa6ab95a12 is described below

commit aa6ab95a1224d7435e212b5d6f20e231d482754e
Author: Raúl Cumplido <[email protected]>
AuthorDate: Mon Sep 16 15:38:38 2024 +0200

    GH-43518: [Python][Packaging][CI] Drop Python 3.8 support (#43970)
    
    ### Rationale for this change
    
    Python 3.8 is End of Support on 31st October 2023. We can drop support for 
pyarrow 18.0.0.
    See: https://endoflife.date/python
    
    ### What changes are included in this PR?
    
    Remove support for 3.8. Update minimum required Python version and update 
some CI jobs to use the minimum Python supported version
    
    ### Are these changes tested?
    
    They will be tested via Archery
    
    ### Are there any user-facing changes?
    
    Yes in terms of not supporting older versions of Python. This will be a 
breaking change for some users but not for the API itself
    
    * GitHub Issue: #43518
    
    Authored-by: Raúl Cumplido <[email protected]>
    Signed-off-by: Joris Van den Bossche <[email protected]>
---
 .env                                               |  4 +-
 .github/workflows/dev.yml                          |  1 +
 .github/workflows/go.yml                           |  4 +-
 .github/workflows/integration.yml                  |  2 +-
 .github/workflows/java.yml                         |  2 +-
 .github/workflows/java_jni.yml                     |  4 +-
 .github/workflows/js.yml                           |  2 +-
 .github/workflows/python.yml                       | 54 +++++++++++-----------
 .github/workflows/r.yml                            |  4 +-
 .github/workflows/ruby.yml                         |  2 +-
 ci/docker/conda-python-cpython-debug.dockerfile    |  4 +-
 ci/docker/conda-python-cython2.dockerfile          |  2 +-
 ci/docker/conda-python-dask.dockerfile             |  2 +-
 ci/docker/conda-python-hdfs.dockerfile             |  2 +-
 ci/docker/conda-python-jpype.dockerfile            |  2 +-
 ci/docker/conda-python-pandas.dockerfile           |  2 +-
 ci/docker/conda-python-spark.dockerfile            |  2 +-
 ci/docker/conda-python.dockerfile                  |  2 +-
 ci/docker/linux-apt-python-3.dockerfile            |  1 +
 ci/docker/python-wheel-manylinux.dockerfile        |  4 +-
 .../python-wheel-windows-test-vs2019.dockerfile    |  9 ++--
 ci/docker/python-wheel-windows-vs2019.dockerfile   |  9 ++--
 ci/scripts/install_python.sh                       |  6 +--
 ci/scripts/r_install_system_dependencies.sh        |  2 +-
 dev/archery/setup.py                               | 10 ++--
 dev/release/verify-release-candidate-wheels.bat    |  9 ++--
 dev/release/verify-release-candidate.bat           |  2 +-
 dev/release/verify-release-candidate.sh            |  6 +--
 dev/tasks/macros.jinja                             |  2 +-
 dev/tasks/python-sdist/github.yml                  |  3 +-
 dev/tasks/python-wheels/github.linux.yml           |  4 +-
 dev/tasks/tasks.yml                                | 37 +++++++++------
 docker-compose.yml                                 |  7 +--
 .../developers/continuous_integration/archery.rst  |  2 +-
 .../developers/continuous_integration/crossbow.rst |  2 +-
 docs/source/python/install.rst                     |  2 +-
 python/asv.conf.json                               |  2 +-
 python/pyarrow/tests/test_csv.py                   |  7 +--
 python/pyarrow/tests/test_flight.py                |  4 +-
 python/pyarrow/tests/test_types.py                 | 11 ++---
 python/pyarrow/tests/util.py                       | 14 ------
 python/pyproject.toml                              |  3 +-
 r/tests/testthat/test-python.R                     |  4 +-
 43 files changed, 124 insertions(+), 135 deletions(-)

diff --git a/.env b/.env
index c8c236d5ac..6accb27262 100644
--- a/.env
+++ b/.env
@@ -70,8 +70,8 @@ NODE=18
 NUMBA=latest
 NUMPY=latest
 PANDAS=latest
-PYTHON=3.8
-PYTHON_IMAGE_TAG=3.8
+PYTHON=3.9
+PYTHON_IMAGE_TAG=3.9
 R=4.4
 SPARK=master
 TURBODBC=latest
diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml
index 3879a045fd..d2436fe3c4 100644
--- a/.github/workflows/dev.yml
+++ b/.github/workflows/dev.yml
@@ -66,6 +66,7 @@ jobs:
         env:
           ARCHERY_DOCKER_USER: ${{ secrets.DOCKERHUB_USER }}
           ARCHERY_DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_TOKEN }}
+          UBUNTU: 22.04
         run: |
           source ci/scripts/util_enable_core_dumps.sh
           archery docker run -e GITHUB_ACTIONS=true ubuntu-lint
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index d463549206..9eba4c8636 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -211,7 +211,7 @@ jobs:
       - name: Setup Python
         uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # 
v5.2.0
         with:
-          python-version: 3.8
+          python-version: 3.12
       - name: Setup Archery
         run: pip install -e dev/archery[docker]
       - name: Execute Docker Build
@@ -251,7 +251,7 @@ jobs:
       - name: Setup Python
         uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # 
v5.2.0
         with:
-          python-version: 3.8
+          python-version: 3.12
       - name: Setup Archery
         run: pip install -e dev/archery[docker]
       - name: Execute Docker Build
diff --git a/.github/workflows/integration.yml 
b/.github/workflows/integration.yml
index b73f900e61..bffc1c597b 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -93,7 +93,7 @@ jobs:
       - name: Setup Python
         uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # 
v5.2.0
         with:
-          python-version: 3.8
+          python-version: 3.12
       - name: Setup Archery
         run: pip install -e dev/archery[docker]
       - name: Execute Docker Build
diff --git a/.github/workflows/java.yml b/.github/workflows/java.yml
index 57f834bcba..ad39dbc7d0 100644
--- a/.github/workflows/java.yml
+++ b/.github/workflows/java.yml
@@ -80,7 +80,7 @@ jobs:
       - name: Setup Python
         uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # 
v5.2.0
         with:
-          python-version: 3.8
+          python-version: 3.12
       - name: Setup Archery
         run: pip install -e dev/archery[docker]
       - name: Execute Docker Build
diff --git a/.github/workflows/java_jni.yml b/.github/workflows/java_jni.yml
index e730a5bf3e..56aa1d0992 100644
--- a/.github/workflows/java_jni.yml
+++ b/.github/workflows/java_jni.yml
@@ -74,7 +74,7 @@ jobs:
       - name: Setup Python
         uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # 
v5.2.0
         with:
-          python-version: 3.8
+          python-version: 3.12
       - name: Setup Archery
         run: pip install -e dev/archery[docker]
       - name: Execute Docker Build
@@ -116,7 +116,7 @@ jobs:
       - name: Setup Python
         uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # 
v5.2.0
         with:
-          python-version: 3.8
+          python-version: 3.12
       - name: Setup Archery
         run: pip install -e dev/archery[docker]
       - name: Execute Docker Build
diff --git a/.github/workflows/js.yml b/.github/workflows/js.yml
index 9ab4edf085..c7693c0513 100644
--- a/.github/workflows/js.yml
+++ b/.github/workflows/js.yml
@@ -58,7 +58,7 @@ jobs:
       - name: Setup Python
         uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # 
v5.2.0
         with:
-          python-version: 3.8
+          python-version: 3.12
       - name: Setup Archery
         run: pip install -e dev/archery[docker]
       - name: Execute Docker Build
diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml
index d5de099464..4916287556 100644
--- a/.github/workflows/python.yml
+++ b/.github/workflows/python.yml
@@ -58,41 +58,41 @@ jobs:
       matrix:
         name:
           - conda-python-docs
-          - conda-python-3.9-nopandas
-          - conda-python-3.8-pandas-1.0
-          - conda-python-3.10-pandas-latest
-          - conda-python-3.10-no-numpy
+          - conda-python-3.10-nopandas
+          - conda-python-3.9-pandas-1.1.3
+          - conda-python-3.11-pandas-latest
+          - conda-python-3.11-no-numpy
         include:
           - name: conda-python-docs
-            cache: conda-python-3.9
+            cache: conda-python-3.10
             image: conda-python-docs
-            title: AMD64 Conda Python 3.9 Sphinx & Numpydoc
-            python: 3.9
-          - name: conda-python-3.9-nopandas
-            cache: conda-python-3.9
+            title: AMD64 Conda Python 3.10 Sphinx & Numpydoc
+            python: "3.10"
+          - name: conda-python-3.10-nopandas
+            cache: conda-python-3.10
             image: conda-python
-            title: AMD64 Conda Python 3.9 Without Pandas
-            python: 3.9
-          - name: conda-python-3.8-pandas-1.0
-            cache: conda-python-3.8
+            title: AMD64 Conda Python 3.10 Without Pandas
+            python: "3.10"
+          - name: conda-python-3.9-pandas-1.1.3
+            cache: conda-python-3.9
             image: conda-python-pandas
-            title: AMD64 Conda Python 3.8 Pandas 1.0
-            python: 3.8
-            pandas: "1.0"
-            numpy: 1.16
-          - name: conda-python-3.10-pandas-latest
-            cache: conda-python-3.10
+            title: AMD64 Conda Python 3.9 Pandas 1.1.3
+            python: 3.9
+            pandas: "1.1.3"
+            numpy: 1.19.5
+          - name: conda-python-3.11-pandas-latest
+            cache: conda-python-3.11
             image: conda-python-pandas
-            title: AMD64 Conda Python 3.10 Pandas latest
-            python: "3.10"
+            title: AMD64 Conda Python 3.11 Pandas latest
+            python: "3.11"
             pandas: latest
-          - name: conda-python-3.10-no-numpy
-            cache: conda-python-3.10
+          - name: conda-python-3.11-no-numpy
+            cache: conda-python-3.11
             image: conda-python-no-numpy
-            title: AMD64 Conda Python 3.10 without NumPy
-            python: "3.10"
+            title: AMD64 Conda Python 3.11 without NumPy
+            python: "3.11"
     env:
-      PYTHON: ${{ matrix.python || 3.8 }}
+      PYTHON: ${{ matrix.python || 3.9 }}
       UBUNTU: ${{ matrix.ubuntu || 20.04 }}
       PANDAS: ${{ matrix.pandas || 'latest' }}
       NUMPY: ${{ matrix.numpy || 'latest' }}
@@ -111,7 +111,7 @@ jobs:
       - name: Setup Python
         uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # 
v5.2.0
         with:
-          python-version: 3.8
+          python-version: 3.12
       - name: Setup Archery
         run: pip install -e dev/archery[docker]
       - name: Execute Docker Build
diff --git a/.github/workflows/r.yml b/.github/workflows/r.yml
index f7e6616336..9abedcd767 100644
--- a/.github/workflows/r.yml
+++ b/.github/workflows/r.yml
@@ -150,7 +150,7 @@ jobs:
       - name: Setup Python
         uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # 
v5.2.0
         with:
-          python-version: 3.8
+          python-version: 3.12
       - name: Setup Archery
         run: pip install -e dev/archery[docker]
       - name: Execute Docker Build
@@ -209,7 +209,7 @@ jobs:
       - name: Setup Python
         uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # 
v5.2.0
         with:
-          python-version: 3.8
+          python-version: 3.12
       - name: Setup Archery
         run: pip install -e dev/archery[docker]
       - name: Execute Docker Build
diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml
index 05b7b317ff..83a066dc27 100644
--- a/.github/workflows/ruby.yml
+++ b/.github/workflows/ruby.yml
@@ -87,7 +87,7 @@ jobs:
       - name: Setup Python
         uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # 
v5.2.0
         with:
-          python-version: 3.8
+          python-version: 3.12
       - name: Setup Archery
         run: pip install -e dev/archery[docker]
       - name: Execute Docker Build
diff --git a/ci/docker/conda-python-cpython-debug.dockerfile 
b/ci/docker/conda-python-cpython-debug.dockerfile
index 87bdcafe40..36ba7865a8 100644
--- a/ci/docker/conda-python-cpython-debug.dockerfile
+++ b/ci/docker/conda-python-cpython-debug.dockerfile
@@ -17,11 +17,11 @@
 
 ARG repo
 ARG arch
-ARG python=3.8
+ARG python=3.9
 FROM ${repo}:${arch}-conda-python-${python}
 
 # (Docker oddity: ARG needs to be repeated after FROM)
-ARG python=3.8
+ARG python=3.9
 RUN mamba install -y 
"conda-forge/label/python_debug::python=${python}[build=*_cpython]" && \
     mamba clean --all
 # Quick check that we do have a debug mode CPython
diff --git a/ci/docker/conda-python-cython2.dockerfile 
b/ci/docker/conda-python-cython2.dockerfile
index d67ef67727..859ad868b0 100644
--- a/ci/docker/conda-python-cython2.dockerfile
+++ b/ci/docker/conda-python-cython2.dockerfile
@@ -17,7 +17,7 @@
 
 ARG repo
 ARG arch
-ARG python=3.8
+ARG python=3.9
 FROM ${repo}:${arch}-conda-python-${python}
 
 RUN mamba install -q -y "cython<3" && \
diff --git a/ci/docker/conda-python-dask.dockerfile 
b/ci/docker/conda-python-dask.dockerfile
index 4484011081..2c063b2e64 100644
--- a/ci/docker/conda-python-dask.dockerfile
+++ b/ci/docker/conda-python-dask.dockerfile
@@ -17,7 +17,7 @@
 
 ARG repo
 ARG arch=amd64
-ARG python=3.8
+ARG python=3.9
 FROM ${repo}:${arch}-conda-python-${python}
 
 ARG dask=latest
diff --git a/ci/docker/conda-python-hdfs.dockerfile 
b/ci/docker/conda-python-hdfs.dockerfile
index 4e5e1a402e..4cf35f4b37 100644
--- a/ci/docker/conda-python-hdfs.dockerfile
+++ b/ci/docker/conda-python-hdfs.dockerfile
@@ -17,7 +17,7 @@
 
 ARG repo
 ARG arch=amd64
-ARG python=3.8
+ARG python=3.9
 FROM ${repo}:${arch}-conda-python-${python}
 
 ARG jdk=11
diff --git a/ci/docker/conda-python-jpype.dockerfile 
b/ci/docker/conda-python-jpype.dockerfile
index d9b43afdae..c28400f026 100644
--- a/ci/docker/conda-python-jpype.dockerfile
+++ b/ci/docker/conda-python-jpype.dockerfile
@@ -17,7 +17,7 @@
 
 ARG repo
 ARG arch=amd64
-ARG python=3.8
+ARG python=3.9
 FROM ${repo}:${arch}-conda-python-${python}
 
 ARG jdk=11
diff --git a/ci/docker/conda-python-pandas.dockerfile 
b/ci/docker/conda-python-pandas.dockerfile
index 83ad52a13d..9ee62cd282 100644
--- a/ci/docker/conda-python-pandas.dockerfile
+++ b/ci/docker/conda-python-pandas.dockerfile
@@ -17,7 +17,7 @@
 
 ARG repo
 ARG arch=amd64
-ARG python=3.8
+ARG python=3.9
 FROM ${repo}:${arch}-conda-python-${python}
 
 ARG pandas=latest
diff --git a/ci/docker/conda-python-spark.dockerfile 
b/ci/docker/conda-python-spark.dockerfile
index d95fe58b52..a8e8250797 100644
--- a/ci/docker/conda-python-spark.dockerfile
+++ b/ci/docker/conda-python-spark.dockerfile
@@ -17,7 +17,7 @@
 
 ARG repo
 ARG arch=amd64
-ARG python=3.8
+ARG python=3.9
 FROM ${repo}:${arch}-conda-python-${python}
 
 ARG jdk=11
diff --git a/ci/docker/conda-python.dockerfile 
b/ci/docker/conda-python.dockerfile
index 7e8dbe76f6..3897a7217d 100644
--- a/ci/docker/conda-python.dockerfile
+++ b/ci/docker/conda-python.dockerfile
@@ -20,7 +20,7 @@ ARG arch
 FROM ${repo}:${arch}-conda-cpp
 
 # install python specific packages
-ARG python=3.8
+ARG python=3.9
 COPY ci/conda_env_python.txt \
      /arrow/ci/
 # If the Python version being tested is the same as the Python used by the 
system gdb,
diff --git a/ci/docker/linux-apt-python-3.dockerfile 
b/ci/docker/linux-apt-python-3.dockerfile
index 2e07c24401..e215976d44 100644
--- a/ci/docker/linux-apt-python-3.dockerfile
+++ b/ci/docker/linux-apt-python-3.dockerfile
@@ -23,6 +23,7 @@ COPY python/requirements-build.txt \
      /arrow/python/
 
 ENV ARROW_PYTHON_VENV /arrow-dev
+
 RUN python3 -m venv ${ARROW_PYTHON_VENV} && \
     . ${ARROW_PYTHON_VENV}/bin/activate && \
     pip install -U pip setuptools wheel && \
diff --git a/ci/docker/python-wheel-manylinux.dockerfile 
b/ci/docker/python-wheel-manylinux.dockerfile
index 5cc1711608..a797bedff1 100644
--- a/ci/docker/python-wheel-manylinux.dockerfile
+++ b/ci/docker/python-wheel-manylinux.dockerfile
@@ -47,7 +47,7 @@ RUN dnf install -y git flex curl autoconf zip perl-IPC-Cmd 
wget
 # on manylinux_2_28, no system python is installed.
 # We therefore override the PATH with Python 3.8 in /opt/python
 # so that we have a consistent Python version across base images.
-ENV CPYTHON_VERSION=cp38
+ENV CPYTHON_VERSION=cp39
 ENV PATH=/opt/python/${CPYTHON_VERSION}-${CPYTHON_VERSION}/bin:${PATH}
 
 # Install CMake
@@ -104,7 +104,7 @@ RUN vcpkg install \
 RUN pipx upgrade auditwheel
 
 # Configure Python for applications running in the bash shell of this 
Dockerfile
-ARG python=3.8
+ARG python=3.9
 ENV PYTHON_VERSION=${python}
 RUN PYTHON_ROOT=$(find /opt/python -name 
cp${PYTHON_VERSION/./}-cp${PYTHON_VERSION/./}) && \
     echo "export PATH=$PYTHON_ROOT/bin:\$PATH" >> /etc/profile.d/python.sh
diff --git a/ci/docker/python-wheel-windows-test-vs2019.dockerfile 
b/ci/docker/python-wheel-windows-test-vs2019.dockerfile
index bffc1bd13d..8c17ebfa2f 100644
--- a/ci/docker/python-wheel-windows-test-vs2019.dockerfile
+++ b/ci/docker/python-wheel-windows-test-vs2019.dockerfile
@@ -48,13 +48,12 @@ COPY ci/scripts/install_gcs_testbench.bat 
C:/arrow/ci/scripts/
 RUN call "C:\arrow\ci\scripts\install_gcs_testbench.bat" && \
     storage-testbench -h
 
-# Define the full version number otherwise choco falls back to patch number 0 
(3.8 => 3.8.0)
-ARG python=3.8
-RUN (if "%python%"=="3.8" setx PYTHON_VERSION "3.8.10") & \
-    (if "%python%"=="3.9" setx PYTHON_VERSION "3.9.13") & \
+# Define the full version number otherwise choco falls back to patch number 0 
(3.9 => 3.9.0)
+ARG python=3.9
+RUN (if "%python%"=="3.9" setx PYTHON_VERSION "3.9.13") & \
     (if "%python%"=="3.10" setx PYTHON_VERSION "3.10.11") & \
     (if "%python%"=="3.11" setx PYTHON_VERSION "3.11.9") & \
-    (if "%python%"=="3.12" setx PYTHON_VERSION "3.12.4") & \
+    (if "%python%"=="3.12" setx PYTHON_VERSION "3.12.5") & \
     (if "%python%"=="3.13" setx PYTHON_VERSION "3.13.0-rc1")
 
 # Install archiver to extract xz archives
diff --git a/ci/docker/python-wheel-windows-vs2019.dockerfile 
b/ci/docker/python-wheel-windows-vs2019.dockerfile
index 5a17e3e4c5..f9d31eb577 100644
--- a/ci/docker/python-wheel-windows-vs2019.dockerfile
+++ b/ci/docker/python-wheel-windows-vs2019.dockerfile
@@ -78,13 +78,12 @@ RUN vcpkg install \
 RUN wmic product where "name like 'python%%'" call uninstall /nointeractive && 
\
     rm -rf Python*
 
-# Define the full version number otherwise choco falls back to patch number 0 
(3.8 => 3.8.0)
-ARG python=3.8
-RUN (if "%python%"=="3.8" setx PYTHON_VERSION "3.8.10" && setx PATH 
"%PATH%;C:\Python38;C:\Python38\Scripts") & \
-    (if "%python%"=="3.9" setx PYTHON_VERSION "3.9.13" && setx PATH 
"%PATH%;C:\Python39;C:\Python39\Scripts") & \
+# Define the full version number otherwise choco falls back to patch number 0 
(3.9 => 3.9.0)
+ARG python=3.9
+RUN (if "%python%"=="3.9" setx PYTHON_VERSION "3.9.13" && setx PATH 
"%PATH%;C:\Python39;C:\Python39\Scripts") & \
     (if "%python%"=="3.10" setx PYTHON_VERSION "3.10.11" && setx PATH 
"%PATH%;C:\Python310;C:\Python310\Scripts") & \
     (if "%python%"=="3.11" setx PYTHON_VERSION "3.11.9" && setx PATH 
"%PATH%;C:\Python311;C:\Python311\Scripts") & \
-    (if "%python%"=="3.12" setx PYTHON_VERSION "3.12.4" && setx PATH 
"%PATH%;C:\Python312;C:\Python312\Scripts") & \
+    (if "%python%"=="3.12" setx PYTHON_VERSION "3.12.5" && setx PATH 
"%PATH%;C:\Python312;C:\Python312\Scripts") & \
     (if "%python%"=="3.13" setx PYTHON_VERSION "3.13.0-rc1" && setx PATH 
"%PATH%;C:\Python313;C:\Python313\Scripts")
 RUN choco install -r -y --pre --no-progress python --version=%PYTHON_VERSION%
 RUN python -m pip install -U pip setuptools
diff --git a/ci/scripts/install_python.sh b/ci/scripts/install_python.sh
index 42d0e9ca17..21d8a16e3c 100755
--- a/ci/scripts/install_python.sh
+++ b/ci/scripts/install_python.sh
@@ -25,11 +25,10 @@ platforms=([windows]=Windows
            [linux]=Linux)
 
 declare -A versions
-versions=([3.8]=3.8.10
-          [3.9]=3.9.13
+versions=([3.9]=3.9.13
           [3.10]=3.10.11
           [3.11]=3.11.9
-          [3.12]=3.12.4
+          [3.12]=3.12.5
           [3.13]=3.13.0)
 
 if [ "$#" -ne 2 ]; then
@@ -73,4 +72,5 @@ if [ $platform = "macOS" ]; then
     $pip install -U pip setuptools
 else
     echo "Unsupported platform: $platform"
+    exit 1
 fi
diff --git a/ci/scripts/r_install_system_dependencies.sh 
b/ci/scripts/r_install_system_dependencies.sh
index 7ddc2604f6..ae2a04656c 100755
--- a/ci/scripts/r_install_system_dependencies.sh
+++ b/ci/scripts/r_install_system_dependencies.sh
@@ -54,7 +54,7 @@ if [ "$ARROW_S3" == "ON" ] || [ "$ARROW_GCS" == "ON" ] || [ 
"$ARROW_R_DEV" == "T
     case "$PACKAGE_MANAGER" in
       zypper)
         # python3 is Python 3.6 on OpenSUSE 15.3.
-        # PyArrow supports Python 3.8 or later.
+        # PyArrow supports Python 3.9 or later.
         $PACKAGE_MANAGER install -y python39-pip
         ln -s /usr/bin/python3.9 /usr/local/bin/python
         ln -s /usr/bin/pip3.9 /usr/local/bin/pip
diff --git a/dev/archery/setup.py b/dev/archery/setup.py
index f87316dcc7..59e6b5ca38 100755
--- a/dev/archery/setup.py
+++ b/dev/archery/setup.py
@@ -21,12 +21,8 @@ import operator
 import sys
 from setuptools import setup, find_packages
 
-# pygit2>=1.14.0 requires python 3.9, so crossbow and all
-# both technically require python 3.9 — however we still need to
-# support 3.8 when using docker. When 3.8 is EOLed and we bump
-# to Python 3.9 this will resolve itself.
-if sys.version_info < (3, 8):
-    sys.exit('Python < 3.8 is not supported')
+if sys.version_info < (3, 9):
+    sys.exit('Python < 3.9 is not supported')
 
 # For pathlib.Path compatibility
 jinja_req = 'jinja2>=2.11'
@@ -57,7 +53,7 @@ setup(
     maintainer_email='[email protected]',
     packages=find_packages(),
     include_package_data=True,
-    python_requires='>=3.8',
+    python_requires='>=3.9',
     install_requires=['click>=7'],
     tests_require=['pytest', 'responses'],
     extras_require=extras,
diff --git a/dev/release/verify-release-candidate-wheels.bat 
b/dev/release/verify-release-candidate-wheels.bat
index 06deb0c5b2..d846b69da8 100644
--- a/dev/release/verify-release-candidate-wheels.bat
+++ b/dev/release/verify-release-candidate-wheels.bat
@@ -57,9 +57,6 @@ call deactivate
 set ARROW_TEST_DATA=%cd%\arrow\testing\data
 
 
-CALL :verify_wheel 3.8
-if errorlevel 1 GOTO error
-
 CALL :verify_wheel 3.9
 if errorlevel 1 GOTO error
 
@@ -69,6 +66,12 @@ if errorlevel 1 GOTO error
 CALL :verify_wheel 3.11
 if errorlevel 1 GOTO error
 
+CALL :verify_wheel 3.12
+if errorlevel 1 GOTO error
+
+CALL :verify_wheel 3.13
+if errorlevel 1 GOTO error
+
 :done
 cd %_CURRENT_DIR%
 
diff --git a/dev/release/verify-release-candidate.bat 
b/dev/release/verify-release-candidate.bat
index 06d3016c72..bba62b9c01 100644
--- a/dev/release/verify-release-candidate.bat
+++ b/dev/release/verify-release-candidate.bat
@@ -56,7 +56,7 @@ if "%VERSION%"=="" (
 
 set ARROW_TEST_DATA=!ARROW_SOURCE!\testing\data
 set PARQUET_TEST_DATA=!ARROW_SOURCE!\cpp\submodules\parquet-testing\data
-set PYTHON=3.8
+set PYTHON=3.9
 
 @rem Using call with conda.bat seems necessary to avoid terminating the batch
 @rem script execution
diff --git a/dev/release/verify-release-candidate.sh 
b/dev/release/verify-release-candidate.sh
index cdea4ca0d0..8aaffb591b 100755
--- a/dev/release/verify-release-candidate.sh
+++ b/dev/release/verify-release-candidate.sh
@@ -1146,7 +1146,7 @@ test_linux_wheels() {
     local arch="x86_64"
   fi
 
-  local python_versions="${TEST_PYTHON_VERSIONS:-3.8 3.9 3.10 3.11 3.12 3.13}"
+  local python_versions="${TEST_PYTHON_VERSIONS:-3.9 3.10 3.11 3.12 3.13}"
   local 
platform_tags="${TEST_WHEEL_PLATFORM_TAGS:-manylinux_2_17_${arch}.manylinux2014_${arch}
 manylinux_2_28_${arch}}"
 
   for python in ${python_versions}; do
@@ -1170,11 +1170,11 @@ test_macos_wheels() {
 
   # apple silicon processor
   if [ "$(uname -m)" = "arm64" ]; then
-    local python_versions="3.8 3.9 3.10 3.11 3.12 3.13"
+    local python_versions="3.9 3.10 3.11 3.12 3.13"
     local platform_tags="macosx_11_0_arm64"
     local check_flight=OFF
   else
-    local python_versions="3.8 3.9 3.10 3.11 3.12 3.13"
+    local python_versions="3.9 3.10 3.11 3.12 3.13"
     local platform_tags="macosx_10_15_x86_64"
   fi
 
diff --git a/dev/tasks/macros.jinja b/dev/tasks/macros.jinja
index 082d33b124..4c504a120d 100644
--- a/dev/tasks/macros.jinja
+++ b/dev/tasks/macros.jinja
@@ -211,7 +211,7 @@ env:
 {%- macro azure_upload_releases(pattern) -%}
   - task: UsePythonVersion@0
     inputs:
-      versionSpec: '3.8'
+      versionSpec: '3.9'
   - script: pip install -e arrow/dev/archery[crossbow-upload]
     displayName: Install Crossbow
   - bash: |
diff --git a/dev/tasks/python-sdist/github.yml 
b/dev/tasks/python-sdist/github.yml
index ef36e358aa..8a141c4099 100644
--- a/dev/tasks/python-sdist/github.yml
+++ b/dev/tasks/python-sdist/github.yml
@@ -22,7 +22,7 @@
 jobs:
   build:
     name: "Build sdist"
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-latest
     steps:
       {{ macros.github_checkout_arrow()|indent }}
       {{ macros.github_install_archery()|indent }}
@@ -39,6 +39,7 @@ jobs:
       - name: Test sdist
         run: archery docker run ubuntu-python-sdist-test
         env:
+          UBUNTU: 22.04
           PYARROW_VERSION: {{ arrow.no_rc_version }}
 
       {{ macros.github_upload_releases("arrow/python/dist/*.tar.gz")|indent }}
diff --git a/dev/tasks/python-wheels/github.linux.yml 
b/dev/tasks/python-wheels/github.linux.yml
index faca698b71..f3011ae118 100644
--- a/dev/tasks/python-wheels/github.linux.yml
+++ b/dev/tasks/python-wheels/github.linux.yml
@@ -66,7 +66,7 @@ jobs:
       - name: Test wheel on AlmaLinux 8
         shell: bash
         if: |
-          '{{ python_version }}' == '3.8'
+          '{{ python_version }}' == '3.9'
         env:
           ALMALINUX: "8"
         run: |
@@ -82,7 +82,7 @@ jobs:
       - name: Test wheel on Ubuntu 20.04
         shell: bash
         if: |
-          '{{ python_version }}' == '3.8'
+          '{{ python_version }}' == '3.9'
         env:
           UBUNTU: "20.04"
         run: |
diff --git a/dev/tasks/tasks.yml b/dev/tasks/tasks.yml
index 9bb7eedd7b..4dcafc73a2 100644
--- a/dev/tasks/tasks.yml
+++ b/dev/tasks/tasks.yml
@@ -390,8 +390,7 @@ tasks:
       - pyarrow-{no_rc_version}-py310(h[a-z0-9]+)_0_cuda.conda
       - pyarrow-{no_rc_version}-py311(h[a-z0-9]+)_0_cuda.conda
 
-{% for python_version, python_tag, abi_tag in [("3.8", "cp38", "cp38"),
-                                               ("3.9", "cp39", "cp39"),
+{% for python_version, python_tag, abi_tag in [("3.9", "cp39", "cp39"),
                                                ("3.10", "cp310", "cp310"),
                                                ("3.11", "cp311", "cp311"),
                                                ("3.12", "cp312", "cp312"),
@@ -1203,7 +1202,7 @@ tasks:
         UBUNTU: 22.04
       image: ubuntu-cpp-emscripten
 
-{% for python_version in ["3.8", "3.9", "3.10", "3.11", "3.12"] %}
+{% for python_version in ["3.9", "3.10", "3.11", "3.12"] %}
   test-conda-python-{{ python_version }}:
     ci: github
     template: docker-tests/github.linux.yml
@@ -1286,20 +1285,20 @@ tasks:
       flags: "-e ARROW_S3=OFF -e ARROW_GANDIVA=OFF"
       image: debian-python
 
-  test-ubuntu-20.04-python-3:
+  test-ubuntu-22.04-python-3:
     ci: github
     template: docker-tests/github.linux.yml
     params:
       env:
-        UBUNTU: 20.04
+        UBUNTU: 22.04
       image: ubuntu-python
 
-  test-ubuntu-22.04-python-3:
+  test-ubuntu-24.04-python-3:
     ci: github
     template: docker-tests/github.linux.yml
     params:
       env:
-        UBUNTU: 22.04
+        UBUNTU: 24.04
       image: ubuntu-python
 
   test-fedora-39-python-3:
@@ -1515,16 +1514,28 @@ tasks:
 
   ############################## CUDA tests #################################
 
-  test-cuda-cpp:
+  test-cuda-cpp-ubuntu-20.04-cuda-11.2.2:
     ci: github
     template: docker-tests/github.cuda.yml
     params:
       image: ubuntu-cuda-cpp
 
-  test-cuda-python:
+  test-cuda-cpp-ubuntu-22.04-cuda-11.7.1:
     ci: github
     template: docker-tests/github.cuda.yml
     params:
+      env:
+        UBUNTU: 22.04
+        CUDA: 11.7.1
+      image: ubuntu-cuda-cpp
+
+  test-cuda-python-ubuntu-22.04-cuda-11.7.1:
+    ci: github
+    template: docker-tests/github.cuda.yml
+    params:
+      env:
+        UBUNTU: 22.04
+        CUDA: 11.7.1
       image: ubuntu-cuda-python
 
   ############################## Fuzz tests #################################
@@ -1542,11 +1553,11 @@ tasks:
 
   ############################## Integration tests ############################
 
-{% for python_version, pandas_version, numpy_version, cache_leaf in [("3.8", 
"1.0", "1.19", True),
-                                                                     ("3.9", 
"latest", "latest", False),
-                                                                     ("3.10", 
"latest", "1.26", False),
+{% for python_version, pandas_version, numpy_version, cache_leaf in [("3.9", 
"1.1.3", "1.19.5", True),
                                                                      ("3.10", 
"latest", "latest", False),
-                                                                     ("3.10", 
"nightly", "nightly", False),
+                                                                     ("3.11", 
"latest", "1.26", False),
+                                                                     ("3.11", 
"latest", "latest", False),
+                                                                     ("3.11", 
"nightly", "nightly", False),
                                                                      ("3.11", 
"upstream_devel", "nightly", False)] %}
   test-conda-python-{{ python_version }}-pandas-{{ pandas_version }}-numpy-{{ 
numpy_version }}:
     ci: github
diff --git a/docker-compose.yml b/docker-compose.yml
index 6d9b738d8d..6660715731 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -855,7 +855,7 @@ services:
     #   docker-compose run --rm conda-python
     # Parameters:
     #   ARCH: amd64, arm32v7
-    #   PYTHON: 3.8, 3.9, 3.10, 3.11
+    #   PYTHON: 3.9, 3.10, 3.11, 3.12
     image: ${REPO}:${ARCH}-conda-python-${PYTHON}
     build:
       context: .
@@ -917,6 +917,7 @@ services:
     # Parameters:
     #   ARCH: amd64
     #   CUDA: <depends on your nvidia driver, should match system CUDA>
+    #   UBUNTU: 22.04, 24.04
     image: ${REPO}:${ARCH}-ubuntu-${UBUNTU}-cuda-${CUDA}-python-3
     build:
       context: .
@@ -984,7 +985,7 @@ services:
     #   docker-compose run --rm ubuntu-python
     # Parameters:
     #   ARCH: amd64, arm64v8, ...
-    #   UBUNTU: 20.04, 22.04
+    #   UBUNTU: 22.04, 24.04
     image: ${REPO}:${ARCH}-ubuntu-${UBUNTU}-python-3
     build:
       context: .
@@ -1064,7 +1065,7 @@ services:
     # Parameters:
     #   ARCH: amd64, arm64v8, ...
     #   PYARROW_VERSION: The test target pyarrow version such as "3.0.0"
-    #   UBUNTU: 20.04, 22.04
+    #   UBUNTU: 22.04, 24.04
     image: ${REPO}:${ARCH}-ubuntu-${UBUNTU}-python-3
     build:
       context: .
diff --git a/docs/source/developers/continuous_integration/archery.rst 
b/docs/source/developers/continuous_integration/archery.rst
index d190a0a96c..2580693480 100644
--- a/docs/source/developers/continuous_integration/archery.rst
+++ b/docs/source/developers/continuous_integration/archery.rst
@@ -26,7 +26,7 @@ utility called Archery.
 Installation
 ------------
 
-Archery requires Python 3.8 or later. It is recommended to install Archery in
+Archery requires Python 3.9 or later. It is recommended to install Archery in
 *editable* mode with the ``-e`` flag to automatically update the installation
 when pulling the Arrow repository. After cloning the Arrow repository, from
 the top level directory install Archery by using the command
diff --git a/docs/source/developers/continuous_integration/crossbow.rst 
b/docs/source/developers/continuous_integration/crossbow.rst
index 50ac607f4d..44f41895d4 100644
--- a/docs/source/developers/continuous_integration/crossbow.rst
+++ b/docs/source/developers/continuous_integration/crossbow.rst
@@ -119,7 +119,7 @@ to step 3:
 
    - Confirm the `auto cancellation`_ feature is turned off for branch builds. 
This should be the default setting.
 
-7. Install Python (minimum supported version is 3.8):
+7. Install Python (minimum supported version is 3.9):
 
    | Miniconda is preferred, see installation instructions:
    | https://conda.io/docs/user-guide/install/index.html
diff --git a/docs/source/python/install.rst b/docs/source/python/install.rst
index 84d6253691..9727a68f74 100644
--- a/docs/source/python/install.rst
+++ b/docs/source/python/install.rst
@@ -27,7 +27,7 @@ Linux distributions. We strongly recommend using a 64-bit 
system.
 Python Compatibility
 --------------------
 
-PyArrow is currently compatible with Python 3.8, 3.9, 3.10 and 3.11.
+PyArrow is currently compatible with Python 3.9, 3.10, 3.11, 3.12 and 3.13.
 
 Using Conda
 -----------
diff --git a/python/asv.conf.json b/python/asv.conf.json
index 4d8d73e34b..86fcd3537d 100644
--- a/python/asv.conf.json
+++ b/python/asv.conf.json
@@ -65,7 +65,7 @@
 
     // The Pythons you'd like to test against.  If not provided, defaults
     // to the current version of Python used to run `asv`.
-    "pythons": ["3.8"],
+    "pythons": ["3.9"],
 
     // The matrix of dependencies to test.  Each key is the name of a
     // package (in PyPI) and the values are version numbers.  An empty
diff --git a/python/pyarrow/tests/test_csv.py b/python/pyarrow/tests/test_csv.py
index dcf96f68c4..6a36b41daf 100644
--- a/python/pyarrow/tests/test_csv.py
+++ b/python/pyarrow/tests/test_csv.py
@@ -1444,14 +1444,11 @@ class BaseCSVTableRead(BaseTestCSV):
         if (threading.current_thread().ident !=
                 threading.main_thread().ident):
             pytest.skip("test only works from main Python thread")
-        # Skips test if not available
-        raise_signal = util.get_raise_signal()
-        signum = signal.SIGINT
 
         def signal_from_thread():
             # Give our workload a chance to start up
             time.sleep(0.2)
-            raise_signal(signum)
+            signal.raise_signal(signal.SIGINT)
 
         # We start with a small CSV reading workload and increase its size
         # until it's large enough to get an interruption during it, even in
@@ -1507,7 +1504,7 @@ class BaseCSVTableRead(BaseTestCSV):
         assert last_duration <= 2.0
         e = exc_info.__context__
         assert isinstance(e, pa.ArrowCancelled)
-        assert e.signum == signum
+        assert e.signum == signal.SIGINT
 
     @pytest.mark.threading
     def test_cancellation_disabled(self):
diff --git a/python/pyarrow/tests/test_flight.py 
b/python/pyarrow/tests/test_flight.py
index 029a2695b9..f0ceba37d6 100644
--- a/python/pyarrow/tests/test_flight.py
+++ b/python/pyarrow/tests/test_flight.py
@@ -2101,12 +2101,10 @@ class CancelFlightServer(FlightServerBase):
 def test_interrupt():
     if threading.current_thread().ident != threading.main_thread().ident:
         pytest.skip("test only works from main Python thread")
-    # Skips test if not available
-    raise_signal = util.get_raise_signal()
 
     def signal_from_thread():
         time.sleep(0.5)
-        raise_signal(signal.SIGINT)
+        signal.raise_signal(signal.SIGINT)
 
     exc_types = (KeyboardInterrupt, pa.ArrowCancelled)
 
diff --git a/python/pyarrow/tests/test_types.py 
b/python/pyarrow/tests/test_types.py
index cc680939ac..2a05f87615 100644
--- a/python/pyarrow/tests/test_types.py
+++ b/python/pyarrow/tests/test_types.py
@@ -383,13 +383,10 @@ def test_tzinfo_to_string_errors():
     with pytest.raises(TypeError):
         pa.lib.tzinfo_to_string("Europe/Budapest")
 
-    if sys.version_info >= (3, 8):
-        # before 3.8 it was only possible to create timezone objects with whole
-        # number of minutes
-        tz = datetime.timezone(datetime.timedelta(hours=1, seconds=30))
-        msg = "Offset must represent whole number of minutes"
-        with pytest.raises(ValueError, match=msg):
-            pa.lib.tzinfo_to_string(tz)
+    tz = datetime.timezone(datetime.timedelta(hours=1, seconds=30))
+    msg = "Offset must represent whole number of minutes"
+    with pytest.raises(ValueError, match=msg):
+        pa.lib.tzinfo_to_string(tz)
 
 
 if tzst:
diff --git a/python/pyarrow/tests/util.py b/python/pyarrow/tests/util.py
index aa6dd21f80..acbb2a5c0d 100644
--- a/python/pyarrow/tests/util.py
+++ b/python/pyarrow/tests/util.py
@@ -309,20 +309,6 @@ class ProxyHandler(pyarrow.fs.FileSystemHandler):
         return self._fs.open_append_stream(path, metadata=metadata)
 
 
-def get_raise_signal():
-    if sys.version_info >= (3, 8):
-        return signal.raise_signal
-    elif os.name == 'nt':
-        # On Windows, os.kill() doesn't actually send a signal,
-        # it just terminates the process with the given exit code.
-        pytest.skip("test requires Python 3.8+ on Windows")
-    else:
-        # On Unix, emulate raise_signal() with os.kill().
-        def raise_signal(signum):
-            os.kill(os.getpid(), signum)
-        return raise_signal
-
-
 @contextlib.contextmanager
 def signal_wakeup_fd(*, warn_on_full_buffer=False):
     # Use a socket pair, rather a self-pipe, so that select() can be used
diff --git a/python/pyproject.toml b/python/pyproject.toml
index 7c3fcae5cb..9322100443 100644
--- a/python/pyproject.toml
+++ b/python/pyproject.toml
@@ -34,7 +34,7 @@ build-backend = "setuptools.build_meta"
 [project]
 name = "pyarrow"
 dynamic = ["version"]
-requires-python = ">=3.8"
+requires-python = ">=3.9"
 dependencies = [
     "numpy >= 1.16.6"
 ]
@@ -43,7 +43,6 @@ readme = {file = "README.md", content-type = "text/markdown"}
 license = {text = "Apache Software License"}
 classifiers  = [
     'License :: OSI Approved :: Apache Software License',
-    'Programming Language :: Python :: 3.8',
     'Programming Language :: Python :: 3.9',
     'Programming Language :: Python :: 3.10',
     'Programming Language :: Python :: 3.11',
diff --git a/r/tests/testthat/test-python.R b/r/tests/testthat/test-python.R
index c9dbd02485..279a532003 100644
--- a/r/tests/testthat/test-python.R
+++ b/r/tests/testthat/test-python.R
@@ -22,8 +22,8 @@ test_that("install_pyarrow", {
   # Windows CI machine doesn't pick up the right python or something
   skip_on_os("windows")
   skip_if_not_installed("reticulate")
-  # PyArrow doesn't support Python 3.7 or earlier
-  skip_on_python_older_than("3.8")
+  # PyArrow doesn't support Python 3.8 or earlier
+  skip_on_python_older_than("3.9")
   # no pyarrow wheels for macos 10.13
   skip_if(on_macos_10_13_or_lower())
 


Reply via email to