Skip to content

Commit

Permalink
Adding "better" python version propagation, and removing hardcoded py…
Browse files Browse the repository at this point in the history
…thon versions. (#484)

- There are now three defined python versions you can use in templates,
  they are derived from python_versions and available through jinja macros.
- py.pref(), py.max(), and py.min() are the macros, using the preferred import
  {%- import 'python-versions.jinja' as py -%}. Notably this is the only type
  of import that copier will accept in files who's pathnames contain templates.
  which eliminates several more syntactically ergonomic methods of achieving this
  same interface.
- py.pref(python_versions), the preferred version, is the "middle-est"
  in the python_versions list, see python-versions.jinja for the math. For
  the default case where python_versions = [3.9,3.10,3,11], 3.10 is the preferred
  python version.
- Hardcoded mentions of python 3.9 and python 3.10 have been
  set to py.min(python_versions) or py.pref(python_versions) respectively so that
  this change does not affect projects using the default configuration, and
  any python upgrade compatibility issues can be deferred until either the project
  template or an individual project changes python version support.
- References to python_versions[0] have been replaced with py.min(python_versions)
  for consistency.
  • Loading branch information
mtauraso authored Oct 1, 2024
1 parent 82f1f91 commit 8aa5e4a
Show file tree
Hide file tree
Showing 15 changed files with 72 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{%- import 'python-versions.jinja' as py %}
# This workflow runs pre-commit hooks on pushes and pull requests to main
# to enforce coding style. To ensure correct configuration, please refer to:
# https://lincc-ppt.readthedocs.io/en/latest/practices/ci_precommit.html
Expand All @@ -19,7 +20,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
python-version: '{{ py.pref(python_versions) }}'
- name: Install dependencies
run: |
sudo apt-get update
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{%- import 'python-versions.jinja' as py %}
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://github.com/pypa/gh-action-pypi-publish#trusted-publishing

Expand Down Expand Up @@ -26,7 +27,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
python-version: '{{ py.pref(python_versions) }}'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ on:
branches: [ main ]

env:
PYTHON_VERSION: "3.10"
{%- endraw %}
{%- import 'python-versions.jinja' as py%}
PYTHON_VERSION: "{{ py.pref(python_versions) }}"
{%- raw %}
ASV_VERSION: "0.6.4"
WORKING_DIR: ${{github.workspace}}/benchmarks

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ on:
workflow_dispatch:

env:
PYTHON_VERSION: "3.10"
{%- endraw %}
{%- import 'python-versions.jinja' as py%}
PYTHON_VERSION: "{{ py.pref(python_versions) }}"
{%- raw %}
ASV_VERSION: "0.6.4"
WORKING_DIR: ${{github.workspace}}/benchmarks
NIGHTLY_HASH_FILE: nightly-hash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ concurrency:
cancel-in-progress: true

env:
PYTHON_VERSION: "3.10"
{%- endraw %}
{%- import 'python-versions.jinja' as py%}
PYTHON_VERSION: "{{ py.pref(python_versions) }}"
{%- raw %}
ASV_VERSION: "0.6.4"
WORKING_DIR: ${{github.workspace}}/benchmarks
ARTIFACTS_DIR: ${{github.workspace}}/artifacts
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{%- import 'python-versions.jinja' as py %}
# This workflow will install Python dependencies, build the package and then build the documentation.

name: Build documentation
Expand All @@ -20,10 +21,10 @@ jobs:

steps:
- uses: actions/checkout@v4
- name: Set up Python 3.10
- name: Set up Python {{ py.pref(python_versions) }}
uses: actions/setup-python@v5
with:
python-version: '3.10'
python-version: '{{ py.pref(python_versions) }}'
- name: Install dependencies
run: |
sudo apt-get update
Expand Down
3 changes: 2 additions & 1 deletion python-project-template/.pre-commit-config.yaml.jinja
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{%- import 'python-versions.jinja' as py %}
repos:
# Compare the local template version to the latest remote template version
# This hook should always pass. It will print a message if the local version
Expand Down Expand Up @@ -98,7 +99,7 @@ repos:
# supported by your project here, or alternatively use
# pre-commit's default_language_version, see
# https://pre-commit.com/#top_level-default_language_version
language_version: python3.10
language_version: python{{ py.pref(python_versions) }}
{%- endif %}
{%- if 'ruff_lint' in enforce_style %}
- repo: https://github.com/astral-sh/ruff-pre-commit
Expand Down
3 changes: 2 additions & 1 deletion python-project-template/README.md.jinja
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{%- import 'python-versions.jinja' as py %}
# {{project_name}}

[![Template](https://img.shields.io/badge/Template-LINCC%20Frameworks%20Python%20Project%20Template-brightgreen)](https://lincc-ppt.readthedocs.io/en/latest/)
Expand Down Expand Up @@ -29,7 +30,7 @@ environments. If you have conda installed locally, you can run the following to
create and activate a new environment.

```
>> conda create -n <env_name> python=3.10
>> conda create -n <env_name> python={{ py.pref(python_versions) }}
>> conda activate <env_name>
```

Expand Down
7 changes: 4 additions & 3 deletions python-project-template/pyproject.toml.jinja
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{%- import 'python-versions.jinja' as py %}
[project]
name = "{{project_name}}"
license = {file = "LICENSE"}
Expand All @@ -18,7 +19,7 @@ classifiers = [
"Programming Language :: Python",
]
dynamic = ["version"]
requires-python = ">={{ python_versions[0] }}"
requires-python = ">={{ py.min(python_versions) }}"
dependencies = [
]

Expand Down Expand Up @@ -66,15 +67,15 @@ testpaths = [

[tool.black]
line-length = 110
target-version = ["py{{ python_versions[0] | replace(".", "") }}"]
target-version = ["py{{ py.min(python_versions) | replace(".", "") }}"]

[tool.isort]
profile = "black"
line_length = 110

[tool.ruff]
line-length = 110
target-version = "py{{ python_versions[0] | replace(".", "") }}"
target-version = "py{{ py.min(python_versions) | replace(".", "") }}"

[tool.ruff.lint]
select = [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{%- import 'python-versions.jinja' as py %}
[MAIN]

# Analyse import fallback blocks. This can be used to support both Python 2 and
Expand Down Expand Up @@ -87,7 +88,7 @@ persistent=yes

# Minimum Python version to use for version dependent checks. Will default to
# the version used to run pylint.
py-version=3.9
py-version={{ py.min(python_versions) }}

# Discover python modules and packages in the file system subtree.
recursive=no
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{%- import 'python-versions.jinja' as py %}
[MAIN]

# Analyse import fallback blocks. This can be used to support both Python 2 and
Expand Down Expand Up @@ -87,7 +88,7 @@ persistent=yes

# Minimum Python version to use for version dependent checks. Will default to
# the version used to run pylint.
py-version=3.9
py-version={{ py.min(python_versions) }}

# Discover python modules and packages in the file system subtree.
recursive=no
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{%- import 'python-versions.jinja' as py %}
{
// The version of the config file format. Do not change, unless
// you know what you are doing.
Expand Down Expand Up @@ -36,7 +37,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.10"
"{{ py.pref(python_versions) }}"
],
// The matrix of dependencies to test. Each key is the name of a
// package (in PyPI) and the values are version numbers. An empty
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{%- import 'python-versions.jinja' as py %}
# .readthedocs.yml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
Expand All @@ -8,7 +9,7 @@ version: 2
build:
os: ubuntu-22.04
tools:
python: "3.10"
python: "{{ py.pref(python_versions) }}"

# Build documentation in the docs/ directory with Sphinx
sphinx:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{%- import 'python-versions.jinja' as py %}
.. {{package_name}} documentation main file.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Expand All @@ -15,7 +16,7 @@ create and activate a new environment.

.. code-block:: console

>> conda create env -n <env_name> python=3.10
>> conda create env -n <env_name> python={{ py.pref(python_versions) }}
>> conda activate <env_name>


Expand Down
35 changes: 35 additions & 0 deletions python-versions.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{# You use this file by including it via jinja like:
{%- import 'python-versions.jinja' as py -%}
Then pass the python_versions list into the various macros like so:
{{ py.min(python_versions) }}
This template creates no output, but does allow you to transform python_versions answer into a
number of helpful values for when you need a single python version.
Note that the import syntax and access MUST BE in the form above. Copier has problems processing import lines
that are any more complex when they occur in files who's paths are also jinja templated. #}


{# This gives a middle python version from a potentially long list of versions
For even-length lists we prefer the older of the two middle values.
["3.9","3.10","3.11","3.12"] -> "3.10"
For odd-length lists we prefer the middle value
["3.9","3.10","3.11"] -> "3.10" #}
{% macro pref(python_versions) -%}
{%- set n = python_versions | length -%}
{{ python_versions[((n+1)//2 - 1)] }}
{%- endmacro -%}

{# These give the minimum and maximum python versions supported #}
{% macro min(python_versions) -%}
{%- set n = python_versions | length -%}
{{ python_versions[0] }}
{%- endmacro -%}

{% macro max(python_versions) -%}
{%- set n = python_versions | length -%}
{{ python_versions[n-1] }}
{%- endmacro -%}

0 comments on commit 8aa5e4a

Please sign in to comment.