[pypy-commit] pypy default: In RPython, this adds the ability to automatically redirect some
arigo
noreply at buildbot.pypy.org
Sun Aug 31 12:41:09 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r73223:3c3f30ffed49
Date: 2014-08-31 12:40 +0200
http://bitbucket.org/pypy/pypy/changeset/3c3f30ffed49/
Log: In RPython, this adds the ability to automatically redirect some
functions from os.path to our own functions in rpython.rlib.rpath.
diff --git a/rpython/flowspace/specialcase.py b/rpython/flowspace/specialcase.py
--- a/rpython/flowspace/specialcase.py
+++ b/rpython/flowspace/specialcase.py
@@ -14,6 +14,16 @@
SPECIAL_CASES[func] = sc_func
return decorate
+def redirect_function(srcfunc, dstfuncname):
+ @register_flow_sc(srcfunc)
+ def sc_redirected_function(ctx, *args_w):
+ components = dstfuncname.split('.')
+ obj = __import__('.'.join(components[:-1]))
+ for name in components[1:]:
+ obj = getattr(obj, name)
+ return ctx.appcall(obj, *args_w)
+
+
@register_flow_sc(__import__)
def sc_import(ctx, *args_w):
assert all(isinstance(arg, Constant) for arg in args_w)
@@ -44,34 +54,23 @@
from rpython.flowspace.operation import op
return op.getattr(w_obj, w_index).eval(ctx)
- at register_flow_sc(open)
-def sc_open(ctx, *args_w):
- from rpython.rlib.rfile import create_file
- return ctx.appcall(create_file, *args_w)
+# _________________________________________________________________________
- at register_flow_sc(os.fdopen)
-def sc_os_fdopen(ctx, *args_w):
- from rpython.rlib.rfile import create_fdopen_rfile
- return ctx.appcall(create_fdopen_rfile, *args_w)
+redirect_function(open, 'rpython.rlib.rfile.create_file')
+redirect_function(os.fdopen, 'rpython.rlib.rfile.create_fdopen_rfile')
+redirect_function(os.tmpfile, 'rpython.rlib.rfile.create_temp_rfile')
- at register_flow_sc(os.tmpfile)
-def sc_os_tmpfile(ctx):
- from rpython.rlib.rfile import create_temp_rfile
- return ctx.appcall(create_temp_rfile)
+# on top of PyPy only: 'os.remove != os.unlink'
+# (on CPython they are '==', but not identical either)
+redirect_function(os.remove, 'os.unlink')
- at register_flow_sc(os.remove)
-def sc_os_remove(ctx, *args_w):
- # on top of PyPy only: 'os.remove != os.unlink'
- # (on CPython they are '==', but not identical either)
- return ctx.appcall(os.unlink, *args_w)
+redirect_function(os.path.isdir, 'rpython.rlib.rpath.risdir')
+redirect_function(os.path.isabs, 'rpython.rlib.rpath.risabs')
+redirect_function(os.path.abspath, 'rpython.rlib.rpath.rabspath')
+redirect_function(os.path.join, 'rpython.rlib.rpath.rjoin')
+if hasattr(os.path, 'splitdrive'):
+ redirect_function(os.path.splitdrive, 'rpython.rlib.rpath.rsplitdrive')
-if os.name == 'nt':
- @register_flow_sc(os.path.isdir)
- def sc_os_path_isdir(ctx, *args_w):
- # Cpython win32 reroutes os.path.isdir to nt._isdir
- # which is not rpython
- import genericpath
- return ctx.appcall(genericpath.isdir, *args_w)
# _________________________________________________________________________
# a simplified version of the basic printing routines, for RPython programs
class StdOutBuffer:
diff --git a/rpython/flowspace/test/test_objspace.py b/rpython/flowspace/test/test_objspace.py
--- a/rpython/flowspace/test/test_objspace.py
+++ b/rpython/flowspace/test/test_objspace.py
@@ -1265,6 +1265,18 @@
assert ops[1].opname == 'simple_call'
assert ops[1].args[0].value is os.unlink
+ def test_rabspath(self):
+ import os.path
+ def f(s):
+ return os.path.abspath(s)
+ graph = self.codetest(f)
+ simplify_graph(graph)
+ ops = graph.startblock.operations
+ assert ops[0].opname == 'simple_call'
+ #
+ from rpython.rlib import rpath
+ assert ops[0].args[0].value is rpath.rabspath
+
def test_constfold_in(self):
def f():
if 'x' in "xyz":
diff --git a/rpython/rlib/rpath.py b/rpython/rlib/rpath.py
--- a/rpython/rlib/rpath.py
+++ b/rpython/rlib/rpath.py
@@ -2,10 +2,29 @@
Minimal (and limited) RPython version of some functions contained in os.path.
"""
-import os
+import os, stat
from rpython.rlib import rposix
+# ____________________________________________________________
+#
+# Generic implementations in RPython for both POSIX and NT
+#
+
+def risdir(s):
+ """Return true if the pathname refers to an existing directory."""
+ try:
+ st = os.stat(s)
+ except OSError:
+ return False
+ return stat.S_ISDIR(st.st_mode)
+
+
+# ____________________________________________________________
+#
+# POSIX-only implementations
+#
+
def _posix_risabs(s):
"""Test whether a path is absolute"""
return s.startswith('/')
@@ -36,6 +55,11 @@
return path
+# ____________________________________________________________
+#
+# NT-only implementations
+#
+
def _nt_risabs(s):
"""Test whether a path is absolute"""
s = _nt_rsplitdrive(s)[1]
@@ -108,6 +132,9 @@
return result_drive + result_path
+# ____________________________________________________________
+
+
if os.name == 'posix':
sep = altsep = '/'
risabs = _posix_risabs
diff --git a/rpython/rlib/test/test_rpath.py b/rpython/rlib/test/test_rpath.py
--- a/rpython/rlib/test/test_rpath.py
+++ b/rpython/rlib/test/test_rpath.py
@@ -44,3 +44,8 @@
assert rpath._nt_risabs('\\foo\\bar')
assert rpath._nt_risabs('C:\\FOO')
assert not rpath._nt_risabs('C:FOO')
+
+def test_risdir(tmpdir):
+ assert rpath.risdir(tmpdir)
+ assert not rpath.risdir('_some_non_existant_file_')
+ assert not rpath.risdir(os.path.join(tmpdir, '_some_non_existant_file_'))
More information about the pypy-commit
mailing list