Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

pycatch

CI License: MIT Python 3.12+

Release candidate. pycatch est en 1.0.0rc1 : l'API est considérée figée mais n'a pas encore été éprouvée par un usage réel en dehors de ce dépôt. Les retours (issues, cas d'usage, bugs) sont les bienvenus avant de tagger la version 1.0.0 finale — voir RELEASING.md.

Gestion d'erreurs fluide pour Python, inspirée du type Result de Rust.

pycatch expose Result, Ok, Err et un décorateur catch pour éviter d'empiler des dizaines de try/except imbriqués. Les erreurs deviennent des valeurs explicites dans le typage de vos fonctions, et se traitent avec le pattern matching natif de Python (match/case).

Installation

Le paquet est publié sur PyPI sous le nom pycatch-safe (le nom pycatch était déjà pris) — l'import Python, lui, reste pycatch :

pip install pycatch-safe
import pycatch

Pourquoi

Avant — les erreurs possibles sont invisibles dans la signature :

def get_user_avatar(user_id: int) -> str:
    user = db.fetch_user(user_id)       # peut lever UserNotFound
    res = http_client.get(user.avatar_url)  # peut lever HTTPError ou Timeout
    return res.json()["url"]            # peut lever KeyError

Après — la signature annonce la couleur : ça réussit avec str, ou ça échoue avec une erreur explicite :

def get_user_avatar(user_id: int) -> Result[str, UserError]:
    ...

Usage

Le décorateur catch

catch(*exceptions) capture les exceptions listées et retourne un Result au lieu de lever — tout le reste continue de se propager normalement.

from pycatch import Ok, Err, catch

@catch(ValueError, KeyError)
def parse_age(data: dict) -> int:
    return int(data["age"])

res = parse_age({"age": "invalid"})

match res:
    case Ok(val):
        print(f"Âge : {val}")
    case Err(err):
        print(f"Erreur capturée : {err}")

catch fonctionne aussi bien sur des fonctions async def que sur des méthodes d'instance :

class Parser:
    @catch(ValueError)
    async def parse(self, value: str) -> int:
        return int(value)

Pattern matching sur le type d'exception

match result:
    case Ok(age):
        print(f"User age is valid: {age}")
    case Err(ValueError() as err):
        print(f"Invalid age provided: {err}")
    case Err(KeyError() as err):
        print(f"Missing age field in payload: {err}")

L'API Result

Ok[T] et Err[E] exposent la même API, façon Rust :

Méthode Description
is_ok() / is_err() Teste la variante
ok() / err() T | None / E | None
unwrap() / unwrap_err() Extrait la valeur ou l'erreur, lève UnwrapError si la variante ne correspond pas
unwrap_or(default) Valeur, ou default si Err
unwrap_or_else(fn) Valeur, ou fn(error) si Err
unwrap_or_raise() Valeur, ou relève l'exception d'origine contenue dans Err — pont vers du code legacy basé sur des exceptions
map(fn) Transforme la valeur si Ok, no-op si Err
map_err(fn) Transforme l'erreur si Err, no-op si Ok
and_then(fn) Chaîne une opération qui retourne elle-même un Result — évite d'imbriquer les try/except
result = (
    parse_age({"age": "30"})
    .map(lambda age: age + 1)
    .and_then(lambda age: Ok(age) if age < 150 else Err(ValueError("trop vieux")))
)

Ok et Err sont de simples constructeurs, librement instanciables — pas de factory imposée : Ok(42), Err(ValueError("...")).

Typage

Le package est entièrement typé (py.typed, mypy --strict), avec des génériques modernes (PEP 695, Python 3.12+). Le décorateur catch préserve la signature de la fonction décorée grâce à ParamSpec.

Compatibilité

pycatch nécessite Python 3.12+. C'est un choix assumé, pas un oubli : Ok/Err/Result utilisent la syntaxe générique moderne de PEP 695 (class Ok[T], type Result[T, E] = ...), qui n'existe pas avant 3.12. Supporter 3.10/3.11 demanderait de réécrire ces génériques avec Generic[T]/TypeVar — ce n'est pas prévu à court terme, mais une contribution est bienvenue si ce besoin se fait sentir.

Développement

uv sync
uv run ruff check src tests
uv run ruff format --check src tests
uv run mypy
uv run pytest --cov=pycatch --cov-report=term-missing

Voir CONTRIBUTING.md pour contribuer, CHANGELOG.md pour l'historique des versions, et RELEASING.md pour le process de publication.

Licence

MIT

Metadata

Release files for pycatch-safe 1.0.0rc1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pycatch-safe 1.0.0rc1
File Size Uploaded Provenance
pycatch_safe-1.0.0rc1.tar.gz 45.5 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pycatch-safe 1.0.0rc1
File Interpreter ABI Platform
pycatch_safe-1.0.0rc1-py3-none-any.whl Python 3 none any Details

Total release size: 54.3 kB

Release files / pycatch_safe-1.0.0rc1.tar.gz

Download URL pycatch_safe-1.0.0rc1.tar.gz
Size 45.5 kB
Tags Source
SHA-256 checksum
How to use checksums
4eb4f65a6554776715fe39e05518a00b860d83b82445c3616828fbb060de14ae
BLAKE2b-256 checksum
How to use checksums
84d6da122a99706a5bf69a499e26142ccf4e81466d0a00625fa176b8fb88507b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.

Transparency log

Release files / pycatch_safe-1.0.0rc1-py3-none-any.whl

Download URL pycatch_safe-1.0.0rc1-py3-none-any.whl
Size 8.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2a1cb2915d480779791a5139278f308d11a3b628396a1a9eb442289ed9c4896d
BLAKE2b-256 checksum
How to use checksums
25bb9485d06e6763e2dcc0a6cf058476aff7c6082145080348ef3b39a1b6db2b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.

Transparency log

Security for pycatch-safe 1.0.0rc1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pycatch_safe-1.0.0rc1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page