{"record":{"id":"9f2a5dee8051fb28","repo":"xtekky/gpt4free","slug":"relative-imports-are-not-allowed-inside-a-pa-py-s","errorCode":null,"errorMessage":"Relative imports are not allowed inside a .pa.py sandbox.","messagePattern":"Relative imports are not allowed inside a \\.pa\\.py sandbox\\.","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"g4f/mcp/pa_provider.py","lineNumber":446,"sourceCode":"            \"g4f.Provider\",\n            \"g4f.config\",\n        }\n    )\n\n    # Explicit allowlist for g4f sub-paths that would otherwise be blocked.\n    # Checked *before* the blocklist so these entries take priority.\n    _ALLOWED_G4F_SUBPATHS: FrozenSet[str] = frozenset(\n        {\n            \"g4f.Provider.helper\",\n            \"g4f.Provider.base_provider\",\n            \"g4f.Provider.template\",\n            \"g4f.typing\",\n        }\n    )\n\n    def _restricted_import(name, globals=None, locals=None, fromlist=(), level=0):\n        if level > 0:\n            raise ImportError(\n                \"Relative imports are not allowed inside a .pa.py sandbox.\"\n            )\n        base = name.split(\".\")[0]\n        # Return the restricted os shim instead of the real os module.\n        if base == \"os\":\n            _os_shim = _make_restricted_os()\n            if name == \"os\":\n                return _os_shim\n            # Handle \"os.submodule\" — try to resolve from the shim\n            obj = _os_shim\n            for part in name.split(\".\")[1:]:\n                obj = getattr(obj, part, None)\n                if obj is None:\n                    raise ImportError(\n                        f\"'{name}' is not available in the restricted os shim.\"\n                    )\n            return obj\n        if base not in allowed:","sourceCodeStart":428,"sourceCodeEnd":464,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/mcp/pa_provider.py#L428-L464","documentation":"Thrown by the sandbox's restricted __import__ replacement (_restricted_import in pa_provider.py) when level > 0, i.e. the module uses a relative import ('from . import sibling', 'from ..pkg import x'). Sandboxed .pa.py modules are compiled with __package__ = \"\" and loaded standalone, so Python's relative-import machinery has no package context to resolve against — the sandbox rejects it up front with this explicit ImportError.","triggerScenarios":"A .pa.py file containing 'from .helpers import run' or 'from ..tools import api'; usually code lifted from a real package where the module lived inside a package tree.","commonSituations":"Copying a module out of a package into the sandbox without rewriting its imports; refactoring shared utilities into sibling files and importing them relatively.","solutions":["Rewrite relative imports as absolute ones using allowed top-level modules: 'from helpers import run' only works if helpers is loadable/approved; otherwise inline the needed code or use supported g4f subpaths.","Keep each .pa.py self-contained — the sandbox is designed for standalone tool modules.","If shared code is required, put it in an allowed installed package and import it absolutely (e.g. from g4f.Provider import helper)."],"exampleFix":"// before (module.pa.py)\nfrom .utils import parse\n\n// after\ndef parse(x):\n    ...  # inlined, or: from an allowed absolute module","handlingStrategy":"validation","validationCode":"import ast\n\ndef has_relative_imports(source: str) -> bool:\n    tree = ast.parse(source)\n    return any(\n        isinstance(n, ast.ImportFrom) and n.level > 0\n        for n in ast.walk(tree)\n    )","typeGuard":null,"tryCatchPattern":"try:\n    module = load_workspace_module(name, source_path)\nexcept ImportError as e:\n    if \"Relative imports are not allowed\" in str(e):\n        reject_upload(\"rewrite relative imports as absolute or inline the code\")\n    raise","preventionTips":["Keep .pa.py modules standalone; never lift files out of packages without rewriting imports.","AST-scan uploads for ImportFrom with level>0 and reject early with a clear message."],"tags":["sandbox","relative-import","workspace","pa-provider"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}