python skill
명명 규칙, 타입 어노테이션, 데이터 클래스, 동시성 패턴을 포함하여 현대적인 Python 3.14+ 개발을 위한 가이드를 제공합니다.
- GitHub 스타
- 23
- 파일
- 6
- 마지막 커밋
- 2026년 11월 11일
- 라이선스
- MIT
- 허용된 도구
- —
python skill은 무엇을 하나요?
python은(는) agent skill입니다. 명명 규칙, 타입 어노테이션, 데이터 클래스, 동시성 패턴을 포함하여 현대적인 Python 3.14+ 개발을 위한 가이드를 제공합니다.
skill의 SKILL.md에서 생성된 요약입니다.
python skill 정보
Python 3.14+를 사용하는 개발자는 이 SKILL을 사용하여 코드가 현대적인 언어 표준 및 관용적 패턴을 준수하도록 할 수 있습니다. 이 SKILL은 최신 문법과 구조적 베스트 프랙티스를 강제함으로써 Python 프로젝트를 작성, 리뷰, 리팩터링 및 디버깅하기 위한 구체적인 지침을 제공합니다. 높은 가독성과 타입 안전성을 유지하기 위해 Python 코드와 상호작용하는 모든 작업에서 이 SKILL을 호출하도록 설계되었습니다.
에이전트가 이 SKILL을 로드하면 타입 어노테이션 패턴, uv 및 pyproject.toml을 이용한 프로젝트 패키징, 모듈 시스템, asyncio 및 TaskGroup을 이용한 동시성 등을 다루는 전문 참조 문서에 접근할 수 있습니다. 또한 구조적 패턴 매칭, slots를 포함한 데이터 클래스, 고급 제네릭과 같은 현대적인 기능을 구현하는 데 도움을 줍니다. 이 가이드를 따르면 개발자는 내장 제네릭, 별칭을 위한 type 문, 컨텍스트 매니저를 통한 효율적인 리소스 관리를 활용하는 코드를 작성할 수 있습니다.
agent가 수행할 수 있는 작업
- 1레거시 Python 코드 리팩터링이전 버전의 Python 스크립트를 현대적인 3.14+ 문법 및 타입 어노테이션을 사용하도록 업데이트합니다.
- 2타입 안전한 API 구현제네릭, 프로토콜, 유니온을 위한 파이프 연산자를 포함한 현대적인 타입 힌팅 패턴을 적용합니다.
- 3데이터 구조 최적화표준 클래스를 dataclasses를 사용하여 메모리 효율적이고 불변적인 데이터 컨테이너로 변환합니다.
- 4의존성 관리 현대화pyproject.toml 및 uv 워크플로우를 사용하여 프로젝트 레이아웃과 의존성 그룹을 구성합니다.
skill의 SKILL.md를 기반으로 작성되었습니다. 모든 사용 사례는 해당 문서의 인용구와 대조 확인되었습니다.
python skill 설치 방법
각 명령은 skill 폴더를 클라이언트의 skills 디렉터리에 복사합니다. 클라이언트를 재시작하거나 새 세션을 시작하여 로드하세요.플러그인에 python skill 설치
/plugin marketplace add xobotyi/cc-foundry /plugin install python@foundry
Claude Code에 python skill 설치
~/.claude/skills/python/SKILL.md
$ npx degit xobotyi/cc-foundry/plugins/python/skills/python ~/.claude/skills/pythonClaude Code (project)에 python skill 설치
.claude/skills/python/SKILL.md
$ npx degit xobotyi/cc-foundry/plugins/python/skills/python .claude/skills/pythonCodex에 python skill 설치
~/.agents/skills/python/SKILL.md
$ npx degit xobotyi/cc-foundry/plugins/python/skills/python ~/.agents/skills/pythonGemini CLI에 python skill 설치
~/.gemini/skills/python/SKILL.md
$ npx degit xobotyi/cc-foundry/plugins/python/skills/python ~/.gemini/skills/pythonClaude.ai에 python skill 설치
npx degit xobotyi/cc-foundry/plugins/python/skills/python python && zip -r python.zip python # claude.ai → Customize → Skills → + → Create skill → Upload a skill → python.zip
SKILL.md
GitHub에서 보기Python
Readability counts. Explicit is better than implicit. If your code needs a comment to explain its control flow, restructure it.
Python 3.14+ is the baseline. Use modern syntax unconditionally — no backward compatibility with older Python versions unless the project explicitly requires it.
References
- [
${CLAUDE_SKILL_DIR}/references/typing.md] — Type annotation patterns, generics, overloads, TypeVar, variance: full annotation examples, generic class patterns, Protocol implementation, TypeVar usage - [
${CLAUDE_SKILL_DIR}/references/packaging.md] — Project layout, pyproject.toml, uv, dependency management: pyproject.toml templates, uv workflows, src layout, dependency groups, build backends - [
${CLAUDE_SKILL_DIR}/references/modules.md] — Module system, imports, namespace packages,__init__.py: import resolution order, circular import fixes, lazy imports, namespace packages - [
${CLAUDE_SKILL_DIR}/references/concurrency.md] — asyncio, TaskGroup, cancellation, timeouts, threading interop: TaskGroup error handling, timeout scopes, cancellation semantics, to_thread, eager task factory
Naming
- Variables, functions, methods — snake_case:
user_name,fetch_data - Classes, type aliases — PascalCase:
UserService,HttpClient - Constants — UPPER_SNAKE_CASE:
MAX_RETRIES,API_BASE_URL - Modules, packages — snake_case, short:
user_store,auth - Private attributes/methods —
_prefix:_internal_cache,_validate() - Name-mangled attributes —
__prefix:__secret(rarely needed) - Type variables — PascalCase, short:
T,KT,VT,ResponseT - Protocols — PascalCase,
-able/-iblesuffix:Renderable,Serializable - Descriptive names.
user_countnotn. Short names (i,x) only in tiny scopes (comprehensions, simple lambdas). - No redundant context.
car.makenotcar.car_make. - Boolean names:
is_/has_/can_/should_prefix:is_valid,has_access. - Dunder methods are reserved for the data model. Never invent custom dunder names.
- Avoid single-character names outside loop indices, comprehension variables, and well-established conventions (
ffor file,efor exception,k/vfor key/value).
Type Annotations
Python 3.14+ uses modern annotation syntax natively. No from __future__ import annotations needed — all annotations
are evaluated lazily by default.
Core Rules
- Annotate all public API boundaries — function signatures, class attributes, module-level variables. Internal code often needs fewer annotations; types flow from context.
- Use built-in generics:
list[str],dict[str, int],tuple[int, ...],set[float]. Never importList,Dict,Tuple,Setfromtyping. - Union with
|:str | None,int | float. NeverOptional[X]orUnion[X, Y]. typestatement for aliases:type Vector = list[float]. NotTypeAliasannotation.Nonereturn: annotate-> Noneon functions that return nothing. Omit return type only on__init__.- Avoid
Any— it disables type checking. Useobjectwhen you mean "any type but still type-safe." UseAnyonly at true interop boundaries with untyped code.
Generics
typeparameter syntax (3.12+):class Stack[T]:anddef first[T](items: list[T]) -> T:instead ofTypeVardeclarations.- Constrained type parameters:
def process[T: (str, bytes)](data: T) -> T:for a finite set of allowed types. - Bounded type parameters:
def sort[T: Comparable](items: list[T]) -> list[T]:for upper-bound constraints. - Variance is inferred from usage in 3.12+ generics. No manual
covariant/contravariantflags needed.
Protocols (Structural Typing)
- Prefer protocols over ABCs when you don't control the implementing types or when structural compatibility is sufficient.
@runtime_checkableonly when you needisinstance()checks — it adds overhead and only validates method presence, not signatures.- Keep protocols small — one to three methods. A protocol with many methods is a sign you need an ABC or a concrete base class.
from typing import Protocol, runtime_checkable
@runtime_checkable
class Renderable(Protocol):
def render(self) -> str: ...
Callable Types
collections.abc.Callablefor callable annotations:Callable[[int, str], bool].ParamSpecfor decorators that preserve signatures:def decorator[**P, R](fn: Callable[P, R]) -> Callable[P, R]:.- Use
Protocolfor complex callable signatures with keyword arguments or overloads.
TypeGuard and TypeIs
TypeIs(3.13+) for narrowing that refines the input type:def is_str_list(val: list[object]) -> TypeIs[list[str]]:.TypeGuardfor narrowing where the output type is unrelated to input:def is_valid_config(data: object) -> TypeGuard[Config]:.
See ${CLAUDE_SKILL_DIR}/references/typing.md for full annotation patterns, generics, overloads, and variance.
Data Classes and Structured Data
dataclasses
- Use
@dataclassfor data containers — classes that primarily hold data with minimal behavior. frozen=Truefor immutable data:@dataclass(frozen=True). Default to frozen unless mutation is required.slots=Truefor memory efficiency and attribute safety:@dataclass(slots=True, frozen=True).kw_only=Truewhen constructors have more than 3 fields — prevents positional argument ordering bugs.field(default_factory=list)for mutable defaults. Never use mutable default arguments.- Post-init processing:
__post_init__for derived fields and validation.
@dataclass(frozen=True, slots=True, kw_only=True)
class User:
name: str
email: str
roles: list[str] = field(default_factory=list)
When NOT to Use dataclasses
- Simple value containers with 1-2 fields: use
NamedTupleor plain tuples. - Config/settings with validation: use Pydantic or attrs with validators.
- Persistence/ORM models: use the ORM's model base class.
NamedTuple
- Use
classsyntax over functional form:class Point(NamedTuple): x: float; y: float. - NamedTuples are immutable and iterable — useful as dict keys and in destructuring.
Enums
- Use
enum.Enumfor categorical constants. Never use bare strings or ints as pseudo-enums. enum.StrEnumwhen the enum must interoperate with string APIs (JSON, config keys).enum.IntEnumonly when integer interop is mandatory (legacy protocols). PreferEnumotherwise.@enum.uniqueto prevent duplicate values.- Access by value:
Color(1). Access by name:Color["RED"]. Iteration:for c in Color:. - Never subclass enums with members. Enums with members are final.
from enum import StrEnum, unique
@unique
class Status(StrEnum):
ACTIVE = "active"
INACTIVE = "inactive"
SUSPENDED = "suspended"
Pattern Matching
match/case (3.10+) is the preferred dispatch mechanism for structural patterns.
- Use match for structural dispatch — matching on type, shape, or destructured values. Don't use match as a
substitute for simple
if/elifchains on a single value. - Always include a wildcard
case _:arm unless the match is provably exhaustive. - Guard clauses with
if:case Point(x, y) if x > 0:. - Use
|for alternatives:case "quit" | "exit" | "q":. - Capture with walrus:
case {"error": str() as msg}:captures while matching type. - Class patterns require
__match_args__or keyword patterns:case Point(x=0, y=y):.
match command:
case {"action": "move", "direction": str() as direction}:
move(direction)
case {"action": "attack", "target": str() as target}:
attack(target)
case _:
raise ValueError(f"Unknown command: {command}")
Functions
- Early return. Guard clauses first, happy path flat. Reduce nesting.
- One function, one job. If the name contains "and", split it.
- Type-annotate all parameters and return types on public functions.
- Default arguments: immutable values only. Use
None+ conditional for mutable defaults:def f(items: list[int] | None = None):thenitems = items or []in body. Neverdef f(items: list[int] = []):. *to force keyword-only arguments after positional params:def connect(host: str, *, port: int = 443):./to force positional-only for parameters that callers shouldn't name:def sqrt(x: float, /) -> float:.- Prefer returning values over mutating arguments. Functions should be referentially transparent when possible.
Nonemeans absent, not error. ReturnT | Nonefor optional results. Raise exceptions for errors.
Decorators
-
Preserve signatures with
functools.wraps:def retry[**P, R](fn: Callable[P, R]) -> Callable[P, R]: @functools.wraps(fn) def wrapper(*args: P.args, **kwargs: P.kwargs) -> R: ... return wrapper -
Decorator order matters. Decorators apply bottom-up.
@staticmethodand@classmethodmust be outermost (topmost in source). -
Parametric decorators return a decorator:
@retry(attempts=3)meansretryreturns the actual decorator function. -
Don't over-abstract with decorators. If the decorator hides important control flow (error handling, transaction management), make it explicit instead.
Context Managers
-
contextlib.contextmanagerfor simple resource management:@contextmanager def managed_connection(url: str) -> Iterator[Connection]: conn = Connection(url) try: yield conn finally: conn.close() -
Class-based context managers when state management is complex — implement
__enter__and__exit__. -
contextlib.suppress(ExceptionType)instead of emptyexcept: pass. -
contextlib.closing(thing)for objects with.close()but no__exit__. -
contextlib.asynccontextmanagerfor async resource management. -
Always use
withfor files, locks, database connections, and any resource that needs deterministic cleanup.
Generators and Iterators
- Generators for lazy sequences. Use
yieldto produce values on demand instead of building full lists in memory. - Generator expressions over list comprehensions when the result is iterated only once:
sum(x * x for x in range(1000)). yield fromto delegate to sub-generators — preserves.send(),.throw(),.close()protocol.itertoolsfor composition:chain,islice,groupby,batched(3.12+),pairwise(3.10+).- Annotate generators:
def gen() -> Iterator[int]:for simple generators,Generator[YieldType, SendType, ReturnType]when using.send(). - Never exhaust a generator twice. Generators are single-pass. If you need multiple passes, materialize to a list or
use
itertools.tee.
Comprehensions
- List/dict/set comprehensions for simple transforms:
[x.name for x in users if x.active]. - One level of nesting maximum. Two nested
forclauses are the absolute limit. Beyond that, extract to a function. - Don't use comprehensions for side effects.
[print(x) for x in items]is wrong — use aforloop. - Walrus operator in comprehensions for compute-once-filter-and-use:
[y for x in data if (y := transform(x)) is not None]. - Dict comprehensions for key transformations:
{k.lower(): v for k, v in headers.items()}.
Exception Handling
-
Be specific. Catch the narrowest exception type:
except ValueError:notexcept Exception:. -
Never bare
except:. It catchesSystemExit,KeyboardInterrupt, andGeneratorExit. At minimum useexcept Exception:. -
except* ExceptionGroup(3.11+) for handling multiple concurrent exceptions fromTaskGroupand similar. -
Wrap with context.
raise AppError("context") from errchains the original cause. -
Don't use exceptions for flow control.
if key in dict:nottry: dict[key] except KeyError:(unless the miss is rare and lookup is expensive). -
Custom exceptions inherit from a project-specific base that extends
Exception:class AppError(Exception): ... class NotFoundError(AppError): ... class ValidationError(AppError): ... -
Error strings: lowercase, no trailing punctuation. They compose in chains:
"parse config: invalid format". -
elseclause runs only when no exception was raised — use for code that should execute on success but isn't part of thetrybody. -
finallyfor unconditional cleanup — prefer context managers when possible. -
Exception groups (3.11+): use
ExceptionGroupto bundle multiple errors. Handle withexcept*which matches by type and re-raises unhandled exceptions. -
Add notes with
.add_note()(3.11+) to attach context without creating new exception types.
Strings
- f-strings for interpolation. Never
%formatting or.format()in new code. - f-string expressions must be simple. No function calls with multiple arguments, no nested f-strings, no complex expressions. Extract to a variable first.
str.removeprefix()/str.removesuffix()(3.9+) over slicing.- Triple-quoted strings for multiline. Use
textwrap.dedentwhen indentation matters. "".join(parts)for building strings in loops — never+=in a loop.- Raw strings
r"..."for regex patterns and Windows paths.
Pathlib
pathlib.Pathfor all filesystem operations. Neveros.pathin new code./operator for path joining:base / "subdir" / "file.txt".- Common operations:
path.exists(),path.is_file(),path.is_dir(),path.read_text(),path.write_text(),path.mkdir(parents=True, exist_ok=True),path.iterdir(),path.glob("*.py"),path.rglob("**/*.py"). path.resolve()for absolute paths.path.relative_to(base)for relative paths.- Accept
str | Pathin public APIs, convert toPathinternally.
Imports
- Absolute imports by default:
from mypackage.utils import helper. - Relative imports only within packages for tightly coupled modules:
from .models import User. - Import grouping (separated by blank lines):
- Standard library (
import os,from pathlib import Path) - Third-party (
import httpx,from pydantic import BaseModel) - Local (
from myapp.models import User)
- Standard library (
- Import specific names:
from collections import defaultdictnotimport collections(unless you use many names from the module). - Never
from module import *— pollutes namespace, breaks type checkers, hides dependencies. if TYPE_CHECKING:block for imports used only in annotations — avoids circular imports and runtime overhead. In 3.14+ with lazy annotations, this is less necessary but still useful for avoiding circular import side effects.- Lazy imports in function bodies when a top-level import would create a circular dependency or when the import is expensive and rarely needed.
Classes
Slots
- Always use
__slots__on classes that will have many instances — prevents__dict__creation, saves memory, catches typos in attribute names. @dataclass(slots=True)adds slots automatically.- Slots and inheritance: every class in the hierarchy must declare
__slots__. Missing slots on a parent reintroduces__dict__.
Dunder Methods
__repr__on every class — must be unambiguous:def __repr__(self) -> str: return f"User(name={self.name!r})".__str__only when a human-readable form differs from repr.__eq__and__hash__— if you define__eq__, define__hash__too (or set__hash__ = Noneto make unhashable). Mutable objects should not be hashable.__bool__— define when truthiness of instances has meaningful semantics.__enter__/__exit__for context manager protocol.__init_subclass__for class registration patterns without metaclasses.__class_getitem__to make classes subscriptable for generic type hints.
Inheritance
- Composition over inheritance. Use inheritance only for true "is-a" relationships.
- ABCs for interfaces when you control both sides and need enforced implementation:
from abc import ABC, abstractmethod. - Protocols for duck typing when you don't control implementations.
super()— always usesuper()(no arguments in 3.x). Never hardcode parent class names.- MRO awareness. Understand method resolution order in diamond inheritance. When in doubt, avoid multiple inheritance.
Class Methods and Static Methods
@classmethodfor alternative constructors:User.from_dict(data).@staticmethodfor utility functions that don't need class or instance state — but prefer module-level functions unless the function is logically part of the class's API.
Packaging and Toolchain
pyproject.toml
pyproject.tomlis the single source of truth for project metadata, dependencies, tool configuration. Neversetup.pyorsetup.cfgin new projects.- Build backend: use
hatchling,flit-core, orsetuptoolswith[build-system]table. - Dependency specification: pin with
>=lower bound, avoid upper bounds unless genuinely incompatible:httpx>=0.27.
uv
uvis the preferred Python package manager and environment tool.uv syncto install dependencies from lock file.uv add <package>to add dependencies.uv run <command>to run commands in the project environment.uv lockto generate/update the lock file.uv venvto create virtual environments.uv python install 3.14to install Python versions.
Project Layout
my-project/
├── pyproject.toml
├── uv.lock
├── src/
│ └── my_package/
│ ├── __init__.py
│ └── ...
└── tests/
├── conftest.py
└── ...
- src layout — package code lives under
src/. Prevents accidental imports from the project root during testing. __init__.py— keep minimal. Define__all__for public API. Don't put substantial logic in init files.
Linting and Formatting
rufffor both linting and formatting. Single tool, fast.ruff checkto lint.ruff formatto format.- Configure in
pyproject.tomlunder[tool.ruff].
See ${CLAUDE_SKILL_DIR}/references/packaging.md for pyproject.toml templates, uv workflows, and dependency management
patterns.
Concurrency
asyncio
async/awaitfor I/O-bound concurrency.asyncio.TaskGroup(3.11+) for structured concurrency — replacesasyncio.gather()with better error handling.- Never use
asyncio.gather()in new code — it has inconsistent error semantics. UseTaskGroupinstead. asyncio.run()as the single entry point. Neverloop.run_until_complete().- Cancel via
asyncio.CancelledError— always clean up resources infinallyblocks.
threading
concurrent.futures.ThreadPoolExecutorfor CPU-light I/O-bound parallel work.threading.Lockfor shared mutable state. Always usewith lock:context manager.- GIL note: in CPython, threads don't achieve true parallelism for CPU-bound work. Use
multiprocessingorProcessPoolExecutorfor CPU-bound tasks. - Free-threaded Python (3.13+): when running with
--disable-gil, standard thread-safety practices become critical. Guard all shared mutable state with locks.
General Rules
- Structured concurrency preferred.
TaskGroupand context managers over barecreate_task(). - Never fire-and-forget tasks or threads — always track completion.
- Cancellation must be cooperative. Check for cancellation and clean up.
Logging
loggingmodule overprint()for anything beyond quick debugging.logger = logging.getLogger(__name__)at module level.- Lazy formatting:
logger.info("User %s logged in", user_id)notlogger.info(f"User {user_id} logged in")— f-string evaluates even when level is disabled. - Use appropriate levels:
DEBUGfor diagnostics,INFOfor operational events,WARNINGfor degraded but working,ERRORfor failures,CRITICALfor system-down.
Application
When writing Python code: apply all conventions silently — don't narrate each rule. If an existing codebase contradicts a convention, follow the codebase and flag the divergence once.
When reviewing Python code: cite the specific violation and show the fix inline. Don't lecture — state what's wrong and how to fix it.
Bad: "According to Python best practices, you should use type unions
with the pipe operator instead of Optional..."
Good: "Optional[str] -> str | None"
Code Navigation — LSP Required
A pyright-langserver LSP server is configured for .py and .pyi files. Always use LSP tools for code navigation
instead of Grep or Glob. LSP understands Python's module system, type inference, scope rules, and package boundaries —
text search does not.
Tool Routing
goToDefinition— find where a function/class/variable is defined: resolves imports, re-exports, aliasesfindReferences— find all usages of a symbol: scope-aware, no false positives from string matcheshover— get type signature, docs, or return types: instant type info without reading source filesdocumentSymbol— list all symbols in a file: structured output vs grepping fordef/classworkspaceSymbol— find a symbol by name across the project: searches all packages, respects__all__goToImplementation— find implementations of a Protocol or ABC: knows the type system and structural subtypingincomingCalls— find what calls a function: precise call graph across module boundariesoutgoingCalls— find what a function calls: structured dependency map
Grep/Glob remain appropriate for: text in comments, string literals, log messages, TODO markers, config values, env vars, file name patterns, URLs, error message text — anything that isn't a Python identifier.
When spawning subagents for Python codebase exploration, instruct them to use LSP tools. Subagents have access to the same LSP server.
Toolchain
ruff: single entry point for linting and formatting. Must pass before committing.ruff check— lint.ruff check --fix— auto-fix.ruff format— format.
uv: package management, virtual environments, Python version management.mypyorpyright: static type checking. Configure inpyproject.toml.
Integration
The coding skill governs workflow (discovery, planning, verification); this skill governs Python implementation choices. The pytest skill governs testing conventions — both are active simultaneously when writing Python tests.
Readability counts. If you read a function twice to understand it, rewrite it once to make it clear.
이 스킬의 파일
6python skill 질문
Claude Code에 python skill을 어떻게 설치하나요?
npx degit xobotyi/cc-foundry/plugins/python/skills/python ~/.claude/skills/python를 실행합니다. Claude Code는 ~/.claude/skills(모든 프로젝트) 또는 .claude/skills(한 프로젝트)에서 skills를 로드하며, 설명이 작업과 일치할 때 skill을 사용합니다.
python skill을 사용할 수 있는 클라이언트는 무엇인가요?
Agent Skills 형식을 읽는 모든 클라이언트(Claude Code, Codex, Gemini CLI, claude.ai(ZIP으로 업로드))가 사용할 수 있습니다. skill 내 스크립트는 클라이언트가 코드 실행을 허용하는 경우에만 실행됩니다.
이 SKILL의 기준 Python 버전은 무엇인가요?
기준은 Python 3.14+입니다. 프로젝트에서 명시적으로 하위 호환성을 요구하지 않는 한, 현대적인 문법을 조건 없이 사용해야 합니다.
현대적인 Python에서 유니온(union) 타입 어노테이션은 어떻게 처리해야 하나요?
typing 모듈의 Optional이나 Union을 사용하는 대신, str | None 또는 int | float과 같이 파이프 연산자를 사용하십시오.
추상 기본 클래스(ABC) 대신 프로토콜(protocol)을 사용해야 하는 경우는 언제인가요?
구현 타입을 직접 제어할 수 없거나 구조적 호환성만으로 충분한 경우 프로토콜을 우선적으로 사용하십시오.
데이터 컨테이너를 정의하는 권장 방법은 무엇인가요?
동작이 거의 없고 주로 데이터를 보유하는 클래스에는 @dataclass 데코레이터를 사용하며, 불변성을 위해 기본적으로 frozen=True를 설정하십시오.