RyanCodrai/turbovec · error · AttributeError
module {__name__!r} has no attribute {name!r}
Error message
module {__name__!r} has no attribute {name!r} What it means
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.
Source
Thrown at turbovec-python/python/turbovec/__init__.py:42
__all__ = ["BATCH_CHUNK_SIZE", "IdMapIndex", "TurboQuantIndex", "__version__"]
def __getattr__(name: str) -> str:
# PEP 562: resolve __version__ lazily on first access. Importing
# importlib.metadata costs ~20 ms — an order of magnitude more than
# the rest of `import turbovec` — so it must not run at import time.
if name == "__version__":
from importlib.metadata import PackageNotFoundError, version
try:
v = version("turbovec")
except PackageNotFoundError:
# Source tree without installed dist metadata (e.g. the
# extension built in place); an obviously-dev marker.
v = "0.0.0.dev0"
globals()["__version__"] = v # cache: __getattr__ never fires again
return v
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
def __dir__() -> list:
# PEP 562 companion: advertise the lazy attribute before its first
# access (the set-union keeps it single once cached in globals()).
return sorted(set(globals()) | {"__version__"})
View on GitHub (pinned to ccab9f325e)
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.
Example fix
// before from turbovec import deduplcate // after from turbovec import deduplicate # or: import turbovec; dir(turbovec) to list names
Defensive patterns
Strategy: type-guard
Validate before calling
import turbovec
name = 'deduplicate'
assert name in dir(turbovec), f'turbovec has no attribute {name}' Type guard
def has_attr(mod, name: str) -> bool:
return name in dir(mod) Try / catch
try:
fn = getattr(turbovec, name)
except AttributeError:
fn = None # or log and fall back
if fn is None:
... Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- duplicate id in batch: {k!r}
- {prefix} {version}; this turbovec accepts versions {list(com
- side-car key {key!r} at {_crumb_path(entry)} is {type(key)._
- side-car value at {_crumb_path(entry)} is {obj!r}, which JSO
- persisted store is corrupt: duplicate {what} handles in the
AI-assisted analysis of RyanCodrai/turbovec@ccab9f325e (2026-09-06).
Data as JSON: /api/errors/dbc5d87d70dffff3.
Report an issue: GitHub.