{"record":{"id":"6f2368439211a113","repo":"pola-rs/polars","slug":"cannot-override-cls-name-name-with-custo","errorCode":null,"errorMessage":"cannot override `{cls.__name__}.{name}` with custom namespace {ns_class.__name__!r}","messagePattern":"cannot override `(.+?)\\.(.+?)` with custom namespace (.+?)","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/api.py","lineNumber":60,"sourceCode":"\n        ns_instance = self._ns(instance)  # type: ignore[call-arg]\n        setattr(instance, self._accessor, ns_instance)\n        return ns_instance\n\n\ndef _create_namespace(\n    name: str, cls: type[Expr | DataFrame | LazyFrame | Series]\n) -> Callable[[type[NS]], type[NS]]:\n    \"\"\"Register custom namespace against the underlying Polars class.\"\"\"\n\n    def namespace(ns_class: type[NS]) -> type[NS]:\n        if name in _reserved_namespaces:\n            msg = f\"cannot override reserved namespace {name!r}\"\n            raise AttributeError(msg)\n        elif (attr := getattr(cls, name, None)) is not None:\n            if isfunction(attr) or isinstance(attr, property) or name.startswith(\"_\"):\n                msg = f\"cannot override `{cls.__name__}.{name}` with custom namespace {ns_class.__name__!r}\"\n                raise AttributeError(msg)\n            warn(\n                f\"overriding existing custom namespace {name!r} (on {cls.__name__})\",\n                UserWarning,\n                stacklevel=find_stacklevel(),\n            )\n\n        setattr(cls, name, NameSpace(name, ns_class))\n        cls._accessors.add(name)\n        return ns_class\n\n    return namespace\n\n\ndef register_expr_namespace(name: str) -> Callable[[type[NS]], type[NS]]:\n    \"\"\"\n    Decorator for registering custom functionality with a Polars Expr.\n\n    Parameters","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/py-polars/src/polars/api.py#L42-L78","documentation":"When registering a custom namespace, Polars raises AttributeError if the target class already has an attribute with that name that is a function, a property, or starts with an underscore. This prevents custom namespaces from shadowing real methods or private attributes of DataFrame/LazyFrame/Series. Distinct from the reserved-namespace error: this covers any existing method/property, not just built-in namespaces.","triggerScenarios":"`@pl.api.register_lazyframe_namespace(\"filter\")` or any name matching an existing method/property/underscore-prefixed attribute on the target class.","commonSituations":"Naming a custom namespace after a common DataFrame method like 'head', 'columns', or 'group_by'; re-running module registration code that now collides after a Polars upgrade added a new method with that name.","solutions":["Rename the namespace to something that does not clash with an existing method (e.g. prefix it)","If a prior custom registration is being replaced, use a different module load path; overriding is only allowed for previously-registered custom namespaces (which emits a warning, not this error)"],"exampleFix":"// before\n@pl.api.register_dataframe_namespace(\"columns\")\nclass ColumnsNS: ...\n// after\n@pl.api.register_dataframe_namespace(\"my_columns\")\nclass ColumnsNS: ...","handlingStrategy":"validation","validationCode":"existing = getattr(pl.DataFrame, ns_name, None)\nassert existing is None or (not callable(existing) and not isinstance(existing, property) and not ns_name.startswith('_'))","typeGuard":"def is_free_namespace_name(cls: type, name: str) -> bool:\n    attr = getattr(cls, name, None)\n    return attr is None or not (callable(attr) or isinstance(attr, property) or name.startswith('_'))","tryCatchPattern":"try:\n    pl.api.register_dataframe_namespace(\"head\")(MyNS)\nexcept AttributeError as e:\n    if \"cannot override\" in str(e):\n        pl.api.register_dataframe_namespace(\"my_head\")(MyNS)\n    else:\n        raise","preventionTips":["Avoid namespace names that match DataFrame/LazyFrame/Series methods or start with '_'","Keep registrations idempotent and centralized to detect collisions at import time","Re-run registration tests after polars upgrades (new methods may collide)"],"tags":["python","namespace","naming-collision"],"backgroundTag":"invalid-identifier","analyzedSha":"fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e","analyzedAt":"2026-09-18T22:14:11.667Z","contentChangedAt":"2026-09-18T22:14:11.667Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}