From 3cfcdd074790a9b101f2c14de02ef898e1371979 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Wed, 18 Feb 2026 17:42:40 -0800 Subject: [PATCH 1/9] Upgraded versions of Python for base image and for version matrix. --- .github/workflows/ci-workflow.yml | 11 +++-------- .github/workflows/test-runner.yml | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci-workflow.yml b/.github/workflows/ci-workflow.yml index 33f47f541e4..528105a1eec 100644 --- a/.github/workflows/ci-workflow.yml +++ b/.github/workflows/ci-workflow.yml @@ -6,7 +6,6 @@ name: Exercises check on: push: branches: - - master - main pull_request: @@ -19,7 +18,7 @@ jobs: - name: Set up Python uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 with: - python-version: 3.11.2 + python-version: 3.13.5 - name: Download & Install dependencies run: | @@ -53,7 +52,7 @@ jobs: needs: housekeeping strategy: matrix: - python-version: [3.7, 3.8, 3.9, 3.10.6, 3.11.2] + python-version: [3.10.6, 3.11.2, 3.12, 3.13.5] steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 @@ -61,12 +60,8 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Install dataclasses package - if: ${{ matrix.python-version == '3.6' }} - run: pip install dataclasses - - name: Install pytest - run: pip install pytest~=7.2.2 + run: pip install pytest~=8.4.0 - name: Check exercises run: | diff --git a/.github/workflows/test-runner.yml b/.github/workflows/test-runner.yml index f32c41b958a..c009ed1b820 100644 --- a/.github/workflows/test-runner.yml +++ b/.github/workflows/test-runner.yml @@ -8,7 +8,7 @@ on: jobs: test-runner: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 - name: Run test-runner From 564d68d37afc4274b206ff56a9b640bafc07daf3 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Wed, 18 Feb 2026 17:43:24 -0800 Subject: [PATCH 2/9] Upgraded refrences to supported Python versions and generally edited and updated links and docs. --- docs/ABOUT.md | 24 +++++++++++----------- docs/INSTALLATION.md | 15 +++++++------- docs/LEARNING.md | 30 ++++++++++++++++++---------- docs/PROBLEM-SOLVING.md | 8 ++++---- docs/RESOURCES.md | 22 +++++++++++---------- docs/TOOLS.md | 44 +++++++++++++++++++++++++++++++++++------ 6 files changed, 94 insertions(+), 49 deletions(-) diff --git a/docs/ABOUT.md b/docs/ABOUT.md index 6177394a518..8f06e20267a 100644 --- a/docs/ABOUT.md +++ b/docs/ABOUT.md @@ -20,14 +20,14 @@ Code can be written and executed from the command line, in an interactive interp The [zen of Python (PEP 20)][the zen of python] and [What is Pythonic?][what is pythonic] lay out additional philosophies and perspectives on the language. -Tests and tooling for this track currently support `3.7` - `3.11.2` (_tests_) and [`Python 3.11.2`][311-new-features] (_tooling_). -It is highly recommended that students upgrade to at least `Python 3.8`, as some features used by this track may not be supported in earlier versions. +Tests and tooling for this track currently support `3.10` - `3.13.5` (_tests_) and [`Python 3.13.5`][313-new-features] (_tooling_). +It is highly recommended that students upgrade to at least `Python 3.10`, as some features used by this track may not be supported in earlier versions. That being said, most of the exercises will work with `Python 3.6+`, or even earlier versions. But we don't guarantee support for versions not listed under [Active Python Releases][active-python-releases]. We will try to note when a feature is only available in a certain version. -Complete documentation for the current release of Python (3.11.x) can be found at [docs.python.org][python docs]. +Complete documentation for the current release of Python (3.13.x) can be found at [docs.python.org][python docs]. - [Python Tutorial][python tutorial] - [Python Library Reference][python library reference] @@ -37,8 +37,8 @@ Complete documentation for the current release of Python (3.11.x) can be found a - [Python Glossary of Terms][python glossary of terms] -[311-new-features]: https://docs.python.org/3/whatsnew/3.11.html -[active-python-releases]: https://www.python.org/downloads/ +[313-new-features]: https://docs.python.org/3/whatsnew/3.13.html +[active-python-releases]: https://devguide.python.org/versions/#full-chart [duck typing]: https://en.wikipedia.org/wiki/Duck_typing [dynamic typing in python]: https://stackoverflow.com/questions/11328920/is-python-strongly-typed [editors for python]: https://djangostars.com/blog/python-ide/ @@ -49,16 +49,16 @@ Complete documentation for the current release of Python (3.11.x) can be found a [peps]: https://www.python.org/dev/peps/ [psf membership]: https://www.python.org/psf/membership/ [psf]: https://www.python.org/psf/ -[python docs]: https://docs.python.org/3/ -[python faqs]: https://docs.python.org/3/faq/index.html +[python docs]: https://docs.python.org/3.13/ +[python faqs]: https://docs.python.org/3.13/faq/index.html [python for beginners]: https://www.python.org/about/gettingstarted/ [python glossary of terms]: https://docs.python.org/3/glossary.html -[python how tos]: https://docs.python.org/3/howto/index.html +[python how tos]: https://docs.python.org/3.13/howto/index.html [python is used extensively]: https://www.python.org/about/apps/ -[python language reference]: https://docs.python.org/3/reference/index.html -[python library reference]: https://docs.python.org/3/library/index.html -[python tutorial]: https://docs.python.org/3/tutorial/index.html -[significant indentation]: https://docs.python.org/3/reference/lexical_analysis.html#indentation +[python language reference]: https://docs.python.org/3.13/reference/index.html +[python library reference]: https://docs.python.org/3.13/library/index.html +[python tutorial]: https://docs.python.org/3.13/tutorial/index.html +[significant indentation]: https://docs.python.org/3.13/reference/lexical_analysis.html#indentation [the zen of python]: https://www.python.org/dev/peps/pep-0020/ [type hints]: https://docs.python.org/3/library/typing.html [what is pythonic]: https://blog.startifact.com/posts/older/what-is-pythonic.html diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md index 7be6910710d..d70d15153f7 100644 --- a/docs/INSTALLATION.md +++ b/docs/INSTALLATION.md @@ -14,24 +14,25 @@ Some quick links into the documentation by operating system: - [Windows][windows] Additionally, this Microsoft article on [installing Python on windows][python-on-windows] is helpful. - [Unix & Linux Systems][unix-and-linux] (_these largely work for MacOS as well_) -- [MacOS][macos] : **This is outdated.** - We recommend reviewing some of the methods outlined in the Real Python article [Installing Python][installing-python] or the articles by Brett Cannon linked above. +- [MacOS][macos] + We also recommend reviewing some of the methods outlined in the Real Python article [Installing Python][installing-python] or the articles by Brett Cannon linked above. -Exercism tests and tooling currently support `3.7` - `3.11.5` (_tests_) and [`Python 3.11.5`][311-new-features] (_tooling_). + +Exercism tests and tooling currently support `3.10` - `3.13.5` (_tests_) and [`Python 3.13.5`][313-new-features] (_tooling_). Exceptions to this support are noted where they occur. Most of the exercises will work with `Python 3.6+`, or even earlier versions. But we don't guarantee support for versions not listed under [Active Python Releases][active-python-releases]. -Please refer to the [Python 3.11.x documentation][3.11 docs] for what is currently supported. +Please refer to the [Python 3.13.x documentation][3.13 docs] for what is currently supported. -[3.11 docs]: https://docs.python.org/3.11/ -[311-new-features]: https://docs.python.org/3/whatsnew/3.11.html +[3.13 docs]: https://docs.python.org/3.13/ +[313-new-features]: https://docs.python.org/3/whatsnew/3.13.html [Python-three downloads]: https://www.python.org/downloads/ [active-python-releases]: https://www.python.org/downloads/ [helpful guide]: https://realpython.com/installing-python/ -[installing-python]: https://realpython.com/installing-python/#what-your-options-are_1 +[installing-python]: https://realpython.com/installing-python/ [macos]: https://docs.python.org/3/using/mac.html [python-m-pip]: https://snarky.ca/why-you-should-use-python-m-pip/ [python-on-windows]: https://docs.microsoft.com/en-us/windows/python/beginners diff --git a/docs/LEARNING.md b/docs/LEARNING.md index d71a95455cc..4a85339a936 100644 --- a/docs/LEARNING.md +++ b/docs/LEARNING.md @@ -13,14 +13,19 @@ Below you will find some additional jumping-off places to start your learning jo - [Python Documentation Tutorial][Python Documentation Tutorial] +- [Stanford Code in Place Course][code in place] +- [Stanford Code in Place Self-Guided][cip self guided] - [Automate the Boring Stuff with Python (_book_)][automate the boring stuff] -- [Automate the Boring Stuff Videos (_covers first 15 book chapters_)][automate the videos] +- [Automate the Boring Stuff with Python Workbook (_exercises_)][automate the boring stuff workbook] +- [Think Python][Think Python] +- [Beyond the Basic Stuff with Python][beyond the basics] +- [Beyond the Basic Stuff with Python Video][beyond the basics video] +- [Python Programming Exercises, Gently Explained][PPEG] +- [Python for Non-Programmers][python-for-non-programmers] - [Learn X in Y minutes (where X = Python3)][Learn X in Y minutes] - [Python at Free Code Camp][python at free code camp] +- [Python at Khan Academy][python at kahn academy] - [Intro to Python (_python-course.eu_)][python-course.eu] -- [Think Python][Think Python] -- [Python for Non-Programmers][python-for-non-programmers] -- [Python 4 Everyone][python4everyone] - [Googles Python Class][googles python class] - [Microsoft's Python Learning Path][MS Python] - [Introduction to Computer Science and Programming in Python (MIT)][mitocw600] @@ -30,14 +35,19 @@ Below you will find some additional jumping-off places to start your learning jo [CS50P]: https://pll.harvard.edu/course/cs50s-introduction-programming-python?delta=0 [Learn X in Y minutes]: https://learnxinyminutes.com/docs/python3/ [MS Python]: https://docs.microsoft.com/en-us/learn/paths/python-language/ +[PPEG]: https://inventwithpython.com/pythongently/ [Python Documentation Tutorial]: https://docs.python.org/3/tutorial/index.html -[Python at Free Code Camp]: https://www.freecodecamp.org/learn/scientific-computing-with-python/ -[Think Python]: http://www.greenteapress.com/thinkpython/html/index.html -[automate the boring stuff]: https://automatetheboringstuff.com/2e/ -[automate the videos]: https://www.youtube.com/watch?v=1F_OgqRuSdI&list=PL0-84-yl1fUnRuXGFe_F7qSH1LEnn9LkW -[googles python class]: https://developers.google.com/edu/python/introduction +[Python at Free Code Camp]: https://www.freecodecamp.org/learn/python-v9/ +[Think Python]: https://allendowney.github.io/ThinkPython/ +[automate the boring stuff workbook]: https://automatetheboringstuff.com/#toc +[automate the boring stuff]: https://automatetheboringstuff.com/#toc +[beyond the basics video]: https://www.youtube.com/watch?v=kSrnLbioN6w +[beyond the basics]: https://inventwithpython.com/beyond/ +[cip self guided]: https://codeinplace.stanford.edu/public/studenthome +[code in place]: https://codeinplace.stanford.edu/ +[googles python class]: https://developers.google.com/edu/python [mitocw600]: https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/ +[python at kahn academy]: https://www.khanacademy.org/computing/intro-to-python-fundamentals [python-course.eu]: https://python-course.eu/python-tutorial/ [python-for-non-programmers]: https://store.lerner.co.il/python-for-non-programmers-live -[python4everyone]: https://www.py4e.com/ [wikipython]: https://en.wikipedia.org/wiki/Python_(programming_language) diff --git a/docs/PROBLEM-SOLVING.md b/docs/PROBLEM-SOLVING.md index 198b9ea5ef9..47a99e8a8ab 100644 --- a/docs/PROBLEM-SOLVING.md +++ b/docs/PROBLEM-SOLVING.md @@ -8,9 +8,9 @@ Below are some community-sourced articles, videos, and books that can help you d - Free Code Camp offers a good overview article on [How to Think Like a Programmer - Lessons in Problem-Solving][free-code-camp-think-like-a-programmer]. -- Kurtis Pykes writing for Towards Data Science has a nice [hands-on tutorial for problem-solving][Kurtis Pykes: Hands-on Tutorial - How to Improve Your Problem-Solving Skills as A Programmer]. -- UC Berkeley has a nice PDF summary of [G. Polya's Problem Solving Techniques][g-polya-how-to-solve-it-summary]. +- Jeremy Howard, founder of fast.ai has a nice summary of [G. Polya's Problem Solving Techniques][g-polya-how-to-solve-it-summary]. - Originally written in 1945 as guidance for tackling complicated math problems,[G. Polya's How To Solve It][g-polya-how-to-solve-it] (full book) is still _excellent_ advice for problem-solving in general. +- Kurtis Pykes writing for Towards Data Science has a nice [hands-on tutorial for problem-solving][Kurtis Pykes: Hands-on Tutorial - How to Improve Your Problem-Solving Skills as A Programmer]. - Mentioned in the Free Code Camp Article, V. Anton Spraul's [Think Like a Programmer: An Introduction to Creative Problem Solving][v-anton-spraul-think-like-a-programmer] is a more modern and programming-focused take on the same general methods Polya outlines for mathematics. - [Felienne Hermans][felienne-hermans] is more focused on _how_ people learn the art of coding and how that maps to learning in general. She has written [The Programmers Brian][programmers-brain-free-online], with strategies for reading code better, thinking about code clearly, writing better code, and becoming a better code collaborator. @@ -32,8 +32,8 @@ Membership (paid) information is available at [acm(dot)org][association-for-comp [felienne-hermans-programming-is-writing-is-programming]: https://www.youtube.com/watch?v=uO3a4HIBDU4 [felienne-hermans]: https://www.felienne.com/ [free-code-camp-think-like-a-programmer]: https://www.freecodecamp.org/news/how-to-think-like-a-programmer-lessons-in-problem-solving-d1d8bf1de7d2/ -[g-polya-how-to-solve-it-summary]: https://math.berkeley.edu/~gmelvin/polya.pdf -[g-polya-how-to-solve-it]: https://press.princeton.edu/books/paperback/9780691164076/how-to-solve-it +[g-polya-how-to-solve-it-summary]: https://gist.github.com/jph00/d60301884c56fe063101a7cc6193b3af +[g-polya-how-to-solve-it]: https://archive.org/details/howtosolveit0000gpol_c0p2/page/n9/mode/2up [paul-vickers-how-to-think-like-a-programmer]: https://www.researchgate.net/publication/236270907_How_to_Think_like_a_Programmer_Problem_Solving_for_the_Bewildered [programmers-brain-free-online]: https://www.manning.com/books/the-programmers-brain#toc [programmers-brain-manning]: https://www.manning.com/books/the-programmers-brain diff --git a/docs/RESOURCES.md b/docs/RESOURCES.md index ea8527592ab..f04fcf601d0 100644 --- a/docs/RESOURCES.md +++ b/docs/RESOURCES.md @@ -5,24 +5,26 @@ - [The Docs on pip][pip] - [Tall, Snarky Canadian (_The Blog of Core Python Developer Brett Cannon_)][Tall, Snarky Canadian] - [Practical Python][practical python] -- [Python 3 Module of the Week (PyMOTW-3)][pymotw-3] -- [Beyond the Basic Stuff with Python][Beyond the Basic Stuff with Python] -- [The Big Book of Small Python Projects][The Big Book of Small Python Projects] - [Data Structures and Information Retrieval in Python][Data Structures and Information Retrieval in Python] -- [python practice projects][python practice projects] -- [Python Courses eu][python-course.eu main] -- [Fluent Python Notebooks][fluent-notebooks] +- [Fluent Python, 2nd Edition][Fluent Python 2] (_you might be able to find free access through a library or online_) +- [Fluent Python Notebooks][fluent-notebooks] (_these are based on the first edition, but still really good_) +- [The Big Book of Small Python Projects][The Big Book of Small Python Projects] +- [Practice Python Projects][practice python projects] +- [Dataquest: Python Projects for Beginners][Python projects for beginners] +- [Mouse vs Python (Mike Driscoll's blog)][mouse vs python] +- [Simon Willison's Weblog][simon willison] -[Beyond the Basic Stuff with Python]: https://inventwithpython.com/beyond/ [Data Structures and Information Retrieval in Python]: https://allendowney.github.io/DSIRP/ [Practical Python]: https://dabeaz-course.github.io/practical-python/ +[Python projects for beginners]: https://www.dataquest.io/blog/python-projects-for-beginners/ [Tall, Snarky Canadian]: https://snarky.ca/ [The Big Book of Small Python Projects]: http://inventwithpython.com/bigbookpython/ [The Python Library Reference]: https://docs.python.org/3/library/index.html +[fluent python 2]: https://www.oreilly.com/library/view/fluent-python-2nd/9781492056348/ [fluent-notebooks]: https://github.com/AllenDowney/fluent-python-notebooks +[mouse vs python]: https://www.blog.pythonlibrary.org/ [pip]: https://pip.pypa.io/en/stable/user_guide/ -[pymotw-3]: https://pymotw.com/3/ +[practice python projects]: https://learnbyexample.github.io/practice_python_projects/preface.html [python docs]: https://docs.python.org/3/ -[python practice projects]: http://pythonpracticeprojects.com/ -[python-course.eu main]: https://python-course.eu/ +[simon willison]: https://simonwillison.net/ diff --git a/docs/TOOLS.md b/docs/TOOLS.md index bacb8626aaa..11713826c14 100644 --- a/docs/TOOLS.md +++ b/docs/TOOLS.md @@ -15,6 +15,7 @@ If you have an editor, IDE, tool, or plugin recommendation, we encourage you to - [Environments](#virtual-environments) - [Venv](#creating-a-virtual-environment-with-venv) - [Conda](#creating-a-virtual-environment-using-conda) + - [uv](#uv) - [Virtual Environment Wrapper](#virtual-environment-wrapper) - [Editors and IDEs](#editors-and-ides) - [Visual Studio Code](#visual-studio-code) @@ -30,9 +31,9 @@ If you have an editor, IDE, tool, or plugin recommendation, we encourage you to Before you start exploring, make sure that you have a recent version of Python installed. -The Exercism web platform currently supports `Python 3.7 - 3.11.5` (_exercises and tests_) and `Python 3.11.5` (_tooling_). -Our online test runner currently uses `pytest 7.2.2` and `pytest-subtests 0.11.0`. -Our online analyzer uses `pylint 2.17.7`. +The Exercism web platform currently supports `Python 3.10 - 3.13.5` (_exercises and tests_) and `Python 3.13.5` (_tooling_). +Our online test runner currently uses `pytest 8.4.0` and `pytest-subtests 0.14.2`. +Our online analyzer uses `pylint 4.0.4`. Using different versions of `Python`, `pytest`, or `pylint` locally might give you different results than the website. For more information, please refer to [Installing Python locally][Installing Python locally]. @@ -45,10 +46,16 @@ Python virtual environments offer lightweight runtime and package isolation. Different environments can hold different versions of the Python runtime together with any project or library dependencies. This helps avoid bugs and incompatibilities caused by upgrading a library for one project that "breaks" a dependency in a different one. -There are two major *virtual environment* tools in use today, the Python standard library [`venv`][venv] and the third-party [`conda env`][condaenv], using the [`conda`][conda] package manager and (_usually_) the Anaconda Python distribution. -Both of are straightforward to use and/or install. +There are many *virtual environment* and *virtual environment-like* tools in use today, and a growing movement to use [inline script metadata][PEP723], [dev containers][dev containers], or [docker][docker] instead of virtual environments. +It is important to try out different strategies and find one that suits your development style and project needs. +Don't assume that the strategies here are one-size-fits all, or are your only options. +For a more general rundown of tools not covered here, check out [this blog post by Bas Nijholt][bas nihholt] and stay curious. -Additionally, [`PyEnv`][pyenv] and [virtualenvwrapper][virtualenvwrapper] are tools that can help to manage multiple versions of Python and multiple Python environments on the same machine. + +There are three major *virtual environment* tools we'll cover here, the Python standard library [`venv`][venv], the third-party [`conda env`][condaenv], using the [`conda`][conda] package manager and (_usually_) the Anaconda Python distribution, and the third-party `pip` + `venv` replacement [`uv`][uv]. +All three are fairly straightforward to use and/or install. + +Additionally, [`PyEnv`][pyenv], [`Poetry`][poetry], and [virtualenvwrapper][virtualenvwrapper] are tools that can help to manage multiple versions of Python and multiple Python environments on the same machine.
@@ -208,6 +215,19 @@ Executing transaction: done
+### UV + +Working on Projects with uv: [uv][uv-docs] + +`uv` is a Python package + project management tool from [Astral][astral] written in [Rust][rust programming language]. +It was designed to replace `pip`, `venv`, `poetry`, and other Python packaging/dependency management tools. +Unlike `Conda` or `Mamba`, uv is specialized/tailored to only Python. + However, uv does support building Python extension modules written in other languages such as Fortran. +Astral is also the developer of the popular [Ruff][ruff] linter and [TY][ty], a static type checker for Python type hints, both written in Rust. + + +Rather than go into detail here, the [UV documentation][uv documentation] is your best source for installation and setup. + ### Virtual Environment wrapper Documents and background: [virtualenvwrapper][virtualenvwrapper]. @@ -369,14 +389,19 @@ You can also [develop plugins][sublime plugin development] of your own for the e [Installing Python locally]: https://exercism.org/docs/tracks/Python/installation [MS Python extension]: https://marketplace.visualstudio.com/items?itemName=ms-python.python +[PEP723]: https://packaging.python.org/en/latest/specifications/inline-script-metadata/#inline-script-metadata [anaconda]: https://www.anaconda.com/products/individual +[astral]: https://astral.sh/about [atom]: https://atom.io/ +[bas nihholt]: https://www.nijho.lt/post/python-environments/ [conda command ref]: https://docs.conda.io/projects/conda/en/latest/commands.html#conda-vs-pip-vs-virtualenv-commands [conda-cheatsheet]: https://docs.conda.io/projects/conda/en/latest/_downloads/843d9e0198f2a193a3484886fa28163c/conda-cheatsheet.pdf [conda-docs]: https://docs.conda.io/projects/conda/en/latest/user-guide/index.html [conda]: https://docs.conda.io/projects/conda/en/latest/index.html [condaenv]: https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html +[dev containers]: https://andypickup.com/developing-in-python-with-dev-containers-part-1-setup-f1aeb89cbfed [docker in vscode]: https://code.visualstudio.com/docs/containers/overview +[docker]: https://www.docker.com/blog/containerized-python-development-part-1/ [emacs at fullstack python]: https://www.fullstackpython.com/emacs.html [emacs setup at real python]: https://realpython.com/emacs-the-best-python-editor [emacs wiki python programming]: https://www.emacswiki.org/emacs/PythonProgrammingInEmacs#h5o-4 @@ -390,6 +415,7 @@ You can also [develop plugins][sublime plugin development] of your own for the e [linting python in vscode]: https://code.visualstudio.com/docs/python/linting [miniconda]: https://docs.conda.io/en/latest/miniconda.html [opensource spacemacs guide]: https://opensource.com/article/19/12/spacemacs +[poetry]: https://github.com/python-poetry/poetry [pycharm config venv]: https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html [pycharm database tools]: https://www.jetbrains.com/help/pycharm/relational-databases.html [pycharm debug configuration]: https://www.jetbrains.com/help/pycharm/run-debug-configuration-py-test.html @@ -407,6 +433,8 @@ You can also [develop plugins][sublime plugin development] of your own for the e [python testing in vscode]: https://code.visualstudio.com/docs/python/testing [python web dev in vscode]: https://code.visualstudio.com/docs/python/tutorial-django [rtorr vim cheat sheet]: https://vim.rtorr.com/ +[ruff]: https://docs.astral.sh/ruff/ +[rust programming language]: https://rust-lang.org/ [spacemacs github repo]: https://github.com/syl20bnr/spacemacs [spacemacs official docs]: https://github.com/syl20bnr/spacemacs#documentation [spacemacs python layer]: https://www.spacemacs.org/layers/+lang/python/README.html @@ -434,6 +462,10 @@ You can also [develop plugins][sublime plugin development] of your own for the e [sublime support docs]: https://www.sublimetext.com/support [sublime text 4]: https://www.sublimetext.com/ [sublime text at real python]: https://realpython.com/setting-up-sublime-text-3-for-full-stack-python-development/ +[ty]: https://docs.astral.sh/ty/ +[uv documentation]: https://docs.astral.sh/uv/getting-started/ +[uv-docs]: https://docs.astral.sh/uv/guides/projects/#working-on-projects +[uv]: https://github.com/astral-sh/uv [venv wrapper tutorial]: https://virtualenvwrapper.readthedocs.io/en/latest/plugins.html#plugins [venv]: https://docs.python.org/3.9/tutorial/venv.html [vim cheat sheet]: https://vimsheet.com/ From 8e5266958f36ca1494458ae5f0d22386e39557bd Mon Sep 17 00:00:00 2001 From: BethanyG Date: Wed, 18 Feb 2026 17:44:08 -0800 Subject: [PATCH 3/9] Updated doc to reflect new fixes and changes in representer code. --- exercises/shared/.docs/representations.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/exercises/shared/.docs/representations.md b/exercises/shared/.docs/representations.md index 8439ca9aab4..ec803d01dc8 100644 --- a/exercises/shared/.docs/representations.md +++ b/exercises/shared/.docs/representations.md @@ -7,7 +7,7 @@ The [Python representer][representer] processes and normalizes student solutions - For troubleshooting purposes, `representation.out` includes starting AST, edited AST, and a code representation with normalizations applied. - Removals: - - typehints + - typehints (_including typehints in dataclasses, see Normalizations below_) - `print()` statements - `if __name__ == __main__` blocks - comments @@ -28,6 +28,8 @@ The [Python representer][representer] processes and normalizes student solutions - **1e2+1_23e0+4.4e-1** --> 100.0 + 123.0 + 0.44 #223.44 - **7e6+7e5+5e4+9.98e2+4.45_779e-1** -->7000000.0 + 700000.0 + 50000.0 + 998.0 + 0.445779 #7750998.445779 - **(7e6+7e5+5e4+9.98e1+4.457_79e-1)+(1e2+1.23e1+4.444_23e-1)*1*j** --> (7000000.0 + 700000.0 + 50000.0 + 99.8 + 0.445779 + (100.0 + 12.3 + 0.444423) * 1j) #7750100.245779+112.744423j + - functions and classes that have empty bodies after docstring removal have `pass` assigned to the body. + - dataclasses that have type hinted but unassigned data members have those data members assigned `None` as a value. See the docstring starting on line 153 of normalizer.py for more details. [representer]: https://github.com/exercism/python-representer/tree/main/representer [python-ast]: https://docs.python.org/3/library/ast.html#module-ast From daa9b93e138659e483929453fe238773a39f47c2 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Wed, 18 Feb 2026 17:45:27 -0800 Subject: [PATCH 4/9] Updated refrences to supported Python versions and changes to tooling and linting. --- CONTRIBUTING.md | 23 +++++++++++------------ README.md | 6 +++--- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d9c30d85e0a..6ff557f7087 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,9 +32,9 @@ Hi.  ๐Ÿ‘‹๐Ÿฝ  ๐Ÿ‘‹  **We are happy you are here.**  ๐ŸŽ‰&nb **`exercism/Python`** is one of many programming language tracks on [exercism(dot)org][exercism-website]. This repo holds all the instructions, tests, code, & support files for Python _exercises_ currently under development or implemented & available for students. -๐ŸŒŸ   Track exercises support Python `3.7` - `3.11.5`. +๐ŸŒŸ   Track exercises support Python `3.10` - `3.13.5`. Exceptions to this support are noted where they occur. -๐ŸŒŸ   Track tooling (_test-runner, representer, analyzer, and Continuous Integration_) runs on Python `3.11.2`. +๐ŸŒŸ   Track tooling (_test-runner, representer, analyzer, and Continuous Integration_) runs on Python `3.13.5`. Exercises are grouped into **concept** exercises which teach the [Python syllabus][python-syllabus], and **practice** exercises, which are unlocked by progressing in the syllabus tree  ๐ŸŒด . Concept exercises are constrained to a small set of language or syntax features. @@ -71,15 +71,14 @@ We're leaving the track contributing docs below for our long-term collaborators

In General


-- Maintainers are happy to review your work and help troubleshoot with you. ๐Ÿ’› ๐Ÿ’™  +- Maintainers are happy to review your work and help troubleshoot with you. ๐Ÿ’› ๐Ÿ’™  If you need help, comment in the Pull Request/issue.  ๐Ÿ™‹๐Ÿฝโ€โ™€๏ธ   + - **Please wait at least 72 hours before pinging or `@`ing reviewers directly.** - Requests are reviewed as soon as is practical/possible. - - (โ— ) Reviewers may be in a different timezone โŒš , or tied up  ๐Ÿงถ  with other tasks. - - **Please wait at least 72 hours before pinging.** -- If you need help, comment in the Pull Request/issue.  ๐Ÿ™‹๐Ÿฝโ€โ™€๏ธ   + - (โ— ) Keep in mind that reviewers may be in a different timezone โŒš , or tied up  ๐Ÿงถ  with other tasks. - If you would like in-progress feedback/discussion, please mark your Pull Request as a **`[draft]`** - Pull Requests should be focused around a single exercise, issue, or change. - Pull Request titles and descriptions should make clear **what** has changed and **why**. - - Please link  ๐Ÿ”—  to any related issues the PR addresses. + - Please link  ๐Ÿ”—  to any related forum discussions or issues the PR addresses. - ๐Ÿ“› [ Open an issue ][open-an-issue]๐Ÿ“›  and discuss it with  ๐Ÿงฐ  maintainers _**before**_: - creating a Pull Request making significant or breaking changes. - for changes across multiple exercises, even if they are typos or small. @@ -204,13 +203,13 @@ _We know it, and trust us, we are working on fixing it._ But if you see  
-This track officially supports Python `3.7 - 3.11.2` for students completing exercises. -The track `test runner`, `analyzer`, and `representer` run in docker on `python:3.11.2-slim`. +This track officially supports Python `3.10 - 3.13.5` for students completing exercises. +The track `test runner`, `analyzer`, and `representer` run in docker on `python:3.13.5-alpine3.22`. Although the majority of test cases are written using `unittest.TestCase`, -- All exercises should be written for compatibility with Python `3.7` - `3.11.2`. -- Version backward _incompatibility_ (_e.g_ an exercise using features introduced in `3.8`, `3.9`, or `3.10`) should be clearly noted in any exercise hints, links, introductions or other notes. +- All exercises should be written for compatibility with Python `3.10` - `3.13.5`. +- Version backward _incompatibility_ (_e.g_ an exercise using features introduced in Python `3.10`+ that would not work in Python `3.10`) should be clearly noted in any exercise hints, links, introductions or other notes. - Here is an example of how the Python documentation handles [version-tagged  ๐Ÿท ][version-tagged-language-features] feature introduction. @@ -231,7 +230,7 @@ Although the majority of test cases are written using `unittest.TestCase`, - For specifications, refer to [Concept Exercise Anatomy][concept-exercise-anatomy], or [Practice Exercise Anatomy][practice-exercise-anatomy] depending on which type of exercise you are contributing to. -- **Practice exercise**, descriptions and instructions come from a centralized, cross-track [problem specifications][problem-specifications] repository. +- **Practice exercise** descriptions and instructions come from a centralized, cross-track [problem specifications][problem-specifications] repository. - Any updates or changes need to be proposed/approved in `problem-specifications` first. - If Python-specific changes become necessary, they need to be appended to the canonical instructions by creating a `instructions.append.md` file in this (`exercism/Python`) repository. diff --git a/README.md b/README.md index f3d083aab42..fd9be64f715 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,9 @@ Hi.  ๐Ÿ‘‹๐Ÿฝ  ๐Ÿ‘‹  **We are happy you are here.**  ๐ŸŽ‰&nb **`exercism/Python`** is one of many programming language tracks on [exercism(dot)org][exercism-website]. This repo holds all the instructions, tests, code, & support files for Python _exercises_ currently under development or implemented & available for students. -๐ŸŒŸ   Track exercises support Python `3.7` - `3.11.5`. +๐ŸŒŸ   Track exercises support Python `3.10` - `3.13.5`. Exceptions to this support are noted where they occur. -๐ŸŒŸ   Track tooling (_test-runner, representer, analyzer, and Continuous Integration_) runs on Python `3.11.5`. +๐ŸŒŸ   Track tooling (_test-runner, representer, analyzer, and Continuous Integration_) runs on Python `3.13.5`. Exercises are grouped into **concept** exercises which teach the [Python syllabus][python-syllabus], and **practice** exercises, which are unlocked by progressing in the syllabus tree  ๐ŸŒด . Concept exercises are constrained to a small set of language or syntax features. @@ -84,7 +84,7 @@ _Thoughtful suggestions will likely result in faster & more enthusiastic respons ## Python Software and Documentation -**Copyright ยฉ 2001-2025 Python Software Foundation. All rights reserved.** +**Copyright ยฉ 2001-2026 Python Software Foundation. All rights reserved.** Python software and documentation are licensed under the [PSF License Agreement][psf-license]. From a61c9ec1a82adbf99a81bf00ad730ea49a4f2f69 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Wed, 18 Feb 2026 17:46:00 -0800 Subject: [PATCH 5/9] Updated lnks and refrences. --- exercises/shared/.docs/help.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exercises/shared/.docs/help.md b/exercises/shared/.docs/help.md index ef95bd6193b..f4114f8b2cb 100644 --- a/exercises/shared/.docs/help.md +++ b/exercises/shared/.docs/help.md @@ -3,13 +3,13 @@ Below are some resources for getting help if you run into trouble: - [The PSF](https://www.python.org) hosts Python downloads, documentation, and community resources. +- [Python Community Forums](https://discuss.python.org/) help, PEP discussion, core Python committers, and more. - [The Exercism Community on Discord](https://exercism.org/r/discord) +- [The Exercism Community Discussion Forums](https://forum.exercsim.org) - [Python Community on Discord](https://pythondiscord.com/) is a very helpful and active community. - [/r/learnpython/](https://www.reddit.com/r/learnpython/) is a subreddit designed for Python learners. - [#python on Libera.chat](https://www.python.org/community/irc/) this is where the core developers for the language hang out and get work done. -- [Python Community Forums](https://discuss.python.org/) - [Free Code Camp Community Forums](https://forum.freecodecamp.org/) -- [CodeNewbie Community Help Tag](https://community.codenewbie.org/t/help) - [Pythontutor](http://pythontutor.com/) for stepping through small code snippets visually. Additionally, [StackOverflow](http://stackoverflow.com/questions/tagged/python) is a good spot to search for your problem/question to see if it has been answered already. From 054d80d51935da1c4b9a5569d1a3c99e6862b8d3 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Wed, 18 Feb 2026 17:46:51 -0800 Subject: [PATCH 6/9] Updated pylintrc to match the analyzer pylintrc. Updated libs and python versions in requirements. --- pylintrc | 522 ++++++++++++++++++------------------- requirements-generator.txt | 13 +- requirements.txt | 12 +- 3 files changed, 262 insertions(+), 285 deletions(-) diff --git a/pylintrc b/pylintrc index 09795978bc4..4c362789429 100644 --- a/pylintrc +++ b/pylintrc @@ -2,373 +2,345 @@ # This pylintrc file contains a best-effort configuration to uphold the # best-practices and style for the Python track of exercism.org. # -# It is based on the Google pylintrc & the Google Python style guide: -# https://google.github.io/styleguide/pyguide.html, -# https://google.github.io/styleguide/pylintrc +# It is based on the default pylint rc with enabled extensions, and is the same +# pylintrc file used in our generic Analyzer. # -# Additions & alterations to the Google Style guide are noted in +# Additions & alterations to the base configuration are noted in # the Exercism Python Track contributing guide: # https://github.com/exercism/python/blob/main/CONTRIBUTING.md ########################################################################### -[MASTER] +[MAIN] -# Files or directories to be skipped. They should be base names, not paths. +analyse-fallback-blocks=no +clear-cache-post-run=yes +extension-pkg-allow-list= +extension-pkg-whitelist= ignore=third_party - -# Files or directories matching the regex patterns are skipped. The regex -# matches against base names, not paths. -ignore-patterns= - -# Pickle collected data for later comparisons. -persistent=no - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - -# Use multiple processes to speed up Pylint. jobs=4 - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. +limit-inference-results=100 unsafe-load-any-extension=no +persistent=no +prefer-stubs=no +recursive=no +# Specify a score threshold under which the program will exit with error. +fail-under=10 -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED -confidence= - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -#enable= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once).You can also use "--disable=all" to -# disable everything first and then re-enable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use"--disable=all --enable=classes -# --disable=W" -# As of Pylint 2.6+, the following options are not supported, so they're commented out: -# -# misplaced-comparison-constant -# relative-import -# input-builtin -# inconsistent-return-statements -# no-absolute-import -# raising-string -# round-builtin - -disable=arguments-differ, - attribute-defined-outside-init, - fixme, - global-statement, - implicit-str-concat-in-sequence, - import-error, - import-self, - locally-disabled, - no-else-break, - no-else-continue, - no-else-raise, - no-else-return, - no-member, - no-name-in-module, - signature-differs, - suppressed-message, - too-many-boolean-expressions, - too-many-branches, - too-many-locals, - too-many-public-methods, - too-many-return-statements, - too-many-statements, - unnecessary-pass, - unused-argument, - useless-suppression - - -[REPORTS] - -# Set the output format. Available formats are text, parseable, colorized, msvs -# (visual studio) and html. You can also give a reporter class, eg -# mypackage.mymodule.MyReporterClass. -output-format=colorized - -# Tells whether to display a full report or only the messages -reports=no - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details -#msg-template= +# List of plugins (as comma separated values of python module names) to load, +# usually to register additional checkers. +load-plugins = pylint.extensions.bad_builtin, + # pylint.extensions.code_style, + pylint.extensions.comparison_placement, + pylint.extensions.consider_refactoring_into_while_condition, + # pylint.extensions.docparams, + pylint.extensions.dunder, + pylint.extensions.eq_without_hash, + pylint.extensions.for_any_all, + # pylint.extensions.mccabe, + pylint.extensions.no_self_use, + pylint.extensions.overlapping_exceptions, + pylint.extensions.private_import, + pylint.extensions.redefined_loop_name, + pylint.extensions.set_membership, [BASIC] -# Good variable names which should always be accepted, separated by a comma -good-names=main,_ - -# Bad variable names which should always be refused, separated by a comma -bad-names=x,y,i,l - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Include a hint for the correct naming format with invalid-name -include-naming-hint=no +module-naming-style=snake_case +const-naming-style=UPPER_CASE +variable-naming-style=snake_case +function-naming-style=snake_case +argument-naming-style=snake_case +attr-naming-style=snake_case +class-naming-style=PascalCase +class-attribute-naming-style=any +class-const-naming-style=UPPER_CASE +method-naming-style=snake_case +inlinevar-naming-style=snake_case + +# Include a hint for the correct naming format with invalid-name. +include-naming-hint=yes + +# Bad variable names which should always be refused, separated by a comma. +bad-names=x, + y, + i, + l, + a, + b, + j, + o, + z + +# Good variable names which should always be accepted, separated by a comma. +good-names=main, # List of decorators that produce properties, such as abc.abstractproperty. Add # to this list to register other decorators that produce valid properties. -property-classes=abc.abstractproperty,cached_property.cached_property,cached_property.threaded_cached_property,cached_property.cached_property_with_ttl,cached_property.threaded_cached_property_with_ttl - -# Regular expression matching correct function names -function-rgx=^(?:(?PsetUp|tearDown|setUpModule|tearDownModule)|(?P_?[A-Z][a-zA-Z0-9]*)|(?P_?[a-z][a-z0-9_]*))$ - -# Regular expression matching correct variable names -variable-rgx=^[a-z][a-z0-9_]*$ +# These decorators are taken in consideration only for invalid-name. +property-classes=abc.abstractproperty, + cached_property.cached_property, + cached_property.threaded_cached_property, + cached_property.cached_property_with_ttl, + cached_property.threaded_cached_property_with_ttl -# Regular expression matching correct constant names -const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$ - -# Regular expression matching correct attribute names -attr-rgx=^_{0,2}[a-z][a-z0-9_]*$ - -# Regular expression matching correct argument names -argument-rgx=^[a-z][a-z0-9_]*$ +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=5 -# Regular expression matching correct class attribute names -class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$ +# Bad variable names regexes, separated by a comma. If names match any regex, +# they will always be refused +bad-names-rgxs=^.{1,2}$ -# Regular expression matching correct inline iteration names -inlinevar-rgx=^[a-z][a-z0-9_]*$ +# Good variable names regexes, separated by a comma. If names match any regex, +# they will always be accepted +good-names-rgxs= -# Regular expression matching correct class names -class-rgx=^_?[A-Z][a-zA-Z0-9]*$ -# Regular expression matching correct module names -module-rgx=^(_?[a-z][a-z0-9_]*|__init__)$ +[CLASSES] -# Regular expression matching correct method names -method-rgx=(?x)^(?:(?P_[a-z0-9_]+__|runTest|setUp|tearDown|setUpTestCase|tearDownTestCase|setupSelf|tearDownClass|setUpClass|(test|assert)_*[A-Z0-9][a-zA-Z0-9_]*|next)|(?P_{0,2}[A-Z][a-zA-Z0-9_]*)|(?P_{0,2}[a-z][a-z0-9_]*))$ +check-protected-access-in-special-methods=no +defining-attr-methods=__init__, + __new__, + setUp -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=(__.*__|main|test.*|.*test|.*Test)$ +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=10 +valid-classmethod-first-arg=cls, + class_ +valid-metaclass-classmethod-first-arg=mcs -[TYPECHECK] -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager,contextlib2.contextmanager +[DESIGN] -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes +max-args=5 +max-attributes=7 +max-bool-expr=5 +max-branches=12 +max-locals=15 +max-parents=7 +max-positional-arguments=5 +max-public-methods=20 +max-returns=6 +max-statements=50 +min-public-methods=2 -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis. It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local +[EXCEPTIONS] -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= +# Exceptions that will emit a warning when caught. +overgeneral-exceptions=StandardError, + Exception, + BaseException [FORMAT] +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + # Maximum number of characters on a single line. max-line-length=120 -# TODO(https://github.com/PyCQA/pylint/issues/3352): Direct pylint to exempt -# lines made too long by directives to pytype. - # Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=(?x)( - ^\s*(\#\ )??$| - ^\s*(from\s+\S+\s+)?import\s+.+$) +ignore-long-lines=(?x)(^\s*(\#\ )??$|^\s*(from\s+\S+\s+)?import\s+.+$) -# Allow the body of an if to be on the same line as the test if there is no -# else. +# Maximum number of lines in a module. +max-module-lines=99999 + +single-line-class-stmt=no single-line-if-stmt=yes -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -# no-space-check= -# Maximum number of lines in a module -max-module-lines=99999 +[IMPORTS] -# String used as indentation unit. Currently 4, consistent with -# PEP 8. -indent-string=' ' +# Allow explicit reexports by alias from a package __init__. +allow-reexport-from-package=no -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules=regsub, + TERMIOS, + Bastion, + rexec, + sets +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant, + absl -[MISCELLANEOUS] +[LOGGING] -# List of note tags to take in consideration, separated by a comma. -notes=TODO +# The type of string formatting that logging methods do. `old` means using % +# formatting, `new` is for `{}` formatting. +logging-format-style=old +# Logging modules to check that the string format arguments are in logging +# function parameter format. +logging-modules=logging,absl.logging -[STRING] -# This flag controls whether inconsistent-quotes generates a warning when the -# character used as a quote delimiter is used inconsistently within a module. -check-quote-consistency=yes +[MESSAGES CONTROL] +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, CONTROL_FLOW, INFERENCE, INFERENCE_FAILURE, +# UNDEFINED. +confidence=HIGH, + CONTROL_FLOW, + INFERENCE, + INFERENCE_FAILURE, + UNDEFINED + +# Disable the message, report, category or checker with the given id(s). +disable=raw-checker-failed, + locally-disabled, + suppressed-message, + arguments-differ, + fixme, + line-too-long, + global-statement, + import-error, + no-member, + signature-differs, + too-many-locals, + too-many-public-methods, + too-many-return-statements, + too-many-statements, + unnecessary-pass -[VARIABLES] +# Include some helpful details on errors messages for naming rules: +include-naming-hint = yes -# Tells whether we should check for unused import in __init__ files. -init-import=no -# A regular expression matching the name of dummy variables (i.e. expectedly -# not used). -dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_) +[METHOD_ARGS] -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= +# List of qualified names (i.e., library.method) which require a timeout +# parameter e.g. 'requests.api.get,requests.api.post' +timeout-methods=requests.api.delete, + requests.api.get, + requests.api.head, + requests.api.options, + requests.api.patch, + requests.api.post, + requests.api.put, + requests.api.request -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks= -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six,six.moves,past.builtins,future.builtins,functools +[MISCELLANEOUS] +check-fixme-in-docstring=no +notes=TODO -[LOGGING] -# Logging modules to check that the string format arguments are in logging -# function parameter format -logging-modules=logging,absl.logging +[REFACTORING] +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 -[SIMILARITIES] +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit,argparse.parse_error -# Minimum lines number of a similarity. -min-similarity-lines=4 +# Let 'consider-using-join' be raised when the separator to join on would be +# non-empty (resulting in expected fixes of the type: ``"- " + " - +# ".join(items)``) +suggest-join-with-non-empty-separator=yes -# Ignore comments when computing similarities. -ignore-comments=yes -# Ignore docstrings when computing similarities. -ignore-docstrings=yes +[REPORTS] -# Ignore imports when computing similarities. -ignore-imports=no +reports=no [SPELLING] -# Spelling dictionary name. Available dictionaries: none. To make it working -# install python-enchant package. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= +# Limits count of emitted suggestions for spelling mistakes. +max-spelling-suggestions=4 -# A path to a file that contains private dictionary; one word per line. -spelling-private-dict-file= +# List of comma separated words that should be considered directives if they +# appear at the beginning of a comment and should not be checked. +spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy: -# Tells whether to store unknown words to indicated private dictionary in -# --spelling-private-dict-file option instead of raising a message. spelling-store-unknown-words=no -[IMPORTS] +[STRING] -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=regsub, - TERMIOS, - Bastion, - rexec, - sets +check-quote-consistency=yes +check-str-concat-over-line-jumps=yes -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= +[VARIABLES] -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= +allow-global-unused-variables=yes +dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_) +ignored-argument-names=_.*|^ignored_|^unused_ +redefining-builtins-modules=six,six.moves,past.builtins,future.builtins,functools -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= +# Tells whether we should check for unused import in __init__ files. +init-import=no -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant, absl +[TYPECHECK] -[CLASSES] +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager,contextlib2.contextmanager -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__, - __new__, - setUp +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict, - _fields, - _replace, - _source, - _make +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +ignore-none=yes -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls, - class_ +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=mcs +# List of symbolic message names to ignore for Mixin members. +ignored-checks-for-mixins=no-member, + not-async-context-manager, + not-context-manager, + attribute-defined-outside-init + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes -[EXCEPTIONS] +# The maximum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=StandardError, - Exception, - BaseException +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + +# Regex pattern to define which classes are considered mixins. +mixin-class-rgx=.*[Mm]ixin + +# List of decorators that change the signature of a decorated function. +signature-mutators= diff --git a/requirements-generator.txt b/requirements-generator.txt index d472d158b9b..f33a14d63ed 100644 --- a/requirements-generator.txt +++ b/requirements-generator.txt @@ -1,6 +1,9 @@ -black<=22.3.0 -flake8~=5.0.4 -Jinja2~=3.1.2 +Jinja2~=3.1.6 +black<=25.1.0 +flake8~=7.3.0 +markupsafe==3.0.2 +pytest-subtests~=0.14.2 +pytest~=8.4.0 python-dateutil==2.8.1 -markupsafe==2.0.1 -tomli>=1.1.0; python_full_version < '3.11.2' +requests~=2.32.4 +tomli>=2.2.1; python_full_version < '3.11.2' diff --git a/requirements.txt b/requirements.txt index 712608f8550..6d2f03a4e7d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,7 @@ -flake8~=5.0.4 -pylint~=2.17.1 -black<=22.3.0 -yapf~=0.32.0 -tomli>=1.1.0; python_full_version < '3.11.2' +black<=25.1.0 +yapf~=0.43.0 +flake8~=7.3.0 +pylint ~=4.0.4 +pytest~=8.4.0 +pytest-subtests~=0.14.2 +tomli>=2.2.1; python_full_version < '3.11.2' From a1e676a6ad2bd3011215d5b8bb20ae60fba2b4b8 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Wed, 18 Feb 2026 19:10:21 -0800 Subject: [PATCH 7/9] Changed requirements for generator to later version of dateutils and regenerated test files. --- exercises/practice/acronym/acronym_test.py | 2 +- exercises/practice/affine-cipher/affine_cipher_test.py | 2 +- exercises/practice/alphametics/alphametics_test.py | 2 +- exercises/practice/bob/bob_test.py | 2 +- exercises/practice/book-store/book_store_test.py | 2 +- exercises/practice/circular-buffer/circular_buffer_test.py | 2 +- exercises/practice/connect/connect_test.py | 2 +- exercises/practice/diamond/diamond_test.py | 2 +- .../difference-of-squares/difference_of_squares_test.py | 2 +- exercises/practice/diffie-hellman/diffie_hellman_test.py | 2 +- exercises/practice/etl/etl_test.py | 2 +- exercises/practice/food-chain/food_chain_test.py | 2 +- exercises/practice/forth/forth_test.py | 2 +- exercises/practice/game-of-life/game_of_life_test.py | 2 +- exercises/practice/go-counting/go_counting_test.py | 2 +- exercises/practice/grade-school/grade_school_test.py | 2 +- exercises/practice/grains/grains_test.py | 2 +- exercises/practice/luhn/luhn_test.py | 2 +- exercises/practice/pig-latin/pig_latin_test.py | 2 +- exercises/practice/pov/pov_test.py | 2 +- exercises/practice/prime-factors/prime_factors_test.py | 2 +- exercises/practice/rail-fence-cipher/rail_fence_cipher_test.py | 2 +- exercises/practice/rotational-cipher/rotational_cipher_test.py | 2 +- exercises/practice/sgf-parsing/sgf_parsing_test.py | 2 +- exercises/practice/swift-scheduling/swift_scheduling_test.py | 2 +- exercises/practice/triangle/triangle_test.py | 2 +- .../variable-length-quantity/variable_length_quantity_test.py | 2 +- requirements-generator.txt | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/exercises/practice/acronym/acronym_test.py b/exercises/practice/acronym/acronym_test.py index 984deef60d2..65f39754950 100644 --- a/exercises/practice/acronym/acronym_test.py +++ b/exercises/practice/acronym/acronym_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/acronym/canonical-data.json -# File last updated on 2023-07-20 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/affine-cipher/affine_cipher_test.py b/exercises/practice/affine-cipher/affine_cipher_test.py index f6d7c106c33..8c3b756a557 100644 --- a/exercises/practice/affine-cipher/affine_cipher_test.py +++ b/exercises/practice/affine-cipher/affine_cipher_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/affine-cipher/canonical-data.json -# File last updated on 2023-07-20 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/alphametics/alphametics_test.py b/exercises/practice/alphametics/alphametics_test.py index 6279b805c59..8c9e63d3360 100644 --- a/exercises/practice/alphametics/alphametics_test.py +++ b/exercises/practice/alphametics/alphametics_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/alphametics/canonical-data.json -# File last updated on 2023-07-20 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/bob/bob_test.py b/exercises/practice/bob/bob_test.py index 755d5c935e4..97ba338aa25 100644 --- a/exercises/practice/bob/bob_test.py +++ b/exercises/practice/bob/bob_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/bob/canonical-data.json -# File last updated on 2025-01-10 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/book-store/book_store_test.py b/exercises/practice/book-store/book_store_test.py index 87b0051faa2..1fcd55819a8 100644 --- a/exercises/practice/book-store/book_store_test.py +++ b/exercises/practice/book-store/book_store_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/book-store/canonical-data.json -# File last updated on 2023-07-20 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/circular-buffer/circular_buffer_test.py b/exercises/practice/circular-buffer/circular_buffer_test.py index eb0663cf503..f37fe967844 100644 --- a/exercises/practice/circular-buffer/circular_buffer_test.py +++ b/exercises/practice/circular-buffer/circular_buffer_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/circular-buffer/canonical-data.json -# File last updated on 2023-07-20 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/connect/connect_test.py b/exercises/practice/connect/connect_test.py index e7303d35131..4d128a03771 100644 --- a/exercises/practice/connect/connect_test.py +++ b/exercises/practice/connect/connect_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/connect/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/diamond/diamond_test.py b/exercises/practice/diamond/diamond_test.py index 6a3a2295098..b551582aee7 100644 --- a/exercises/practice/diamond/diamond_test.py +++ b/exercises/practice/diamond/diamond_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/diamond/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/difference-of-squares/difference_of_squares_test.py b/exercises/practice/difference-of-squares/difference_of_squares_test.py index aa7271907ac..d2287a6846b 100644 --- a/exercises/practice/difference-of-squares/difference_of_squares_test.py +++ b/exercises/practice/difference-of-squares/difference_of_squares_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/difference-of-squares/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/diffie-hellman/diffie_hellman_test.py b/exercises/practice/diffie-hellman/diffie_hellman_test.py index e24c4e742a1..ca7a2fc979f 100644 --- a/exercises/practice/diffie-hellman/diffie_hellman_test.py +++ b/exercises/practice/diffie-hellman/diffie_hellman_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/diffie-hellman/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/etl/etl_test.py b/exercises/practice/etl/etl_test.py index d6eed70a574..ff7acea5f5b 100644 --- a/exercises/practice/etl/etl_test.py +++ b/exercises/practice/etl/etl_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/etl/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/food-chain/food_chain_test.py b/exercises/practice/food-chain/food_chain_test.py index 0cd42356ab1..eb1b58cff94 100644 --- a/exercises/practice/food-chain/food_chain_test.py +++ b/exercises/practice/food-chain/food_chain_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/food-chain/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/forth/forth_test.py b/exercises/practice/forth/forth_test.py index 1489bbd7df0..cf6e1da9844 100644 --- a/exercises/practice/forth/forth_test.py +++ b/exercises/practice/forth/forth_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/forth/canonical-data.json -# File last updated on 2024-11-04 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/game-of-life/game_of_life_test.py b/exercises/practice/game-of-life/game_of_life_test.py index b62b74407cb..1132eb35185 100644 --- a/exercises/practice/game-of-life/game_of_life_test.py +++ b/exercises/practice/game-of-life/game_of_life_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/game-of-life/canonical-data.json -# File last updated on 2026-01-26 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/go-counting/go_counting_test.py b/exercises/practice/go-counting/go_counting_test.py index aec80a1b369..356458f3529 100644 --- a/exercises/practice/go-counting/go_counting_test.py +++ b/exercises/practice/go-counting/go_counting_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/go-counting/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/grade-school/grade_school_test.py b/exercises/practice/grade-school/grade_school_test.py index 30d91c6c57d..5fa9cc86f00 100644 --- a/exercises/practice/grade-school/grade_school_test.py +++ b/exercises/practice/grade-school/grade_school_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/grade-school/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/grains/grains_test.py b/exercises/practice/grains/grains_test.py index 177f91faa1a..a4475324f3a 100644 --- a/exercises/practice/grains/grains_test.py +++ b/exercises/practice/grains/grains_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/grains/canonical-data.json -# File last updated on 2023-09-27 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/luhn/luhn_test.py b/exercises/practice/luhn/luhn_test.py index 58234eb7d55..344c7d302c8 100644 --- a/exercises/practice/luhn/luhn_test.py +++ b/exercises/practice/luhn/luhn_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/luhn/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/pig-latin/pig_latin_test.py b/exercises/practice/pig-latin/pig_latin_test.py index 1217d6883f9..07766dd9132 100644 --- a/exercises/practice/pig-latin/pig_latin_test.py +++ b/exercises/practice/pig-latin/pig_latin_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/pig-latin/canonical-data.json -# File last updated on 2025-01-10 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/pov/pov_test.py b/exercises/practice/pov/pov_test.py index 2436ebc2db9..b2ab6a0e314 100644 --- a/exercises/practice/pov/pov_test.py +++ b/exercises/practice/pov/pov_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/pov/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/prime-factors/prime_factors_test.py b/exercises/practice/prime-factors/prime_factors_test.py index 4f6865036e5..d03a0b62de7 100644 --- a/exercises/practice/prime-factors/prime_factors_test.py +++ b/exercises/practice/prime-factors/prime_factors_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/prime-factors/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/rail-fence-cipher/rail_fence_cipher_test.py b/exercises/practice/rail-fence-cipher/rail_fence_cipher_test.py index f82066ca274..c9cbc003874 100644 --- a/exercises/practice/rail-fence-cipher/rail_fence_cipher_test.py +++ b/exercises/practice/rail-fence-cipher/rail_fence_cipher_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/rail-fence-cipher/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/rotational-cipher/rotational_cipher_test.py b/exercises/practice/rotational-cipher/rotational_cipher_test.py index ca22735ef9b..a2c8dd5146a 100644 --- a/exercises/practice/rotational-cipher/rotational_cipher_test.py +++ b/exercises/practice/rotational-cipher/rotational_cipher_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/rotational-cipher/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/sgf-parsing/sgf_parsing_test.py b/exercises/practice/sgf-parsing/sgf_parsing_test.py index c33a5dbecff..aee0a7ddecb 100644 --- a/exercises/practice/sgf-parsing/sgf_parsing_test.py +++ b/exercises/practice/sgf-parsing/sgf_parsing_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/sgf-parsing/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/swift-scheduling/swift_scheduling_test.py b/exercises/practice/swift-scheduling/swift_scheduling_test.py index 08ed2485b9c..c4d7a20562b 100644 --- a/exercises/practice/swift-scheduling/swift_scheduling_test.py +++ b/exercises/practice/swift-scheduling/swift_scheduling_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/swift-scheduling/canonical-data.json -# File last updated on 2025-06-25 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/triangle/triangle_test.py b/exercises/practice/triangle/triangle_test.py index b279c83c325..b008974039a 100644 --- a/exercises/practice/triangle/triangle_test.py +++ b/exercises/practice/triangle/triangle_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/triangle/canonical-data.json -# File last updated on 2023-07-19 +# File last updated on 2026-02-19 import unittest diff --git a/exercises/practice/variable-length-quantity/variable_length_quantity_test.py b/exercises/practice/variable-length-quantity/variable_length_quantity_test.py index e059f82ee3f..bfc66cc71c4 100644 --- a/exercises/practice/variable-length-quantity/variable_length_quantity_test.py +++ b/exercises/practice/variable-length-quantity/variable_length_quantity_test.py @@ -1,6 +1,6 @@ # These tests are auto-generated with test data from: # https://github.com/exercism/problem-specifications/tree/main/exercises/variable-length-quantity/canonical-data.json -# File last updated on 2025-08-28 +# File last updated on 2026-02-19 import unittest diff --git a/requirements-generator.txt b/requirements-generator.txt index f33a14d63ed..d894d1ff815 100644 --- a/requirements-generator.txt +++ b/requirements-generator.txt @@ -4,6 +4,6 @@ flake8~=7.3.0 markupsafe==3.0.2 pytest-subtests~=0.14.2 pytest~=8.4.0 -python-dateutil==2.8.1 +python-dateutil==2.9.0 requests~=2.32.4 tomli>=2.2.1; python_full_version < '3.11.2' From b0bb6e50faa8b2fbfbb349fe03f090711fe0fcf6 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Wed, 18 Feb 2026 19:28:07 -0800 Subject: [PATCH 8/9] Regenerated test files this time with Python 3.13.5 Black, to match CI. --- exercises/practice/acronym/acronym_test.py | 1 + exercises/practice/affine-cipher/affine_cipher_test.py | 1 + exercises/practice/alphametics/alphametics_test.py | 1 + exercises/practice/bob/bob_test.py | 1 + exercises/practice/book-store/book_store_test.py | 1 + .../practice/circular-buffer/circular_buffer_test.py | 1 + exercises/practice/connect/connect_test.py | 1 + exercises/practice/diamond/diamond_test.py | 1 + .../difference-of-squares/difference_of_squares_test.py | 1 + exercises/practice/diffie-hellman/diffie_hellman_test.py | 9 +++++---- exercises/practice/etl/etl_test.py | 1 + exercises/practice/food-chain/food_chain_test.py | 1 + exercises/practice/forth/forth_test.py | 1 + exercises/practice/game-of-life/game_of_life_test.py | 1 + exercises/practice/go-counting/go_counting_test.py | 1 + exercises/practice/grade-school/grade_school_test.py | 1 + exercises/practice/grains/grains_test.py | 1 + exercises/practice/luhn/luhn_test.py | 1 + exercises/practice/pig-latin/pig_latin_test.py | 1 + exercises/practice/pov/pov_test.py | 1 + exercises/practice/prime-factors/prime_factors_test.py | 1 + .../practice/rail-fence-cipher/rail_fence_cipher_test.py | 1 + .../practice/rotational-cipher/rotational_cipher_test.py | 1 + exercises/practice/sgf-parsing/sgf_parsing_test.py | 1 + .../practice/swift-scheduling/swift_scheduling_test.py | 1 + exercises/practice/triangle/triangle_test.py | 3 +++ .../variable_length_quantity_test.py | 1 + requirements-generator.txt | 1 - 28 files changed, 33 insertions(+), 5 deletions(-) diff --git a/exercises/practice/acronym/acronym_test.py b/exercises/practice/acronym/acronym_test.py index 65f39754950..a10f2bf3dc2 100644 --- a/exercises/practice/acronym/acronym_test.py +++ b/exercises/practice/acronym/acronym_test.py @@ -10,6 +10,7 @@ class AcronymTest(unittest.TestCase): + def test_basic(self): self.assertEqual(abbreviate("Portable Network Graphics"), "PNG") diff --git a/exercises/practice/affine-cipher/affine_cipher_test.py b/exercises/practice/affine-cipher/affine_cipher_test.py index 8c3b756a557..db265953691 100644 --- a/exercises/practice/affine-cipher/affine_cipher_test.py +++ b/exercises/practice/affine-cipher/affine_cipher_test.py @@ -11,6 +11,7 @@ class AffineCipherTest(unittest.TestCase): + def test_encode_yes(self): self.assertEqual(encode("yes", 5, 7), "xbt") diff --git a/exercises/practice/alphametics/alphametics_test.py b/exercises/practice/alphametics/alphametics_test.py index 8c9e63d3360..30e54813093 100644 --- a/exercises/practice/alphametics/alphametics_test.py +++ b/exercises/practice/alphametics/alphametics_test.py @@ -10,6 +10,7 @@ class AlphameticsTest(unittest.TestCase): + def test_puzzle_with_three_letters(self): self.assertEqual(solve("I + BB == ILL"), {"I": 1, "B": 9, "L": 0}) diff --git a/exercises/practice/bob/bob_test.py b/exercises/practice/bob/bob_test.py index 97ba338aa25..46410fa62ba 100644 --- a/exercises/practice/bob/bob_test.py +++ b/exercises/practice/bob/bob_test.py @@ -10,6 +10,7 @@ class BobTest(unittest.TestCase): + def test_stating_something(self): self.assertEqual(response("Tom-ay-to, tom-aaaah-to."), "Whatever.") diff --git a/exercises/practice/book-store/book_store_test.py b/exercises/practice/book-store/book_store_test.py index 1fcd55819a8..d25bdc5a25b 100644 --- a/exercises/practice/book-store/book_store_test.py +++ b/exercises/practice/book-store/book_store_test.py @@ -10,6 +10,7 @@ class BookStoreTest(unittest.TestCase): + def test_only_a_single_book(self): basket = [1] self.assertEqual(total(basket), 800) diff --git a/exercises/practice/circular-buffer/circular_buffer_test.py b/exercises/practice/circular-buffer/circular_buffer_test.py index f37fe967844..031d970fabc 100644 --- a/exercises/practice/circular-buffer/circular_buffer_test.py +++ b/exercises/practice/circular-buffer/circular_buffer_test.py @@ -12,6 +12,7 @@ class CircularBufferTest(unittest.TestCase): + def test_reading_empty_buffer_should_fail(self): buf = CircularBuffer(1) with self.assertRaises(BufferError) as err: diff --git a/exercises/practice/connect/connect_test.py b/exercises/practice/connect/connect_test.py index 4d128a03771..9214cda9800 100644 --- a/exercises/practice/connect/connect_test.py +++ b/exercises/practice/connect/connect_test.py @@ -10,6 +10,7 @@ class ConnectTest(unittest.TestCase): + def test_an_empty_board_has_no_winner(self): game = ConnectGame( """. . . . . diff --git a/exercises/practice/diamond/diamond_test.py b/exercises/practice/diamond/diamond_test.py index b551582aee7..448f65d5326 100644 --- a/exercises/practice/diamond/diamond_test.py +++ b/exercises/practice/diamond/diamond_test.py @@ -10,6 +10,7 @@ class DiamondTest(unittest.TestCase): + def test_degenerate_case_with_a_single_a_row(self): result = ["A"] self.assertEqual(rows("A"), result) diff --git a/exercises/practice/difference-of-squares/difference_of_squares_test.py b/exercises/practice/difference-of-squares/difference_of_squares_test.py index d2287a6846b..3536a20f8f8 100644 --- a/exercises/practice/difference-of-squares/difference_of_squares_test.py +++ b/exercises/practice/difference-of-squares/difference_of_squares_test.py @@ -12,6 +12,7 @@ class DifferenceOfSquaresTest(unittest.TestCase): + def test_square_of_sum_1(self): self.assertEqual(square_of_sum(1), 1) diff --git a/exercises/practice/diffie-hellman/diffie_hellman_test.py b/exercises/practice/diffie-hellman/diffie_hellman_test.py index ca7a2fc979f..f6a2a9c1cfd 100644 --- a/exercises/practice/diffie-hellman/diffie_hellman_test.py +++ b/exercises/practice/diffie-hellman/diffie_hellman_test.py @@ -12,11 +12,12 @@ class DiffieHellmanTest(unittest.TestCase): + def test_private_key_is_greater_than_1_and_less_than_p(self): for prime in [5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]: with self.subTest(f"prime={prime}"): key = private_key(prime) - self.assertTrue(1 < key < prime, msg=f"{key} out of range, expected to be >1 and <{prime}") # fmt: skip + self.assertTrue(1 < key < prime, msg=f"{key} out of range, expected to be >1 and <{prime}") # fmt: skip def test_private_key_is_random(self): """ @@ -30,19 +31,19 @@ def test_can_calculate_public_key_using_private_key(self): p = 23 g = 5 private_key = 6 - self.assertEqual(8, public_key(p, g, private_key, )) # fmt: skip + self.assertEqual(8, public_key(p, g, private_key, )) # fmt: skip def test_can_calculate_public_key_when_given_a_different_private_key(self): p = 23 g = 5 private_key = 15 - self.assertEqual(19, public_key(p, g, private_key, )) # fmt: skip + self.assertEqual(19, public_key(p, g, private_key, )) # fmt: skip def test_can_calculate_secret_using_other_party_s_public_key(self): p = 23 their_public_key = 19 my_private_key = 6 - self.assertEqual(2, secret(p, their_public_key, my_private_key, )) # fmt: skip + self.assertEqual(2, secret(p, their_public_key, my_private_key, )) # fmt: skip def test_key_exchange(self): p = 23 diff --git a/exercises/practice/etl/etl_test.py b/exercises/practice/etl/etl_test.py index ff7acea5f5b..ef24e9af484 100644 --- a/exercises/practice/etl/etl_test.py +++ b/exercises/practice/etl/etl_test.py @@ -10,6 +10,7 @@ class EtlTest(unittest.TestCase): + def test_single_letter(self): legacy_data = {1: ["A"]} data = {"a": 1} diff --git a/exercises/practice/food-chain/food_chain_test.py b/exercises/practice/food-chain/food_chain_test.py index eb1b58cff94..4ce21d81339 100644 --- a/exercises/practice/food-chain/food_chain_test.py +++ b/exercises/practice/food-chain/food_chain_test.py @@ -10,6 +10,7 @@ class FoodChainTest(unittest.TestCase): + def test_fly(self): self.assertEqual( recite(1, 1), diff --git a/exercises/practice/forth/forth_test.py b/exercises/practice/forth/forth_test.py index cf6e1da9844..848da9ed2f9 100644 --- a/exercises/practice/forth/forth_test.py +++ b/exercises/practice/forth/forth_test.py @@ -11,6 +11,7 @@ class ForthTest(unittest.TestCase): + def test_parsing_and_numbers_numbers_just_get_pushed_onto_the_stack(self): self.assertEqual(evaluate(["1 2 3 4 5"]), [1, 2, 3, 4, 5]) diff --git a/exercises/practice/game-of-life/game_of_life_test.py b/exercises/practice/game-of-life/game_of_life_test.py index 1132eb35185..24f89e6f73c 100644 --- a/exercises/practice/game-of-life/game_of_life_test.py +++ b/exercises/practice/game-of-life/game_of_life_test.py @@ -10,6 +10,7 @@ class GameOfLifeTest(unittest.TestCase): + def test_empty_matrix(self): matrix = [] expected = [] diff --git a/exercises/practice/go-counting/go_counting_test.py b/exercises/practice/go-counting/go_counting_test.py index 356458f3529..036e3c26fd7 100644 --- a/exercises/practice/go-counting/go_counting_test.py +++ b/exercises/practice/go-counting/go_counting_test.py @@ -13,6 +13,7 @@ class GoCountingTest(unittest.TestCase): + def test_black_corner_territory_on_5x5_board(self): board = Board([" B ", " B B ", "B W B", " W W ", " W "]) stone, territory = board.territory(x=0, y=1) diff --git a/exercises/practice/grade-school/grade_school_test.py b/exercises/practice/grade-school/grade_school_test.py index 5fa9cc86f00..638c776474a 100644 --- a/exercises/practice/grade-school/grade_school_test.py +++ b/exercises/practice/grade-school/grade_school_test.py @@ -10,6 +10,7 @@ class GradeSchoolTest(unittest.TestCase): + def test_roster_is_empty_when_no_student_is_added(self): school = School() expected = [] diff --git a/exercises/practice/grains/grains_test.py b/exercises/practice/grains/grains_test.py index a4475324f3a..bd924723348 100644 --- a/exercises/practice/grains/grains_test.py +++ b/exercises/practice/grains/grains_test.py @@ -11,6 +11,7 @@ class GrainsTest(unittest.TestCase): + def test_grains_on_square_1(self): self.assertEqual(square(1), 1) diff --git a/exercises/practice/luhn/luhn_test.py b/exercises/practice/luhn/luhn_test.py index 344c7d302c8..7d26c9ae02f 100644 --- a/exercises/practice/luhn/luhn_test.py +++ b/exercises/practice/luhn/luhn_test.py @@ -10,6 +10,7 @@ class LuhnTest(unittest.TestCase): + def test_single_digit_strings_can_not_be_valid(self): self.assertIs(Luhn("1").valid(), False) diff --git a/exercises/practice/pig-latin/pig_latin_test.py b/exercises/practice/pig-latin/pig_latin_test.py index 07766dd9132..10c2f76419d 100644 --- a/exercises/practice/pig-latin/pig_latin_test.py +++ b/exercises/practice/pig-latin/pig_latin_test.py @@ -10,6 +10,7 @@ class PigLatinTest(unittest.TestCase): + def test_word_beginning_with_a(self): self.assertEqual(translate("apple"), "appleay") diff --git a/exercises/practice/pov/pov_test.py b/exercises/practice/pov/pov_test.py index b2ab6a0e314..0399300eac0 100644 --- a/exercises/practice/pov/pov_test.py +++ b/exercises/practice/pov/pov_test.py @@ -10,6 +10,7 @@ class PovTest(unittest.TestCase): + def test_results_in_the_same_tree_if_the_input_tree_is_a_singleton(self): tree = Tree("x") expected = Tree("x") diff --git a/exercises/practice/prime-factors/prime_factors_test.py b/exercises/practice/prime-factors/prime_factors_test.py index d03a0b62de7..a1d5d4d2fbb 100644 --- a/exercises/practice/prime-factors/prime_factors_test.py +++ b/exercises/practice/prime-factors/prime_factors_test.py @@ -10,6 +10,7 @@ class PrimeFactorsTest(unittest.TestCase): + def test_no_factors(self): self.assertEqual(factors(1), []) diff --git a/exercises/practice/rail-fence-cipher/rail_fence_cipher_test.py b/exercises/practice/rail-fence-cipher/rail_fence_cipher_test.py index c9cbc003874..4cbca167cb9 100644 --- a/exercises/practice/rail-fence-cipher/rail_fence_cipher_test.py +++ b/exercises/practice/rail-fence-cipher/rail_fence_cipher_test.py @@ -11,6 +11,7 @@ class RailFenceCipherTest(unittest.TestCase): + def test_encode_with_two_rails(self): self.assertMultiLineEqual(encode("XOXOXOXOXOXOXOXOXO", 2), "XXXXXXXXXOOOOOOOOO") diff --git a/exercises/practice/rotational-cipher/rotational_cipher_test.py b/exercises/practice/rotational-cipher/rotational_cipher_test.py index a2c8dd5146a..9c226ace3f1 100644 --- a/exercises/practice/rotational-cipher/rotational_cipher_test.py +++ b/exercises/practice/rotational-cipher/rotational_cipher_test.py @@ -10,6 +10,7 @@ class RotationalCipherTest(unittest.TestCase): + def test_rotate_a_by_0_same_output_as_input(self): self.assertEqual(rotate("a", 0), "a") diff --git a/exercises/practice/sgf-parsing/sgf_parsing_test.py b/exercises/practice/sgf-parsing/sgf_parsing_test.py index aee0a7ddecb..35e08d66dfe 100644 --- a/exercises/practice/sgf-parsing/sgf_parsing_test.py +++ b/exercises/practice/sgf-parsing/sgf_parsing_test.py @@ -11,6 +11,7 @@ class SgfParsingTest(unittest.TestCase): + def test_empty_input(self): input_string = "" with self.assertRaises(ValueError) as err: diff --git a/exercises/practice/swift-scheduling/swift_scheduling_test.py b/exercises/practice/swift-scheduling/swift_scheduling_test.py index c4d7a20562b..234f7feec0d 100644 --- a/exercises/practice/swift-scheduling/swift_scheduling_test.py +++ b/exercises/practice/swift-scheduling/swift_scheduling_test.py @@ -10,6 +10,7 @@ class SwiftSchedulingTest(unittest.TestCase): + def test_now_translates_to_two_hours_later(self): self.assertEqual( delivery_date("2012-02-13T09:00:00", "NOW"), "2012-02-13T11:00:00" diff --git a/exercises/practice/triangle/triangle_test.py b/exercises/practice/triangle/triangle_test.py index b008974039a..d4f7269e398 100644 --- a/exercises/practice/triangle/triangle_test.py +++ b/exercises/practice/triangle/triangle_test.py @@ -12,6 +12,7 @@ class EquilateralTriangleTest(unittest.TestCase): + def test_all_sides_are_equal(self): self.assertIs(equilateral([2, 2, 2]), True) @@ -29,6 +30,7 @@ def test_sides_may_be_floats(self): class IsoscelesTriangleTest(unittest.TestCase): + def test_last_two_sides_are_equal(self): self.assertIs(isosceles([3, 4, 4]), True) @@ -58,6 +60,7 @@ def test_sides_may_be_floats(self): class ScaleneTriangleTest(unittest.TestCase): + def test_no_sides_are_equal(self): self.assertIs(scalene([5, 4, 6]), True) diff --git a/exercises/practice/variable-length-quantity/variable_length_quantity_test.py b/exercises/practice/variable-length-quantity/variable_length_quantity_test.py index bfc66cc71c4..7404128a882 100644 --- a/exercises/practice/variable-length-quantity/variable_length_quantity_test.py +++ b/exercises/practice/variable-length-quantity/variable_length_quantity_test.py @@ -11,6 +11,7 @@ class VariableLengthQuantityTest(unittest.TestCase): + def test_zero(self): self.assertEqual(encode([0x0]), [0x0]) diff --git a/requirements-generator.txt b/requirements-generator.txt index d894d1ff815..4f1cc2172c0 100644 --- a/requirements-generator.txt +++ b/requirements-generator.txt @@ -4,6 +4,5 @@ flake8~=7.3.0 markupsafe==3.0.2 pytest-subtests~=0.14.2 pytest~=8.4.0 -python-dateutil==2.9.0 requests~=2.32.4 tomli>=2.2.1; python_full_version < '3.11.2' From 8694ced770d214ac99487b2d434c08a99e904c59 Mon Sep 17 00:00:00 2001 From: BethanyG Date: Wed, 18 Feb 2026 19:31:07 -0800 Subject: [PATCH 9/9] Added dateutil back in. Evidently, the generator needs it. --- requirements-generator.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements-generator.txt b/requirements-generator.txt index 4f1cc2172c0..7385618bb4f 100644 --- a/requirements-generator.txt +++ b/requirements-generator.txt @@ -4,5 +4,6 @@ flake8~=7.3.0 markupsafe==3.0.2 pytest-subtests~=0.14.2 pytest~=8.4.0 +python-dateutil~=2.9.0 requests~=2.32.4 tomli>=2.2.1; python_full_version < '3.11.2'