Skip to content

Commit 22e8d14

Browse files
authored
[Tooling & Documentation]: Upgrade to python 3.13.5 (#74)
* Added pylint examples of bad code for linting rules. * Added pylint examples of good code for linting rules. * Added pylint linting rules details files. * Added generic pylint analyzer for exercises without any customized analysis. * Added pylint linting rules related info files. * Custom analyzer stub, ready for additional rules beyond the existing PyLint analyzers. * Details comment file for unused-wildcard-import lint rule. * Added exercise metadata and exemplar code to test exercises. * Added exercise solution code to test exercises. * Added exercise golden analysis.json for test exercises. * Upgraded dockerfile to python:3.13.5-alpine3.22 * Required init files for test and lib. * Updated readme with new docker-based instructions. * Updated PyLint comment files with good code, bad code, refs, and details from PyLint docs. * Removed unneeded pylint config file from exercise. * Added 10 general recommendations for when the analyzer has no feedback. * Cleaned up and formatted run scripts. * Upgraded requirements for Python 3.13.5. * Upgraded the general PyLint config file with the 4.4.0 version and enabled all extensions. * Added new golden tests for slect exercises to better test Analyzer and Analyzer feedback. * Modified analyzer to use new method now that epylint is depricated. Added extended PyLint messaging for PyLint comments. Added a generic analyzer for when no custom analyzer is found. * Added exercise names file and modified exercise.py to read exercise names from file instead of using empty directories,
1 parent f9772ef commit 22e8d14

File tree

1,192 files changed

+12307
-787
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,192 files changed

+12307
-787
lines changed

Dockerfile

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
FROM python:3.11.2-slim
1+
FROM python:3.13.5-alpine3.22
22

3-
RUN apt-get update \
4-
&& apt-get install curl -y \
5-
&& apt-get remove curl -y \
6-
&& apt-get autoremove -y \
7-
&& rm -rf /var/lib/apt/lists/*
3+
COPY requirements.txt /requirements.txt
4+
COPY dev-requirements.txt /dev-requirements.txt
5+
6+
RUN pip install -r /requirements.txt -r /dev-requirements.txt
87

9-
RUN mkdir /opt/analyzer
108
COPY . /opt/analyzer
11-
WORKDIR /opt/analyzer
129

13-
RUN pip install -r requirements.txt -r dev-requirements.txt
14-
ENTRYPOINT ["/opt/analyzer/bin/run.sh"]
10+
WORKDIR /opt/analyzer
1511

12+
ENTRYPOINT ["sh", "/opt/analyzer/bin/run.sh"]

README.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
# Exercism's Python Analyzer
22

3-
This is Exercism's automated analyzer for the Python track.
3+
This is Exercism's automated analyzer for the Python track exercises.
4+
It is based on and uses [PyLint][pylint-github].
45

5-
It is run with `./bin/run.sh $EXERCISM $PATH_TO_FILES $PATH_FOR_OUTPUT` and will read the source code from `$PATH_TO_FILES` and write a text file with an analysis to `$PATH_FOR_OUTPUT`.
6+
It is run from a docker container using `./bin/run-in-docker.sh $EXERCISM $PATH_TO_FILES $PATH_FOR_OUTPUT` and will read the source code from `$PATH_TO_FILES` and write a text file with an analysis to `$PATH_FOR_OUTPUT`.
67

78
For example:
89

910
```bash
10-
./bin/run.sh two_fer ~/solution-238382y7sds7fsadfasj23j/ ~/solution-238382y7sds7fsadfasj23j/output/
11+
./bin/run-in-docker.sh two_fer ~/solution-238382y7sds7fsadfasj23j/ ~/solution-238382y7sds7fsadfasj23j/output/
1112
```
1213

13-
Unit tests can be run from this directory:
14+
Unit tests also require [docker][docker] and can be run locally or from within GitHub via [codespaces][codespaces]:
1415

1516
```bash
16-
pytest -x
17+
18+
#run from the python-analyzer (project root) directory.
19+
./bin/run-tests-in-docker.sh
1720
```
21+
22+
[pylint-github]: https://github.com/pylint-dev/pylint
23+
[docker]: https://www.docker.com/
24+
[codespaces]: https://github.com/features/codespaces

bin/run-in-docker.sh

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ mkdir -p "$output_dir"
3434

3535
# run image passing the arguments
3636
docker run \
37+
--rm \
38+
--network none \
39+
--read-only \
3740
--mount type=bind,src=$PWD/$2,dst=/solution \
3841
--mount type=bind,src=$PWD/$output_dir,dst=/output \
39-
python-analyzer $1 /solution/ /output/
40-
41-
42+
--mount type=tmpfs,destination=/tmp \
43+
exercism/python-analyzer $1 /solution/ /output/

bin/run-tests-in-docker.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env sh
2+
3+
# Synopsis:
4+
# Test the test runner Docker image by running it against a predefined set of
5+
# solutions with an expected output.
6+
# The test runner Docker image is built automatically.
7+
8+
# Output:
9+
# Outputs the diff of the expected test results against the actual test results
10+
# generated by the test runner Docker image.
11+
12+
# Example:
13+
# ./bin/run-tests-in-docker.sh
14+
15+
# Stop executing when a command returns a non-zero return code
16+
set -e
17+
18+
# Build the Docker image
19+
docker build --rm -t exercism/python-analyzer .
20+
21+
# Run the Docker image using the settings mimicking the production environment
22+
docker run \
23+
--rm \
24+
--network none \
25+
--read-only \
26+
--mount type=bind,src="${PWD}/test",dst=/opt/analyzer/test \
27+
--mount type=tmpfs,dst=/tmp \
28+
--workdir /opt/analyzer \
29+
--entrypoint pytest \
30+
exercism/python-analyzer -vv --disable-warnings

bin/run.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
CLI for the auto-analyzer for the Python track on Exercism.org.
44
./bin/run.sh two_fer ~/solution-238382y7sds7fsadfasj23j/ ~/solution-238382y7sds7fsadfasj23j/output/
55
"""
6+
7+
68
import argparse
79
import importlib.util
810
import sys
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
1. Get familiar with the conventions outlined in [PEP 8][pep-8].
2+
While these are not "law", they are the standard used in the Python project itself and are a great baseline in most coding situations.
3+
2. Read and think about the ideas outlined in [PEP 20 (aka "The Zen of Python")][pep-20].
4+
Like PEP 8, these are not "laws", but they are solid guiding principles for better and clearer Python code.
5+
3. Prefer clear and easy to follow code over comments. But DO comment where needed for clarity.
6+
4. Consider using type hints to clarify your code.
7+
Explore the type hint [documentation][type-hint-docs] and [why you might not want to type hint][type-hint-nos].
8+
5. Try to follow the docstring guidelines laid out in [PEP 257][pep-257].
9+
Good documentation matters.
10+
6. Avoid [magic numbers][magic-numbers].
11+
7. Prefer [`enumerate()`][enumerate-docs] over [`range(len())`][range-docs] in loops that need both an index and element.
12+
8. Prefer [comprehensions][comprehensions] and [generator expressions][generators] over loops that append to a data structure.
13+
But don't [overuse comprehensions][comprehension-overuse].
14+
9. When joining more than few substrings or concatenating in a loop, prefer [`str.join()`][join] over other methods of string concatenation.
15+
10. Get familiar with Python's rich set of [built-in functions][built-in-functions] and the [Standard Library][standard-lib].
16+
Go [here][standard-lib-overview] for a brief tour and some interesting highlights.
17+
18+
[built-in-functions]: https://docs.python.org/3/library/functions.html
19+
[comprehension-overuse]: https://treyhunner.com/2019/03/abusing-and-overusing-list-comprehensions-in-python/
20+
[comprehensions]: https://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/
21+
[enumerate-docs]: https://docs.python.org/3/library/functions.html#enumerate
22+
[generators]: https://www.pythonmorsels.com/how-write-generator-expression/
23+
[join]: https://docs.python.org/3/library/stdtypes.html#str.join
24+
[magic-numbers]: https://en.wikipedia.org/wiki/Magic_number_(programming)
25+
[pep-20]: https://peps.python.org/pep-0020/
26+
[pep-257]: https://peps.python.org/pep-0257/
27+
[pep-8]: https://peps.python.org/pep-0008/
28+
[range-docs]: https://docs.python.org/3/library/functions.html#func-range
29+
[standard-lib-overview]: https://docs.python.org/3/tutorial/stdlib.html
30+
[standard-lib]: https://docs.python.org/3/library/index.html
31+
[type-hint-docs]: https://typing.python.org/en/latest/index.html
32+
[type-hint-nos]: https://typing.python.org/en/latest/guides/typing_anti_pitch.html

comments/pylint/convention.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
# pylint convention
22

3-
**Line %{lineno}** [ _%{code}_ ] : %{message}.
4-
Was reported.
3+
**Line %{lineno} [_%{code}_]** was reported by Pylint:
54

6-
Which means this code doesn't follow general [`code style`][PEP8] conventions.
5+
%{message}.
6+
7+
This code doesn't follow general [Python code style][code style] conventions.
78
While this type of issue generally doesn't affect the way code _executes_, it can hurt readability or the performance of automated tools such as documentation generators or test runners.
89

9-
[PEP8]: https://www.python.org/dev/peps/pep-0008/
10+
%{bad_code}
11+
%{good_code}
12+
%{related_info}
13+
%{details}
14+
15+
[code style]: https://www.python.org/dev/peps/pep-0008/

comments/pylint/error.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# pylint informational
22

3-
**Line %{lineno}** [ _%{code}_ ] : %{message}.
4-
Was reported.
3+
**Line %{lineno} [_%{code}_]** was reported by Pylint:
4+
5+
%{message}.
56

67
This code has an error or problem that should be addressed.
8+
9+
%{bad_code}
10+
%{good_code}
11+
%{related_info}
12+
%{details}

comments/pylint/fatal.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# pylint fatal
22

3-
**Line %{lineno}** [ _%{code}_ ] : %{message}.
4-
Was reported.
3+
**Line %{lineno} [_%{code}_]** was reported by Pylint:
54

6-
This is a fatal error.
7-
Something went wrong, and the code cannot be processed any further.
5+
%{message}.
86

7+
8+
This is a fatal error. Something went wrong, and the code cannot be processed any further.

comments/pylint/informatonal.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
# pylint informational
22

3-
**Line %{lineno}** [ _%{code}_ ] : %{message}.
4-
Was reported.
3+
**Line %{lineno} [_%{code}_]** was reported by Pylint:
4+
5+
%{message}.
56

67
There is `FIXME`/`TODO`/`XXX` style comment or other "informational" pattern or note in the code.
7-
These tags are often used to annotate places where code is stubbed out but needs work - or to highlight potential design flaws or bugs that need to be addressed in the future.
8+
These tags are often used to annotate places where code is stubbed out but needs work - or to highlight potential design flaws or bugs that need to be addressed in the future.
89

10+
%{bad_code}
11+
%{good_code}
12+
%{related_info}
13+
%{details}

0 commit comments

Comments
 (0)