{"record":{"id":"e925ec2629a88ec5","repo":"opendatalab/MinerU","slug":"module-name-r-has-no-attribute-name-r-e925ec","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":"mineru/data/io/__init__.py","lineNumber":18,"sourceCode":"# Copyright (c) Opendatalab. All rights reserved.\n\nfrom .base import IOReader, IOWriter\nfrom .http import HttpReader, HttpWriter\n\n__all__ = ['IOReader', 'IOWriter', 'HttpReader', 'HttpWriter', 'S3Reader', 'S3Writer']\n\n\ndef __getattr__(name):\n    \"\"\"按需加载 S3 IO 类，避免默认安装场景强制依赖 boto3。\"\"\"\n    if name in {'S3Reader', 'S3Writer'}:\n        from .s3 import S3Reader, S3Writer\n\n        s3_exports = {'S3Reader': S3Reader, 'S3Writer': S3Writer}\n        globals().update(s3_exports)\n        return s3_exports[name]\n\n    raise AttributeError(f\"module {__name__!r} has no attribute {name!r}\")\n","sourceCodeStart":1,"sourceCodeEnd":19,"githubUrl":"https://github.com/opendatalab/MinerU/blob/4fe4bde114a23ee5dd637eae99b767f4669bf58c/mineru/data/io/__init__.py#L1-L19","documentation":"AttributeError raised by the module-level __getattr__ in mineru/data/io/__init__.py (PEP 562) for any attribute access that is not one of the eagerly listed names ('IOReader', 'IOWriter', 'HttpReader', 'HttpWriter') or the lazily loaded 'S3Reader'/'S3Writer'. The module defers importing the S3 classes to avoid a hard boto3 dependency, so unknown names fall through to this explicit error.","triggerScenarios":"`from mineru.data.io import S3Reeder` (typo), `getattr(mineru.data.io, 'FsReader')`, or `hasattr`/dir-driven probing of names removed or never exported from the package.","commonSituations":"Upgrades where a class was renamed or moved but old import statements remain; IDE autocomplete suggesting a stale name; generic plugin loaders that iterate candidate class names via getattr.","solutions":["Check __all__ in mineru/data/io/__init__.py and import only listed names: IOReader, IOWriter, HttpReader, HttpWriter, S3Reader, S3Writer.","Fix the typo in the import (e.g. S3Reeder -> S3Reader).","If importing S3Reader/S3Writer, ensure the [s3] extra is installed since the lazy import of .s3 still needs boto3.","For renamed/moved classes, grep the package for the new location instead of relying on old paths."],"exampleFix":"# before\nfrom mineru.data.io import S3Reeder  # AttributeError via __getattr__\n\n# after\nfrom mineru.data.io import S3Reader","handlingStrategy":"type-guard","validationCode":"import mineru.data.io as mineru_io\n\nALLOWED = set(mineru_io.__all__)\n\ndef safe_getattr(name: str):\n    if name not in ALLOWED:\n        raise AttributeError(f'mineru.data.io exports only {sorted(ALLOWED)}, not {name!r}')\n    return getattr(mineru_io, name)","typeGuard":"def is_mineru_io_export(name: str) -> bool:\n    import mineru.data.io as m\n    return name in m.__all__  # ['IOReader','IOWriter','HttpReader','HttpWriter','S3Reader','S3Writer']","tryCatchPattern":"try:\n    from mineru.data.io import S3Reader\nexcept ImportError as e:\n    raise ImportError(\n        \"expected 'mineru.data.io' exports: \"\n        \"IOReader, IOWriter, HttpReader, HttpWriter, S3Reader, S3Writer\"\n    ) from e","preventionTips":["Import only names listed in mineru.data.io.__all__.","Pin the mineru version so renamed exports don't surprise you on upgrade.","Let the IDE resolve imports from the installed package, not from memory of an old version."],"tags":["python","imports","lazy-import","pep-562","api-surface"],"backgroundTag":null,"analyzedSha":"4fe4bde114a23ee5dd637eae99b767f4669bf58c","analyzedAt":"2026-08-14T21:29:18.456Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}