mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
2.2 KiB
2.2 KiB
Code Style & Conventions
General
from __future__ import annotationsat the top of every Python file- Full type hints on all function signatures and class fields
- Max line length: 99 characters (ruff enforced)
- snake_case for Python names; camelCase used only in
__api_method__strings
Pydantic models
- All Telegram types extend
TelegramObject(BotContextController, BaseModel)fromaiogram/types/base.py TelegramObjectis frozen; useMutableTelegramObjectwhen mutation is needed- Fields default to
Nonefor optional API parameters; useField(None, json_schema_extra={"deprecated": True})for deprecated fields - Use
Default("key")sentinel (fromaiogram.client.default) for user-configurable defaults likeparse_mode,protect_content TYPE_CHECKINGguards for circular imports — keep runtime imports lean
API Methods
- Each method is a class inheriting
TelegramMethod[ReturnType]fromaiogram/methods/base.py - Required class attrs:
__returning__(return type),__api_method__(camelCase string) - Fields with
Nonedefault = optional param - Method docstring format: short description +
Source: https://core.telegram.org/bots/api#methodname - File name: snake_case of method name (e.g.,
SendMessage→send_message.py)
Imports order (ruff/isort enforced)
- stdlib
- third-party
aiogram(first-party)- relative imports
Ruff rules enforced
- A (annotations), B (bugbear), C4 (comprehensions), DTZ (datetimez), E, F, I (isort), PERF, PL (pylint), Q (quotes), RET, SIM, T10, T20, UP (pyupgrade)
- Several PLR rules disabled (Telegram API naturally has many params/methods)
F401disabled (re-exports in__init__.pyintentional)
Code generation convention
- Never hand-edit generated files (
.butcher/**/entity.json, auto-generatedaiogram/types/*.py,aiogram/methods/*.py,aiogram/enums/*.py) - Add features via
.butcherYAML config/aliases + templates, then regenerate - After codegen: always run lint + mypy
Naming patterns
- Enums: PascalCase class, UPPER_SNAKE members (e.g.,
ContentType.TEXT) - Test files:
test_<module_name>.py - Test classes:
Test<ClassName>withasync def test_<scenario>(self, bot: MockedBot)