diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 109d7b6..356551a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,14 +23,14 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.9", "3.13"] + python-version: ["3.10", "3.13"] steps: - name: Checking out the cookie cutter repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} @@ -58,9 +58,9 @@ jobs: steps: - name: Checking out the cookie cutter repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: "3.13" diff --git a/README.md b/README.md index 84d7ce2..79c4d7d 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ If your Python package contains compiled C++ modules, you might want to check ou In order to use Python Package Cookiecutter you need the following software installed: -* Python `>= 3.8` +* Python `>= 3.10` * [Cookiecutter](https://github.com/cookiecutter/cookiecutter) e.g. by doing `pip install cookiecutter`. * Git `>= 1.8.2` diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index 7c51b6c..ebe91e2 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -60,7 +60,7 @@ def conditional_remove(condition, path): conditional_remove(not {{ have_precommit }}, ".pre-commit-config.yaml") conditional_remove("{{ cookiecutter.notebooks }}" == "No", "notebooks") conditional_remove("{{ cookiecutter.notebooks }}" == "No", "doc/demo.nblink") -conditional_remove("{{ cookiecutter.commandlineinterface }}" == "No", "{{ cookiecutter|modname }}/__main__.py") +conditional_remove("{{ cookiecutter.commandlineinterface }}" == "No", "src/{{ cookiecutter|modname }}/__main__.py") conditional_remove("{{ cookiecutter.commandlineinterface }}" == "No", "tests/test_cli.py") conditional_remove(os.stat("TODO.md").st_size == 0, "TODO.md") diff --git a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml index 3133982..4cdee23 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml @@ -21,24 +21,24 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] # Here, we are testing the oldest and the newest supported Python version. # If this is insufficient for your package, consider adding more versions. - python-version: ["3.8", "3.12"] + python-version: ["3.10", "3.13"] steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: # setuptools_scm requires a non-shallow clone of the repository fetch-depth: 0 - name: Set up Python ${{ "{{ matrix.python-version }}" }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ "{{ matrix.python-version }}" }} - name: Install Python package run: | python -m pip install .[tests] - + - name: Run Python tests run: | python -m pytest{% if cookiecutter.notebooks == "Yes" %} --nbval{% endif %} @@ -49,9 +49,9 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: "3.13" diff --git a/{{cookiecutter.project_slug}}/.gitlab-ci.yml b/{{cookiecutter.project_slug}}/.gitlab-ci.yml index f52e65d..f16d1eb 100644 --- a/{{cookiecutter.project_slug}}/.gitlab-ci.yml +++ b/{{cookiecutter.project_slug}}/.gitlab-ci.yml @@ -3,14 +3,11 @@ - python -m pip install .[tests] - python -m pytest{% if cookiecutter.notebooks == "Yes" %} --nbval{% endif %} -test-{{ cookiecutter|modname }}-python3.8: - image: python:3.8 +test-{{ cookiecutter|modname }}-python3.10: + image: python:3.10 <<: *template -test-{{ cookiecutter|modname }}-python3.9: - image: python:3.9 +test-{{ cookiecutter|modname }}-python3.13: + image: python:3.13 <<: *template -test-{{ cookiecutter|modname }}-python3.10: - image: python:3.10 - <<: *template diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index 18cf54c..be18e46 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -1,13 +1,16 @@ repos: - # Run Black - the uncompromising Python code formatter - - repo: https://github.com/psf/black - rev: 23.7.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.14.4 hooks: - - id: black-jupyter + # Run the linter + - id: ruff-check + args: [ --fix, --show-fixes ] + # Run the formatter + - id: ruff-format # Add some general purpose useful hooks - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v6.0.0 hooks: # Make sure that contained YAML files are well-formed - id: check-yaml @@ -24,7 +27,7 @@ repos: # Make sure that Jupyter notebooks under version control # have their outputs stripped before committing - repo: https://github.com/kynan/nbstripout - rev: 0.6.1 + rev: 0.8.1 hooks: - id: nbstripout files: ".ipynb" @@ -33,7 +36,7 @@ repos: # GitHub Actions Workflow linter - repo: https://github.com/rhysd/actionlint - rev: v1.6.25 + rev: v1.7.8 hooks: - id: actionlint {%- endif %} diff --git a/{{cookiecutter.project_slug}}/.readthedocs.yml b/{{cookiecutter.project_slug}}/.readthedocs.yml index 190aa1c..36ba997 100644 --- a/{{cookiecutter.project_slug}}/.readthedocs.yml +++ b/{{cookiecutter.project_slug}}/.readthedocs.yml @@ -1,9 +1,9 @@ version: 2 build: - os: ubuntu-20.04 + os: ubuntu-24.04 tools: - python: "3.9" + python: "3.13" sphinx: configuration: doc/conf.py @@ -13,4 +13,6 @@ formats: all python: install: - method: pip - path: .[docs] + path: . + extra_requirements: + - docs diff --git a/{{cookiecutter.project_slug}}/FILESTRUCTURE.md b/{{cookiecutter.project_slug}}/FILESTRUCTURE.md index 2f90b74..ba6c050 100644 --- a/{{cookiecutter.project_slug}}/FILESTRUCTURE.md +++ b/{{cookiecutter.project_slug}}/FILESTRUCTURE.md @@ -1,9 +1,9 @@ This is an explanation of the file structure that the cookiecutter generated for you: * Python source files: - * The Python package source files are located in the `{{ cookiecutter|modname }}` directory. + * The Python package source files are located in the `src/{{ cookiecutter|modname }}` directory. {%- if cookiecutter.commandlineinterface == "Yes" %} - * The file `{{ cookiecutter|modname }}.__main__.py` defines a command line interface that + * The file `src/{{ cookiecutter|modname }}.__main__.py` defines a command line interface that is accessible both as the command `{{ cookiecutter|modname }}` and via `python -m {{ cookiecutter|modname }}`. * `tests/test_cli.py` contains rudimentary testing of this CLI. @@ -33,9 +33,6 @@ This is an explanation of the file structure that the cookiecutter generated for * `pyproject.toml` is the central place for configuration of your Python package. It contains the project metadata, setuptools-specific information and the configuration for your toolchain (like e.g. `pytest`). - * `setup.py` is still required for editable builds, but you should not need to change it. - In the future, `setuptools` will support editable builds purely from `pyproject.toml` - configuration. * Configuration for CI/Code Analysis and documentation services {%- if cookiecutter.github_actions_ci %} * `.github/workflows/ci.yml` describes the Github Workflow for Continuous diff --git a/{{cookiecutter.project_slug}}/doc/Makefile b/{{cookiecutter.project_slug}}/doc/Makefile index b507a95..ed88099 100644 --- a/{{cookiecutter.project_slug}}/doc/Makefile +++ b/{{cookiecutter.project_slug}}/doc/Makefile @@ -17,4 +17,4 @@ help: # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/{{cookiecutter.project_slug}}/doc/demo.nblink b/{{cookiecutter.project_slug}}/doc/demo.nblink index cf1ae47..e0294ef 100644 --- a/{{cookiecutter.project_slug}}/doc/demo.nblink +++ b/{{cookiecutter.project_slug}}/doc/demo.nblink @@ -1,3 +1,3 @@ { "path": "../notebooks/demo.ipynb" -} \ No newline at end of file +} diff --git a/{{cookiecutter.project_slug}}/doc/index.rst b/{{cookiecutter.project_slug}}/doc/index.rst index 79fa608..3054caa 100644 --- a/{{cookiecutter.project_slug}}/doc/index.rst +++ b/{{cookiecutter.project_slug}}/doc/index.rst @@ -16,4 +16,4 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` -* :ref:`search` \ No newline at end of file +* :ref:`search` diff --git a/{{cookiecutter.project_slug}}/doc/intro.rst b/{{cookiecutter.project_slug}}/doc/intro.rst index e2618b8..97d4958 100644 --- a/{{cookiecutter.project_slug}}/doc/intro.rst +++ b/{{cookiecutter.project_slug}}/doc/intro.rst @@ -1 +1 @@ -.. mdinclude:: ../README.md \ No newline at end of file +.. mdinclude:: ../README.md diff --git a/{{cookiecutter.project_slug}}/notebooks/demo.ipynb b/{{cookiecutter.project_slug}}/notebooks/demo.ipynb index 4539a92..190623b 100644 --- a/{{cookiecutter.project_slug}}/notebooks/demo.ipynb +++ b/{{cookiecutter.project_slug}}/notebooks/demo.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "819be38a-921a-485a-8e1f-58daeadc14ac", + "id": "0", "metadata": {}, "source": [ "# Demo of the {{ cookiecutter|modname }} package" @@ -10,7 +10,7 @@ }, { "cell_type": "markdown", - "id": "55984bca-1e25-45f9-8c31-ce080b2cdcfb", + "id": "1", "metadata": {}, "source": [ "In the following we will demonstrate the {{ cookiecutter|modname }} package. It is currently capable of doing impressive things:" @@ -19,7 +19,7 @@ { "cell_type": "code", "execution_count": null, - "id": "89c489c7-9c94-43ee-9696-a4e56681fd8f", + "id": "2", "metadata": {}, "outputs": [], "source": [ @@ -29,7 +29,7 @@ { "cell_type": "code", "execution_count": null, - "id": "e2913ab6-3ae7-40ae-84ef-258bc757676c", + "id": "3", "metadata": {}, "outputs": [], "source": [ @@ -38,7 +38,7 @@ }, { "cell_type": "markdown", - "id": "eb8e87dc-5e78-4b1c-b880-a948658b13d9", + "id": "4", "metadata": {}, "source": [ "There you go: `1+1=2`!" diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 026570e..4a1a6e4 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -25,22 +25,22 @@ dynamic = ["version"] {%- else %} version = "0.0.1" {%- endif %} -requires-python = ">=3.8" +requires-python = ">=3.10" {%- if cookiecutter.license != "None" %} -license = { text = "{{ cookiecutter.license }}" } -{%- endif %} -classifiers = [ - "Programming Language :: Python :: 3", - "Operating System :: OS Independent", +license-files = ["LICEN[CS]E*"] {%- if cookiecutter.license == "MIT" %} - "License :: OSI Approved :: MIT License", +license = "MIT" {%- elif cookiecutter.license == "BSD-2" %} - "License :: OSI Approved :: BSD License", +license = "BSD-2-Clause" {%- elif cookiecutter.license == "GPL-3.0" %} - "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", +license = "GPL-3.0-only" {%- elif cookiecutter.license == "LGPL-3.0" %} - "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", +license = "LGPL-3.0-only" +{%- endif %} {%- endif %} +classifiers = [ + "Programming Language :: Python :: 3", + "Operating System :: OS Independent", ] dependencies = [ {%- if cookiecutter.commandlineinterface == "Yes" %} @@ -59,8 +59,6 @@ tests = [ docs = [ {%- if cookiecutter.notebooks == "Yes" %} "ipykernel", -{%- endif %} -{%- if cookiecutter.notebooks == "Yes" %} "nbsphinx", "nbsphinx-link", {%- endif %} @@ -77,10 +75,8 @@ docs = [ # The following section contains setuptools-specific configuration # options. For a full reference of available options, check the overview # at https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html -[tool.setuptools] -packages = [ - "{{ cookiecutter|modname }}", -] +[tool.setuptools.packages.find] +where = ["src"] {%- if cookiecutter.version_management == "setuptools_scm" %} # Configure setuptools_scm, which extracts the version number from @@ -89,7 +85,7 @@ packages = [ [tool.setuptools_scm] version_scheme = "post-release" local_scheme = "node-and-date" -write_to = "{{ cookiecutter|modname }}/_version.py" +write_to = "src/{{ cookiecutter|modname }}/_version.py" {%- endif %} # The following is the configuration for the pytest test suite diff --git a/{{cookiecutter.project_slug}}/setup.py b/{{cookiecutter.project_slug}}/setup.py deleted file mode 100644 index b024da8..0000000 --- a/{{cookiecutter.project_slug}}/setup.py +++ /dev/null @@ -1,4 +0,0 @@ -from setuptools import setup - - -setup() diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.__modname}}/__init__.py b/{{cookiecutter.project_slug}}/src/{{cookiecutter.__modname}}/__init__.py similarity index 95% rename from {{cookiecutter.project_slug}}/{{cookiecutter.__modname}}/__init__.py rename to {{cookiecutter.project_slug}}/src/{{cookiecutter.__modname}}/__init__.py index 4330ee1..fc80110 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.__modname}}/__init__.py +++ b/{{cookiecutter.project_slug}}/src/{{cookiecutter.__modname}}/__init__.py @@ -1,6 +1,6 @@ {%- if cookiecutter.version_management == "setuptools_scm" %} # The version file is generated automatically by setuptools_scm -from {{ cookiecutter|modname }}._version import version as __version__ +from {{ cookiecutter|modname }}._version import version as __version__ # noqa: F401 {%- else %} from importlib import metadata diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.__modname}}/__main__.py b/{{cookiecutter.project_slug}}/src/{{cookiecutter.__modname}}/__main__.py similarity index 100% rename from {{cookiecutter.project_slug}}/{{cookiecutter.__modname}}/__main__.py rename to {{cookiecutter.project_slug}}/src/{{cookiecutter.__modname}}/__main__.py