| _magic_methods = [ |
| "__subclasscheck__", |
| "__hex__", |
| "__rmul__", |
| "__float__", |
| "__idiv__", |
| "__setattr__", |
| "__div__", |
| "__invert__", |
| "__nonzero__", |
| "__rshift__", |
| "__eq__", |
| "__pos__", |
| "__round__", |
| "__rand__", |
| "__or__", |
| "__complex__", |
| "__divmod__", |
| "__len__", |
| "__reversed__", |
| "__copy__", |
| "__reduce__", |
| "__deepcopy__", |
| "__rdivmod__", |
| "__rrshift__", |
| "__ifloordiv__", |
| "__hash__", |
| "__iand__", |
| "__xor__", |
| "__isub__", |
| "__oct__", |
| "__ceil__", |
| "__imod__", |
| "__add__", |
| "__truediv__", |
| "__unicode__", |
| "__le__", |
| "__delitem__", |
| "__sizeof__", |
| "__sub__", |
| "__ne__", |
| "__pow__", |
| "__bytes__", |
| "__mul__", |
| "__itruediv__", |
| "__bool__", |
| "__iter__", |
| "__abs__", |
| "__gt__", |
| "__iadd__", |
| "__enter__", |
| "__floordiv__", |
| "__call__", |
| "__neg__", |
| "__and__", |
| "__ixor__", |
| "__getitem__", |
| "__exit__", |
| "__cmp__", |
| "__getstate__", |
| "__index__", |
| "__contains__", |
| "__floor__", |
| "__lt__", |
| "__getattr__", |
| "__mod__", |
| "__trunc__", |
| "__delattr__", |
| "__instancecheck__", |
| "__setitem__", |
| "__ipow__", |
| "__ilshift__", |
| "__long__", |
| "__irshift__", |
| "__imul__", |
| "__lshift__", |
| "__dir__", |
| "__ge__", |
| "__int__", |
| "__ior__", |
| ] |
| |
| |
| class MockedObject: |
| _name: str |
| |
| def __new__(cls, *args, **kwargs): |
| # _suppress_err is set by us in the mocked module impl, so that we can |
| # construct instances of MockedObject to hand out to people looking up |
| # module attributes. |
| |
| # Any other attempt to construct a MockedObject instance (say, in the |
| # unpickling process) should give an error. |
| if not kwargs.get("_suppress_err"): |
| raise NotImplementedError( |
| f"Object '{cls._name}' was mocked out during packaging " |
| f"but it is being used in '__new__'. If this error is " |
| "happening during 'load_pickle', please ensure that your " |
| "pickled object doesn't contain any mocked objects." |
| ) |
| # Otherwise, this is just a regular object creation |
| # (e.g. `x = MockedObject("foo")`), so pass it through normally. |
| return super().__new__(cls) |
| |
| def __init__(self, name: str, _suppress_err: bool): |
| self.__dict__["_name"] = name |
| |
| def __repr__(self): |
| return f"MockedObject({self._name})" |
| |
| |
| def install_method(method_name): |
| def _not_implemented(self, *args, **kwargs): |
| raise NotImplementedError( |
| f"Object '{self._name}' was mocked out during packaging but it is being used in {method_name}" |
| ) |
| |
| setattr(MockedObject, method_name, _not_implemented) |
| |
| |
| for method_name in _magic_methods: |
| install_method(method_name) |