Skip to content

Pre-release

Choose a tag to compare

@rlxrd rlxrd released this 29 May 10:28

[0.4.0] — 2026-05-29

Добавлено

  • Все 11 типов событий — именованные декораторы (router.py).
    Ранее 7 типов были доступны только через @app.event(...). Теперь каждый тип
    имеет отдельный декоратор:

    • @app.message_removed() — сообщение удалено (update.message_id, update.chat_id)
    • @app.chat_created() — создан групповой чат (update.chat, update.message_id)
    • @app.chat_title_changed() — изменён заголовок (update.title, update.user)
    • @app.user_added() — пользователь добавлен (update.user, update.inviter_id)
    • @app.user_removed() — пользователь удалён (update.user, update.admin_id)
    • @app.bot_added() — бот добавлен в чат/канал (update.user, update.is_channel)
    • @app.bot_removed() — бот удалён из чата/канала (update.user, update.is_channel)
  • F (MagicFilter)src/maxio/magic.py, экспортируется как from maxio import F.
    Ленивый объект для построения фильтров-выражений без отдельных классов.

    • Шорткаты: F.text, F.data, F.payload, F.photo/F.image, F.video, F.audio, F.file/F.document
    • Операторы: ==, !=, .startswith(), .endswith(), .contains(), .in_(), .not_in_()
    • Комбинаторы: & (AND), | (OR), ~ (NOT)
    • Полный путь: F.message.sender.user_id == 5
  • DI в middleware — middleware теперь получает аргументы через тот же механизм, что и хэндлеры.
    CallNextOuter и CallNextInner стали реальными инжектируемыми классами (раньше — type aliases).
    HandlerKwargs — новый инжектируемый тип для inner middleware: словарь уже резолвленных
    аргументов хэндлера. Все три экспортируются из maxio.middleware и из maxio.

    # Раньше
    async def mw(update: Update, call_next: Any) -> bool: ...
    async def mw(handler: Any, kwargs: Any, call_next: Any) -> None: ...
    
    # Теперь
    async def mw(update: Update, call_next: CallNextOuter, user: User | None) -> bool: ...
    async def mw(call_next: CallNextInner, kwargs: HandlerKwargs, message: Message) -> None: ...
  • Optional в DI — резолвер (injection.py) понимает X | None и Optional[X].
    Если тип недоступен для данного апдейта — подставляется None вместо MaxError.

    @app.bot_started()
    async def on_start(update: Update, message: Message | None) -> None:
        # message == None, bot_started не несёт объект Message
        ...

Изменено

  • MaxBot.__init__ — убран **bot_kwargs: Any, параметры явные и keyword-only:
    storage, timeout, mask_token_in_logs. Убран base_url — адрес API фиксирован
    (https://botapi.max.ru) и не должен меняться пользователем.
  • Bot.__init__ — аналогично убран base_url из публичного API.
  • Примеры (echo_bot.py, showcase.py) переписаны под v0.4: новые декораторы,
    F вместо CallbackPayload, обновлённые сигнатуры middleware.