PageRenderTime 46ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/pypy/objspace/std/fake.py

https://bitbucket.org/varialus/jyjy
Python | 260 lines | 214 code | 35 blank | 11 comment | 44 complexity | 42de181a21b8424d051114e5d417ed86 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 isinstance(type(cpy_type), 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 object or issubclass(cpy_type, Exception):
  91. base = None
  92. elif cpy_type.__base__ is basestring:
  93. from pypy.objspace.std.basestringtype import basestring_typedef
  94. base = basestring_typedef
  95. elif cpy_type.__base__ is tuple:
  96. from pypy.objspace.std.tupletype import tuple_typedef
  97. base = tuple_typedef
  98. elif cpy_type.__base__ is type:
  99. from pypy.objspace.std.typetype import type_typedef
  100. base = type_typedef
  101. else:
  102. raise NotImplementedError(cpy_type, cpy_type.__base__)
  103. class W_Fake(W_Object):
  104. typedef = StdTypeDef(
  105. cpy_type.__name__, base, **kw)
  106. def __init__(w_self, space, val):
  107. w_self.val = val
  108. w_self.space = space
  109. def getdict(w_self, space):
  110. try:
  111. d = w_self.val.__dict__
  112. except AttributeError:
  113. return W_Object.getdict(w_self, space)
  114. return space.wrap(d)
  115. def unwrap(w_self, space):
  116. return w_self.val
  117. if cpy_type is types.FunctionType:
  118. def __get__(self, obj, owner):
  119. return fake_object(self.space, self.val.__get__(obj, owner))
  120. W_Fake.__name__ = 'W_Fake%s'%(cpy_type.__name__.capitalize())
  121. W_Fake.typedef.fakedcpytype = cpy_type
  122. return W_Fake
  123. # ____________________________________________________________
  124. #
  125. # Special case for built-in functions, methods, and slot wrappers.
  126. class CPythonFakeCode(eval.Code):
  127. def __init__(self, cpy_callable):
  128. eval.Code.__init__(self, getattr(cpy_callable, '__name__', '?'))
  129. self.cpy_callable = cpy_callable
  130. assert callable(cpy_callable), cpy_callable
  131. def signature(self):
  132. return argument.Signature([], 'args', 'kwds')
  133. def funcrun(self, func, args):
  134. frame = func.space.createframe(self, func.w_func_globals,
  135. func)
  136. sig = self.signature()
  137. scope_w = args.parse_obj(None, func.name, sig, func.defs_w)
  138. frame.setfastscope(scope_w)
  139. return frame.run()
  140. class CPythonFakeFrame(eval.Frame):
  141. def __init__(self, space, code, w_globals=None):
  142. self.fakecode = code
  143. eval.Frame.__init__(self, space, w_globals)
  144. def getcode(self):
  145. return self.fakecode
  146. def setfastscope(self, scope_w):
  147. w_args, w_kwds = scope_w
  148. try:
  149. self.unwrappedargs = self.space.unwrap(w_args)
  150. self.unwrappedkwds = self.space.unwrap(w_kwds)
  151. except UnwrapError, e:
  152. code = self.fakecode
  153. assert isinstance(code, CPythonFakeCode)
  154. raise UnwrapError('calling %s: %s' % (code.cpy_callable, e))
  155. def getfastscope(self):
  156. raise OperationError(self.space.w_TypeError,
  157. self.space.wrap("cannot get fastscope of a CPythonFakeFrame"))
  158. def run(self):
  159. code = self.fakecode
  160. assert isinstance(code, CPythonFakeCode)
  161. fn = code.cpy_callable
  162. try:
  163. result = apply(fn, self.unwrappedargs, self.unwrappedkwds)
  164. except:
  165. wrap_exception(self.space)
  166. raise
  167. return self.space.wrap(result)
  168. class EvenMoreObscureWrapping(baseobjspace.Wrappable):
  169. def __init__(self, val):
  170. self.val = val
  171. def __spacebind__(self, space):
  172. return fake_builtin_callable(space, self.val)
  173. def fake_builtin_callable(space, val):
  174. return Function(space, CPythonFakeCode(val))
  175. def fake_builtin_function(space, fn):
  176. func = fake_builtin_callable(space, fn)
  177. if fn.__self__ is None:
  178. func = BuiltinFunction(func)
  179. return func
  180. _fake_type_cache[type(len)] = fake_builtin_function
  181. _fake_type_cache[type(list.append)] = fake_builtin_callable
  182. _fake_type_cache[type(type(None).__repr__)] = fake_builtin_callable
  183. class W_FakeDescriptor(Wrappable):
  184. # Mimics pypy.interpreter.typedef.GetSetProperty.
  185. def __init__(self, space, d):
  186. self.name = d.__name__
  187. def descr_descriptor_get(self, space, w_obj, w_cls=None):
  188. # XXX HAAAAAAAAAAAACK (but possibly a good one)
  189. if (space.is_w(w_obj, space.w_None)
  190. and not space.is_w(w_cls, space.type(space.w_None))):
  191. #print self, w_obj, w_cls
  192. return space.wrap(self)
  193. else:
  194. name = self.name
  195. obj = space.unwrap(w_obj)
  196. try:
  197. val = getattr(obj, name) # this gives a "not RPython" warning
  198. except:
  199. wrap_exception(space)
  200. raise
  201. return space.wrap(val)
  202. def descr_descriptor_set(self, space, w_obj, w_value):
  203. name = self.name
  204. obj = space.unwrap(w_obj)
  205. val = space.unwrap(w_value)
  206. try:
  207. setattr(obj, name, val) # this gives a "not RPython" warning
  208. except:
  209. wrap_exception(space)
  210. def descr_descriptor_del(self, space, w_obj):
  211. name = self.name
  212. obj = space.unwrap(w_obj)
  213. try:
  214. delattr(obj, name)
  215. except:
  216. wrap_exception(space)
  217. W_FakeDescriptor.typedef = TypeDef(
  218. "FakeDescriptor",
  219. __get__ = gateway.interp2app(W_FakeDescriptor.descr_descriptor_get),
  220. __set__ = gateway.interp2app(W_FakeDescriptor.descr_descriptor_set),
  221. __delete__ = gateway.interp2app(W_FakeDescriptor.descr_descriptor_del),
  222. )
  223. if hasattr(file, 'softspace'): # CPython only
  224. _fake_type_cache[type(file.softspace)] = W_FakeDescriptor
  225. _fake_type_cache[type(type.__dict__['__dict__'])] = W_FakeDescriptor