{"record":{"id":"8266796934dcf430","repo":"HKUDS/DeepTutor","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":"deeptutor/tools/__init__.py","lineNumber":32,"sourceCode":"    \"TexDownloader\": (\".tex_downloader\", \"TexDownloader\"),\n    \"read_tex_file\": (\".tex_downloader\", \"read_tex_file\"),\n    \"BrainstormTool\": (\".builtin\", \"BrainstormTool\"),\n    \"CodeExecutionTool\": (\".builtin\", \"CodeExecutionTool\"),\n    \"GeoGebraAnalysisTool\": (\".builtin\", \"GeoGebraAnalysisTool\"),\n    \"PaperSearchToolWrapper\": (\".builtin\", \"PaperSearchToolWrapper\"),\n    \"RAGTool\": (\".builtin\", \"RAGTool\"),\n    \"ReasonTool\": (\".builtin\", \"ReasonTool\"),\n    \"WebSearchTool\": (\".builtin\", \"WebSearchTool\"),\n    \"ToolPromptComposer\": (\".prompting\", \"ToolPromptComposer\"),\n    \"load_prompt_hints\": (\".prompting\", \"load_prompt_hints\"),\n}\n\n__all__ = sorted(_LAZY_EXPORTS)\n\n\ndef __getattr__(name: str):\n    if name not in _LAZY_EXPORTS:\n        raise AttributeError(f\"module {__name__!r} has no attribute {name!r}\")\n\n    module_name, attr_name = _LAZY_EXPORTS[name]\n    module = importlib.import_module(module_name, __name__)\n    value = getattr(module, attr_name)\n    globals()[name] = value\n    return value\n\n\n# Question generation tools (lazy import to avoid circular dependencies)\n# Access via: from deeptutor.tools.question import parse_pdf_with_mineru, etc.\n","sourceCodeStart":14,"sourceCodeEnd":43,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/tools/__init__.py#L14-L43","documentation":"deeptutor/tools/__init__.py implements PEP 562 lazy exports via module-level __getattr__: attribute access on the package triggers on-demand import of the real class. Accessing any attribute not listed in _LAZY_EXPORTS raises a plain Python AttributeError naming the module and attribute. This is normal Python behavior, not a library-specific error class.","triggerScenarios":"from deeptutor.tools import SomethingNotExported, or deeptutor.tools.Foo where Foo is not a key in _LAZY_EXPORTS (misspelled tool class, removed export after upgrade, or a private name).","commonSituations":"Typos in tool class names, referencing a tool that was renamed/removed in a newer version, or assuming every module in deeptutor.tools.* is re-exported at package level.","solutions":["Check __all__ / _LAZY_EXPORTS in deeptutor/tools/__init__.py for the exact exported names","Import from the concrete submodule instead (e.g. from deeptutor.tools.builtin import X)","If the name vanished after an upgrade, check the changelog for renames","Fix typos — names are case-sensitive"],"exampleFix":"# before\nfrom deeptutor.tools import WebSerach  # typo\n# after\nfrom deeptutor.tools import WebSearch","handlingStrategy":"type-guard","validationCode":"import deeptutor.tools as dt\n\nif name not in dt.__all__:\n    raise ImportError(f\"deeptutor.tools does not export {name!r}; see dt.__all__\")","typeGuard":"import deeptutor.tools as dt\n\ndef is_lazy_export(name: str) -> bool:\n    \"\"\"Type guard: True if deeptutor.tools exports `name` (PEP 562 lazy attr).\"\"\"\n    return hasattr(dt, name)","tryCatchPattern":"try:\n    Tool = getattr(deeptutor.tools, name)\nexcept AttributeError:\n    raise ImportError(f\"Unknown tool export {name!r}; available: {deeptutor.tools.__all__}\") from None","preventionTips":["Import from concrete submodules (deeptutor.tools.builtin) for stability","Check __all__ when unsure of an export name","Run a quick import smoke test after upgrading deeptutor"],"tags":["python","import","lazy-loading","attribute-error"],"backgroundTag":"attribute-error-import","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}