PageRenderTime 95ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/objspace/std/fake.py

https://bitbucket.org/pwaller/pypy
Python | 253 lines | 207 code | 35 blank | 11 comment | 41 complexity | dca4b0468a48f5a98632769fdaf51218 MD5 | raw file
  1. import types
  2. from pypy.interpreter.error import OperationError, debug_print
  3. from pypy.interpreter import baseobjspace
  4. from pypy.interpreter import eval
  5. from pypy.interpreter.function import Function, BuiltinFunction
  6. from pypy.objspace.std.stdtypedef import *
  7. from pypy.objspace.std.model import W_Object, UnwrapError
  8. from pypy.interpreter.baseobjspace import Wrappable
  9. from pypy.interpreter.typedef import TypeDef
  10. from pypy.interpreter import gateway, argument
  11. # this file automatically generates non-reimplementations of CPython
  12. # types that we do not yet implement in the standard object space
  13. def fake_object(space, x):
  14. if isinstance(x, file):
  15. debug_print("fake-wrapping interp file %s" % x)
  16. if isinstance(x, type):
  17. ft = fake_type(x)
  18. return space.gettypeobject(ft.typedef)
  19. #debug_print("faking obj %s" % x)
  20. ft = fake_type(type(x))
  21. return ft(space, x)
  22. import sys
  23. _fake_type_cache = {}
  24. # real-to-wrapped exceptions
  25. def wrap_exception(space):
  26. """NOT_RPYTHON"""
  27. exc, value, tb = sys.exc_info()
  28. if exc is OperationError:
  29. raise exc, value, tb # just re-raise it
  30. name = exc.__name__
  31. if hasattr(space, 'w_' + name):
  32. w_exc = getattr(space, 'w_' + name)
  33. w_value = space.call_function(w_exc,
  34. *[space.wrap(a) for a in value.args])
  35. for key, value in value.__dict__.items():
  36. if not key.startswith('_'):
  37. space.setattr(w_value, space.wrap(key), space.wrap(value))
  38. else:
  39. debug_print('likely crashes because of faked exception %s: %s' % (
  40. exc.__name__, value))
  41. w_exc = space.wrap(exc)
  42. w_value = space.wrap(value)
  43. raise OperationError, OperationError(w_exc, w_value), tb
  44. def fake_type(cpy_type):
  45. assert type(cpy_type) is type
  46. try:
  47. return _fake_type_cache[cpy_type]
  48. except KeyError:
  49. faked_type = really_build_fake_type(cpy_type)
  50. _fake_type_cache[cpy_type] = faked_type
  51. return faked_type
  52. def really_build_fake_type(cpy_type):
  53. "NOT_RPYTHON (not remotely so!)."
  54. debug_print('faking %r'%(cpy_type,))
  55. kw = {}
  56. if cpy_type.__name__ == 'SRE_Pattern':
  57. import re
  58. import __builtin__
  59. p = re.compile("foo")
  60. for meth_name in p.__methods__:
  61. kw[meth_name] = EvenMoreObscureWrapping(__builtin__.eval("lambda p,*args,**kwds: p.%s(*args,**kwds)" % meth_name))
  62. elif cpy_type.__name__ == 'SRE_Match':
  63. import re
  64. import __builtin__
  65. m = re.compile("foo").match('foo')
  66. for meth_name in m.__methods__:
  67. kw[meth_name] = EvenMoreObscureWrapping(__builtin__.eval("lambda m,*args,**kwds: m.%s(*args,**kwds)" % meth_name))
  68. else:
  69. for s, v in cpy_type.__dict__.items():
  70. if not (cpy_type is unicode and s in ['__add__', '__contains__']):
  71. if s != '__getattribute__' or cpy_type is type(sys) or cpy_type is type(Exception):
  72. kw[s] = v
  73. kw['__module__'] = cpy_type.__module__
  74. def fake__new__(space, w_type, __args__):
  75. args_w, kwds_w = __args__.unpack()
  76. args = [space.unwrap(w_arg) for w_arg in args_w]
  77. kwds = {}
  78. for (key, w_value) in kwds_w.items():
  79. kwds[key] = space.unwrap(w_value)
  80. try:
  81. r = cpy_type.__new__(*[cpy_type]+args, **kwds)
  82. except:
  83. wrap_exception(space)
  84. raise
  85. w_obj = space.allocate_instance(W_Fake, w_type)
  86. W_Fake.__init__(w_obj, space, r)
  87. return w_obj
  88. fake__new__.func_name = "fake__new__" + cpy_type.__name__
  89. kw['__new__'] = gateway.interp2app(fake__new__)
  90. if cpy_type.__base__ is not object and not issubclass(cpy_type, Exception):
  91. assert cpy_type.__base__ is basestring, cpy_type
  92. from pypy.objspace.std.basestringtype import basestring_typedef
  93. base = basestring_typedef
  94. else:
  95. base = None
  96. class W_Fake(W_Object):
  97. typedef = StdTypeDef(
  98. cpy_type.__name__, base, **kw)
  99. def __init__(w_self, space, val):
  100. w_self.val = val
  101. w_self.space = space
  102. def getdict(w_self, space):
  103. try:
  104. d = w_self.val.__dict__
  105. except AttributeError:
  106. return W_Object.getdict(w_self, space)
  107. return space.wrap(d)
  108. def unwrap(w_self, space):
  109. return w_self.val
  110. if cpy_type is types.FunctionType:
  111. def __get__(self, obj, owner):
  112. return fake_object(self.space, self.val.__get__(obj, owner))
  113. W_Fake.__name__ = 'W_Fake%s'%(cpy_type.__name__.capitalize())
  114. W_Fake.typedef.fakedcpytype = cpy_type
  115. return W_Fake
  116. # ____________________________________________________________
  117. #
  118. # Special case for built-in functions, methods, and slot wrappers.
  119. class CPythonFakeCode(eval.Code):
  120. def __init__(self, cpy_callable):
  121. eval.Code.__init__(self, getattr(cpy_callable, '__name__', '?'))
  122. self.cpy_callable = cpy_callable
  123. assert callable(cpy_callable), cpy_callable
  124. def signature(self):
  125. return argument.Signature([], 'args', 'kwds')
  126. def funcrun(self, func, args):
  127. frame = func.space.createframe(self, func.w_func_globals,
  128. func)
  129. sig = self.signature()
  130. scope_w = args.parse_obj(None, func.name, sig, func.defs_w)
  131. frame.setfastscope(scope_w)
  132. return frame.run()
  133. class CPythonFakeFrame(eval.Frame):
  134. def __init__(self, space, code, w_globals=None):
  135. self.fakecode = code
  136. eval.Frame.__init__(self, space, w_globals)
  137. def getcode(self):
  138. return self.fakecode
  139. def setfastscope(self, scope_w):
  140. w_args, w_kwds = scope_w
  141. try:
  142. self.unwrappedargs = self.space.unwrap(w_args)
  143. self.unwrappedkwds = self.space.unwrap(w_kwds)
  144. except UnwrapError, e:
  145. code = self.fakecode
  146. assert isinstance(code, CPythonFakeCode)
  147. raise UnwrapError('calling %s: %s' % (code.cpy_callable, e))
  148. def getfastscope(self):
  149. raise OperationError(self.space.w_TypeError,
  150. self.space.wrap("cannot get fastscope of a CPythonFakeFrame"))
  151. def run(self):
  152. code = self.fakecode
  153. assert isinstance(code, CPythonFakeCode)
  154. fn = code.cpy_callable
  155. try:
  156. result = apply(fn, self.unwrappedargs, self.unwrappedkwds)
  157. except:
  158. wrap_exception(self.space)
  159. raise
  160. return self.space.wrap(result)
  161. class EvenMoreObscureWrapping(baseobjspace.Wrappable):
  162. def __init__(self, val):
  163. self.val = val
  164. def __spacebind__(self, space):
  165. return fake_builtin_callable(space, self.val)
  166. def fake_builtin_callable(space, val):
  167. return Function(space, CPythonFakeCode(val))
  168. def fake_builtin_function(space, fn):
  169. func = fake_builtin_callable(space, fn)
  170. if fn.__self__ is None:
  171. func = BuiltinFunction(func)
  172. return func
  173. _fake_type_cache[type(len)] = fake_builtin_function
  174. _fake_type_cache[type(list.append)] = fake_builtin_callable
  175. _fake_type_cache[type(type(None).__repr__)] = fake_builtin_callable
  176. class W_FakeDescriptor(Wrappable):
  177. # Mimics pypy.interpreter.typedef.GetSetProperty.
  178. def __init__(self, space, d):
  179. self.name = d.__name__
  180. def descr_descriptor_get(self, space, w_obj, w_cls=None):
  181. # XXX HAAAAAAAAAAAACK (but possibly a good one)
  182. if (space.is_w(w_obj, space.w_None)
  183. and not space.is_w(w_cls, space.type(space.w_None))):
  184. #print self, w_obj, w_cls
  185. return space.wrap(self)
  186. else:
  187. name = self.name
  188. obj = space.unwrap(w_obj)
  189. try:
  190. val = getattr(obj, name) # this gives a "not RPython" warning
  191. except:
  192. wrap_exception(space)
  193. raise
  194. return space.wrap(val)
  195. def descr_descriptor_set(self, space, w_obj, w_value):
  196. name = self.name
  197. obj = space.unwrap(w_obj)
  198. val = space.unwrap(w_value)
  199. try:
  200. setattr(obj, name, val) # this gives a "not RPython" warning
  201. except:
  202. wrap_exception(space)
  203. def descr_descriptor_del(self, space, w_obj):
  204. name = self.name
  205. obj = space.unwrap(w_obj)
  206. try:
  207. delattr(obj, name)
  208. except:
  209. wrap_exception(space)
  210. W_FakeDescriptor.typedef = TypeDef(
  211. "FakeDescriptor",
  212. __get__ = gateway.interp2app(W_FakeDescriptor.descr_descriptor_get),
  213. __set__ = gateway.interp2app(W_FakeDescriptor.descr_descriptor_set),
  214. __delete__ = gateway.interp2app(W_FakeDescriptor.descr_descriptor_del),
  215. )
  216. if hasattr(file, 'softspace'): # CPython only
  217. _fake_type_cache[type(file.softspace)] = W_FakeDescriptor
  218. _fake_type_cache[type(type.__dict__['__dict__'])] = W_FakeDescriptor