Skip to content

PY-EXCE0003 · shared_exception_placement

Place reused exception classes in the narrowest justified exceptions.py.

This is a deterministic rule for python. Read its implementation.

Resolve the top-level project classes derived directly or transitively from BaseException, Exception, or an error-named base, match the explicit project from imports that reach them, and report an exception at least minimum_importing_modules distinct ordinary modules import while its defining module is not already named preferred_module. An exception several modules import is a shared contract, and leaving it in the module that happens to raise it makes every consumer depend on that module for a name rather than for behavior.

A relative import is resolved against the package of the module that wrote it, so the same from .service import OrderError line in two packages names two different definitions and each is counted against the one it reaches.

Each finding names the exception, the dotted module that defines it, and every ordinary module that imports it by name. The value is the number of exceptions reused widely enough to move.

A file-local exception and one only a single module imports are excluded, since neither is a shared contract yet. A package __init__.py re-export, an import-only re-export module, a star import, a dynamic import, and module-qualified attribute access are not counted as consumers, because none of them proves that a second module depends on the name. An exception already living in a module named preferred_module is stable and not reported again. Keeping a domain exception beside its sole owner is right whenever moving it would weaken cohesion or introduce an import cycle.

An OrderConflictError defined in orders/service.py and imported independently by orders/api.py and orders/jobs.py returns 1, since two ordinary modules depend on the name. The same class living in orders/exceptions.py returns 0. A LocalParseError raised and caught only inside parser.py returns 0, and so does one that a single module imports and one that only the package initializer hands on.

  • Cites “The Python Tutorial”, user-defined exceptions. Open reference
  • Cites “The Python Language Reference”, import system. Open reference
  • Cites “A Philosophy of Software Design”, chapters 4 and 5