{"record":{"id":"dbc5d87d70dffff3","repo":"RyanCodrai/turbovec","slug":"module-name-r-has-no-attribute-name-r","errorCode":null,"errorMessage":"module {__name__!r} has no attribute {name!r}","messagePattern":"module (.+?) has no attribute (.+?)","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"turbovec-python/python/turbovec/__init__.py","lineNumber":42,"sourceCode":"__all__ = [\"BATCH_CHUNK_SIZE\", \"IdMapIndex\", \"TurboQuantIndex\", \"__version__\"]\n\n\ndef __getattr__(name: str) -> str:\n    # PEP 562: resolve __version__ lazily on first access. Importing\n    # importlib.metadata costs ~20 ms — an order of magnitude more than\n    # the rest of `import turbovec` — so it must not run at import time.\n    if name == \"__version__\":\n        from importlib.metadata import PackageNotFoundError, version\n\n        try:\n            v = version(\"turbovec\")\n        except PackageNotFoundError:\n            # Source tree without installed dist metadata (e.g. the\n            # extension built in place); an obviously-dev marker.\n            v = \"0.0.0.dev0\"\n        globals()[\"__version__\"] = v  # cache: __getattr__ never fires again\n        return v\n    raise AttributeError(f\"module {__name__!r} has no attribute {name!r}\")\n\n\ndef __dir__() -> list:\n    # PEP 562 companion: advertise the lazy attribute before its first\n    # access (the set-union keeps it single once cached in globals()).\n    return sorted(set(globals()) | {\"__version__\"})\n","sourceCodeStart":24,"sourceCodeEnd":49,"githubUrl":"https://github.com/RyanCodrai/turbovec/blob/ccab9f325e6ce2a270a87daf01ae4e443bcf2d49/turbovec-python/python/turbovec/__init__.py#L24-L49","documentation":"turbovec uses PEP 562 module-level __getattr__ to lazily expose __version__ (read from installed distribution metadata) and cache it in globals(). If the requested attribute is not __version__ and not already defined on the module, __getattr__ raises AttributeError. This is the standard mechanism Python itself uses for genuinely missing module attributes, so it surfaces whenever you access a name that does not exist on the turbovec package.","triggerScenarios":"Accessing any undefined attribute of the turbovec module, e.g. `turbovec.vecor` (typo), `from turbovec import nonexistent_fn`, or introspection/probing by tooling (getattr with a default of no sentinel, IDE plugins, pickling probes for __dunder__ names).","commonSituations":"Typo'd imports after a rename; code written against a different library version where the symbol moved or was removed; dynamic attribute access frameworks (pickle, copy, IDE autocomplete) probing common names like __path__ or __version__ on a source-tree install without dist metadata.","solutions":["Check the spelling of the attribute against `dir(turbovec)` (which via __dir__ already includes the lazy __version__).","Verify the symbol exists in your installed turbovec version (`pip show turbovec`, or inspect python/turbovec/__init__.py).","If you need __version__ and it is not resolving, install the package so importlib.metadata finds the distribution, or accept the 0.0.0.dev0 dev marker.","If the symbol was renamed in a newer version, update call sites or pin the older version."],"exampleFix":"// before\nfrom turbovec import deduplcate\n// after\nfrom turbovec import deduplicate  # or: import turbovec; dir(turbovec) to list names","handlingStrategy":"type-guard","validationCode":"import turbovec\nname = 'deduplicate'\nassert name in dir(turbovec), f'turbovec has no attribute {name}'","typeGuard":"def has_attr(mod, name: str) -> bool:\n    return name in dir(mod)","tryCatchPattern":"try:\n    fn = getattr(turbovec, name)\nexcept AttributeError:\n    fn = None  # or log and fall back\nif fn is None:\n    ...","preventionTips":["Run dir(turbovec) or check the package docs before dynamic attribute access.","Use static imports and let a linter/IDE (pyright, mypy) catch typos.","Pin and review the turbovec version when upgrading, since the public surface can change.","Always give getattr a default when probing optional attributes."],"tags":["python","attributeerror","module-api","typo"],"backgroundTag":"invalid-argument-value","analyzedSha":"ccab9f325e6ce2a270a87daf01ae4e443bcf2d49","analyzedAt":"2026-09-06T08:39:18.516Z","contentChangedAt":"2026-09-06T08:39:18.516Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}