def test_strictmodule_uninitialized_missing_getattr(self): foo = StrictModule.__new__(StrictModule) self.assertRaisesRegex( AttributeError, "module has no attribute 'not_here'", getattr, foo, "not_here", )
def test_strictmodule_uninitialized(self): # An uninitialized module has no __dict__ or __name__, # and __doc__ is None foo = StrictModule.__new__(StrictModule) self.assertTrue(foo.__dict__ == None) self.assertRaises(SystemError, dir, foo) try: s = foo.__name__ self.fail("__name__ = %s" % repr(s)) except AttributeError: pass self.assertEqual(foo.__doc__, StrictModule.__doc__)
def exec_module(self, module: ModuleType) -> None: # This ends up being slightly convoluted, because create_module # gets called, then source_to_code gets called, so we don't know if # we have a strict module until after we were requested to create it. # So we'll run the module code we get back in the module that was # initially published in sys.modules, check and see if it's a strict # module, and then run the strict module body after replacing the # entry in sys.modules with a StrictModule entry. This shouldn't # really be observable because no user code runs between publishing # the normal module in sys.modules and replacing it with the # StrictModule. code = self.get_code(module.__name__) if code is None: raise ImportError( f"Cannot import module {module.__name__}; get_code() returned None" ) # fix up the pyc path cached = getattr(module, "__cached__", None) if cached: module.__cached__ = cached = add_strict_tag( cached, self.enable_patching) spec: Optional[ModuleSpec] = module.__spec__ if cached and spec and spec.cached: spec.cached = cached if self.track_import_call: tracker.enter_import() if self.strict: if spec is None: raise ImportError(f"Missing module spec for {module.__name__}") new_dict = { "<fixed-modules>": cast(object, FIXED_MODULES), "<builtins>": builtins.__dict__, "<init-cached-properties>": self.init_cached_properties, } if code.co_flags & CO_STATICALLY_COMPILED: self._ensure_static_python_builtins_enabled() new_dict["<imported-from>"] = code.co_consts[-1] new_dict.update(module.__dict__) strict_mod = StrictModule(new_dict, self.enable_patching) sys.modules[module.__name__] = strict_mod exec(code, new_dict) else: exec(code, module.__dict__) if self.track_import_call: tracker.exit_import()
def _in_strict_module( self, name, code_obj, enable_patching=False, ): d = { "__name__": name, "<builtins>": builtins.__dict__, "<imported-from>": code_obj.co_consts[-1], } add_fixed_module(d) m = StrictModule(d, enable_patching) sys.modules[name] = m exec(code_obj, d) return d, m
modname=args.modname, ) if args.dis: dis(codeobj) if args.c: if args.output: name = args.output else: name = args.input.rsplit(".", 1)[0] + ".pyc" with open(name, "wb") as f: hdr = pycodegen.make_header(int(fileinfo.st_mtime), fileinfo.st_size) f.write(importlib.util.MAGIC_NUMBER) f.write(hdr) marshal.dump(codeobj, f) else: if args.strict and StrictModule is not None: d = {"__name__": "__main__"} mod = StrictModule(d, False) else: mod = type(sys)("__main__") d = mod.__dict__ if args.static: d["<fixed-modules>"] = static.FIXED_MODULES d["<builtins>"] = builtins.__dict__ sys.modules["__main__"] = mod # don't confuse the script with args meant for us sys.argv = sys.argv[:1] exec(codeobj, d, d)
def test_strictmodule_unassigned_field(self): d = {"<assigned:x>": False, "x": 1} foo = StrictModule(d, False) self.assertNotIn("x", foo.__dict__)
def test_strictmodule_patch_enabled_2(self): m = ModuleType("a") d = m.__dict__ foo = StrictModule(m.__dict__, False) d["__dir__"] = 2 self.assertEqual(foo.__dir__, 2)
def strict_module_from_module(mod, enable_patching=False): return StrictModule(dict(mod.__dict__), enable_patching)
def create_strict_module( name="foo", filename="foo.py", enable_patching=False, **kwargs ): kwargs.update(__name__=name, __file__=filename) return StrictModule(kwargs, enable_patching)