diff --git a/roles/ensure-python/README.rst b/roles/ensure-python/README.rst
index b1cfce851..9b568d520 100644
--- a/roles/ensure-python/README.rst
+++ b/roles/ensure-python/README.rst
@@ -15,6 +15,12 @@ There are three ways to install the python interpreter:
 
 **Role Variables**
 
+.. zuul:jobvar:: zuul_work_dir
+   :default: {{ zuul.project.src_dir }}
+
+   The project directory.  Serves as the location for version files for
+   ``python_use_pyenv``.
+
 .. zuul:rolevar:: python_version
    :type: str
 
@@ -27,7 +33,8 @@ There are three ways to install the python interpreter:
    :default: False
 
    Whether to optionally use ``pyenv`` to install python instead of distro
-   packages.
+   packages. If this is given without a ``python_version``,
+   it will look for a ``.python-version`` file in the ``zuul_work_dir``.
 
 .. zuul:rolevar:: python_use_stow
    :type: bool
diff --git a/roles/ensure-python/defaults/main.yaml b/roles/ensure-python/defaults/main.yaml
index 80779118e..fcea3eb6d 100644
--- a/roles/ensure-python/defaults/main.yaml
+++ b/roles/ensure-python/defaults/main.yaml
@@ -1,3 +1,4 @@
+zuul_work_dir: "{{ zuul.project.src_dir }}"
 python_use_pyenv: false
 python_use_stow: false
 python_stow_dir: /usr/local/stow
diff --git a/roles/ensure-python/tasks/main.yaml b/roles/ensure-python/tasks/main.yaml
index 1b1a7b9bb..0aa692632 100644
--- a/roles/ensure-python/tasks/main.yaml
+++ b/roles/ensure-python/tasks/main.yaml
@@ -56,7 +56,6 @@
 
 - name: Install python using pyenv
   when:
-    - python_version is defined
     - python_use_pyenv
   include_tasks: pyenv.yaml
 
diff --git a/roles/ensure-python/tasks/pyenv.yaml b/roles/ensure-python/tasks/pyenv.yaml
index d282a06e7..3e8008533 100644
--- a/roles/ensure-python/tasks/pyenv.yaml
+++ b/roles/ensure-python/tasks/pyenv.yaml
@@ -8,6 +8,12 @@
     - "{{ ansible_distribution }}.yaml"
     - "{{ ansible_os_family }}.yaml"
 
+- name: Put .python-version contents into variable
+  when:
+    - python_version is not defined
+  set_fact:
+    python_version: "{{ lookup('ansible.builtin.file', zuul.executor.work_root ~ '/' ~ zuul.project.src_dir ~ '/.python-version') }}"
+
 - name: Install python build depends
   become: true
   package:
@@ -19,7 +25,7 @@
     dest: "{{ ansible_user_dir }}/.pyenv"
     version: master
 
-# NOTE(mnaser): pyenv does not allow us to let it install Python from a specific
+# NOTE(mnaser): python-build does not allow us to let it install Python from a specific
 #               series so we have to do some magic to find out what's the latest
 #               release from a series
 - name: Determine Python version
diff --git a/test-playbooks/ensure-python-pyenv-python-version.yaml b/test-playbooks/ensure-python-pyenv-python-version.yaml
new file mode 100644
index 000000000..c2522a5eb
--- /dev/null
+++ b/test-playbooks/ensure-python-pyenv-python-version.yaml
@@ -0,0 +1,18 @@
+- hosts: all
+  tasks:
+    - name: Create a python-version file with a python version in it
+      delegate_to: localhost
+      copy:
+        content: 3.11
+        dest: "{{ zuul.executor.work_root }}/{{ zuul.project.src_dir }}/.python-version"
+
+    - name: Include ensure-python role
+      include_role:
+        name: ensure-python
+      vars:
+        python_use_pyenv: true
+
+    - name: Check installed version of Python
+      command: /usr/local/bin/python3 --version
+      register: _check_version
+      failed_when: "'Python 3.11' not in _check_version.stdout"
diff --git a/zuul-tests.d/python-roles-jobs.yaml b/zuul-tests.d/python-roles-jobs.yaml
index 6d9d54949..9d5023859 100644
--- a/zuul-tests.d/python-roles-jobs.yaml
+++ b/zuul-tests.d/python-roles-jobs.yaml
@@ -140,6 +140,80 @@
         - name: ubuntu-noble
           label: ubuntu-noble
 
+- job:
+    name: zuul-jobs-test-ensure-python-pyenv-python-version
+    description: Test the ensure-python role with pyenv and a python-version file
+    files:
+      - roles/ensure-python/.*
+    run: test-playbooks/ensure-python-pyenv-python-version.yaml
+    tags: all-platforms
+
+- job:
+    name: zuul-jobs-test-ensure-python-pyenv-python-version-centos-9-stream
+    description: Test the ensure-python role with pyenv and a python-version file
+      on centos-9-stream
+    parent: zuul-jobs-test-ensure-python-pyenv-python-version
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: centos-9-stream
+          label: centos-9-stream
+
+- job:
+    name: zuul-jobs-test-ensure-python-pyenv-python-version-debian-bookworm
+    description: Test the ensure-python role with pyenv and a python-version file
+      on debian-bookworm
+    parent: zuul-jobs-test-ensure-python-pyenv-python-version
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: debian-bookworm
+          label: debian-bookworm
+
+- job:
+    name: zuul-jobs-test-ensure-python-pyenv-python-version-debian-bullseye
+    description: Test the ensure-python role with pyenv and a python-version file
+      on debian-bullseye
+    parent: zuul-jobs-test-ensure-python-pyenv-python-version
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: debian-bullseye
+          label: debian-bullseye
+
+- job:
+    name: zuul-jobs-test-ensure-python-pyenv-python-version-ubuntu-focal
+    description: Test the ensure-python role with pyenv and a python-version file
+      on ubuntu-focal
+    parent: zuul-jobs-test-ensure-python-pyenv-python-version
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: ubuntu-focal
+          label: ubuntu-focal
+
+- job:
+    name: zuul-jobs-test-ensure-python-pyenv-python-version-ubuntu-jammy
+    description: Test the ensure-python role with pyenv and a python-version file
+      on ubuntu-jammy
+    parent: zuul-jobs-test-ensure-python-pyenv-python-version
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: ubuntu-jammy
+          label: ubuntu-jammy
+
+- job:
+    name: zuul-jobs-test-ensure-python-pyenv-python-version-ubuntu-noble
+    description: Test the ensure-python role with pyenv and a python-version file
+      on ubuntu-noble
+    parent: zuul-jobs-test-ensure-python-pyenv-python-version
+    tags: auto-generated
+    nodeset:
+      nodes:
+        - name: ubuntu-noble
+          label: ubuntu-noble
+
 - project:
     check:
       jobs: &id001
@@ -155,6 +229,12 @@
         - zuul-jobs-test-ensure-python-pyenv-ubuntu-focal
         - zuul-jobs-test-ensure-python-pyenv-ubuntu-jammy
         - zuul-jobs-test-ensure-python-pyenv-ubuntu-noble
+        - zuul-jobs-test-ensure-python-pyenv-python-version-centos-9-stream
+        - zuul-jobs-test-ensure-python-pyenv-python-version-debian-bookworm
+        - zuul-jobs-test-ensure-python-pyenv-python-version-debian-bullseye
+        - zuul-jobs-test-ensure-python-pyenv-python-version-ubuntu-focal
+        - zuul-jobs-test-ensure-python-pyenv-python-version-ubuntu-jammy
+        - zuul-jobs-test-ensure-python-pyenv-python-version-ubuntu-noble
     gate:
       jobs: *id001
     periodic-weekly: