skills/panaversity/agentfactory/python-dev-environment

python-dev-environment

SKILL.md

Python Development Environment Expertise Skill

Purpose: Provides verified, grounded reference data for writing Chapter 14.1 lessons. Every command, version number, and config option below was extracted from official documentation on 2026-02-20.

Usage: Content-implementer subagents MUST reference this skill when writing Ch 14.1 lessons. Never invent commands or config options — use only what is documented here.


1. uv — Package Manager & Project Orchestrator

Version: 0.10.4 (released February 17, 2026) Written in: Rust Maker: Astral (same company as ruff) Source: docs.astral.sh/uv

Installation Commands

# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# macOS / Linux (curl)
curl -LsSf https://astral.sh/uv/install.sh | sh
# macOS (Homebrew)
brew install uv
# Windows (WinGet)
winget install --id=astral-sh.uv -e

uv init — Project Scaffolding

uv init smartnotes          # Create new project in subdirectory
uv init                     # Initialize in current directory
uv init --lib <name>        # Library project
uv init --package <name>    # Packaged application (src layout)

Files created by uv init smartnotes:

smartnotes/
├── .gitignore
├── .python-version          # Contains: 3.12 (or detected version)
├── README.md
├── main.py
└── pyproject.toml

Default main.py:

def main():
    print("Hello from smartnotes!")


if __name__ == "__main__":
    main()

Default pyproject.toml:

[project]
name = "smartnotes"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.11"
dependencies = []

Additional files created on first uv run or uv sync:

  • .venv/ — virtual environment (not version-controlled)
  • uv.lock — cross-platform lockfile with exact versions (should be committed)

uv add — Dependency Management

uv add requests                    # Add runtime dependency
uv add 'requests>=2.28,<3'        # With version constraint
uv add --dev pytest                # Add dev dependency
uv add --dev pytest pyright ruff   # Multiple dev deps at once
uv remove requests                 # Remove a dependency

What uv add does (three steps in one):

  1. Updates pyproject.toml
  2. Updates uv.lock (lockfile)
  3. Syncs the .venv environment

Result in pyproject.toml after uv add --dev pytest pyright ruff:

[dependency-groups]
dev = ["pytest>=9.0.2", "pyright>=1.1.408", "ruff>=0.15.2"]

uv run — Execute in Project Environment

uv run main.py                     # Run a Python file
uv run pytest                      # Run an installed tool
uv run python -c "print('hi')"    # Run inline Python

What happens on uv run:

  1. Verifies uv.lock is up-to-date with pyproject.toml
  2. Verifies .venv is up-to-date with uv.lock
  3. Installs/syncs missing dependencies automatically
  4. Runs the command inside the project's virtual environment

No manual venv activation required. Students never need source .venv/bin/activate.

Why uv Over pip

Dimension pip uv
Speed Baseline 10-100x faster (Rust, parallel downloads, global cache)
Scope Package install only All-in-one: Python install, venvs, deps, scripts, builds
Virtual envs Separate python -m venv step Creates .venv automatically
Lockfile None (needs pip-tools) uv.lock generated automatically
Python versions Need pyenv separately Built-in: uv python install 3.12
Uninstall cleanup Leaves orphaned transitive deps Removes transitive deps on uninstall
Disk usage Separate copies per venv Global cache, up to 40% disk savings
Replaces Just pip pip, pip-tools, pipx, poetry, pyenv, virtualenv

Axiom Callback: uv = Axiom I (Shell as Orchestrator). One command replaces an entire ecosystem.


2. pyright — Static Type Checker

Version: 1.1.408 (released January 8, 2026) Written in: TypeScript (runs via Node.js; pip wrapper handles this transparently) Maker: Microsoft Source: github.com/microsoft/pyright

Installation

uv add --dev pyright               # Recommended via uv

Configuration in pyproject.toml

[tool.pyright]
include = ["src"]
exclude = ["**/__pycache__"]
typeCheckingMode = "strict"
pythonVersion = "3.12"

Also supports pyrightconfig.json (takes precedence if both exist):

{
  "include": ["src"],
  "typeCheckingMode": "strict",
  "pythonVersion": "3.12"
}

Type Checking Modes

Mode Description
"off" All type-checking disabled; syntax errors still reported
"basic" Minimal rule set
"standard" Default (CLI). Moderate coverage
"strict" Most rules enabled; requires complete type annotations

Running Pyright

uv run pyright                     # Check entire project
uv run pyright src/main.py         # Check specific file

Clean output:

0 errors, 0 warnings, 0 informations

Error output:

/path/to/file.py:10:5 - error: Type of parameter "name" is unknown (reportUnknownParameterType)
1 error, 0 warnings, 0 informations

What Strict Mode Catches (28 Additional Rules)

Strict mode enables 28 rules that are "none" in standard but "error" in strict:

Missing annotations:

  • reportMissingParameterType — parameters without type hints
  • reportMissingTypeArgument — generic classes without type args
  • reportUnknownParameterType — parameter type resolves to Unknown
  • reportUnknownVariableType — variable type resolves to Unknown
  • reportUnknownArgumentType — argument type resolves to Unknown
  • reportUnknownMemberType — member access resolves to Unknown
  • reportUnknownLambdaType — lambda parameters Unknown

Code quality:

  • reportUnusedImport — imported symbols not referenced
  • reportUnusedVariable — local variables not referenced
  • reportUnusedFunction — functions not referenced
  • reportUnusedClass — classes not referenced
  • reportDuplicateImport — duplicate imports
  • reportPrivateUsage — accessing private members
  • reportConstantRedefinition — redefining Final variables
  • reportDeprecated — deprecated features

Type safety:

  • reportUntypedBaseClass — base class without types
  • reportUntypedFunctionDecorator — untyped decorators
  • reportUntypedClassDecorator — untyped class decorators
  • reportUntypedNamedTuple — NamedTuple without types
  • reportMatchNotExhaustive — incomplete match
  • reportUnnecessaryCast — unnecessary casts
  • reportUnnecessaryComparison — always-true/false comparisons
  • reportUnnecessaryContains — unnecessary in checks
  • reportUnnecessaryIsInstance — unnecessary isinstance
  • reportIncompleteStub, reportInconsistentConstructor, reportInvalidStubStatement, reportTypeCommentUsage

Before/After Example (for Ch 14.1)

# BEFORE: Passes standard, FAILS strict
def greet(name):
    return f"Hello, {name}"

# AFTER: Passes strict
def greet(name: str) -> str:
    return f"Hello, {name}"

Axiom Callback: pyright = Axiom V (Types Are Guardrails). The compiler catches bugs before runtime.


3. ruff — Linter & Formatter

Version: 0.15.2 (released February 19, 2026) Written in: Rust Maker: Astral (same company as uv) Source: docs.astral.sh/ruff

Installation

uv add --dev ruff                  # Add as dev dependency

Running Ruff

# Linting
uv run ruff check .               # Lint all Python files
uv run ruff check --fix .         # Lint and auto-fix

# Formatting
uv run ruff format .              # Format all Python files
uv run ruff format --check .      # Check without modifying

Configuration in pyproject.toml

[tool.ruff]
line-length = 88
target-version = "py312"

[tool.ruff.lint]
select = [
    "E",    # pycodestyle errors
    "W",    # pycodestyle warnings
    "F",    # Pyflakes (unused imports, undefined names)
    "I",    # isort (import sorting)
    "UP",   # pyupgrade (modernize syntax)
    "B",    # flake8-bugbear (common bugs)
    "SIM",  # flake8-simplify (simplifiable code)
]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

Key Rule Categories (for Teaching)

Prefix Name What It Catches
F Pyflakes Undefined names, unused imports, unused variables
E pycodestyle (errors) PEP 8 style violations (indentation, whitespace)
W pycodestyle (warnings) PEP 8 warnings
I isort Import sorting order
UP pyupgrade Old syntax that can be modernized
B flake8-bugbear Common programming mistakes
SIM flake8-simplify Code that can be simplified
N pep8-naming Naming conventions (CamelCase, snake_case)
S flake8-bandit Security vulnerabilities
T20 flake8-print Print statements left in code

Default enabled rules: E4, E7, E9, and F (minimal safe set). Total rules: 800+ built-in. Suppress inline: # noqa: F841 on a line.

What Ruff Replaces

Ruff is a single binary replacing: Flake8 (+ dozens of plugins), Black, isort, pydocstyle, pyupgrade, autoflake. Speed: 10-100x faster than these tools individually.

Ruff format is a drop-in Black replacement (>99.9% identical formatting).

Axiom Callback: ruff = Axiom IX (Verification is a Pipeline). Automated quality checks in your CI.


4. pytest — Testing Framework

Version: 9.0.2 (released December 6, 2025) Requires: Python >= 3.10 Source: docs.pytest.org

Installation

uv add --dev pytest                # Add as dev dependency

Test Discovery Conventions

Element Convention Example
Files test_*.py or *_test.py test_calculator.py
Functions test_* prefix def test_addition():
Classes Test* prefix (no __init__) class TestCalculator:
Methods test_* inside Test* classes def test_add(self):

Minimal Test File

# test_example.py
def func(x):
    return x + 1

def test_answer():
    assert func(3) == 4

Key: pytest uses plain assert — no special assertion methods needed.

Running Tests

uv run pytest                      # Run all discovered tests
uv run pytest -v                   # Verbose (one line per test)
uv run pytest -q                   # Quiet (minimal output)
uv run pytest test_example.py      # Run specific file
uv run pytest -k "test_answer"     # Run matching keyword

Output Format

Default (dots):

test_example.py .                                                [100%]
========================== 1 passed in 0.12s ===========================

Verbose (-v):

test_example.py::test_answer PASSED                              [100%]
========================== 1 passed in 0.12s ===========================

Output characters:

Character Meaning
. Passed
F Failed
E Error (exception in setup/teardown)
s Skipped
x Expected failure (xfail)

Configuration in pyproject.toml

[tool.pytest.ini_options]
addopts = "-ra -q"
testpaths = ["tests"]

Axiom Callback: pytest = Axiom VII (Tests Are the Specification). Tests define what "correct" means.


5. Git — Version Control

Note: Git is not a Python-specific tool and doesn't need version-grounding the same way. The chapter references Git as the fifth discipline tool.

Key Git Commands for SmartNotes

git init                           # Initialize repo (uv init creates .gitignore)
git add .                          # Stage all changes
git commit -m "message"            # Commit with message
git log --oneline                  # View history
git diff                           # See uncommitted changes

Axiom Callback: Git = Axiom VIII (Version Control is Memory). Every change tracked, reversible.


6. The Unified pyproject.toml (SmartNotes After Full Setup)

After running all setup commands, the SmartNotes pyproject.toml looks like:

[project]
name = "smartnotes"
version = "0.1.0"
description = "A personal note-taking assistant"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []

[dependency-groups]
dev = ["pytest>=9.0.2", "pyright>=1.1.408", "ruff>=0.15.2"]

[tool.pyright]
typeCheckingMode = "strict"
pythonVersion = "3.12"

[tool.ruff]
line-length = 88
target-version = "py312"

[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B", "SIM"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

[tool.pytest.ini_options]
addopts = "-ra -q"
testpaths = ["tests"]

Teaching point: One file configures ALL four tools. This is the power of pyproject.toml as the single source of truth for a Python project.


7. Platform-Specific Notes

Windows

  • uv install: PowerShell command (see Section 1)
  • Paths use \ but uv handles this transparently
  • .venv\Scripts\activate (if manual activation needed, but uv run avoids this)

macOS

  • uv install: curl or Homebrew
  • .venv/bin/activate (if manual activation needed)

Linux

  • uv install: curl
  • Same as macOS for venv paths

Key teaching point: uv run works identically on all platforms. Students never need to know activation differences.


8. Chapter 14 Tone Reference (Condensed)

Characters

  • James: Junior dev, 3 weeks into first job, e-commerce platform team. Learner surrogate. Makes understandable mistakes. Never mocked. Growth narrative.
  • Emma: Senior engineer, 4 years at company. Mentor. Teaches through showing, not lecturing. Delivers quotable one-liners. Calm, slightly dry. Declarative sentences.

Lesson Opening Pattern

  1. Bridge sentence from previous lesson
  2. James hits a crisis (specific time, specific number, visceral detail)
  3. He discovers tools/code are inadequate (shown as code block)
  4. Emma arrives, delivers one-line diagnosis
  5. Emma fixes it

Lesson Section Flow

  1. Title → Narrative opening (4-6 paragraphs)
  2. "The Problem Without This Tool" → pain point
  3. "The Tool Defined" → blockquote + table + image
  4. "From Axiom to Practice" → connects to Ch 14 axiom
  5. "Practical Application" → code examples, configs
  6. "Anti-Patterns" → narrative + table (3-4 columns)
  7. "Try With AI" → exactly 3 prompts with **What you're learning:**
  8. "Key Takeaways" → numbered list, 4-6 items
  9. "Looking Ahead" → bridge to next lesson

YAML Frontmatter Template

---
sidebar_position: N
title: "Lesson Title"
description: "One sentence"
keywords: ["keyword1", "keyword2"]
chapter: 14.1
lesson: N
duration_minutes: 20-25

skills:
  - name: "Skill Name"
    proficiency_level: "A2|B1"
    category: "Conceptual|Technical|Applied"
    bloom_level: "Understand|Apply"
    digcomp_area: "Computational Thinking|Problem Solving"
    measurable_at_this_level: "Student can..."

learning_objectives:
  - objective: "Full sentence"
    proficiency_level: "A2|B1"
    bloom_level: "Apply|Understand"
    assessment_method: "Full sentence"

cognitive_load:
  new_concepts: 5-7
  assessment: "Justification sentence"

differentiation:
  extension_for_advanced: "Advanced activity"
  remedial_for_struggling: "Simplified approach"
---

Code Style

  • Use ```python static tag for Python blocks
  • BAD code first with # BAD: comments, GOOD code follows
  • Inline comments explain intent, not syntax
  • Never two code blocks back-to-back without prose

Voice

  • Third-person narrator for narrative sections
  • "You" for instructional sections (Practical Application, Try With AI)
  • Declarative, confident. No hedging, no exclamation marks.
  • Tables as primary analytical device.

9. Axiom Callbacks (Ch 14.1 → Ch 14 Mapping)

Tool Axiom Connection
uv I — Shell as Orchestrator One command orchestrates entire ecosystem
pyproject.toml II — Knowledge is Markdown Project config as single source of truth
pyright V — Types Are Guardrails Compiler catches bugs before runtime
ruff IX — Verification is a Pipeline Automated lint/format in CI
pytest VII — Tests Are the Specification Tests define "correct" behavior
Git VIII — Version Control is Memory Every change tracked and reversible

10. Confidence Assessment

Data Point Status Source
uv v0.10.4, commands, config VERIFIED docs.astral.sh/uv, PyPI, GitHub
pyright v1.1.408, strict rules VERIFIED github.com/microsoft/pyright, PyPI
ruff v0.15.2, rules, config VERIFIED docs.astral.sh/ruff, PyPI, GitHub
pytest v9.0.2, conventions VERIFIED docs.pytest.org, PyPI, changelog
requires-python default NOTE Shows >=3.11 in docs but varies by detected Python
Platform install differences VERIFIED Official docs for each tool
Ch 14 tone and structure VERIFIED Read from actual lesson files
Weekly Installs
17
GitHub Stars
158
First Seen
Feb 28, 2026
Installed on
opencode17
gemini-cli17
github-copilot17
codex17
kimi-cli17
amp17