HKUDS/Vibe-Trading · warning · AttributeError

module {__name__!r} has no attribute {name!r}

Error message

module {__name__!r} has no attribute {name!r}

What it means

Module-level __getattr__ in factors/_backend.py exposes only HAS_BOTTLENECK and bn lazily; any other attribute access on the module raises AttributeError. This is the standard PEP 562 lazy-import pattern for the optional bottleneck dependency.

Source

Thrown at agent/src/factors/_backend.py:68

        return
    try:
        import bottleneck as _bn

        _bn_module = _bn
        _has_bottleneck = True
    except ImportError:
        pass


def __getattr__(name: str) -> Any:
    """Lazily resolve ``HAS_BOTTLENECK`` and ``bn`` on first attribute access."""
    if name == "HAS_BOTTLENECK":
        _ensure_bottleneck()
        return _has_bottleneck
    if name == "bn":
        _ensure_bottleneck()
        return _bn_module
    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Use only the documented attributes: _backend.HAS_BOTTLENECK and _backend.bn
  2. Import the real dependency (import bottleneck) directly instead of the lazy shim if you need more
  3. Treat _backend as private — depend on the public factors API, not factors._backend

Example fix

# before
from agent.src.factors import _backend
_backend.has_bottleneck

# after
from agent.src.factors import _backend
if _backend.HAS_BOTTLENECK:
    bn = _backend.bn
Defensive patterns

Strategy: type-guard

Validate before calling

from agent.src.factors import _backend
if not hasattr(_backend, 'HAS_BOTTLENECK'):
    raise ImportError('unexpected _backend module layout')

Type guard

def backend_has(attr: str) -> bool:
    return attr in ('HAS_BOTTLENECK', 'bn')

Try / catch

try:
    bn = _backend.bn
except AttributeError:
    bn = None  # fall back to numpy paths

Prevention

When it happens

Trigger: Accessing factors._backend.something_else, or typos like factors._backend.HAS_BOTTLENEK / .bottle. Only 'HAS_BOTTLENECK' and 'bn' resolve; the first also triggers the optional bottleneck import attempt.

Common situations: IDE autocompletion probing module attributes; hasattr checks against the private module; copy-paste of internal imports after the module was refactored to lazy loading; downstream code reaching into the private _backend module.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/4bb42e5390ae2a1b. Report an issue: GitHub.