{"record":{"id":"5a2b944f29df3ecf","repo":"aio-libs/aiohttp","slug":"inheritance-class-cls-name-from-chainmapprox","errorCode":null,"errorMessage":"Inheritance class {cls.__name__} from ChainMapProxy is forbidden","messagePattern":"Inheritance class (.+?) from ChainMapProxy is forbidden","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"aiohttp/helpers.py","lineNumber":967,"sourceCode":"\n\nclass RequestKey(BaseKey[_T]):\n    \"\"\"Keys for static typing support in Request.\"\"\"\n\n\nclass ResponseKey(BaseKey[_T]):\n    \"\"\"Keys for static typing support in Response.\"\"\"\n\n\n@final\nclass ChainMapProxy(Mapping[str | AppKey[Any], Any]):\n    __slots__ = (\"_maps\",)\n\n    def __init__(self, maps: Iterable[Mapping[str | AppKey[Any], Any]]) -> None:\n        self._maps = tuple(maps)\n\n    def __init_subclass__(cls) -> None:\n        raise TypeError(\n            f\"Inheritance class {cls.__name__} from ChainMapProxy is forbidden\"\n        )\n\n    @overload  # type: ignore[override]\n    def __getitem__(self, key: AppKey[_T]) -> _T: ...\n\n    @overload\n    def __getitem__(self, key: str) -> Any: ...\n\n    def __getitem__(self, key: str | AppKey[_T]) -> Any:\n        for mapping in self._maps:\n            try:\n                return mapping[key]\n            except KeyError:\n                pass\n        raise KeyError(key)\n\n    @overload  # type: ignore[override]","sourceCodeStart":949,"sourceCodeEnd":985,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/helpers.py#L949-L985","documentation":"ChainMapProxy.__init_subclass__ raises TypeError when any class attempts to inherit from ChainMapProxy. The class is decorated with @final and uses __init_subclass__ as a hard guard to prevent subclassing. ChainMapProxy is an internal read-only mapping view used for Application storage; subclassing could break its invariants.","triggerScenarios":"Attempting to create a subclass: class MyProxy(ChainMapProxy): ... — the __init_subclass__ classmethod fires at class definition time, before __init__, and immediately raises TypeError.","commonSituations":"Trying to extend ChainMapProxy to add custom behavior to the aiohttp Application storage; copy-pasting from code that extends Mapping without realizing ChainMapProxy is @final; attempting to add type annotations or mixins to the storage layer.","solutions":["Do not subclass ChainMapProxy — use composition instead (wrap it in your own class)","If you need custom storage behavior, subclass aiohttp.web.Application or use a separate storage object","Access ChainMapProxy only through the documented Application API: app['key'] or app.get(key)"],"exampleFix":"# before\nfrom aiohttp.helpers import ChainMapProxy\nclass MyProxy(ChainMapProxy):  # TypeError at class definition\n    pass\n\n# after (composition, not inheritance)\nclass MyStorageWrapper:\n    def __init__(self, proxy: ChainMapProxy):\n        self._proxy = proxy\n    def get_with_default(self, key, default=None):\n        return self._proxy.get(key, default)","handlingStrategy":"validation","validationCode":"# No validation needed at runtime — this is a design-time error.\n# Ensure your codebase does not import or subclass ChainMapProxy.\n# Use Application's public API instead.\nfrom aiohttp.web import Application\napp = Application()\napp['my_key'] = 'value'  # correct way to store data","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never subclass internal aiohttp classes marked @final","Use composition over inheritance for extending framework behavior","Access Application storage only through the documented __getitem__/get API"],"tags":["chainmap-proxy","inheritance","type-error","application","internal-api"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}