PageRenderTime 50ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/rpython/flowspace/specialcase.py

https://bitbucket.org/pypy/pypy/
Python | 91 lines | 66 code | 14 blank | 11 comment | 8 complexity | 7fc14339ae9abbbdc3b0826c10ca0e4c MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import os
  2. from rpython.flowspace.model import Constant
  3. SPECIAL_CASES = {}
  4. def register_flow_sc(func):
  5. """Decorator triggering special-case handling of ``func``.
  6. When the flow graph builder sees ``func``, it calls the decorated function
  7. with ``decorated_func(ctx, *args_w)``, where ``args_w`` is a sequence of
  8. flow objects (Constants or Variables).
  9. """
  10. def decorate(sc_func):
  11. SPECIAL_CASES[func] = sc_func
  12. return decorate
  13. def redirect_function(srcfunc, dstfuncname):
  14. @register_flow_sc(srcfunc)
  15. def sc_redirected_function(ctx, *args_w):
  16. components = dstfuncname.split('.')
  17. obj = __import__('.'.join(components[:-1]))
  18. for name in components[1:]:
  19. obj = getattr(obj, name)
  20. return ctx.appcall(obj, *args_w)
  21. @register_flow_sc(__import__)
  22. def sc_import(ctx, *args_w):
  23. assert all(isinstance(arg, Constant) for arg in args_w)
  24. args = [arg.value for arg in args_w]
  25. return ctx.import_name(*args)
  26. @register_flow_sc(locals)
  27. def sc_locals(_, *args):
  28. raise Exception(
  29. "A function calling locals() is not RPython. "
  30. "Note that if you're translating code outside the PyPy "
  31. "repository, a likely cause is that py.test's --assert=rewrite "
  32. "mode is getting in the way. You should copy the file "
  33. "pytest.ini from the root of the PyPy repository into your "
  34. "own project.")
  35. @register_flow_sc(getattr)
  36. def sc_getattr(ctx, w_obj, w_index, w_default=None):
  37. if w_default is not None:
  38. return ctx.appcall(getattr, w_obj, w_index, w_default)
  39. else:
  40. from rpython.flowspace.operation import op
  41. return op.getattr(w_obj, w_index).eval(ctx)
  42. # _________________________________________________________________________
  43. redirect_function(open, 'rpython.rlib.rfile.create_file')
  44. redirect_function(os.fdopen, 'rpython.rlib.rfile.create_fdopen_rfile')
  45. redirect_function(os.tmpfile, 'rpython.rlib.rfile.create_temp_rfile')
  46. # on top of PyPy only: 'os.remove != os.unlink'
  47. # (on CPython they are '==', but not identical either)
  48. redirect_function(os.remove, 'os.unlink')
  49. redirect_function(os.path.isdir, 'rpython.rlib.rpath.risdir')
  50. redirect_function(os.path.isabs, 'rpython.rlib.rpath.risabs')
  51. redirect_function(os.path.normpath,'rpython.rlib.rpath.rnormpath')
  52. redirect_function(os.path.abspath, 'rpython.rlib.rpath.rabspath')
  53. redirect_function(os.path.join, 'rpython.rlib.rpath.rjoin')
  54. if hasattr(os.path, 'splitdrive'):
  55. redirect_function(os.path.splitdrive, 'rpython.rlib.rpath.rsplitdrive')
  56. # _________________________________________________________________________
  57. # a simplified version of the basic printing routines, for RPython programs
  58. class StdOutBuffer:
  59. linebuf = []
  60. stdoutbuffer = StdOutBuffer()
  61. def rpython_print_item(s):
  62. buf = stdoutbuffer.linebuf
  63. for c in s:
  64. buf.append(c)
  65. buf.append(' ')
  66. rpython_print_item._annenforceargs_ = (str,)
  67. def rpython_print_newline():
  68. buf = stdoutbuffer.linebuf
  69. if buf:
  70. buf[-1] = '\n'
  71. s = ''.join(buf)
  72. del buf[:]
  73. else:
  74. s = '\n'
  75. import os
  76. os.write(1, s)