AgentStack
SKILL verified MIT Self-run

Python Developer

skill-gvre-skills-python-developer · by gvre

A Claude skill from gvre/skills.

No reviews yet
0 installs
7 views
0.0% view→install

Install

$ agentstack add skill-gvre-skills-python-developer

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access Used
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Python Developer? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Python Developer

Guide for writing production-quality Python 3.12+ projects following current best practices.

Version Support

This guide covers:

  • Python 3.12+: Base requirements and common features (all sections below)
  • Python 3.13: Additional features and improvements → See [references/python-3.13-features.md](references/python-3.13-features.md)
  • Python 3.14: Latest features and enhancements → See [references/python-3.14-features.md](references/python-3.14-features.md)

Feature Version Matrix

| Feature | 3.12 | 3.13 | 3.14 | |---------|------|------|------| | Type parameter syntax (def func[T]()) | ✅ | ✅ | ✅ | | Type statement (type X = ...) | ✅ | ✅ | ✅ | | Pattern matching (match/case) | ✅ | ✅ | ✅ | | Exception groups (except*) | ✅ | ✅ | ✅ | | TaskGroup | ✅ | ✅ | ✅ | | TypeIs for type narrowing | ❌ | ✅ | ✅ | | ReadOnly type hint | ❌ | ✅ | ✅ | | Improved REPL | ❌ | ✅ | ✅ | | Bracketless except (PEP 758) | ❌ | ❌ | ✅ | | Experimental JIT | ❌ | ❌ | ✅ | | Free-threaded (no-GIL) | ❌ | ❌ | ✅ |

Quick Reference

Core Requirements (3.12+):

  • Python 3.12+ minimum
  • Use pyproject.toml for all config
  • Type hints everywhere
  • Ruff for formatting/linting
  • ty or mypy for type checking
  • pytest for testing
  • src/ layout structure

Type Checker Comparison:

| Feature | mypy | ty | |---------|------|-----| | Status | ✅ Stable, mature (1.0+) | ⚠️ Beta (0.0.22, Mar 2026) | | Speed | Standard | 10-100x faster | | Language | Python | Rust | | Ecosystem | Extensive | Growing rapidly | | IDE Support | Universal | VS Code, PyCharm, Neovim (built-in language server) | | Production Ready | ✅ Yes | ⚠️ Maturing fast - viable for new projects | | Best for | Production systems, existing codebases | New projects, fast iteration | | Maintainer | Python community | Astral (Ruff/uv creators) | | Configuration | [tool.mypy] | [tool.ty] | | Recommendation | Existing codebases, risk-averse teams | Default for new projects |

Project Overrides

How tool settings are resolved depends on the task:

  • Reviewing existing code / PRs: Read pyproject.toml from the

repository. The project's actual configuration is the source of truth for python-version, line-length, ruff rules, type checker, test framework, and project layout. Do not override what the project already defines.

  • Creating new projects: Use the defaults below when no

pyproject.toml exists yet.

Local overrides (see "What Can Be Overridden") apply in both modes and take precedence over both the project config and the defaults below.

Defaults for New Projects

| Setting | Default | |------------------|------------------------| | python-version | 3.14 | | line-length | 120 | | type-checker | ty | | test-framework | pytest | | test-directory | tests/ | | project-layout | src/ | | docstring-style | Google | | ruff-select | E, F, W, I, B, C4, UP |

What Can Be Overridden

Overrides are not limited to the tool defaults above. A repository can provide any additional context that affects how this skill operates:

  • Domain / business context: what the service does, which external

systems it integrates with, critical business invariants the AI would not know from reading code alone.

  • Review behavior: which priority levels to comment on, what to

skip, confidence threshold, maximum number of comments.

  • Codebase state: ongoing migrations, known tech debt that is

intentional, legacy patterns being phased out (so the AI does not flag them).

  • Team conventions: patterns specific to this codebase that differ

from generic best practices.

  • External caveats: downstream consumers, deployment constraints,

known limitations in third-party dependencies.

How to Override

Place overrides in whichever local rule file your agent platform uses:

  • Cursor: .cursor/rules/python-overrides.mdc (with globs: "**/*.py")
  • Claude Code: CLAUDE.md at the repository root
  • Generic / agentskills.io: AGENTS.md at the repository root

Only include what differs from the defaults or what adds context the AI cannot infer from the code.

Example override (works in any of the above files):

> Python skill overrides for this repository: > > Domain context: > This service is the payment gateway adapter. It integrates with Stripe > and Adyen APIs. Error handling and idempotency are critical — always > flag missing retry logic or non-idempotent mutations in payment flows. > > Review behavior: > - Only flag Priority 1 (Critical) and Priority 2 (Important) issues > - Do not comment on docstring style or naming preferences > - Maximum 5 review comments per PR > > Codebase state: > - Mid-migration from Flask to FastAPI; mixed patterns are intentional > - The legacy/ directory is scheduled for removal in Q3; do not > review files under it > > Tool overrides (only when pyproject.toml does not define them): > - docstring-style: NumPy

Project Structure

project-name/
├── src/
│   └── package_name/
│       ├── __init__.py
│       └── core.py
├── tests/
│   └── test_core.py
├── pyproject.toml
└── README.md

Rules:

  • ALWAYS use src/ layout (never place code at project root)
  • ALWAYS include __init__.py in packages
  • Use underscores in module names: my_module.py not my-module.py

Configuration (pyproject.toml)

Base Configuration

[project]
name = "your-project"
version = "0.1.0"
description = "Your description"
requires-python = ">=3.14"
dependencies = [
    "httpx>=0.28.1",
]

[project.optional-dependencies]
dev = [
    "ruff>=0.14.10",
    "ty>=0.0.5",
]
test = [
    "pytest>=9.0.2",
    "pytest-asyncio>=1.3.0",
    "pytest-cov>=7.0.0",
]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.ruff]
line-length = 120

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

[tool.ty]
python-version = "3.14"

Type Hints (Python 3.12+)

Required everywhere:

  • All function parameters and return types
  • Class attributes
  • Module-level variables when not obvious

Modern syntax (3.10+):

# Use | for unions (not Optional/Union)
def process(data: str | None) -> dict[str, int | float]:
    ...

# Use lowercase generics (not List/Dict)
def filter_items(items: list[str]) -> list[str]:
    ...

# Use collections.abc for abstract types
from collections.abc import Sequence, Mapping, Iterable

def process_items(items: Sequence[str]) -> Iterable[str]:
    """Process items - accepts list, tuple, or any sequence."""
    return (item.upper() for item in items)

Python 3.12+ Type Features (PEP 695):

# Type parameters with new syntax
def first[T](items: list[T]) -> T | None:
    return items[0] if items else None

# Type statement for aliases
type Point = tuple[float, float]

# Generic classes
class Container[T]:
    def __init__(self, value: T) -> None:
        self.value = value

    def get(self) -> T:
        return self.value

Advanced patterns: See [references/core-language-features.md](references/core-language-features.md) for comprehensive type hint patterns, Protocol, TypedDict, Literal, and overload examples.

Forbidden:

  • NEVER import from typing: List, Dict, Tuple, Optional, Union (replaced by built-in generics and | syntax). Imports like Any, Self, Protocol, TypeVar, TypeGuard, TypeIs are still valid.
  • NEVER leave functions untyped

Modern Features

Dataclasses (Python 3.7+, slots from 3.10+)

from dataclasses import dataclass
from typing import Self

@dataclass(slots=True)
class User:
    id: int
    name: str
    email: str | None = None

    def with_email(self, email: str) -> Self:
        return User(id=self.id, name=self.name, email=email)

Pattern Matching - Basic (Python 3.10+)

def handle_command(cmd: str) -> str:
    match cmd:
        case "quit" | "exit":
            return "Exiting"
        case "help":
            return "Showing help"
        case _:
            return f"Unknown: {cmd}"

Functools Patterns

from functools import cache, lru_cache

@cache  # Unbounded cache for pure functions
def expensive_computation(n: int) -> int:
    return n ** 2

@lru_cache(maxsize=128)  # Limited cache
def fetch_data(url: str) -> dict[str, Any]:
    ...

Pathlib (not os.path)

from pathlib import Path

config_dir = Path.home() / ".config" / "myapp"
config_file = config_dir / "config.json"

Context Managers

import os
from collections.abc import Iterator
from contextlib import contextmanager

@contextmanager
def temporary_setting(name: str, value: str) -> Iterator[None]:
    old_value = os.getenv(name)
    os.environ[name] = value
    try:
        yield
    finally:
        if old_value is None:
            del os.environ[name]
        else:
            os.environ[name] = old_value

Async Programming

Basic Async (All versions)

import asyncio
import httpx

async def fetch_url(url: str, timeout: float = 10.0) -> str:
    async with httpx.AsyncClient(timeout=timeout) as client:
        response = await client.get(url)
        return response.text

Task Groups (Python 3.11+)

async def fetch_all(urls: list[str], timeout: float = 30.0) -> list[str]:
    async with asyncio.timeout(timeout):
        async with asyncio.TaskGroup() as tg:
            tasks = [tg.create_task(fetch_url(url)) for url in urls]
    return [task.result() for task in tasks]

Advanced patterns: See [references/core-language-features.md](references/core-language-features.md) for decorators, descriptors, walrus operator, context variables, advanced pattern matching, and metaclasses.

Testing (pytest)

Key patterns:

  • Use pytest (never unittest)
  • Parametrize to test multiple scenarios
  • Mock external dependencies
  • Use fixtures for setup/teardown
  • Mark async tests with @pytest.mark.asyncio

See [references/testing-guide.md](references/testing-guide.md) for comprehensive testing patterns, async testing, mocking, fixtures, and coverage configuration.

Code Quality

Ruff Configuration

[tool.ruff]
line-length = 120

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

Type Checking

# ty (default for new projects)
[tool.ty]
python-version = "3.14"

# mypy (for existing projects that already use it)
[tool.mypy]
python_version = "3.14"
strict = true
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true

Naming Conventions

  • Functions/variables: snake_case
  • Classes: PascalCase
  • Constants: UPPERSNAKECASE
  • Private: prefix with _

✅ GOOD: calculate_average(), UserManager, MAX_RETRIES ❌ BAD: CalculateAverage(), calc_avg(), userManager

Error Handling

Standard exception handling (All versions):

try:
    risky_operation()
except ValueError as e:
    logger.error(f"Invalid value: {e}")
except TimeoutError:
    logger.warning("Operation timed out")

Catching Exception - when it's acceptable:

# ✅ Top-level handler (API endpoint, CLI) - handle gracefully
@app.route("/api/data")
def get_data():
    try:
        return process_data()
    except Exception as e:
        logger.exception("Request failed")
        return {"error": "Internal server error"}, 500

# ✅ Batch processing - log and continue
for item in items:
    try:
        process(item)
    except Exception as e:
        logger.exception(f"Failed to process {item}")
        continue

# ✅ Add context and wrap
except Exception as e:
    raise ProcessingError(f"Failed for {item_id}") from e

# ❌ Never silently swallow
except Exception:
    pass

Exception groups (Python 3.11+):

try:
    async with asyncio.TaskGroup() as tg:
        tg.create_task(task1())
        tg.create_task(task2())
except* ValueError as eg:
    for exc in eg.exceptions:
        handle_value_error(exc)

Logging

Basic setup:

import logging

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s | %(levelname)-8s | %(name)s - %(message)s",
)

Production best practices: See [references/logging-guide.md](references/logging-guide.md) for structured logging (structlog vs python-json-logger), async logging, correlation IDs, request tracking, and performance optimization.

Dependencies

[project]
dependencies = [
    "httpx>=0.28.1",
    "pydantic>=2.5.0",
]

[project.optional-dependencies]
dev = [
    "ruff>=0.14.10",
    "ty>=0.0.5",
]
test = [
    "pytest>=9.0.2",
    "pytest-asyncio>=1.3.0",
    "pytest-cov>=7.0.0",
]

Anti-Patterns (Never Do)

  • ❌ Mutable default arguments: def func(items=[])
  • ❌ Bare except: (catches SystemExit, KeyboardInterrupt)
  • ❌ Silently swallowing exceptions: except Exception: pass
  • ❌ Using eval/exec on user input
  • ❌ Using os.path (use pathlib)
  • from typing import List, Dict (use built-in generics)
  • ❌ Hardcoded secrets or API keys
  • ❌ Unparameterized SQL queries

Documentation

def calculate_average(
    numbers: list[float],
    *,
    weights: list[float] | None = None
) -> float:
    """Calculate the average of numbers.

    Args:
        numbers: List of numbers to average
        weights: Optional weights for weighted average

    Returns:
        The calculated average

    Raises:
        ValueError: If numbers is empty

    Examples:
        >>> calculate_average([1, 2, 3])
        2.0
    """

Rules: Google or NumPy docstring style. Include docstrings for public APIs. Types in signature, not docstring.

Python 3.13 and 3.14 Features

  • Python 3.13: See [references/python-3.13-features.md](references/python-3.13-features.md)
  • Python 3.14: See [references/python-3.14-features.md](references/python-3.14-features.md)

Security Best Practices

Critical rules:

  • ✅ ALWAYS validate and sanitize user input
  • ✅ ALWAYS use parameterized queries for SQL
  • ✅ ALWAYS hash passwords (Argon2 or bcrypt)
  • ✅ ALWAYS load secrets from environment
  • ✅ ALWAYS use HTTPS for external APIs
  • ❌ NEVER hardcode secrets
  • ❌ NEVER use string concatenation for SQL
  • ❌ NEVER log sensitive data

See [references/security-guide.md](references/security-guide.md) for input validation, SQL injection prevention, path traversal prevention, password hashing, secrets management, and comprehensive security patterns.

Checklist

For Code Authors

When creating Python code:

  • [ ] Python 3.12+ features used
  • [ ] All functions have type hints
  • [ ] Modern type syntax used (|, lowercase generics, collections.abc)
  • [ ] Dataclasses with slots=True for data
  • [ ] Pathlib instead of os.path
  • [ ] F-strings for formatting
  • [ ] Specific exceptions caught
  • [ ] Async with proper error handling and timeouts
  • [ ] Tests written (pytest) with mocking
  • [ ] Security best practices followed
  • [ ] Docstrings for public APIs
  • [ ] No hardcoded secrets
  • [ ] Ruff and type checker (ty/mypy) pass
  • [ ] src/ layout used

For Code Reviewers

Review quality rules (apply before writing any comment):

  • Only comment when confident. If you are uncertain whether

something is actually wrong, do not comment. A false positive wastes more reviewer and author time than a missed suggestion.

  • Signal over noise. A review with 2 critical findings is more

valuable than one with 15 mixed-confidence suggestions. Fewer, higher-quality comments.

  • Default scope: Priority 1 and 2 only. Do not comment on Priority

3 issues unless the repository overrides explicitly request it.

  • Never comment on pure style preferences that the configured

linter does not flag. If ruff passes, the style is acceptable.

  • Respect the codebase's current state. If code is in a known

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.