pythonlings 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pythonlings-0.3.0/.github/ISSUE_TEMPLATE/bug_report.md +18 -0
- pythonlings-0.3.0/.github/ISSUE_TEMPLATE/feature_request.md +11 -0
- pythonlings-0.3.0/.github/pull_request_template.md +11 -0
- pythonlings-0.3.0/.github/workflows/ci.yml +26 -0
- pythonlings-0.3.0/.github/workflows/pages.yml +42 -0
- pythonlings-0.3.0/.github/workflows/publish.yml +39 -0
- pythonlings-0.3.0/.gitignore +140 -0
- pythonlings-0.3.0/AGENTS.md +29 -0
- pythonlings-0.3.0/CHANGELOG.md +71 -0
- pythonlings-0.3.0/CLAUDE.md +61 -0
- pythonlings-0.3.0/CNAME +1 -0
- pythonlings-0.3.0/CODE_OF_CONDUCT.md +13 -0
- pythonlings-0.3.0/CONTRIBUTING.md +46 -0
- pythonlings-0.3.0/LICENSE +21 -0
- pythonlings-0.3.0/PKG-INFO +259 -0
- pythonlings-0.3.0/RELEASE.md +48 -0
- pythonlings-0.3.0/Readme.md +224 -0
- pythonlings-0.3.0/SECURITY.md +5 -0
- pythonlings-0.3.0/checks/async/async1.py +4 -0
- pythonlings-0.3.0/checks/async/async10.py +4 -0
- pythonlings-0.3.0/checks/async/async2.py +4 -0
- pythonlings-0.3.0/checks/async/async3.py +4 -0
- pythonlings-0.3.0/checks/async/async4.py +4 -0
- pythonlings-0.3.0/checks/async/async5.py +4 -0
- pythonlings-0.3.0/checks/async/async6.py +4 -0
- pythonlings-0.3.0/checks/async/async7.py +4 -0
- pythonlings-0.3.0/checks/async/async8.py +2 -0
- pythonlings-0.3.0/checks/async/async9.py +4 -0
- pythonlings-0.3.0/checks/classes/classes1.py +3 -0
- pythonlings-0.3.0/checks/classes/classes10.py +5 -0
- pythonlings-0.3.0/checks/classes/classes11.py +5 -0
- pythonlings-0.3.0/checks/classes/classes12.py +16 -0
- pythonlings-0.3.0/checks/classes/classes2.py +3 -0
- pythonlings-0.3.0/checks/classes/classes3.py +4 -0
- pythonlings-0.3.0/checks/classes/classes4.py +4 -0
- pythonlings-0.3.0/checks/classes/classes5.py +5 -0
- pythonlings-0.3.0/checks/classes/classes6.py +4 -0
- pythonlings-0.3.0/checks/classes/classes7.py +3 -0
- pythonlings-0.3.0/checks/classes/classes8.py +3 -0
- pythonlings-0.3.0/checks/classes/classes9.py +4 -0
- pythonlings-0.3.0/checks/collections/collections1.py +4 -0
- pythonlings-0.3.0/checks/collections/collections10.py +15 -0
- pythonlings-0.3.0/checks/collections/collections2.py +4 -0
- pythonlings-0.3.0/checks/collections/collections3.py +5 -0
- pythonlings-0.3.0/checks/collections/collections4.py +4 -0
- pythonlings-0.3.0/checks/collections/collections5.py +5 -0
- pythonlings-0.3.0/checks/collections/collections6.py +6 -0
- pythonlings-0.3.0/checks/collections/collections7.py +4 -0
- pythonlings-0.3.0/checks/collections/collections8.py +5 -0
- pythonlings-0.3.0/checks/collections/collections9.py +9 -0
- pythonlings-0.3.0/checks/comprehensions/comprehensions1.py +3 -0
- pythonlings-0.3.0/checks/comprehensions/comprehensions10.py +5 -0
- pythonlings-0.3.0/checks/comprehensions/comprehensions2.py +3 -0
- pythonlings-0.3.0/checks/comprehensions/comprehensions3.py +3 -0
- pythonlings-0.3.0/checks/comprehensions/comprehensions4.py +6 -0
- pythonlings-0.3.0/checks/comprehensions/comprehensions5.py +3 -0
- pythonlings-0.3.0/checks/comprehensions/comprehensions6.py +3 -0
- pythonlings-0.3.0/checks/comprehensions/comprehensions7.py +4 -0
- pythonlings-0.3.0/checks/comprehensions/comprehensions8.py +5 -0
- pythonlings-0.3.0/checks/comprehensions/comprehensions9.py +3 -0
- pythonlings-0.3.0/checks/conditionals/conditionals1.py +2 -0
- pythonlings-0.3.0/checks/conditionals/conditionals10.py +10 -0
- pythonlings-0.3.0/checks/conditionals/conditionals2.py +5 -0
- pythonlings-0.3.0/checks/conditionals/conditionals3.py +9 -0
- pythonlings-0.3.0/checks/conditionals/conditionals4.py +7 -0
- pythonlings-0.3.0/checks/conditionals/conditionals5.py +9 -0
- pythonlings-0.3.0/checks/conditionals/conditionals6.py +7 -0
- pythonlings-0.3.0/checks/conditionals/conditionals7.py +7 -0
- pythonlings-0.3.0/checks/conditionals/conditionals8.py +9 -0
- pythonlings-0.3.0/checks/conditionals/conditionals9.py +7 -0
- pythonlings-0.3.0/checks/context_managers/context_managers1.py +15 -0
- pythonlings-0.3.0/checks/context_managers/context_managers2.py +10 -0
- pythonlings-0.3.0/checks/context_managers/context_managers3.py +2 -0
- pythonlings-0.3.0/checks/context_managers/context_managers4.py +3 -0
- pythonlings-0.3.0/checks/context_managers/context_managers5.py +5 -0
- pythonlings-0.3.0/checks/context_managers/context_managers6.py +4 -0
- pythonlings-0.3.0/checks/context_managers/context_managers7.py +16 -0
- pythonlings-0.3.0/checks/context_managers/context_managers8.py +15 -0
- pythonlings-0.3.0/checks/dataclasses/dataclasses1.py +3 -0
- pythonlings-0.3.0/checks/dataclasses/dataclasses2.py +5 -0
- pythonlings-0.3.0/checks/dataclasses/dataclasses3.py +4 -0
- pythonlings-0.3.0/checks/dataclasses/dataclasses4.py +3 -0
- pythonlings-0.3.0/checks/dataclasses/dataclasses5.py +9 -0
- pythonlings-0.3.0/checks/dataclasses/dataclasses6.py +6 -0
- pythonlings-0.3.0/checks/dataclasses/dataclasses7.py +6 -0
- pythonlings-0.3.0/checks/dataclasses/dataclasses8.py +5 -0
- pythonlings-0.3.0/checks/datetime/datetime1.py +4 -0
- pythonlings-0.3.0/checks/datetime/datetime2.py +4 -0
- pythonlings-0.3.0/checks/datetime/datetime3.py +6 -0
- pythonlings-0.3.0/checks/datetime/datetime4.py +2 -0
- pythonlings-0.3.0/checks/datetime/datetime5.py +2 -0
- pythonlings-0.3.0/checks/datetime/datetime6.py +2 -0
- pythonlings-0.3.0/checks/datetime/datetime7.py +2 -0
- pythonlings-0.3.0/checks/datetime/datetime8.py +5 -0
- pythonlings-0.3.0/checks/decorators/decorators1.py +8 -0
- pythonlings-0.3.0/checks/decorators/decorators10.py +12 -0
- pythonlings-0.3.0/checks/decorators/decorators2.py +5 -0
- pythonlings-0.3.0/checks/decorators/decorators3.py +4 -0
- pythonlings-0.3.0/checks/decorators/decorators4.py +7 -0
- pythonlings-0.3.0/checks/decorators/decorators5.py +5 -0
- pythonlings-0.3.0/checks/decorators/decorators6.py +8 -0
- pythonlings-0.3.0/checks/decorators/decorators7.py +12 -0
- pythonlings-0.3.0/checks/decorators/decorators8.py +20 -0
- pythonlings-0.3.0/checks/decorators/decorators9.py +4 -0
- pythonlings-0.3.0/checks/dictionaries/dictionaries1.py +3 -0
- pythonlings-0.3.0/checks/dictionaries/dictionaries10.py +5 -0
- pythonlings-0.3.0/checks/dictionaries/dictionaries2.py +2 -0
- pythonlings-0.3.0/checks/dictionaries/dictionaries3.py +5 -0
- pythonlings-0.3.0/checks/dictionaries/dictionaries4.py +5 -0
- pythonlings-0.3.0/checks/dictionaries/dictionaries5.py +11 -0
- pythonlings-0.3.0/checks/dictionaries/dictionaries6.py +4 -0
- pythonlings-0.3.0/checks/dictionaries/dictionaries7.py +5 -0
- pythonlings-0.3.0/checks/dictionaries/dictionaries8.py +4 -0
- pythonlings-0.3.0/checks/dictionaries/dictionaries9.py +4 -0
- pythonlings-0.3.0/checks/enums/enums1.py +4 -0
- pythonlings-0.3.0/checks/enums/enums2.py +3 -0
- pythonlings-0.3.0/checks/enums/enums3.py +3 -0
- pythonlings-0.3.0/checks/enums/enums4.py +2 -0
- pythonlings-0.3.0/checks/enums/enums5.py +4 -0
- pythonlings-0.3.0/checks/enums/enums6.py +3 -0
- pythonlings-0.3.0/checks/exceptions/exceptions1.py +4 -0
- pythonlings-0.3.0/checks/exceptions/exceptions10.py +39 -0
- pythonlings-0.3.0/checks/exceptions/exceptions2.py +5 -0
- pythonlings-0.3.0/checks/exceptions/exceptions3.py +8 -0
- pythonlings-0.3.0/checks/exceptions/exceptions4.py +5 -0
- pythonlings-0.3.0/checks/exceptions/exceptions5.py +10 -0
- pythonlings-0.3.0/checks/exceptions/exceptions6.py +17 -0
- pythonlings-0.3.0/checks/exceptions/exceptions7.py +15 -0
- pythonlings-0.3.0/checks/exceptions/exceptions8.py +6 -0
- pythonlings-0.3.0/checks/exceptions/exceptions9.py +16 -0
- pythonlings-0.3.0/checks/file_io/file_io1.py +15 -0
- pythonlings-0.3.0/checks/file_io/file_io10.py +16 -0
- pythonlings-0.3.0/checks/file_io/file_io2.py +10 -0
- pythonlings-0.3.0/checks/file_io/file_io3.py +15 -0
- pythonlings-0.3.0/checks/file_io/file_io4.py +14 -0
- pythonlings-0.3.0/checks/file_io/file_io5.py +15 -0
- pythonlings-0.3.0/checks/file_io/file_io6.py +10 -0
- pythonlings-0.3.0/checks/file_io/file_io7.py +15 -0
- pythonlings-0.3.0/checks/file_io/file_io8.py +12 -0
- pythonlings-0.3.0/checks/file_io/file_io9.py +10 -0
- pythonlings-0.3.0/checks/functional/functional1.py +4 -0
- pythonlings-0.3.0/checks/functional/functional10.py +7 -0
- pythonlings-0.3.0/checks/functional/functional2.py +5 -0
- pythonlings-0.3.0/checks/functional/functional3.py +3 -0
- pythonlings-0.3.0/checks/functional/functional4.py +4 -0
- pythonlings-0.3.0/checks/functional/functional5.py +6 -0
- pythonlings-0.3.0/checks/functional/functional6.py +8 -0
- pythonlings-0.3.0/checks/functional/functional7.py +8 -0
- pythonlings-0.3.0/checks/functional/functional8.py +7 -0
- pythonlings-0.3.0/checks/functional/functional9.py +8 -0
- pythonlings-0.3.0/checks/functions/functions1.py +9 -0
- pythonlings-0.3.0/checks/functions/functions10.py +12 -0
- pythonlings-0.3.0/checks/functions/functions2.py +4 -0
- pythonlings-0.3.0/checks/functions/functions3.py +6 -0
- pythonlings-0.3.0/checks/functions/functions4.py +6 -0
- pythonlings-0.3.0/checks/functions/functions5.py +6 -0
- pythonlings-0.3.0/checks/functions/functions6.py +8 -0
- pythonlings-0.3.0/checks/functions/functions7.py +7 -0
- pythonlings-0.3.0/checks/functions/functions8.py +6 -0
- pythonlings-0.3.0/checks/functions/functions9.py +7 -0
- pythonlings-0.3.0/checks/generators/generators1.py +4 -0
- pythonlings-0.3.0/checks/generators/generators10.py +7 -0
- pythonlings-0.3.0/checks/generators/generators2.py +3 -0
- pythonlings-0.3.0/checks/generators/generators3.py +4 -0
- pythonlings-0.3.0/checks/generators/generators4.py +9 -0
- pythonlings-0.3.0/checks/generators/generators5.py +10 -0
- pythonlings-0.3.0/checks/generators/generators6.py +8 -0
- pythonlings-0.3.0/checks/generators/generators7.py +11 -0
- pythonlings-0.3.0/checks/generators/generators8.py +8 -0
- pythonlings-0.3.0/checks/generators/generators9.py +13 -0
- pythonlings-0.3.0/checks/itertools/itertools1.py +2 -0
- pythonlings-0.3.0/checks/itertools/itertools2.py +2 -0
- pythonlings-0.3.0/checks/itertools/itertools3.py +2 -0
- pythonlings-0.3.0/checks/itertools/itertools4.py +2 -0
- pythonlings-0.3.0/checks/itertools/itertools5.py +2 -0
- pythonlings-0.3.0/checks/itertools/itertools6.py +2 -0
- pythonlings-0.3.0/checks/itertools/itertools7.py +2 -0
- pythonlings-0.3.0/checks/itertools/itertools8.py +3 -0
- pythonlings-0.3.0/checks/json/json1.py +3 -0
- pythonlings-0.3.0/checks/json/json2.py +2 -0
- pythonlings-0.3.0/checks/json/json3.py +2 -0
- pythonlings-0.3.0/checks/json/json4.py +2 -0
- pythonlings-0.3.0/checks/json/json5.py +2 -0
- pythonlings-0.3.0/checks/json/json6.py +2 -0
- pythonlings-0.3.0/checks/json/json7.py +3 -0
- pythonlings-0.3.0/checks/json/json8.py +4 -0
- pythonlings-0.3.0/checks/lists/lists1.py +2 -0
- pythonlings-0.3.0/checks/lists/lists10.py +5 -0
- pythonlings-0.3.0/checks/lists/lists2.py +3 -0
- pythonlings-0.3.0/checks/lists/lists3.py +4 -0
- pythonlings-0.3.0/checks/lists/lists4.py +3 -0
- pythonlings-0.3.0/checks/lists/lists5.py +4 -0
- pythonlings-0.3.0/checks/lists/lists6.py +3 -0
- pythonlings-0.3.0/checks/lists/lists7.py +4 -0
- pythonlings-0.3.0/checks/lists/lists8.py +7 -0
- pythonlings-0.3.0/checks/lists/lists9.py +4 -0
- pythonlings-0.3.0/checks/loops/loops1.py +2 -0
- pythonlings-0.3.0/checks/loops/loops10.py +6 -0
- pythonlings-0.3.0/checks/loops/loops2.py +2 -0
- pythonlings-0.3.0/checks/loops/loops3.py +2 -0
- pythonlings-0.3.0/checks/loops/loops4.py +3 -0
- pythonlings-0.3.0/checks/loops/loops5.py +2 -0
- pythonlings-0.3.0/checks/loops/loops6.py +2 -0
- pythonlings-0.3.0/checks/loops/loops7.py +2 -0
- pythonlings-0.3.0/checks/loops/loops8.py +2 -0
- pythonlings-0.3.0/checks/loops/loops9.py +3 -0
- pythonlings-0.3.0/checks/modules/modules1.py +2 -0
- pythonlings-0.3.0/checks/modules/modules2.py +2 -0
- pythonlings-0.3.0/checks/modules/modules3.py +5 -0
- pythonlings-0.3.0/checks/modules/modules4.py +8 -0
- pythonlings-0.3.0/checks/modules/modules5.py +7 -0
- pythonlings-0.3.0/checks/modules/modules6.py +4 -0
- pythonlings-0.3.0/checks/modules/modules7.py +4 -0
- pythonlings-0.3.0/checks/modules/modules8.py +15 -0
- pythonlings-0.3.0/checks/oop_advanced/oop_advanced1.py +4 -0
- pythonlings-0.3.0/checks/oop_advanced/oop_advanced10.py +3 -0
- pythonlings-0.3.0/checks/oop_advanced/oop_advanced11.py +3 -0
- pythonlings-0.3.0/checks/oop_advanced/oop_advanced12.py +4 -0
- pythonlings-0.3.0/checks/oop_advanced/oop_advanced2.py +4 -0
- pythonlings-0.3.0/checks/oop_advanced/oop_advanced3.py +3 -0
- pythonlings-0.3.0/checks/oop_advanced/oop_advanced4.py +3 -0
- pythonlings-0.3.0/checks/oop_advanced/oop_advanced5.py +3 -0
- pythonlings-0.3.0/checks/oop_advanced/oop_advanced6.py +2 -0
- pythonlings-0.3.0/checks/oop_advanced/oop_advanced7.py +3 -0
- pythonlings-0.3.0/checks/oop_advanced/oop_advanced8.py +3 -0
- pythonlings-0.3.0/checks/oop_advanced/oop_advanced9.py +4 -0
- pythonlings-0.3.0/checks/pathlib/pathlib1.py +5 -0
- pythonlings-0.3.0/checks/pathlib/pathlib2.py +4 -0
- pythonlings-0.3.0/checks/pathlib/pathlib3.py +6 -0
- pythonlings-0.3.0/checks/pathlib/pathlib4.py +4 -0
- pythonlings-0.3.0/checks/pathlib/pathlib5.py +4 -0
- pythonlings-0.3.0/checks/pathlib/pathlib6.py +5 -0
- pythonlings-0.3.0/checks/recursion/recursion1.py +5 -0
- pythonlings-0.3.0/checks/recursion/recursion2.py +5 -0
- pythonlings-0.3.0/checks/recursion/recursion3.py +6 -0
- pythonlings-0.3.0/checks/recursion/recursion4.py +6 -0
- pythonlings-0.3.0/checks/recursion/recursion5.py +7 -0
- pythonlings-0.3.0/checks/recursion/recursion6.py +7 -0
- pythonlings-0.3.0/checks/recursion/recursion7.py +7 -0
- pythonlings-0.3.0/checks/recursion/recursion8.py +15 -0
- pythonlings-0.3.0/checks/regex/regex1.py +3 -0
- pythonlings-0.3.0/checks/regex/regex10.py +17 -0
- pythonlings-0.3.0/checks/regex/regex2.py +3 -0
- pythonlings-0.3.0/checks/regex/regex3.py +2 -0
- pythonlings-0.3.0/checks/regex/regex4.py +4 -0
- pythonlings-0.3.0/checks/regex/regex5.py +4 -0
- pythonlings-0.3.0/checks/regex/regex6.py +6 -0
- pythonlings-0.3.0/checks/regex/regex7.py +5 -0
- pythonlings-0.3.0/checks/regex/regex8.py +6 -0
- pythonlings-0.3.0/checks/regex/regex9.py +8 -0
- pythonlings-0.3.0/checks/sets/sets1.py +3 -0
- pythonlings-0.3.0/checks/sets/sets10.py +15 -0
- pythonlings-0.3.0/checks/sets/sets2.py +5 -0
- pythonlings-0.3.0/checks/sets/sets3.py +5 -0
- pythonlings-0.3.0/checks/sets/sets4.py +3 -0
- pythonlings-0.3.0/checks/sets/sets5.py +3 -0
- pythonlings-0.3.0/checks/sets/sets6.py +3 -0
- pythonlings-0.3.0/checks/sets/sets7.py +5 -0
- pythonlings-0.3.0/checks/sets/sets8.py +5 -0
- pythonlings-0.3.0/checks/sets/sets9.py +3 -0
- pythonlings-0.3.0/checks/strings/strings1.py +3 -0
- pythonlings-0.3.0/checks/strings/strings10.py +5 -0
- pythonlings-0.3.0/checks/strings/strings2.py +3 -0
- pythonlings-0.3.0/checks/strings/strings3.py +3 -0
- pythonlings-0.3.0/checks/strings/strings4.py +2 -0
- pythonlings-0.3.0/checks/strings/strings5.py +4 -0
- pythonlings-0.3.0/checks/strings/strings6.py +3 -0
- pythonlings-0.3.0/checks/strings/strings7.py +3 -0
- pythonlings-0.3.0/checks/strings/strings8.py +3 -0
- pythonlings-0.3.0/checks/strings/strings9.py +3 -0
- pythonlings-0.3.0/checks/testing/testing1.py +2 -0
- pythonlings-0.3.0/checks/testing/testing10.py +9 -0
- pythonlings-0.3.0/checks/testing/testing11.py +7 -0
- pythonlings-0.3.0/checks/testing/testing12.py +19 -0
- pythonlings-0.3.0/checks/testing/testing2.py +2 -0
- pythonlings-0.3.0/checks/testing/testing3.py +12 -0
- pythonlings-0.3.0/checks/testing/testing4.py +6 -0
- pythonlings-0.3.0/checks/testing/testing5.py +6 -0
- pythonlings-0.3.0/checks/testing/testing6.py +14 -0
- pythonlings-0.3.0/checks/testing/testing7.py +14 -0
- pythonlings-0.3.0/checks/testing/testing8.py +27 -0
- pythonlings-0.3.0/checks/testing/testing9.py +14 -0
- pythonlings-0.3.0/checks/tuples/tuples1.py +3 -0
- pythonlings-0.3.0/checks/tuples/tuples10.py +6 -0
- pythonlings-0.3.0/checks/tuples/tuples2.py +3 -0
- pythonlings-0.3.0/checks/tuples/tuples3.py +4 -0
- pythonlings-0.3.0/checks/tuples/tuples4.py +3 -0
- pythonlings-0.3.0/checks/tuples/tuples5.py +4 -0
- pythonlings-0.3.0/checks/tuples/tuples6.py +5 -0
- pythonlings-0.3.0/checks/tuples/tuples7.py +3 -0
- pythonlings-0.3.0/checks/tuples/tuples8.py +4 -0
- pythonlings-0.3.0/checks/tuples/tuples9.py +5 -0
- pythonlings-0.3.0/checks/type_hints/type_hints1.py +3 -0
- pythonlings-0.3.0/checks/type_hints/type_hints2.py +5 -0
- pythonlings-0.3.0/checks/type_hints/type_hints3.py +5 -0
- pythonlings-0.3.0/checks/type_hints/type_hints4.py +5 -0
- pythonlings-0.3.0/checks/type_hints/type_hints5.py +6 -0
- pythonlings-0.3.0/checks/type_hints/type_hints6.py +7 -0
- pythonlings-0.3.0/checks/type_hints/type_hints7.py +9 -0
- pythonlings-0.3.0/checks/type_hints/type_hints8.py +9 -0
- pythonlings-0.3.0/checks/variables/variables1.py +7 -0
- pythonlings-0.3.0/checks/variables/variables10.py +4 -0
- pythonlings-0.3.0/checks/variables/variables2.py +19 -0
- pythonlings-0.3.0/checks/variables/variables3.py +4 -0
- pythonlings-0.3.0/checks/variables/variables4.py +2 -0
- pythonlings-0.3.0/checks/variables/variables5.py +2 -0
- pythonlings-0.3.0/checks/variables/variables6.py +4 -0
- pythonlings-0.3.0/checks/variables/variables7.py +3 -0
- pythonlings-0.3.0/checks/variables/variables8.py +4 -0
- pythonlings-0.3.0/checks/variables/variables9.py +3 -0
- pythonlings-0.3.0/docs/DEMO_GIF.md +69 -0
- pythonlings-0.3.0/docs/RELEASE_PROCESS.md +27 -0
- pythonlings-0.3.0/docs/assets/demos/pythonlings-demo.gif +0 -0
- pythonlings-0.3.0/docs/assets/screenshots/coding-screen.png +0 -0
- pythonlings-0.3.0/docs/assets/screenshots/docs-reference.png +0 -0
- pythonlings-0.3.0/docs/assets/screenshots/topic-picker.png +0 -0
- pythonlings-0.3.0/docs/demo.tape +43 -0
- pythonlings-0.3.0/docs/roadmap/0.3.0.md +58 -0
- pythonlings-0.3.0/docs/superpowers/plans/2026-05-19-pylings-rustlings-ux.md +2735 -0
- pythonlings-0.3.0/docs/superpowers/plans/2026-05-20-pylings-builtin-editor.md +867 -0
- pythonlings-0.3.0/docs/superpowers/plans/2026-05-20-pylings-hidden-checks.md +927 -0
- pythonlings-0.3.0/docs/superpowers/plans/2026-05-20-pylings-topics-and-curriculum.md +1310 -0
- pythonlings-0.3.0/docs/superpowers/plans/2026-05-22-pylings-interaction-model-upgrade.md +851 -0
- pythonlings-0.3.0/docs/superpowers/plans/2026-05-23-pylings-roadmap-curriculum-completion.md +141 -0
- pythonlings-0.3.0/docs/superpowers/plans/2026-05-25-pylings-product-maturity.md +1325 -0
- pythonlings-0.3.0/docs/superpowers/plans/2026-05-26-pylings-docs-site.md +852 -0
- pythonlings-0.3.0/docs/superpowers/specs/2026-05-19-pylings-rustlings-ux-design.md +438 -0
- pythonlings-0.3.0/docs/superpowers/specs/2026-05-20-pylings-builtin-editor-design.md +306 -0
- pythonlings-0.3.0/docs/superpowers/specs/2026-05-20-pylings-hidden-checks-design.md +292 -0
- pythonlings-0.3.0/docs/superpowers/specs/2026-05-20-pylings-topics-and-curriculum-design.md +290 -0
- pythonlings-0.3.0/docs/superpowers/specs/2026-05-22-pylings-interaction-model-upgrade-design.md +183 -0
- pythonlings-0.3.0/docs/superpowers/specs/2026-05-23-pylings-roadmap-curriculum-completion-design.md +87 -0
- pythonlings-0.3.0/docs/superpowers/specs/2026-05-26-pylings-docs-site-design.md +110 -0
- pythonlings-0.3.0/docs/superpowers/specs/2026-06-02-gap-audit-design.md +148 -0
- pythonlings-0.3.0/docs-site/CNAME +1 -0
- pythonlings-0.3.0/docs-site/contributing.md +38 -0
- pythonlings-0.3.0/docs-site/curriculum.md +58 -0
- pythonlings-0.3.0/docs-site/index.md +36 -0
- pythonlings-0.3.0/docs-site/interface.md +35 -0
- pythonlings-0.3.0/docs-site/local-docs.md +33 -0
- pythonlings-0.3.0/docs-site/quick-start.md +51 -0
- pythonlings-0.3.0/docs-site/roadmap.md +29 -0
- pythonlings-0.3.0/docs-site/robots.txt +4 -0
- pythonlings-0.3.0/exercises/async/async1.py +7 -0
- pythonlings-0.3.0/exercises/async/async10.py +14 -0
- pythonlings-0.3.0/exercises/async/async2.py +10 -0
- pythonlings-0.3.0/exercises/async/async3.py +10 -0
- pythonlings-0.3.0/exercises/async/async4.py +15 -0
- pythonlings-0.3.0/exercises/async/async5.py +13 -0
- pythonlings-0.3.0/exercises/async/async6.py +14 -0
- pythonlings-0.3.0/exercises/async/async7.py +13 -0
- pythonlings-0.3.0/exercises/async/async8.py +11 -0
- pythonlings-0.3.0/exercises/async/async9.py +13 -0
- pythonlings-0.3.0/exercises/classes/classes1.py +13 -0
- pythonlings-0.3.0/exercises/classes/classes10.py +22 -0
- pythonlings-0.3.0/exercises/classes/classes11.py +24 -0
- pythonlings-0.3.0/exercises/classes/classes12.py +33 -0
- pythonlings-0.3.0/exercises/classes/classes2.py +13 -0
- pythonlings-0.3.0/exercises/classes/classes3.py +13 -0
- pythonlings-0.3.0/exercises/classes/classes4.py +16 -0
- pythonlings-0.3.0/exercises/classes/classes5.py +18 -0
- pythonlings-0.3.0/exercises/classes/classes6.py +15 -0
- pythonlings-0.3.0/exercises/classes/classes7.py +18 -0
- pythonlings-0.3.0/exercises/classes/classes8.py +14 -0
- pythonlings-0.3.0/exercises/classes/classes9.py +18 -0
- pythonlings-0.3.0/exercises/collections/collections1.py +11 -0
- pythonlings-0.3.0/exercises/collections/collections10.py +37 -0
- pythonlings-0.3.0/exercises/collections/collections2.py +18 -0
- pythonlings-0.3.0/exercises/collections/collections3.py +17 -0
- pythonlings-0.3.0/exercises/collections/collections4.py +26 -0
- pythonlings-0.3.0/exercises/collections/collections5.py +14 -0
- pythonlings-0.3.0/exercises/collections/collections6.py +18 -0
- pythonlings-0.3.0/exercises/collections/collections7.py +20 -0
- pythonlings-0.3.0/exercises/collections/collections8.py +23 -0
- pythonlings-0.3.0/exercises/collections/collections9.py +21 -0
- pythonlings-0.3.0/exercises/comprehensions/comprehensions1.py +10 -0
- pythonlings-0.3.0/exercises/comprehensions/comprehensions10.py +15 -0
- pythonlings-0.3.0/exercises/comprehensions/comprehensions2.py +12 -0
- pythonlings-0.3.0/exercises/comprehensions/comprehensions3.py +12 -0
- pythonlings-0.3.0/exercises/comprehensions/comprehensions4.py +14 -0
- pythonlings-0.3.0/exercises/comprehensions/comprehensions5.py +12 -0
- pythonlings-0.3.0/exercises/comprehensions/comprehensions6.py +12 -0
- pythonlings-0.3.0/exercises/comprehensions/comprehensions7.py +12 -0
- pythonlings-0.3.0/exercises/comprehensions/comprehensions8.py +15 -0
- pythonlings-0.3.0/exercises/comprehensions/comprehensions9.py +13 -0
- pythonlings-0.3.0/exercises/conditionals/conditionals1.py +15 -0
- pythonlings-0.3.0/exercises/conditionals/conditionals10.py +18 -0
- pythonlings-0.3.0/exercises/conditionals/conditionals2.py +13 -0
- pythonlings-0.3.0/exercises/conditionals/conditionals3.py +18 -0
- pythonlings-0.3.0/exercises/conditionals/conditionals4.py +20 -0
- pythonlings-0.3.0/exercises/conditionals/conditionals5.py +17 -0
- pythonlings-0.3.0/exercises/conditionals/conditionals6.py +15 -0
- pythonlings-0.3.0/exercises/conditionals/conditionals7.py +18 -0
- pythonlings-0.3.0/exercises/conditionals/conditionals8.py +20 -0
- pythonlings-0.3.0/exercises/conditionals/conditionals9.py +12 -0
- pythonlings-0.3.0/exercises/context_managers/context_managers1.py +18 -0
- pythonlings-0.3.0/exercises/context_managers/context_managers2.py +19 -0
- pythonlings-0.3.0/exercises/context_managers/context_managers3.py +24 -0
- pythonlings-0.3.0/exercises/context_managers/context_managers4.py +30 -0
- pythonlings-0.3.0/exercises/context_managers/context_managers5.py +30 -0
- pythonlings-0.3.0/exercises/context_managers/context_managers6.py +26 -0
- pythonlings-0.3.0/exercises/context_managers/context_managers7.py +30 -0
- pythonlings-0.3.0/exercises/context_managers/context_managers8.py +45 -0
- pythonlings-0.3.0/exercises/dataclasses/dataclasses1.py +14 -0
- pythonlings-0.3.0/exercises/dataclasses/dataclasses2.py +23 -0
- pythonlings-0.3.0/exercises/dataclasses/dataclasses3.py +21 -0
- pythonlings-0.3.0/exercises/dataclasses/dataclasses4.py +25 -0
- pythonlings-0.3.0/exercises/dataclasses/dataclasses5.py +25 -0
- pythonlings-0.3.0/exercises/dataclasses/dataclasses6.py +21 -0
- pythonlings-0.3.0/exercises/dataclasses/dataclasses7.py +27 -0
- pythonlings-0.3.0/exercises/dataclasses/dataclasses8.py +30 -0
- pythonlings-0.3.0/exercises/datetime/datetime1.py +8 -0
- pythonlings-0.3.0/exercises/datetime/datetime2.py +9 -0
- pythonlings-0.3.0/exercises/datetime/datetime3.py +9 -0
- pythonlings-0.3.0/exercises/datetime/datetime4.py +9 -0
- pythonlings-0.3.0/exercises/datetime/datetime5.py +10 -0
- pythonlings-0.3.0/exercises/datetime/datetime6.py +10 -0
- pythonlings-0.3.0/exercises/datetime/datetime7.py +10 -0
- pythonlings-0.3.0/exercises/datetime/datetime8.py +11 -0
- pythonlings-0.3.0/exercises/decorators/decorators1.py +19 -0
- pythonlings-0.3.0/exercises/decorators/decorators10.py +32 -0
- pythonlings-0.3.0/exercises/decorators/decorators2.py +22 -0
- pythonlings-0.3.0/exercises/decorators/decorators3.py +18 -0
- pythonlings-0.3.0/exercises/decorators/decorators4.py +24 -0
- pythonlings-0.3.0/exercises/decorators/decorators5.py +25 -0
- pythonlings-0.3.0/exercises/decorators/decorators6.py +19 -0
- pythonlings-0.3.0/exercises/decorators/decorators7.py +25 -0
- pythonlings-0.3.0/exercises/decorators/decorators8.py +25 -0
- pythonlings-0.3.0/exercises/decorators/decorators9.py +26 -0
- pythonlings-0.3.0/exercises/dictionaries/dictionaries1.py +6 -0
- pythonlings-0.3.0/exercises/dictionaries/dictionaries10.py +17 -0
- pythonlings-0.3.0/exercises/dictionaries/dictionaries2.py +9 -0
- pythonlings-0.3.0/exercises/dictionaries/dictionaries3.py +16 -0
- pythonlings-0.3.0/exercises/dictionaries/dictionaries4.py +15 -0
- pythonlings-0.3.0/exercises/dictionaries/dictionaries5.py +15 -0
- pythonlings-0.3.0/exercises/dictionaries/dictionaries6.py +18 -0
- pythonlings-0.3.0/exercises/dictionaries/dictionaries7.py +17 -0
- pythonlings-0.3.0/exercises/dictionaries/dictionaries8.py +17 -0
- pythonlings-0.3.0/exercises/dictionaries/dictionaries9.py +25 -0
- pythonlings-0.3.0/exercises/enums/enums1.py +12 -0
- pythonlings-0.3.0/exercises/enums/enums2.py +11 -0
- pythonlings-0.3.0/exercises/enums/enums3.py +14 -0
- pythonlings-0.3.0/exercises/enums/enums4.py +13 -0
- pythonlings-0.3.0/exercises/enums/enums5.py +14 -0
- pythonlings-0.3.0/exercises/enums/enums6.py +15 -0
- pythonlings-0.3.0/exercises/exceptions/exceptions1.py +15 -0
- pythonlings-0.3.0/exercises/exceptions/exceptions10.py +19 -0
- pythonlings-0.3.0/exercises/exceptions/exceptions2.py +12 -0
- pythonlings-0.3.0/exercises/exceptions/exceptions3.py +13 -0
- pythonlings-0.3.0/exercises/exceptions/exceptions4.py +17 -0
- pythonlings-0.3.0/exercises/exceptions/exceptions5.py +20 -0
- pythonlings-0.3.0/exercises/exceptions/exceptions6.py +13 -0
- pythonlings-0.3.0/exercises/exceptions/exceptions7.py +15 -0
- pythonlings-0.3.0/exercises/exceptions/exceptions8.py +17 -0
- pythonlings-0.3.0/exercises/exceptions/exceptions9.py +20 -0
- pythonlings-0.3.0/exercises/file_io/file_io1.py +18 -0
- pythonlings-0.3.0/exercises/file_io/file_io10.py +25 -0
- pythonlings-0.3.0/exercises/file_io/file_io2.py +16 -0
- pythonlings-0.3.0/exercises/file_io/file_io3.py +18 -0
- pythonlings-0.3.0/exercises/file_io/file_io4.py +21 -0
- pythonlings-0.3.0/exercises/file_io/file_io5.py +19 -0
- pythonlings-0.3.0/exercises/file_io/file_io6.py +22 -0
- pythonlings-0.3.0/exercises/file_io/file_io7.py +20 -0
- pythonlings-0.3.0/exercises/file_io/file_io8.py +18 -0
- pythonlings-0.3.0/exercises/file_io/file_io9.py +19 -0
- pythonlings-0.3.0/exercises/functional/functional1.py +7 -0
- pythonlings-0.3.0/exercises/functional/functional10.py +19 -0
- pythonlings-0.3.0/exercises/functional/functional2.py +8 -0
- pythonlings-0.3.0/exercises/functional/functional3.py +11 -0
- pythonlings-0.3.0/exercises/functional/functional4.py +11 -0
- pythonlings-0.3.0/exercises/functional/functional5.py +11 -0
- pythonlings-0.3.0/exercises/functional/functional6.py +14 -0
- pythonlings-0.3.0/exercises/functional/functional7.py +12 -0
- pythonlings-0.3.0/exercises/functional/functional8.py +13 -0
- pythonlings-0.3.0/exercises/functional/functional9.py +15 -0
- pythonlings-0.3.0/exercises/functions/functions1.py +8 -0
- pythonlings-0.3.0/exercises/functions/functions10.py +19 -0
- pythonlings-0.3.0/exercises/functions/functions2.py +9 -0
- pythonlings-0.3.0/exercises/functions/functions3.py +8 -0
- pythonlings-0.3.0/exercises/functions/functions4.py +8 -0
- pythonlings-0.3.0/exercises/functions/functions5.py +11 -0
- pythonlings-0.3.0/exercises/functions/functions6.py +16 -0
- pythonlings-0.3.0/exercises/functions/functions7.py +11 -0
- pythonlings-0.3.0/exercises/functions/functions8.py +10 -0
- pythonlings-0.3.0/exercises/functions/functions9.py +16 -0
- pythonlings-0.3.0/exercises/generators/generators1.py +13 -0
- pythonlings-0.3.0/exercises/generators/generators10.py +16 -0
- pythonlings-0.3.0/exercises/generators/generators2.py +17 -0
- pythonlings-0.3.0/exercises/generators/generators3.py +19 -0
- pythonlings-0.3.0/exercises/generators/generators4.py +12 -0
- pythonlings-0.3.0/exercises/generators/generators5.py +24 -0
- pythonlings-0.3.0/exercises/generators/generators6.py +20 -0
- pythonlings-0.3.0/exercises/generators/generators7.py +14 -0
- pythonlings-0.3.0/exercises/generators/generators8.py +17 -0
- pythonlings-0.3.0/exercises/generators/generators9.py +26 -0
- pythonlings-0.3.0/exercises/itertools/itertools1.py +10 -0
- pythonlings-0.3.0/exercises/itertools/itertools2.py +8 -0
- pythonlings-0.3.0/exercises/itertools/itertools3.py +10 -0
- pythonlings-0.3.0/exercises/itertools/itertools4.py +12 -0
- pythonlings-0.3.0/exercises/itertools/itertools5.py +9 -0
- pythonlings-0.3.0/exercises/itertools/itertools6.py +9 -0
- pythonlings-0.3.0/exercises/itertools/itertools7.py +10 -0
- pythonlings-0.3.0/exercises/itertools/itertools8.py +18 -0
- pythonlings-0.3.0/exercises/json/json1.py +10 -0
- pythonlings-0.3.0/exercises/json/json2.py +9 -0
- pythonlings-0.3.0/exercises/json/json3.py +10 -0
- pythonlings-0.3.0/exercises/json/json4.py +13 -0
- pythonlings-0.3.0/exercises/json/json5.py +9 -0
- pythonlings-0.3.0/exercises/json/json6.py +10 -0
- pythonlings-0.3.0/exercises/json/json7.py +10 -0
- pythonlings-0.3.0/exercises/json/json8.py +12 -0
- pythonlings-0.3.0/exercises/lists/lists1.py +7 -0
- pythonlings-0.3.0/exercises/lists/lists10.py +28 -0
- pythonlings-0.3.0/exercises/lists/lists2.py +13 -0
- pythonlings-0.3.0/exercises/lists/lists3.py +16 -0
- pythonlings-0.3.0/exercises/lists/lists4.py +16 -0
- pythonlings-0.3.0/exercises/lists/lists5.py +16 -0
- pythonlings-0.3.0/exercises/lists/lists6.py +15 -0
- pythonlings-0.3.0/exercises/lists/lists7.py +13 -0
- pythonlings-0.3.0/exercises/lists/lists8.py +15 -0
- pythonlings-0.3.0/exercises/lists/lists9.py +19 -0
- pythonlings-0.3.0/exercises/loops/loops1.py +8 -0
- pythonlings-0.3.0/exercises/loops/loops10.py +22 -0
- pythonlings-0.3.0/exercises/loops/loops2.py +10 -0
- pythonlings-0.3.0/exercises/loops/loops3.py +10 -0
- pythonlings-0.3.0/exercises/loops/loops4.py +12 -0
- pythonlings-0.3.0/exercises/loops/loops5.py +13 -0
- pythonlings-0.3.0/exercises/loops/loops6.py +10 -0
- pythonlings-0.3.0/exercises/loops/loops7.py +13 -0
- pythonlings-0.3.0/exercises/loops/loops8.py +11 -0
- pythonlings-0.3.0/exercises/loops/loops9.py +11 -0
- pythonlings-0.3.0/exercises/modules/modules1.py +10 -0
- pythonlings-0.3.0/exercises/modules/modules2.py +10 -0
- pythonlings-0.3.0/exercises/modules/modules3.py +13 -0
- pythonlings-0.3.0/exercises/modules/modules4.py +18 -0
- pythonlings-0.3.0/exercises/modules/modules5.py +17 -0
- pythonlings-0.3.0/exercises/modules/modules6.py +12 -0
- pythonlings-0.3.0/exercises/modules/modules7.py +16 -0
- pythonlings-0.3.0/exercises/modules/modules8.py +23 -0
- pythonlings-0.3.0/exercises/oop_advanced/oop_advanced1.py +11 -0
- pythonlings-0.3.0/exercises/oop_advanced/oop_advanced10.py +18 -0
- pythonlings-0.3.0/exercises/oop_advanced/oop_advanced11.py +13 -0
- pythonlings-0.3.0/exercises/oop_advanced/oop_advanced12.py +12 -0
- pythonlings-0.3.0/exercises/oop_advanced/oop_advanced2.py +13 -0
- pythonlings-0.3.0/exercises/oop_advanced/oop_advanced3.py +22 -0
- pythonlings-0.3.0/exercises/oop_advanced/oop_advanced4.py +12 -0
- pythonlings-0.3.0/exercises/oop_advanced/oop_advanced5.py +11 -0
- pythonlings-0.3.0/exercises/oop_advanced/oop_advanced6.py +12 -0
- pythonlings-0.3.0/exercises/oop_advanced/oop_advanced7.py +14 -0
- pythonlings-0.3.0/exercises/oop_advanced/oop_advanced8.py +14 -0
- pythonlings-0.3.0/exercises/oop_advanced/oop_advanced9.py +9 -0
- pythonlings-0.3.0/exercises/pathlib/pathlib1.py +9 -0
- pythonlings-0.3.0/exercises/pathlib/pathlib2.py +9 -0
- pythonlings-0.3.0/exercises/pathlib/pathlib3.py +11 -0
- pythonlings-0.3.0/exercises/pathlib/pathlib4.py +9 -0
- pythonlings-0.3.0/exercises/pathlib/pathlib5.py +9 -0
- pythonlings-0.3.0/exercises/pathlib/pathlib6.py +10 -0
- pythonlings-0.3.0/exercises/recursion/recursion1.py +12 -0
- pythonlings-0.3.0/exercises/recursion/recursion2.py +12 -0
- pythonlings-0.3.0/exercises/recursion/recursion3.py +12 -0
- pythonlings-0.3.0/exercises/recursion/recursion4.py +12 -0
- pythonlings-0.3.0/exercises/recursion/recursion5.py +14 -0
- pythonlings-0.3.0/exercises/recursion/recursion6.py +13 -0
- pythonlings-0.3.0/exercises/recursion/recursion7.py +20 -0
- pythonlings-0.3.0/exercises/recursion/recursion8.py +27 -0
- pythonlings-0.3.0/exercises/regex/regex1.py +16 -0
- pythonlings-0.3.0/exercises/regex/regex10.py +31 -0
- pythonlings-0.3.0/exercises/regex/regex2.py +16 -0
- pythonlings-0.3.0/exercises/regex/regex3.py +16 -0
- pythonlings-0.3.0/exercises/regex/regex4.py +19 -0
- pythonlings-0.3.0/exercises/regex/regex5.py +19 -0
- pythonlings-0.3.0/exercises/regex/regex6.py +23 -0
- pythonlings-0.3.0/exercises/regex/regex7.py +24 -0
- pythonlings-0.3.0/exercises/regex/regex8.py +19 -0
- pythonlings-0.3.0/exercises/regex/regex9.py +22 -0
- pythonlings-0.3.0/exercises/sets/sets1.py +6 -0
- pythonlings-0.3.0/exercises/sets/sets10.py +21 -0
- pythonlings-0.3.0/exercises/sets/sets2.py +12 -0
- pythonlings-0.3.0/exercises/sets/sets3.py +15 -0
- pythonlings-0.3.0/exercises/sets/sets4.py +14 -0
- pythonlings-0.3.0/exercises/sets/sets5.py +14 -0
- pythonlings-0.3.0/exercises/sets/sets6.py +14 -0
- pythonlings-0.3.0/exercises/sets/sets7.py +16 -0
- pythonlings-0.3.0/exercises/sets/sets8.py +16 -0
- pythonlings-0.3.0/exercises/sets/sets9.py +15 -0
- pythonlings-0.3.0/exercises/strings/strings1.py +6 -0
- pythonlings-0.3.0/exercises/strings/strings10.py +11 -0
- pythonlings-0.3.0/exercises/strings/strings2.py +9 -0
- pythonlings-0.3.0/exercises/strings/strings3.py +9 -0
- pythonlings-0.3.0/exercises/strings/strings4.py +8 -0
- pythonlings-0.3.0/exercises/strings/strings5.py +10 -0
- pythonlings-0.3.0/exercises/strings/strings6.py +10 -0
- pythonlings-0.3.0/exercises/strings/strings7.py +10 -0
- pythonlings-0.3.0/exercises/strings/strings8.py +9 -0
- pythonlings-0.3.0/exercises/strings/strings9.py +10 -0
- pythonlings-0.3.0/exercises/testing/testing1.py +16 -0
- pythonlings-0.3.0/exercises/testing/testing10.py +21 -0
- pythonlings-0.3.0/exercises/testing/testing11.py +27 -0
- pythonlings-0.3.0/exercises/testing/testing12.py +51 -0
- pythonlings-0.3.0/exercises/testing/testing2.py +15 -0
- pythonlings-0.3.0/exercises/testing/testing3.py +19 -0
- pythonlings-0.3.0/exercises/testing/testing4.py +19 -0
- pythonlings-0.3.0/exercises/testing/testing5.py +18 -0
- pythonlings-0.3.0/exercises/testing/testing6.py +27 -0
- pythonlings-0.3.0/exercises/testing/testing7.py +27 -0
- pythonlings-0.3.0/exercises/testing/testing8.py +29 -0
- pythonlings-0.3.0/exercises/testing/testing9.py +30 -0
- pythonlings-0.3.0/exercises/tuples/tuples1.py +7 -0
- pythonlings-0.3.0/exercises/tuples/tuples10.py +26 -0
- pythonlings-0.3.0/exercises/tuples/tuples2.py +11 -0
- pythonlings-0.3.0/exercises/tuples/tuples3.py +9 -0
- pythonlings-0.3.0/exercises/tuples/tuples4.py +8 -0
- pythonlings-0.3.0/exercises/tuples/tuples5.py +12 -0
- pythonlings-0.3.0/exercises/tuples/tuples6.py +15 -0
- pythonlings-0.3.0/exercises/tuples/tuples7.py +14 -0
- pythonlings-0.3.0/exercises/tuples/tuples8.py +13 -0
- pythonlings-0.3.0/exercises/tuples/tuples9.py +18 -0
- pythonlings-0.3.0/exercises/type_hints/type_hints1.py +9 -0
- pythonlings-0.3.0/exercises/type_hints/type_hints2.py +13 -0
- pythonlings-0.3.0/exercises/type_hints/type_hints3.py +13 -0
- pythonlings-0.3.0/exercises/type_hints/type_hints4.py +21 -0
- pythonlings-0.3.0/exercises/type_hints/type_hints5.py +15 -0
- pythonlings-0.3.0/exercises/type_hints/type_hints6.py +16 -0
- pythonlings-0.3.0/exercises/type_hints/type_hints7.py +19 -0
- pythonlings-0.3.0/exercises/type_hints/type_hints8.py +27 -0
- pythonlings-0.3.0/exercises/variables/variables1.py +10 -0
- pythonlings-0.3.0/exercises/variables/variables10.py +14 -0
- pythonlings-0.3.0/exercises/variables/variables2.py +11 -0
- pythonlings-0.3.0/exercises/variables/variables3.py +11 -0
- pythonlings-0.3.0/exercises/variables/variables4.py +9 -0
- pythonlings-0.3.0/exercises/variables/variables5.py +11 -0
- pythonlings-0.3.0/exercises/variables/variables6.py +9 -0
- pythonlings-0.3.0/exercises/variables/variables7.py +10 -0
- pythonlings-0.3.0/exercises/variables/variables8.py +12 -0
- pythonlings-0.3.0/exercises/variables/variables9.py +10 -0
- pythonlings-0.3.0/info.toml +1755 -0
- pythonlings-0.3.0/mkdocs.yml +46 -0
- pythonlings-0.3.0/pyproject.toml +76 -0
- pythonlings-0.3.0/pythonlings/__init__.py +0 -0
- pythonlings-0.3.0/pythonlings/__main__.py +4 -0
- pythonlings-0.3.0/pythonlings/app.py +84 -0
- pythonlings-0.3.0/pythonlings/cli.py +318 -0
- pythonlings-0.3.0/pythonlings/core/__init__.py +0 -0
- pythonlings-0.3.0/pythonlings/core/curriculum.py +106 -0
- pythonlings-0.3.0/pythonlings/core/docs.py +68 -0
- pythonlings-0.3.0/pythonlings/core/exercise.py +33 -0
- pythonlings-0.3.0/pythonlings/core/manifest.py +110 -0
- pythonlings-0.3.0/pythonlings/core/reset.py +43 -0
- pythonlings-0.3.0/pythonlings/core/runner.py +114 -0
- pythonlings-0.3.0/pythonlings/core/solutions.py +17 -0
- pythonlings-0.3.0/pythonlings/core/state.py +86 -0
- pythonlings-0.3.0/pythonlings/docs/NOTICE.md +9 -0
- pythonlings-0.3.0/pythonlings/docs/__init__.py +1 -0
- pythonlings-0.3.0/pythonlings/docs/index.json +160 -0
- pythonlings-0.3.0/pythonlings/docs/topics/__init__.py +1 -0
- pythonlings-0.3.0/pythonlings/docs/topics/async.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/classes.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/collections.md +96 -0
- pythonlings-0.3.0/pythonlings/docs/topics/comprehensions.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/conditionals.md +88 -0
- pythonlings-0.3.0/pythonlings/docs/topics/context_managers.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/dataclasses.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/datetime.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/decorators.md +91 -0
- pythonlings-0.3.0/pythonlings/docs/topics/dictionaries.md +96 -0
- pythonlings-0.3.0/pythonlings/docs/topics/enums.md +96 -0
- pythonlings-0.3.0/pythonlings/docs/topics/exceptions.md +96 -0
- pythonlings-0.3.0/pythonlings/docs/topics/file_io.md +96 -0
- pythonlings-0.3.0/pythonlings/docs/topics/functional.md +96 -0
- pythonlings-0.3.0/pythonlings/docs/topics/functions.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/generators.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/itertools.md +96 -0
- pythonlings-0.3.0/pythonlings/docs/topics/json.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/lists.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/loops.md +95 -0
- pythonlings-0.3.0/pythonlings/docs/topics/modules.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/oop_advanced.md +71 -0
- pythonlings-0.3.0/pythonlings/docs/topics/pathlib.md +79 -0
- pythonlings-0.3.0/pythonlings/docs/topics/recursion.md +73 -0
- pythonlings-0.3.0/pythonlings/docs/topics/regex.md +96 -0
- pythonlings-0.3.0/pythonlings/docs/topics/sets.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/strings.md +96 -0
- pythonlings-0.3.0/pythonlings/docs/topics/testing.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/tuples.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/type_hints.md +97 -0
- pythonlings-0.3.0/pythonlings/docs/topics/variables.md +97 -0
- pythonlings-0.3.0/pythonlings/pythonlings.tcss +123 -0
- pythonlings-0.3.0/pythonlings/screens/__init__.py +0 -0
- pythonlings-0.3.0/pythonlings/screens/docs.py +93 -0
- pythonlings-0.3.0/pythonlings/screens/topic_picker.py +107 -0
- pythonlings-0.3.0/pythonlings/screens/track.py +234 -0
- pythonlings-0.3.0/pythonlings/widgets/__init__.py +0 -0
- pythonlings-0.3.0/pythonlings/widgets/editor_pane.py +33 -0
- pythonlings-0.3.0/pythonlings/widgets/exercise_tree.py +33 -0
- pythonlings-0.3.0/pythonlings/widgets/output_panel.py +180 -0
- pythonlings-0.3.0/pythonlings/widgets/progress.py +15 -0
- pythonlings-0.3.0/requirements-docs.txt +1 -0
- pythonlings-0.3.0/scripts/fetch_python_docs.py +275 -0
- pythonlings-0.3.0/scripts/generate_demo_gif.sh +27 -0
- pythonlings-0.3.0/solutions/.keep +1 -0
- pythonlings-0.3.0/solutions/_answers.py +1654 -0
- pythonlings-0.3.0/solutions/async1.py +2 -0
- pythonlings-0.3.0/solutions/async10.py +2 -0
- pythonlings-0.3.0/solutions/async2.py +2 -0
- pythonlings-0.3.0/solutions/async3.py +2 -0
- pythonlings-0.3.0/solutions/async4.py +2 -0
- pythonlings-0.3.0/solutions/async5.py +2 -0
- pythonlings-0.3.0/solutions/async6.py +2 -0
- pythonlings-0.3.0/solutions/async7.py +2 -0
- pythonlings-0.3.0/solutions/async8.py +2 -0
- pythonlings-0.3.0/solutions/async9.py +2 -0
- pythonlings-0.3.0/solutions/classes1.py +2 -0
- pythonlings-0.3.0/solutions/classes10.py +2 -0
- pythonlings-0.3.0/solutions/classes11.py +2 -0
- pythonlings-0.3.0/solutions/classes12.py +2 -0
- pythonlings-0.3.0/solutions/classes2.py +2 -0
- pythonlings-0.3.0/solutions/classes3.py +2 -0
- pythonlings-0.3.0/solutions/classes4.py +2 -0
- pythonlings-0.3.0/solutions/classes5.py +2 -0
- pythonlings-0.3.0/solutions/classes6.py +2 -0
- pythonlings-0.3.0/solutions/classes7.py +2 -0
- pythonlings-0.3.0/solutions/classes8.py +2 -0
- pythonlings-0.3.0/solutions/classes9.py +2 -0
- pythonlings-0.3.0/solutions/collections1.py +2 -0
- pythonlings-0.3.0/solutions/collections10.py +2 -0
- pythonlings-0.3.0/solutions/collections2.py +2 -0
- pythonlings-0.3.0/solutions/collections3.py +2 -0
- pythonlings-0.3.0/solutions/collections4.py +2 -0
- pythonlings-0.3.0/solutions/collections5.py +2 -0
- pythonlings-0.3.0/solutions/collections6.py +2 -0
- pythonlings-0.3.0/solutions/collections7.py +2 -0
- pythonlings-0.3.0/solutions/collections8.py +2 -0
- pythonlings-0.3.0/solutions/collections9.py +2 -0
- pythonlings-0.3.0/solutions/comprehensions1.py +2 -0
- pythonlings-0.3.0/solutions/comprehensions10.py +2 -0
- pythonlings-0.3.0/solutions/comprehensions2.py +2 -0
- pythonlings-0.3.0/solutions/comprehensions3.py +2 -0
- pythonlings-0.3.0/solutions/comprehensions4.py +2 -0
- pythonlings-0.3.0/solutions/comprehensions5.py +2 -0
- pythonlings-0.3.0/solutions/comprehensions6.py +2 -0
- pythonlings-0.3.0/solutions/comprehensions7.py +2 -0
- pythonlings-0.3.0/solutions/comprehensions8.py +2 -0
- pythonlings-0.3.0/solutions/comprehensions9.py +2 -0
- pythonlings-0.3.0/solutions/conditionals1.py +2 -0
- pythonlings-0.3.0/solutions/conditionals10.py +2 -0
- pythonlings-0.3.0/solutions/conditionals2.py +2 -0
- pythonlings-0.3.0/solutions/conditionals3.py +2 -0
- pythonlings-0.3.0/solutions/conditionals4.py +2 -0
- pythonlings-0.3.0/solutions/conditionals5.py +2 -0
- pythonlings-0.3.0/solutions/conditionals6.py +2 -0
- pythonlings-0.3.0/solutions/conditionals7.py +2 -0
- pythonlings-0.3.0/solutions/conditionals8.py +2 -0
- pythonlings-0.3.0/solutions/conditionals9.py +2 -0
- pythonlings-0.3.0/solutions/context_managers1.py +2 -0
- pythonlings-0.3.0/solutions/context_managers2.py +2 -0
- pythonlings-0.3.0/solutions/context_managers3.py +2 -0
- pythonlings-0.3.0/solutions/context_managers4.py +2 -0
- pythonlings-0.3.0/solutions/context_managers5.py +2 -0
- pythonlings-0.3.0/solutions/context_managers6.py +2 -0
- pythonlings-0.3.0/solutions/context_managers7.py +2 -0
- pythonlings-0.3.0/solutions/context_managers8.py +2 -0
- pythonlings-0.3.0/solutions/dataclasses1.py +2 -0
- pythonlings-0.3.0/solutions/dataclasses2.py +2 -0
- pythonlings-0.3.0/solutions/dataclasses3.py +2 -0
- pythonlings-0.3.0/solutions/dataclasses4.py +2 -0
- pythonlings-0.3.0/solutions/dataclasses5.py +2 -0
- pythonlings-0.3.0/solutions/dataclasses6.py +2 -0
- pythonlings-0.3.0/solutions/dataclasses7.py +2 -0
- pythonlings-0.3.0/solutions/dataclasses8.py +2 -0
- pythonlings-0.3.0/solutions/datetime1.py +2 -0
- pythonlings-0.3.0/solutions/datetime2.py +2 -0
- pythonlings-0.3.0/solutions/datetime3.py +2 -0
- pythonlings-0.3.0/solutions/datetime4.py +2 -0
- pythonlings-0.3.0/solutions/datetime5.py +2 -0
- pythonlings-0.3.0/solutions/datetime6.py +2 -0
- pythonlings-0.3.0/solutions/datetime7.py +2 -0
- pythonlings-0.3.0/solutions/datetime8.py +2 -0
- pythonlings-0.3.0/solutions/decorators1.py +2 -0
- pythonlings-0.3.0/solutions/decorators10.py +2 -0
- pythonlings-0.3.0/solutions/decorators2.py +2 -0
- pythonlings-0.3.0/solutions/decorators3.py +2 -0
- pythonlings-0.3.0/solutions/decorators4.py +2 -0
- pythonlings-0.3.0/solutions/decorators5.py +2 -0
- pythonlings-0.3.0/solutions/decorators6.py +2 -0
- pythonlings-0.3.0/solutions/decorators7.py +2 -0
- pythonlings-0.3.0/solutions/decorators8.py +2 -0
- pythonlings-0.3.0/solutions/decorators9.py +2 -0
- pythonlings-0.3.0/solutions/dictionaries1.py +2 -0
- pythonlings-0.3.0/solutions/dictionaries10.py +2 -0
- pythonlings-0.3.0/solutions/dictionaries2.py +2 -0
- pythonlings-0.3.0/solutions/dictionaries3.py +2 -0
- pythonlings-0.3.0/solutions/dictionaries4.py +2 -0
- pythonlings-0.3.0/solutions/dictionaries5.py +2 -0
- pythonlings-0.3.0/solutions/dictionaries6.py +2 -0
- pythonlings-0.3.0/solutions/dictionaries7.py +2 -0
- pythonlings-0.3.0/solutions/dictionaries8.py +2 -0
- pythonlings-0.3.0/solutions/dictionaries9.py +2 -0
- pythonlings-0.3.0/solutions/enums1.py +2 -0
- pythonlings-0.3.0/solutions/enums2.py +2 -0
- pythonlings-0.3.0/solutions/enums3.py +2 -0
- pythonlings-0.3.0/solutions/enums4.py +2 -0
- pythonlings-0.3.0/solutions/enums5.py +2 -0
- pythonlings-0.3.0/solutions/enums6.py +2 -0
- pythonlings-0.3.0/solutions/exceptions1.py +2 -0
- pythonlings-0.3.0/solutions/exceptions10.py +2 -0
- pythonlings-0.3.0/solutions/exceptions2.py +2 -0
- pythonlings-0.3.0/solutions/exceptions3.py +2 -0
- pythonlings-0.3.0/solutions/exceptions4.py +2 -0
- pythonlings-0.3.0/solutions/exceptions5.py +2 -0
- pythonlings-0.3.0/solutions/exceptions6.py +2 -0
- pythonlings-0.3.0/solutions/exceptions7.py +2 -0
- pythonlings-0.3.0/solutions/exceptions8.py +2 -0
- pythonlings-0.3.0/solutions/exceptions9.py +2 -0
- pythonlings-0.3.0/solutions/file_io1.py +2 -0
- pythonlings-0.3.0/solutions/file_io10.py +2 -0
- pythonlings-0.3.0/solutions/file_io2.py +2 -0
- pythonlings-0.3.0/solutions/file_io3.py +2 -0
- pythonlings-0.3.0/solutions/file_io4.py +2 -0
- pythonlings-0.3.0/solutions/file_io5.py +2 -0
- pythonlings-0.3.0/solutions/file_io6.py +2 -0
- pythonlings-0.3.0/solutions/file_io7.py +2 -0
- pythonlings-0.3.0/solutions/file_io8.py +2 -0
- pythonlings-0.3.0/solutions/file_io9.py +2 -0
- pythonlings-0.3.0/solutions/functional1.py +2 -0
- pythonlings-0.3.0/solutions/functional10.py +2 -0
- pythonlings-0.3.0/solutions/functional2.py +2 -0
- pythonlings-0.3.0/solutions/functional3.py +2 -0
- pythonlings-0.3.0/solutions/functional4.py +2 -0
- pythonlings-0.3.0/solutions/functional5.py +2 -0
- pythonlings-0.3.0/solutions/functional6.py +2 -0
- pythonlings-0.3.0/solutions/functional7.py +2 -0
- pythonlings-0.3.0/solutions/functional8.py +2 -0
- pythonlings-0.3.0/solutions/functional9.py +2 -0
- pythonlings-0.3.0/solutions/functions1.py +2 -0
- pythonlings-0.3.0/solutions/functions10.py +2 -0
- pythonlings-0.3.0/solutions/functions2.py +2 -0
- pythonlings-0.3.0/solutions/functions3.py +2 -0
- pythonlings-0.3.0/solutions/functions4.py +2 -0
- pythonlings-0.3.0/solutions/functions5.py +2 -0
- pythonlings-0.3.0/solutions/functions6.py +2 -0
- pythonlings-0.3.0/solutions/functions7.py +2 -0
- pythonlings-0.3.0/solutions/functions8.py +2 -0
- pythonlings-0.3.0/solutions/functions9.py +2 -0
- pythonlings-0.3.0/solutions/generators1.py +2 -0
- pythonlings-0.3.0/solutions/generators10.py +2 -0
- pythonlings-0.3.0/solutions/generators2.py +2 -0
- pythonlings-0.3.0/solutions/generators3.py +2 -0
- pythonlings-0.3.0/solutions/generators4.py +2 -0
- pythonlings-0.3.0/solutions/generators5.py +2 -0
- pythonlings-0.3.0/solutions/generators6.py +2 -0
- pythonlings-0.3.0/solutions/generators7.py +2 -0
- pythonlings-0.3.0/solutions/generators8.py +2 -0
- pythonlings-0.3.0/solutions/generators9.py +2 -0
- pythonlings-0.3.0/solutions/itertools1.py +2 -0
- pythonlings-0.3.0/solutions/itertools2.py +2 -0
- pythonlings-0.3.0/solutions/itertools3.py +2 -0
- pythonlings-0.3.0/solutions/itertools4.py +2 -0
- pythonlings-0.3.0/solutions/itertools5.py +2 -0
- pythonlings-0.3.0/solutions/itertools6.py +2 -0
- pythonlings-0.3.0/solutions/itertools7.py +2 -0
- pythonlings-0.3.0/solutions/itertools8.py +2 -0
- pythonlings-0.3.0/solutions/json1.py +2 -0
- pythonlings-0.3.0/solutions/json2.py +2 -0
- pythonlings-0.3.0/solutions/json3.py +2 -0
- pythonlings-0.3.0/solutions/json4.py +2 -0
- pythonlings-0.3.0/solutions/json5.py +2 -0
- pythonlings-0.3.0/solutions/json6.py +2 -0
- pythonlings-0.3.0/solutions/json7.py +2 -0
- pythonlings-0.3.0/solutions/json8.py +2 -0
- pythonlings-0.3.0/solutions/lists1.py +2 -0
- pythonlings-0.3.0/solutions/lists10.py +2 -0
- pythonlings-0.3.0/solutions/lists2.py +2 -0
- pythonlings-0.3.0/solutions/lists3.py +2 -0
- pythonlings-0.3.0/solutions/lists4.py +2 -0
- pythonlings-0.3.0/solutions/lists5.py +2 -0
- pythonlings-0.3.0/solutions/lists6.py +2 -0
- pythonlings-0.3.0/solutions/lists7.py +2 -0
- pythonlings-0.3.0/solutions/lists8.py +2 -0
- pythonlings-0.3.0/solutions/lists9.py +2 -0
- pythonlings-0.3.0/solutions/loops1.py +2 -0
- pythonlings-0.3.0/solutions/loops10.py +2 -0
- pythonlings-0.3.0/solutions/loops2.py +2 -0
- pythonlings-0.3.0/solutions/loops3.py +2 -0
- pythonlings-0.3.0/solutions/loops4.py +2 -0
- pythonlings-0.3.0/solutions/loops5.py +2 -0
- pythonlings-0.3.0/solutions/loops6.py +2 -0
- pythonlings-0.3.0/solutions/loops7.py +2 -0
- pythonlings-0.3.0/solutions/loops8.py +2 -0
- pythonlings-0.3.0/solutions/loops9.py +2 -0
- pythonlings-0.3.0/solutions/modules1.py +2 -0
- pythonlings-0.3.0/solutions/modules2.py +2 -0
- pythonlings-0.3.0/solutions/modules3.py +2 -0
- pythonlings-0.3.0/solutions/modules4.py +2 -0
- pythonlings-0.3.0/solutions/modules5.py +2 -0
- pythonlings-0.3.0/solutions/modules6.py +2 -0
- pythonlings-0.3.0/solutions/modules7.py +2 -0
- pythonlings-0.3.0/solutions/modules8.py +2 -0
- pythonlings-0.3.0/solutions/oop_advanced1.py +2 -0
- pythonlings-0.3.0/solutions/oop_advanced10.py +2 -0
- pythonlings-0.3.0/solutions/oop_advanced11.py +2 -0
- pythonlings-0.3.0/solutions/oop_advanced12.py +2 -0
- pythonlings-0.3.0/solutions/oop_advanced2.py +2 -0
- pythonlings-0.3.0/solutions/oop_advanced3.py +2 -0
- pythonlings-0.3.0/solutions/oop_advanced4.py +2 -0
- pythonlings-0.3.0/solutions/oop_advanced5.py +2 -0
- pythonlings-0.3.0/solutions/oop_advanced6.py +2 -0
- pythonlings-0.3.0/solutions/oop_advanced7.py +2 -0
- pythonlings-0.3.0/solutions/oop_advanced8.py +2 -0
- pythonlings-0.3.0/solutions/oop_advanced9.py +2 -0
- pythonlings-0.3.0/solutions/pathlib1.py +2 -0
- pythonlings-0.3.0/solutions/pathlib2.py +2 -0
- pythonlings-0.3.0/solutions/pathlib3.py +2 -0
- pythonlings-0.3.0/solutions/pathlib4.py +2 -0
- pythonlings-0.3.0/solutions/pathlib5.py +2 -0
- pythonlings-0.3.0/solutions/pathlib6.py +2 -0
- pythonlings-0.3.0/solutions/recursion1.py +2 -0
- pythonlings-0.3.0/solutions/recursion2.py +2 -0
- pythonlings-0.3.0/solutions/recursion3.py +2 -0
- pythonlings-0.3.0/solutions/recursion4.py +2 -0
- pythonlings-0.3.0/solutions/recursion5.py +2 -0
- pythonlings-0.3.0/solutions/recursion6.py +2 -0
- pythonlings-0.3.0/solutions/recursion7.py +2 -0
- pythonlings-0.3.0/solutions/recursion8.py +2 -0
- pythonlings-0.3.0/solutions/regex1.py +2 -0
- pythonlings-0.3.0/solutions/regex10.py +2 -0
- pythonlings-0.3.0/solutions/regex2.py +2 -0
- pythonlings-0.3.0/solutions/regex3.py +2 -0
- pythonlings-0.3.0/solutions/regex4.py +2 -0
- pythonlings-0.3.0/solutions/regex5.py +2 -0
- pythonlings-0.3.0/solutions/regex6.py +2 -0
- pythonlings-0.3.0/solutions/regex7.py +2 -0
- pythonlings-0.3.0/solutions/regex8.py +2 -0
- pythonlings-0.3.0/solutions/regex9.py +2 -0
- pythonlings-0.3.0/solutions/sets1.py +2 -0
- pythonlings-0.3.0/solutions/sets10.py +2 -0
- pythonlings-0.3.0/solutions/sets2.py +2 -0
- pythonlings-0.3.0/solutions/sets3.py +2 -0
- pythonlings-0.3.0/solutions/sets4.py +2 -0
- pythonlings-0.3.0/solutions/sets5.py +2 -0
- pythonlings-0.3.0/solutions/sets6.py +2 -0
- pythonlings-0.3.0/solutions/sets7.py +2 -0
- pythonlings-0.3.0/solutions/sets8.py +2 -0
- pythonlings-0.3.0/solutions/sets9.py +2 -0
- pythonlings-0.3.0/solutions/strings1.py +2 -0
- pythonlings-0.3.0/solutions/strings10.py +2 -0
- pythonlings-0.3.0/solutions/strings2.py +2 -0
- pythonlings-0.3.0/solutions/strings3.py +2 -0
- pythonlings-0.3.0/solutions/strings4.py +2 -0
- pythonlings-0.3.0/solutions/strings5.py +2 -0
- pythonlings-0.3.0/solutions/strings6.py +2 -0
- pythonlings-0.3.0/solutions/strings7.py +2 -0
- pythonlings-0.3.0/solutions/strings8.py +2 -0
- pythonlings-0.3.0/solutions/strings9.py +2 -0
- pythonlings-0.3.0/solutions/testing1.py +2 -0
- pythonlings-0.3.0/solutions/testing10.py +2 -0
- pythonlings-0.3.0/solutions/testing11.py +2 -0
- pythonlings-0.3.0/solutions/testing12.py +2 -0
- pythonlings-0.3.0/solutions/testing2.py +2 -0
- pythonlings-0.3.0/solutions/testing3.py +2 -0
- pythonlings-0.3.0/solutions/testing4.py +2 -0
- pythonlings-0.3.0/solutions/testing5.py +2 -0
- pythonlings-0.3.0/solutions/testing6.py +2 -0
- pythonlings-0.3.0/solutions/testing7.py +2 -0
- pythonlings-0.3.0/solutions/testing8.py +2 -0
- pythonlings-0.3.0/solutions/testing9.py +2 -0
- pythonlings-0.3.0/solutions/tuples1.py +2 -0
- pythonlings-0.3.0/solutions/tuples10.py +2 -0
- pythonlings-0.3.0/solutions/tuples2.py +2 -0
- pythonlings-0.3.0/solutions/tuples3.py +2 -0
- pythonlings-0.3.0/solutions/tuples4.py +2 -0
- pythonlings-0.3.0/solutions/tuples5.py +2 -0
- pythonlings-0.3.0/solutions/tuples6.py +2 -0
- pythonlings-0.3.0/solutions/tuples7.py +2 -0
- pythonlings-0.3.0/solutions/tuples8.py +2 -0
- pythonlings-0.3.0/solutions/tuples9.py +2 -0
- pythonlings-0.3.0/solutions/type_hints1.py +2 -0
- pythonlings-0.3.0/solutions/type_hints2.py +2 -0
- pythonlings-0.3.0/solutions/type_hints3.py +2 -0
- pythonlings-0.3.0/solutions/type_hints4.py +2 -0
- pythonlings-0.3.0/solutions/type_hints5.py +2 -0
- pythonlings-0.3.0/solutions/type_hints6.py +2 -0
- pythonlings-0.3.0/solutions/type_hints7.py +2 -0
- pythonlings-0.3.0/solutions/type_hints8.py +2 -0
- pythonlings-0.3.0/solutions/variables1.py +2 -0
- pythonlings-0.3.0/solutions/variables10.py +2 -0
- pythonlings-0.3.0/solutions/variables2.py +2 -0
- pythonlings-0.3.0/solutions/variables3.py +2 -0
- pythonlings-0.3.0/solutions/variables4.py +2 -0
- pythonlings-0.3.0/solutions/variables5.py +2 -0
- pythonlings-0.3.0/solutions/variables6.py +2 -0
- pythonlings-0.3.0/solutions/variables7.py +2 -0
- pythonlings-0.3.0/solutions/variables8.py +2 -0
- pythonlings-0.3.0/solutions/variables9.py +2 -0
- pythonlings-0.3.0/tests/__init__.py +0 -0
- pythonlings-0.3.0/tests/fixtures/multi_topic/checks/alpha/a1.py +1 -0
- pythonlings-0.3.0/tests/fixtures/multi_topic/checks/alpha/a2.py +1 -0
- pythonlings-0.3.0/tests/fixtures/multi_topic/checks/beta/b1.py +1 -0
- pythonlings-0.3.0/tests/fixtures/multi_topic/exercises/alpha/a1.py +2 -0
- pythonlings-0.3.0/tests/fixtures/multi_topic/exercises/alpha/a2.py +2 -0
- pythonlings-0.3.0/tests/fixtures/multi_topic/exercises/beta/b1.py +2 -0
- pythonlings-0.3.0/tests/fixtures/multi_topic/info.toml +19 -0
- pythonlings-0.3.0/tests/fixtures/passing_curriculum/checks/passing1.py +3 -0
- pythonlings-0.3.0/tests/fixtures/passing_curriculum/checks/passing2.py +2 -0
- pythonlings-0.3.0/tests/fixtures/passing_curriculum/exercises/passing1.py +1 -0
- pythonlings-0.3.0/tests/fixtures/passing_curriculum/exercises/passing2.py +2 -0
- pythonlings-0.3.0/tests/fixtures/passing_curriculum/info.toml +13 -0
- pythonlings-0.3.0/tests/fixtures/tiny_curriculum/checks/asserts.py +1 -0
- pythonlings-0.3.0/tests/fixtures/tiny_curriculum/checks/passing.py +2 -0
- pythonlings-0.3.0/tests/fixtures/tiny_curriculum/checks/pending.py +2 -0
- pythonlings-0.3.0/tests/fixtures/tiny_curriculum/checks/syntax.py +1 -0
- pythonlings-0.3.0/tests/fixtures/tiny_curriculum/exercises/asserts.py +1 -0
- pythonlings-0.3.0/tests/fixtures/tiny_curriculum/exercises/passing.py +1 -0
- pythonlings-0.3.0/tests/fixtures/tiny_curriculum/exercises/pending.py +1 -0
- pythonlings-0.3.0/tests/fixtures/tiny_curriculum/exercises/syntax.py +2 -0
- pythonlings-0.3.0/tests/fixtures/tiny_curriculum/info.toml +24 -0
- pythonlings-0.3.0/tests/integration/__init__.py +0 -0
- pythonlings-0.3.0/tests/integration/test_cli_cold_start.py +44 -0
- pythonlings-0.3.0/tests/integration/test_cli_dry_run.py +7 -0
- pythonlings-0.3.0/tests/integration/test_cli_hint.py +27 -0
- pythonlings-0.3.0/tests/integration/test_cli_reset.py +60 -0
- pythonlings-0.3.0/tests/integration/test_cli_run.py +39 -0
- pythonlings-0.3.0/tests/integration/test_cli_solution.py +54 -0
- pythonlings-0.3.0/tests/integration/test_cli_topics.py +60 -0
- pythonlings-0.3.0/tests/integration/test_cli_verify.py +66 -0
- pythonlings-0.3.0/tests/integration/test_cli_workspace.py +60 -0
- pythonlings-0.3.0/tests/integration/test_installed_package.py +11 -0
- pythonlings-0.3.0/tests/integration/test_solution_verify.py +18 -0
- pythonlings-0.3.0/tests/tui/__init__.py +0 -0
- pythonlings-0.3.0/tests/tui/test_app_pilot.py +328 -0
- pythonlings-0.3.0/tests/tui/test_editor_pane.py +57 -0
- pythonlings-0.3.0/tests/tui/test_output_panel.py +128 -0
- pythonlings-0.3.0/tests/unit/__init__.py +0 -0
- pythonlings-0.3.0/tests/unit/test_curriculum.py +56 -0
- pythonlings-0.3.0/tests/unit/test_docs.py +50 -0
- pythonlings-0.3.0/tests/unit/test_exercise.py +56 -0
- pythonlings-0.3.0/tests/unit/test_manifest.py +212 -0
- pythonlings-0.3.0/tests/unit/test_reset.py +104 -0
- pythonlings-0.3.0/tests/unit/test_runner.py +128 -0
- pythonlings-0.3.0/tests/unit/test_solution_coverage.py +18 -0
- pythonlings-0.3.0/tests/unit/test_state.py +106 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
name: ci
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: ${{ matrix.python-version }}
|
|
19
|
+
- run: pip install -e ".[dev]"
|
|
20
|
+
- run: pytest -v
|
|
21
|
+
- run: pythonlings --root tests/fixtures/passing_curriculum verify
|
|
22
|
+
- run: python -m pip install build
|
|
23
|
+
- run: python -m build
|
|
24
|
+
- run: python -m pip install --force-reinstall dist/*.whl
|
|
25
|
+
- run: pythonlings init --path /tmp/pythonlings-workspace
|
|
26
|
+
- run: pythonlings --root /tmp/pythonlings-workspace list
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: pages
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
pages: write
|
|
11
|
+
id-token: write
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: pages
|
|
15
|
+
cancel-in-progress: false
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
build:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
- uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: "3.13"
|
|
25
|
+
cache: pip
|
|
26
|
+
cache-dependency-path: requirements-docs.txt
|
|
27
|
+
- uses: actions/configure-pages@v5
|
|
28
|
+
- run: python -m pip install -r requirements-docs.txt
|
|
29
|
+
- run: mkdocs build --strict
|
|
30
|
+
- uses: actions/upload-pages-artifact@v3
|
|
31
|
+
with:
|
|
32
|
+
path: site
|
|
33
|
+
|
|
34
|
+
deploy:
|
|
35
|
+
environment:
|
|
36
|
+
name: github-pages
|
|
37
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
needs: build
|
|
40
|
+
steps:
|
|
41
|
+
- id: deployment
|
|
42
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
environment: pypi
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
id-token: write
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.13"
|
|
19
|
+
- name: Check release tag matches project version
|
|
20
|
+
run: |
|
|
21
|
+
version=$(python - <<'PY'
|
|
22
|
+
import tomllib
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
|
|
25
|
+
data = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))
|
|
26
|
+
print(data["project"]["version"])
|
|
27
|
+
PY
|
|
28
|
+
)
|
|
29
|
+
test "${GITHUB_REF_NAME}" = "v${version}"
|
|
30
|
+
- run: python -m pip install build
|
|
31
|
+
- run: python -m build
|
|
32
|
+
- run: python -m pip install --force-reinstall dist/*.whl
|
|
33
|
+
- run: pythonlings --version
|
|
34
|
+
- run: pythonlings init --path /tmp/pythonlings-workspace
|
|
35
|
+
- run: pythonlings --root /tmp/pythonlings-workspace list
|
|
36
|
+
- run: pythonlings --root /tmp/pythonlings-workspace solution variables1
|
|
37
|
+
- run: pythonlings --root /tmp/pythonlings-workspace reset variables1 --yes
|
|
38
|
+
- run: pythonlings --root tests/fixtures/passing_curriculum verify
|
|
39
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
pip-wheel-metadata/
|
|
24
|
+
share/python-wheels/
|
|
25
|
+
*.egg-info/
|
|
26
|
+
.installed.cfg
|
|
27
|
+
*.egg
|
|
28
|
+
MANIFEST
|
|
29
|
+
|
|
30
|
+
# PyInstaller
|
|
31
|
+
# Usually these files are written by a python script from a template
|
|
32
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
33
|
+
*.manifest
|
|
34
|
+
*.spec
|
|
35
|
+
|
|
36
|
+
# Installer logs
|
|
37
|
+
pip-log.txt
|
|
38
|
+
pip-delete-this-directory.txt
|
|
39
|
+
|
|
40
|
+
# Unit test / coverage reports
|
|
41
|
+
htmlcov/
|
|
42
|
+
.tox/
|
|
43
|
+
.nox/
|
|
44
|
+
.coverage
|
|
45
|
+
.coverage.*
|
|
46
|
+
.cache
|
|
47
|
+
nosetests.xml
|
|
48
|
+
coverage.xml
|
|
49
|
+
*.cover
|
|
50
|
+
*.py,cover
|
|
51
|
+
.hypothesis/
|
|
52
|
+
.pytest_cache/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
target/
|
|
76
|
+
|
|
77
|
+
# Jupyter Notebook
|
|
78
|
+
.ipynb_checkpoints
|
|
79
|
+
|
|
80
|
+
# IPython
|
|
81
|
+
profile_default/
|
|
82
|
+
ipython_config.py
|
|
83
|
+
|
|
84
|
+
# pyenv
|
|
85
|
+
.python-version
|
|
86
|
+
|
|
87
|
+
# pipenv
|
|
88
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
89
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
90
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
91
|
+
# install all needed dependencies.
|
|
92
|
+
#Pipfile.lock
|
|
93
|
+
|
|
94
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
95
|
+
__pypackages__/
|
|
96
|
+
|
|
97
|
+
# Celery stuff
|
|
98
|
+
celerybeat-schedule
|
|
99
|
+
celerybeat.pid
|
|
100
|
+
|
|
101
|
+
# SageMath parsed files
|
|
102
|
+
*.sage.py
|
|
103
|
+
|
|
104
|
+
# Environments
|
|
105
|
+
.env
|
|
106
|
+
.venv
|
|
107
|
+
env/
|
|
108
|
+
venv/
|
|
109
|
+
ENV/
|
|
110
|
+
env.bak/
|
|
111
|
+
venv.bak/
|
|
112
|
+
|
|
113
|
+
# Spyder project settings
|
|
114
|
+
.spyderproject
|
|
115
|
+
.spyproject
|
|
116
|
+
|
|
117
|
+
# Rope project settings
|
|
118
|
+
.ropeproject
|
|
119
|
+
|
|
120
|
+
# mkdocs documentation
|
|
121
|
+
/site
|
|
122
|
+
|
|
123
|
+
# mypy
|
|
124
|
+
.mypy_cache/
|
|
125
|
+
.dmypy.json
|
|
126
|
+
dmypy.json
|
|
127
|
+
|
|
128
|
+
# Pyre type checker
|
|
129
|
+
.pyre/
|
|
130
|
+
|
|
131
|
+
# Pythonlings runtime state (root install and any nested fixture roots)
|
|
132
|
+
.pythonlings/
|
|
133
|
+
.superpowers/
|
|
134
|
+
.worktrees
|
|
135
|
+
|
|
136
|
+
# Local artifacts from older pythonlings workspaces; not part of this package.
|
|
137
|
+
/pythonlings/.gitignore
|
|
138
|
+
/pythonlings/.git/
|
|
139
|
+
/pythonlings/.pythonlings.toml
|
|
140
|
+
/pythonlings/exercises/
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Repository Guidelines
|
|
2
|
+
|
|
3
|
+
## Project Structure & Module Organization
|
|
4
|
+
|
|
5
|
+
`pythonlings/` contains the installable application package. Core exercise loading, workspace setup, state, reset, solutions, and runner logic live in `pythonlings/core/`; CLI entry points are in `pythonlings/cli.py` and `pythonlings/__main__.py`; Textual screens/widgets live in `pythonlings/screens/` and `pythonlings/widgets/`; `pythonlings/pythonlings.tcss` holds TUI styles.
|
|
6
|
+
|
|
7
|
+
Curriculum files are split between `exercises/<topic>/<exercise>.py` for learner code, `checks/<topic>/<exercise>.py` for hidden assertions, and `solutions/<exercise>.py` for reference answers. Keep these trees aligned with `info.toml`, which defines order, hints, and docs URLs. Tests live in `tests/unit/`, `tests/integration/`, and `tests/tui/`, with fixtures in `tests/fixtures/`.
|
|
8
|
+
|
|
9
|
+
## Build, Test, and Development Commands
|
|
10
|
+
|
|
11
|
+
- `pip install -e ".[dev]"`: install pythonlings locally with pytest dependencies.
|
|
12
|
+
- `pythonlings init --path ./learn-python`: create a self-contained learner workspace.
|
|
13
|
+
- `pythonlings`, `pythonlings topics`, `pythonlings list`: launch the TUI or inspect progress.
|
|
14
|
+
- `pythonlings run variables1`, `pythonlings dry-run variables1`, `pythonlings solution variables1`: test exercise and solution flows.
|
|
15
|
+
- `pythonlings --root tests/fixtures/passing_curriculum verify`: smoke-test a known passing fixture.
|
|
16
|
+
- `python -m pytest -q`: run the full suite configured in `pyproject.toml`.
|
|
17
|
+
- `python -m build`: build source and wheel distributions.
|
|
18
|
+
|
|
19
|
+
## Coding Style & Naming Conventions
|
|
20
|
+
|
|
21
|
+
Use Python 3.11+ idioms and 4-space indentation. Prefer small, typed functions where practical. Keep UI behavior in `screens` or `widgets`; keep filesystem, manifest, reset, and runner behavior in `core`. Name tests `test_<behavior>.py` and test functions `test_<expected_behavior>`. Curriculum names use topic plus ordinal, such as `variables1.py` or `collections10.py`.
|
|
22
|
+
|
|
23
|
+
## Testing Guidelines
|
|
24
|
+
|
|
25
|
+
Use pytest for all tests; async tests are supported by `pytest-asyncio` in auto mode. Add unit tests for core behavior, integration tests for CLI/workspace flows, and TUI tests for Textual interactions. When changing curriculum, update `exercises/`, `checks/`, `solutions/`, and `info.toml`, then run relevant pytest files plus `pythonlings --root tests/fixtures/passing_curriculum verify`.
|
|
26
|
+
|
|
27
|
+
## Commit & Pull Request Guidelines
|
|
28
|
+
|
|
29
|
+
Recent history uses conventional prefixes such as `feat:`, `fix:`, `docs:`, `chore:`, and merge commits between `feature/*`, `dev`, and `main`. Keep commits focused and imperative, for example `fix: reset exercise originals`. Pull requests should explain the user-facing change, list tests run, link issues when applicable, and include screenshots or terminal output for TUI/CLI changes.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. Pythonlings follows
|
|
4
|
+
Semantic Versioning.
|
|
5
|
+
|
|
6
|
+
## [0.3.0] - 2026-06-10
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- The in-app reference (`F5`) now bundles a second complementary section from
|
|
11
|
+
the official Python documentation for every topic, roughly tripling each
|
|
12
|
+
topic's offline reference content.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- The project is renamed from pylings to **pythonlings**. The PyPI package
|
|
17
|
+
(previously `python-learnings`), the CLI command (previously `pylings`),
|
|
18
|
+
and the Python package are all now `pythonlings`. Existing workspaces are
|
|
19
|
+
migrated automatically: a legacy `.pylings/` state directory is renamed to
|
|
20
|
+
`.pythonlings/` on the next run, preserving progress and reset snapshots.
|
|
21
|
+
- The README and quick-start now describe the built-in editor accurately:
|
|
22
|
+
checks rerun as you type in the TUI editor.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Running `pythonlings` outside a workspace now explains how to create one
|
|
27
|
+
with `pythonlings init` instead of a bare "info.toml not found".
|
|
28
|
+
|
|
29
|
+
### Removed
|
|
30
|
+
|
|
31
|
+
- The unused `watchdog` dependency, for a lighter install.
|
|
32
|
+
|
|
33
|
+
## [0.2.0] - 2026-05-30
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- Support for Python 3.9 and 3.10 (minimum was 3.11), broadening
|
|
38
|
+
compatibility with stock macOS and Debian/Ubuntu interpreters.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- The `type_hints4`, `type_hints8`, and `itertools8` exercises carry a small
|
|
43
|
+
forward-compatibility shim (`from __future__ import annotations` and a
|
|
44
|
+
`tee`-based `pairwise` fallback) so their modern syntax and stdlib usage run
|
|
45
|
+
on Python 3.9 and 3.10. The learner's task is unchanged.
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
- Manifest loading now falls back to the `tomli` backport on Python < 3.11,
|
|
50
|
+
where `tomllib` is not available in the standard library. Previously the
|
|
51
|
+
package would install but crash on launch under older interpreters.
|
|
52
|
+
|
|
53
|
+
## [0.1.0] - 2026-05-25
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
- Interactive Textual coding workflow with topic picker, resume state, hints,
|
|
58
|
+
reset, and automatic check reruns.
|
|
59
|
+
- CLI commands for listing topics, running exercises, printing hints, resetting
|
|
60
|
+
files, and verifying curricula.
|
|
61
|
+
- 292 Python exercises across 31 topics with mirrored hidden checks.
|
|
62
|
+
- Bundled local Python documentation snippets generated from official docs.
|
|
63
|
+
- In-app documentation modal with `F5`, `Esc`, and `O` keyboard flow.
|
|
64
|
+
- PyPI distribution name `pythonlings`, which installs the `pythonlings` command.
|
|
65
|
+
- Contributor guide, screenshots, release flow notes, and MIT license.
|
|
66
|
+
|
|
67
|
+
### Verified
|
|
68
|
+
|
|
69
|
+
- Full test suite: `125 passed`.
|
|
70
|
+
- Curriculum/docs audit: every exercise has a configured docs URL and a bundled
|
|
71
|
+
local snippet.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
Pythonlings is "Rustlings for Python": a terminal TUI (Textual) where learners fix small broken exercises and checks rerun on save. Published on PyPI as `pythonlings` (formerly `python-learnings`; the unrelated `pylings` PyPI name belongs to a different project).
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install -e ".[dev]" # local install with pytest deps
|
|
11
|
+
|
|
12
|
+
python -m pytest -q # full suite
|
|
13
|
+
python -m pytest tests/unit/test_runner.py -q # one file
|
|
14
|
+
python -m pytest tests/unit/test_state.py::test_name -q # one test
|
|
15
|
+
|
|
16
|
+
pylings --root tests/fixtures/passing_curriculum verify # smoke-test: all solutions pass their checks
|
|
17
|
+
|
|
18
|
+
python -m build # sdist + wheel
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Manual testing of flows: `pylings init --path ./learn-python` (create a learner workspace), `pylings` (TUI), `pylings run variables1`, `pylings dry-run variables1`, `pylings solution variables1`, `pylings hint`, `pylings list`, `pylings topics`, `pylings reset`. `--root` points any command at an arbitrary workspace (used heavily by tests against `tests/fixtures/`).
|
|
22
|
+
|
|
23
|
+
## Architecture
|
|
24
|
+
|
|
25
|
+
Two distinct trees in this repo:
|
|
26
|
+
|
|
27
|
+
1. **The application** — `pylings/` (installable package)
|
|
28
|
+
2. **The curriculum** — repo-root `exercises/`, `checks/`, `solutions/`, and `info.toml`
|
|
29
|
+
|
|
30
|
+
At build time, hatch `force-include` maps the curriculum into the wheel as `pylings/curriculum/` (see `pyproject.toml`). `pylings init` copies that bundled curriculum into a self-contained learner workspace; progress lives in `<workspace>/.pylings/state.json` (written atomically, with `.bak` recovery on corruption).
|
|
31
|
+
|
|
32
|
+
### Curriculum model
|
|
33
|
+
|
|
34
|
+
Each exercise is a triple that must stay in sync, plus a manifest entry:
|
|
35
|
+
|
|
36
|
+
- `exercises/<topic>/<name>.py` — the broken code the learner edits, containing the `# I AM NOT DONE` marker (defined in `core/exercise.py`)
|
|
37
|
+
- `checks/<topic>/<name>.py` — hidden bare `assert` statements (not pytest)
|
|
38
|
+
- `solutions/<name>.py` — reference answer
|
|
39
|
+
- `info.toml` — ordered `[[exercises]]` entries with `name`, `path`, `hint`, `docs` URL; this file is the source of truth for exercise order and topics
|
|
40
|
+
|
|
41
|
+
When changing curriculum, update all four, then run the relevant tests plus `pylings --root tests/fixtures/passing_curriculum verify`. Exercise names are topic + ordinal (`variables1`, `collections10`).
|
|
42
|
+
|
|
43
|
+
### How checks run (`core/runner.py`)
|
|
44
|
+
|
|
45
|
+
An exercise passes when a generated runner script `exec()`s the exercise source and then the check source in a shared namespace, in a fresh subprocess with a 5s timeout. The check sees the exercise's variables directly — that's why checks are bare asserts. Passing checks alone aren't enough: the learner must also remove `# I AM NOT DONE` to advance.
|
|
46
|
+
|
|
47
|
+
### Layering
|
|
48
|
+
|
|
49
|
+
- `pythonlings/core/` — all filesystem, manifest, state, reset, solutions, and runner logic. No UI imports. (Checks rerun on a debounce in the TUI editor, not a filesystem watcher.)
|
|
50
|
+
- `pylings/screens/` and `pylings/widgets/` — Textual UI only; `pylings/app.py` wires them up; `pylings.tcss` holds styles.
|
|
51
|
+
- `pylings/cli.py` — argparse subcommands; entry point `pylings = "pylings.cli:main"`.
|
|
52
|
+
|
|
53
|
+
Keep UI behavior in screens/widgets and behavior logic in core — tests depend on this split (`tests/unit/` for core, `tests/integration/` for CLI/workspace flows, `tests/tui/` for Textual pilot tests, fixtures in `tests/fixtures/`).
|
|
54
|
+
|
|
55
|
+
## Conventions
|
|
56
|
+
|
|
57
|
+
- `requires-python = ">=3.9"`: guard newer-stdlib usage (e.g. `tomllib` falls back to `tomli` in `core/manifest.py`); `from __future__ import annotations` at the top of modules.
|
|
58
|
+
- Async tests run under `pytest-asyncio` in auto mode (configured in `pyproject.toml`).
|
|
59
|
+
- Tests are named `test_<behavior>.py` / `test_<expected_behavior>`.
|
|
60
|
+
- Commits use conventional prefixes (`feat:`, `fix:`, `docs:`, `chore:`); work flows through `feature/*` → `dev` → `main`.
|
|
61
|
+
- `AGENTS.md` holds the same contributor guidelines in long form.
|
pythonlings-0.3.0/CNAME
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pythonlings.abhik.ai
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
Pythonlings follows the Contributor Covenant Code of Conduct, version 2.1.
|
|
4
|
+
|
|
5
|
+
## Our Standards
|
|
6
|
+
|
|
7
|
+
Use welcoming and inclusive language, respect different experience levels, accept constructive feedback, and focus on what is best for the community.
|
|
8
|
+
|
|
9
|
+
Unacceptable behavior includes harassment, personal attacks, sexualized language or imagery, publishing private information, or sustained disruption of project work.
|
|
10
|
+
|
|
11
|
+
## Enforcement
|
|
12
|
+
|
|
13
|
+
Report unacceptable behavior through GitHub Security Advisories. Maintainers may remove comments, close issues, block users, or take other appropriate action.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Pythonlings is actively developed and **open to contributors** — beginners welcome.
|
|
4
|
+
The fastest way in is a [`good first issue`](https://github.com/abhiksark/pythonlings/issues?q=is%3Aopen+label%3A%22good+first+issue%22).
|
|
5
|
+
|
|
6
|
+
## Where the work is
|
|
7
|
+
|
|
8
|
+
- **[0.3.0 roadmap](docs/roadmap/0.3.0.md)** — the current focus (wider adoption
|
|
9
|
+
for beginners). Each roadmap issue is written to be picked up cold: it has
|
|
10
|
+
context, scope, the exact files to touch, and how to verify.
|
|
11
|
+
- Browse open issues by label: [`good first issue`](https://github.com/abhiksark/pythonlings/issues?q=is%3Aopen+label%3A%22good+first+issue%22),
|
|
12
|
+
[`help wanted`](https://github.com/abhiksark/pythonlings/issues?q=is%3Aopen+label%3A%22help+wanted%22).
|
|
13
|
+
|
|
14
|
+
## Claiming an issue
|
|
15
|
+
|
|
16
|
+
1. Comment on the issue to claim it (e.g. "I'd like to take this"). This avoids
|
|
17
|
+
two people doing the same work.
|
|
18
|
+
2. Ask any questions right on the issue — happy to clarify scope.
|
|
19
|
+
3. Open a PR that references the issue (`Closes #NN`).
|
|
20
|
+
|
|
21
|
+
No need to wait for a formal assignment; claiming by comment is enough.
|
|
22
|
+
|
|
23
|
+
## Development Setup
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
git clone git@github.com:abhiksark/pythonlings.git
|
|
27
|
+
cd pythonlings
|
|
28
|
+
pip install -e ".[dev]" # or: uv pip install -e ".[dev]"
|
|
29
|
+
python -m pytest -q
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Supported Python: 3.9+.
|
|
33
|
+
|
|
34
|
+
## Curriculum Changes
|
|
35
|
+
|
|
36
|
+
Update `info.toml`, `exercises/`, `checks/`, and `solutions/` together. Exercise
|
|
37
|
+
and check paths must mirror each other, and **every exercise must have a passing
|
|
38
|
+
reference solution** (`tests/integration/test_solution_verify.py` enforces this).
|
|
39
|
+
|
|
40
|
+
## Pull Requests
|
|
41
|
+
|
|
42
|
+
- Use focused branches named `feature/<name>` or `fix/<name>`.
|
|
43
|
+
- Reference the issue you're closing (`Closes #NN`).
|
|
44
|
+
- Include a short description, test output (`python -m pytest -q`), and
|
|
45
|
+
screenshots/GIFs for TUI changes.
|
|
46
|
+
- Keep PRs scoped to one issue where possible.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Abhik Sarkar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|