Author: Antonio Cuni <[email protected]>
Branch: py3k
Changeset: r52837:303252b916c9
Date: 2012-02-24 10:14 +0100
http://bitbucket.org/pypy/pypy/changeset/303252b916c9/
Log: hg merge default
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -329,7 +329,7 @@
raise
modname = self.str_w(w_modname)
mod = self.interpclass_w(w_mod)
- if isinstance(mod, Module):
+ if isinstance(mod, Module) and not mod.startup_called:
self.timer.start("startup " + modname)
mod.init(self)
self.timer.stop("startup " + modname)
diff --git a/pypy/interpreter/test/test_objspace.py
b/pypy/interpreter/test/test_objspace.py
--- a/pypy/interpreter/test/test_objspace.py
+++ b/pypy/interpreter/test/test_objspace.py
@@ -314,3 +314,14 @@
space.ALL_BUILTIN_MODULES.pop()
del space._builtinmodule_list
mods = space.get_builtinmodule_to_install()
+
+ def test_dont_reload_builtin_mods_on_startup(self):
+ from pypy.tool.option import make_config, make_objspace
+ config = make_config(None)
+ space = make_objspace(config)
+ w_executable = space.wrap('executable')
+ assert space.str_w(space.getattr(space.sys, w_executable)) == 'py.py'
+ space.setattr(space.sys, w_executable, space.wrap('foobar'))
+ assert space.str_w(space.getattr(space.sys, w_executable)) == 'foobar'
+ space.startup()
+ assert space.str_w(space.getattr(space.sys, w_executable)) == 'foobar'
diff --git a/pypy/interpreter/test/test_zpy.py
b/pypy/interpreter/test/test_zpy.py
--- a/pypy/interpreter/test/test_zpy.py
+++ b/pypy/interpreter/test/test_zpy.py
@@ -23,14 +23,14 @@
def test_executable():
"""Ensures sys.executable points to the py.py script"""
# TODO : watch out for spaces/special chars in pypypath
- output = run(sys.executable, pypypath,
+ output = run(sys.executable, pypypath, '-S',
"-c", "import sys;print(sys.executable)")
assert output.splitlines()[-1] == pypypath
def test_special_names():
"""Test the __name__ and __file__ special global names"""
cmd = "print(__name__); print('__file__' in globals())"
- output = run(sys.executable, pypypath, '-c', cmd)
+ output = run(sys.executable, pypypath, '-S', '-c', cmd)
assert output.splitlines()[-2] == '__main__'
assert output.splitlines()[-1] == 'False'
@@ -39,24 +39,24 @@
tmpfile.write("print(__name__); print(__file__)\n")
tmpfile.close()
- output = run(sys.executable, pypypath, tmpfilepath)
+ output = run(sys.executable, pypypath, '-S', tmpfilepath)
assert output.splitlines()[-2] == '__main__'
assert output.splitlines()[-1] == str(tmpfilepath)
def test_argv_command():
"""Some tests on argv"""
# test 1 : no arguments
- output = run(sys.executable, pypypath,
+ output = run(sys.executable, pypypath, '-S',
"-c", "import sys;print(sys.argv)")
assert output.splitlines()[-1] == str(['-c'])
# test 2 : some arguments after
- output = run(sys.executable, pypypath,
+ output = run(sys.executable, pypypath, '-S',
"-c", "import sys;print(sys.argv)", "hello")
assert output.splitlines()[-1] == str(['-c','hello'])
# test 3 : additionnal pypy parameters
- output = run(sys.executable, pypypath,
+ output = run(sys.executable, pypypath, '-S',
"-O", "-c", "import sys;print(sys.argv)", "hello")
assert output.splitlines()[-1] == str(['-c','hello'])
@@ -71,15 +71,15 @@
tmpfile.close()
# test 1 : no arguments
- output = run(sys.executable, pypypath, tmpfilepath)
+ output = run(sys.executable, pypypath, '-S', tmpfilepath)
assert output.splitlines()[-1] == str([tmpfilepath])
# test 2 : some arguments after
- output = run(sys.executable, pypypath, tmpfilepath, "hello")
+ output = run(sys.executable, pypypath, '-S', tmpfilepath, "hello")
assert output.splitlines()[-1] == str([tmpfilepath,'hello'])
# test 3 : additionnal pypy parameters
- output = run(sys.executable, pypypath, "-O", tmpfilepath, "hello")
+ output = run(sys.executable, pypypath, '-S', "-O", tmpfilepath, "hello")
assert output.splitlines()[-1] == str([tmpfilepath,'hello'])
diff --git a/pypy/jit/backend/x86/test/test_ztranslation.py
b/pypy/jit/backend/x86/test/test_ztranslation.py
--- a/pypy/jit/backend/x86/test/test_ztranslation.py
+++ b/pypy/jit/backend/x86/test/test_ztranslation.py
@@ -52,6 +52,7 @@
set_param(jitdriver, "trace_eagerness", 2)
total = 0
frame = Frame(i)
+ j = float(j)
while frame.i > 3:
jitdriver.can_enter_jit(frame=frame, total=total, j=j)
jitdriver.jit_merge_point(frame=frame, total=total, j=j)
diff --git a/pypy/jit/metainterp/test/test_ajit.py
b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -2943,11 +2943,18 @@
self.check_resops(arraylen_gc=3)
def test_ulonglong_mod(self):
- myjitdriver = JitDriver(greens = [], reds = ['n', 'sa', 'i'])
+ myjitdriver = JitDriver(greens = [], reds = ['n', 'a'])
+ class A:
+ pass
def f(n):
sa = i = rffi.cast(rffi.ULONGLONG, 1)
+ a = A()
while i < rffi.cast(rffi.ULONGLONG, n):
- myjitdriver.jit_merge_point(sa=sa, n=n, i=i)
+ a.sa = sa
+ a.i = i
+ myjitdriver.jit_merge_point(n=n, a=a)
+ sa = a.sa
+ i = a.i
sa += sa % i
i += 1
res = self.meta_interp(f, [32])
diff --git a/pypy/jit/tl/tinyframe/tinyframe.py
b/pypy/jit/tl/tinyframe/tinyframe.py
--- a/pypy/jit/tl/tinyframe/tinyframe.py
+++ b/pypy/jit/tl/tinyframe/tinyframe.py
@@ -210,7 +210,7 @@
def repr(self):
return "<function %s(%s)>" % (self.outer.repr(), self.inner.repr())
-driver = JitDriver(greens = ['code', 'i'], reds = ['self'],
+driver = JitDriver(greens = ['i', 'code'], reds = ['self'],
virtualizables = ['self'])
class Frame(object):
diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py
--- a/pypy/module/_io/interp_iobase.py
+++ b/pypy/module/_io/interp_iobase.py
@@ -327,7 +327,12 @@
def autoflush(self, space):
w_iobase = self.w_iobase_ref()
if w_iobase is not None:
- space.call_method(w_iobase, 'flush') # XXX: ignore IOErrors?
+ try:
+ space.call_method(w_iobase, 'flush')
+ except OperationError, e:
+ # if it's an IOError, ignore it
+ if not e.match(space, space.w_IOError):
+ raise
class AutoFlusher(object):
diff --git a/pypy/module/_io/test/test_fileio.py
b/pypy/module/_io/test/test_fileio.py
--- a/pypy/module/_io/test/test_fileio.py
+++ b/pypy/module/_io/test/test_fileio.py
@@ -177,3 +177,20 @@
""")
space.finish()
assert tmpfile.read() == '42'
+
+def test_flush_at_exit_IOError():
+ from pypy import conftest
+ from pypy.tool.option import make_config, make_objspace
+
+ config = make_config(conftest.option)
+ space = make_objspace(config)
+ space.appexec([], """():
+ import io
+ class MyStream(io.IOBase):
+ def flush(self):
+ raise IOError
+
+ s = MyStream()
+ import sys; sys._keepalivesomewhereobscure = s
+ """)
+ space.finish() # the IOError has been ignored
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -384,6 +384,7 @@
"Tuple": "space.w_tuple",
"List": "space.w_list",
"Set": "space.w_set",
+ "FrozenSet": "space.w_frozenset",
"Int": "space.w_int",
"Bool": "space.w_bool",
"Float": "space.w_float",
diff --git a/pypy/module/cpyext/eval.py b/pypy/module/cpyext/eval.py
--- a/pypy/module/cpyext/eval.py
+++ b/pypy/module/cpyext/eval.py
@@ -1,16 +1,24 @@
from pypy.interpreter.error import OperationError
+from pypy.interpreter.astcompiler import consts
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.module.cpyext.api import (
cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, fread, feof, Py_ssize_tP,
cpython_struct)
from pypy.module.cpyext.pyobject import PyObject, borrow_from
from pypy.module.cpyext.pyerrors import PyErr_SetFromErrno
+from pypy.module.cpyext.funcobject import PyCodeObject
from pypy.module.__builtin__ import compiling
PyCompilerFlags = cpython_struct(
- "PyCompilerFlags", ())
+ "PyCompilerFlags", (("cf_flags", rffi.INT),))
PyCompilerFlagsPtr = lltype.Ptr(PyCompilerFlags)
+PyCF_MASK = (consts.CO_FUTURE_DIVISION |
+ consts.CO_FUTURE_ABSOLUTE_IMPORT |
+ consts.CO_FUTURE_WITH_STATEMENT |
+ consts.CO_FUTURE_PRINT_FUNCTION |
+ consts.CO_FUTURE_UNICODE_LITERALS)
+
@cpython_api([PyObject, PyObject, PyObject], PyObject)
def PyEval_CallObjectWithKeywords(space, w_obj, w_arg, w_kwds):
return space.call(w_obj, w_arg, w_kwds)
@@ -48,6 +56,17 @@
return None
return borrow_from(None, caller.w_globals)
+@cpython_api([PyCodeObject, PyObject, PyObject], PyObject)
+def PyEval_EvalCode(space, w_code, w_globals, w_locals):
+ """This is a simplified interface to PyEval_EvalCodeEx(), with just
+ the code object, and the dictionaries of global and local variables.
+ The other arguments are set to NULL."""
+ if w_globals is None:
+ w_globals = space.w_None
+ if w_locals is None:
+ w_locals = space.w_None
+ return compiling.eval(space, w_code, w_globals, w_locals)
+
@cpython_api([PyObject, PyObject], PyObject)
def PyObject_CallObject(space, w_obj, w_arg):
"""
@@ -74,7 +93,7 @@
Py_file_input = 257
Py_eval_input = 258
-def compile_string(space, source, filename, start):
+def compile_string(space, source, filename, start, flags=0):
w_source = space.wrap(source)
start = rffi.cast(lltype.Signed, start)
if start == Py_file_input:
@@ -86,7 +105,7 @@
else:
raise OperationError(space.w_ValueError, space.wrap(
"invalid mode parameter for compilation"))
- return compiling.compile(space, w_source, filename, mode)
+ return compiling.compile(space, w_source, filename, mode, flags)
def run_string(space, source, filename, start, w_globals, w_locals):
w_code = compile_string(space, source, filename, start)
@@ -109,6 +128,24 @@
filename = "<string>"
return run_string(space, source, filename, start, w_globals, w_locals)
+@cpython_api([rffi.CCHARP, rffi.INT_real, PyObject, PyObject,
+ PyCompilerFlagsPtr], PyObject)
+def PyRun_StringFlags(space, source, start, w_globals, w_locals, flagsptr):
+ """Execute Python source code from str in the context specified by the
+ dictionaries globals and locals with the compiler flags specified by
+ flags. The parameter start specifies the start token that should be used
to
+ parse the source code.
+
+ Returns the result of executing the code as a Python object, or NULL if an
+ exception was raised."""
+ source = rffi.charp2str(source)
+ if flagsptr:
+ flags = rffi.cast(lltype.Signed, flagsptr.c_cf_flags)
+ else:
+ flags = 0
+ w_code = compile_string(space, source, "<string>", start, flags)
+ return compiling.eval(space, w_code, w_globals, w_locals)
+
@cpython_api([FILEP, CONST_STRING, rffi.INT_real, PyObject, PyObject],
PyObject)
def PyRun_File(space, fp, filename, start, w_globals, w_locals):
"""This is a simplified interface to PyRun_FileExFlags() below, leaving
@@ -150,7 +187,7 @@
@cpython_api([rffi.CCHARP, rffi.CCHARP, rffi.INT_real, PyCompilerFlagsPtr],
PyObject)
-def Py_CompileStringFlags(space, source, filename, start, flags):
+def Py_CompileStringFlags(space, source, filename, start, flagsptr):
"""Parse and compile the Python source code in str, returning the
resulting code object. The start token is given by start; this
can be used to constrain the code which can be compiled and should
@@ -160,7 +197,30 @@
returns NULL if the code cannot be parsed or compiled."""
source = rffi.charp2str(source)
filename = rffi.charp2str(filename)
- if flags:
- raise OperationError(space.w_NotImplementedError, space.wrap(
- "cpyext Py_CompileStringFlags does not accept flags"))
- return compile_string(space, source, filename, start)
+ if flagsptr:
+ flags = rffi.cast(lltype.Signed, flagsptr.c_cf_flags)
+ else:
+ flags = 0
+ return compile_string(space, source, filename, start, flags)
+
+@cpython_api([PyCompilerFlagsPtr], rffi.INT_real, error=CANNOT_FAIL)
+def PyEval_MergeCompilerFlags(space, cf):
+ """This function changes the flags of the current evaluation
+ frame, and returns true on success, false on failure."""
+ flags = rffi.cast(lltype.Signed, cf.c_cf_flags)
+ result = flags != 0
+ current_frame = space.getexecutioncontext().gettopframe_nohidden()
+ if current_frame:
+ codeflags = current_frame.pycode.co_flags
+ compilerflags = codeflags & PyCF_MASK
+ if compilerflags:
+ result = 1
+ flags |= compilerflags
+ # No future keyword at the moment
+ # if codeflags & CO_GENERATOR_ALLOWED:
+ # result = 1
+ # flags |= CO_GENERATOR_ALLOWED
+ cf.c_cf_flags = rffi.cast(rffi.INT, flags)
+ return result
+
+
diff --git a/pypy/module/cpyext/funcobject.py b/pypy/module/cpyext/funcobject.py
--- a/pypy/module/cpyext/funcobject.py
+++ b/pypy/module/cpyext/funcobject.py
@@ -1,6 +1,6 @@
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.module.cpyext.api import (
- PyObjectFields, generic_cpy_call, CONST_STRING,
+ PyObjectFields, generic_cpy_call, CONST_STRING, CANNOT_FAIL,
cpython_api, bootstrap_function, cpython_struct, build_type_checkers)
from pypy.module.cpyext.pyobject import (
PyObject, make_ref, from_ref, Py_DecRef, make_typedescr, borrow_from)
@@ -48,6 +48,7 @@
PyFunction_Check, PyFunction_CheckExact = build_type_checkers("Function",
Function)
PyMethod_Check, PyMethod_CheckExact = build_type_checkers("Method", Method)
+PyCode_Check, PyCode_CheckExact = build_type_checkers("Code", PyCode)
def function_attach(space, py_obj, w_obj):
py_func = rffi.cast(PyFunctionObject, py_obj)
@@ -160,3 +161,9 @@
freevars=[],
cellvars=[]))
+@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
+def PyCode_GetNumFree(space, w_co):
+ """Return the number of free variables in co."""
+ co = space.interp_w(PyCode, w_co)
+ return len(co.co_freevars)
+
diff --git a/pypy/module/cpyext/include/Python.h
b/pypy/module/cpyext/include/Python.h
--- a/pypy/module/cpyext/include/Python.h
+++ b/pypy/module/cpyext/include/Python.h
@@ -113,6 +113,7 @@
#include "compile.h"
#include "frameobject.h"
#include "eval.h"
+#include "pymath.h"
#include "pymem.h"
#include "pycobject.h"
#include "pycapsule.h"
diff --git a/pypy/module/cpyext/include/code.h
b/pypy/module/cpyext/include/code.h
--- a/pypy/module/cpyext/include/code.h
+++ b/pypy/module/cpyext/include/code.h
@@ -13,13 +13,19 @@
/* Masks for co_flags above */
/* These values are also in funcobject.py */
-#define CO_OPTIMIZED 0x0001
-#define CO_NEWLOCALS 0x0002
-#define CO_VARARGS 0x0004
-#define CO_VARKEYWORDS 0x0008
+#define CO_OPTIMIZED 0x0001
+#define CO_NEWLOCALS 0x0002
+#define CO_VARARGS 0x0004
+#define CO_VARKEYWORDS 0x0008
#define CO_NESTED 0x0010
#define CO_GENERATOR 0x0020
+#define CO_FUTURE_DIVISION 0x02000
+#define CO_FUTURE_ABSOLUTE_IMPORT 0x04000
+#define CO_FUTURE_WITH_STATEMENT 0x08000
+#define CO_FUTURE_PRINT_FUNCTION 0x10000
+#define CO_FUTURE_UNICODE_LITERALS 0x20000
+
#ifdef __cplusplus
}
#endif
diff --git a/pypy/module/cpyext/include/pymath.h
b/pypy/module/cpyext/include/pymath.h
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/include/pymath.h
@@ -0,0 +1,20 @@
+#ifndef Py_PYMATH_H
+#define Py_PYMATH_H
+
+/**************************************************************************
+Symbols and macros to supply platform-independent interfaces to mathematical
+functions and constants
+**************************************************************************/
+
+/* HUGE_VAL is supposed to expand to a positive double infinity. Python
+ * uses Py_HUGE_VAL instead because some platforms are broken in this
+ * respect. We used to embed code in pyport.h to try to worm around that,
+ * but different platforms are broken in conflicting ways. If you're on
+ * a platform where HUGE_VAL is defined incorrectly, fiddle your Python
+ * config to #define Py_HUGE_VAL to something that works on your platform.
+ */
+#ifndef Py_HUGE_VAL
+#define Py_HUGE_VAL HUGE_VAL
+#endif
+
+#endif /* Py_PYMATH_H */
diff --git a/pypy/module/cpyext/include/pythonrun.h
b/pypy/module/cpyext/include/pythonrun.h
--- a/pypy/module/cpyext/include/pythonrun.h
+++ b/pypy/module/cpyext/include/pythonrun.h
@@ -19,6 +19,14 @@
int cf_flags; /* bitmask of CO_xxx flags relevant to future */
} PyCompilerFlags;
+#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \
+ CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \
+ CO_FUTURE_UNICODE_LITERALS)
+#define PyCF_MASK_OBSOLETE (CO_NESTED)
+#define PyCF_SOURCE_IS_UTF8 0x0100
+#define PyCF_DONT_IMPLY_DEDENT 0x0200
+#define PyCF_ONLY_AST 0x0400
+
#define Py_CompileString(str, filename, start) Py_CompileStringFlags(str,
filename, start, NULL)
#ifdef __cplusplus
diff --git a/pypy/module/cpyext/stubs.py b/pypy/module/cpyext/stubs.py
--- a/pypy/module/cpyext/stubs.py
+++ b/pypy/module/cpyext/stubs.py
@@ -182,16 +182,6 @@
used as the positional and keyword parameters to the object's
constructor."""
raise NotImplementedError
-@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyCode_Check(space, co):
- """Return true if co is a code object"""
- raise NotImplementedError
-
-@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
-def PyCode_GetNumFree(space, co):
- """Return the number of free variables in co."""
- raise NotImplementedError
-
@cpython_api([PyObject], rffi.INT_real, error=-1)
def PyCodec_Register(space, search_function):
"""Register a new codec search function.
@@ -1853,26 +1843,6 @@
"""
raise NotImplementedError
-@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
-def Py_UNICODE_ISTITLE(space, ch):
- """Return 1 or 0 depending on whether ch is a titlecase character."""
- raise NotImplementedError
-
-@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
-def Py_UNICODE_ISDIGIT(space, ch):
- """Return 1 or 0 depending on whether ch is a digit character."""
- raise NotImplementedError
-
-@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
-def Py_UNICODE_ISNUMERIC(space, ch):
- """Return 1 or 0 depending on whether ch is a numeric character."""
- raise NotImplementedError
-
-@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
-def Py_UNICODE_ISALPHA(space, ch):
- """Return 1 or 0 depending on whether ch is an alphabetic character."""
- raise NotImplementedError
-
@cpython_api([rffi.CCHARP], PyObject)
def PyUnicode_FromFormat(space, format):
"""Take a C printf()-style format string and a variable number of
@@ -2317,17 +2287,6 @@
use the default error handling."""
raise NotImplementedError
-@cpython_api([PyObject, PyObject, Py_ssize_t, Py_ssize_t, rffi.INT_real],
rffi.INT_real, error=-1)
-def PyUnicode_Tailmatch(space, str, substr, start, end, direction):
- """Return 1 if substr matches str*[*start:end] at the given tail end
- (direction == -1 means to do a prefix match, direction == 1 a suffix
match),
- 0 otherwise. Return -1 if an error occurred.
-
- This function used an int type for start and end. This
- might require changes in your code for properly supporting 64-bit
- systems."""
- raise NotImplementedError
-
@cpython_api([PyObject, PyObject, Py_ssize_t, Py_ssize_t, rffi.INT_real],
Py_ssize_t, error=-2)
def PyUnicode_Find(space, str, substr, start, end, direction):
"""Return the first position of substr in str*[*start:end] using the given
@@ -2524,17 +2483,6 @@
source code is read from fp instead of an in-memory string."""
raise NotImplementedError
-@cpython_api([rffi.CCHARP, rffi.INT_real, PyObject, PyObject,
PyCompilerFlags], PyObject)
-def PyRun_StringFlags(space, str, start, globals, locals, flags):
- """Execute Python source code from str in the context specified by the
- dictionaries globals and locals with the compiler flags specified by
- flags. The parameter start specifies the start token that should be used
to
- parse the source code.
-
- Returns the result of executing the code as a Python object, or NULL if an
- exception was raised."""
- raise NotImplementedError
-
@cpython_api([FILE, rffi.CCHARP, rffi.INT_real, PyObject, PyObject,
rffi.INT_real], PyObject)
def PyRun_FileEx(space, fp, filename, start, globals, locals, closeit):
"""This is a simplified interface to PyRun_FileExFlags() below, leaving
@@ -2555,13 +2503,6 @@
returns."""
raise NotImplementedError
-@cpython_api([PyCodeObject, PyObject, PyObject], PyObject)
-def PyEval_EvalCode(space, co, globals, locals):
- """This is a simplified interface to PyEval_EvalCodeEx(), with just
- the code object, and the dictionaries of global and local variables.
- The other arguments are set to NULL."""
- raise NotImplementedError
-
@cpython_api([PyCodeObject, PyObject, PyObject, PyObjectP, rffi.INT_real,
PyObjectP, rffi.INT_real, PyObjectP, rffi.INT_real, PyObject], PyObject)
def PyEval_EvalCodeEx(space, co, globals, locals, args, argcount, kws,
kwcount, defs, defcount, closure):
"""Evaluate a precompiled code object, given a particular environment for
its
@@ -2586,12 +2527,6 @@
throw() methods of generator objects."""
raise NotImplementedError
-@cpython_api([PyCompilerFlags], rffi.INT_real, error=CANNOT_FAIL)
-def PyEval_MergeCompilerFlags(space, cf):
- """This function changes the flags of the current evaluation frame, and
returns
- true on success, false on failure."""
- raise NotImplementedError
-
@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
def PyWeakref_Check(space, ob):
"""Return true if ob is either a reference or proxy object.
diff --git a/pypy/module/cpyext/test/test_eval.py
b/pypy/module/cpyext/test/test_eval.py
--- a/pypy/module/cpyext/test/test_eval.py
+++ b/pypy/module/cpyext/test/test_eval.py
@@ -2,9 +2,10 @@
from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
from pypy.module.cpyext.test.test_api import BaseApiTest
from pypy.module.cpyext.eval import (
- Py_single_input, Py_file_input, Py_eval_input)
+ Py_single_input, Py_file_input, Py_eval_input, PyCompilerFlags)
from pypy.module.cpyext.api import fopen, fclose, fileno, Py_ssize_tP
from pypy.interpreter.gateway import interp2app
+from pypy.interpreter.astcompiler import consts
from pypy.tool.udir import udir
import sys, os
@@ -63,6 +64,22 @@
assert space.int_w(w_res) == 10
+ def test_evalcode(self, space, api):
+ w_f = space.appexec([], """():
+ def f(*args):
+ assert isinstance(args, tuple)
+ return len(args) + 8
+ return f
+ """)
+
+ w_t = space.newtuple([space.wrap(1), space.wrap(2)])
+ w_globals = space.newdict()
+ w_locals = space.newdict()
+ space.setitem(w_locals, space.wrap("args"), w_t)
+ w_res = api.PyEval_EvalCode(w_f.code, w_globals, w_locals)
+
+ assert space.int_w(w_res) == 10
+
def test_run_simple_string(self, space, api):
def run(code):
buf = rffi.str2charp(code)
@@ -96,6 +113,16 @@
assert 42 * 43 == space.unwrap(
api.PyObject_GetItem(w_globals, space.wrap("a")))
+ def test_run_string_flags(self, space, api):
+ flags = lltype.malloc(PyCompilerFlags, flavor='raw')
+ flags.c_cf_flags = rffi.cast(rffi.INT, consts.PyCF_SOURCE_IS_UTF8)
+ w_globals = space.newdict()
+ api.PyRun_StringFlags("a = u'caf\xc3\xa9'", Py_single_input,
+ w_globals, w_globals, flags)
+ w_a = space.getitem(w_globals, space.wrap("a"))
+ assert space.unwrap(w_a) == u'caf\xe9'
+ lltype.free(flags, flavor='raw')
+
def test_run_file(self, space, api):
filepath = udir / "cpyext_test_runfile.py"
filepath.write("raise ZeroDivisionError")
@@ -256,3 +283,21 @@
print dir(mod)
print mod.__dict__
assert mod.f(42) == 47
+
+ def test_merge_compiler_flags(self):
+ module = self.import_extension('foo', [
+ ("get_flags", "METH_NOARGS",
+ """
+ PyCompilerFlags flags;
+ flags.cf_flags = 0;
+ int result = PyEval_MergeCompilerFlags(&flags);
+ return Py_BuildValue("ii", result, flags.cf_flags);
+ """),
+ ])
+ assert module.get_flags() == (0, 0)
+
+ ns = {'module':module}
+ exec """from __future__ import division \nif 1:
+ def nested_flags():
+ return module.get_flags()""" in ns
+ assert ns['nested_flags']() == (1, 0x2000) # CO_FUTURE_DIVISION
diff --git a/pypy/module/cpyext/test/test_funcobject.py
b/pypy/module/cpyext/test/test_funcobject.py
--- a/pypy/module/cpyext/test/test_funcobject.py
+++ b/pypy/module/cpyext/test/test_funcobject.py
@@ -78,6 +78,14 @@
rffi.free_charp(filename)
rffi.free_charp(funcname)
+ def test_getnumfree(self, space, api):
+ w_function = space.appexec([], """():
+ a = 5
+ def method(x): return a, x
+ return method
+ """)
+ assert api.PyCode_GetNumFree(w_function.code) == 1
+
def test_classmethod(self, space, api):
w_function = space.appexec([], """():
def method(x): return x
diff --git a/pypy/module/cpyext/test/test_unicodeobject.py
b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -239,8 +239,18 @@
assert api.Py_UNICODE_ISSPACE(unichr(char))
assert not api.Py_UNICODE_ISSPACE(u'a')
+ assert api.Py_UNICODE_ISALPHA(u'a')
+ assert not api.Py_UNICODE_ISALPHA(u'0')
+ assert api.Py_UNICODE_ISALNUM(u'a')
+ assert api.Py_UNICODE_ISALNUM(u'0')
+ assert not api.Py_UNICODE_ISALNUM(u'+')
+
assert api.Py_UNICODE_ISDECIMAL(u'\u0660')
assert not api.Py_UNICODE_ISDECIMAL(u'a')
+ assert api.Py_UNICODE_ISDIGIT(u'9')
+ assert not api.Py_UNICODE_ISDIGIT(u'@')
+ assert api.Py_UNICODE_ISNUMERIC(u'9')
+ assert not api.Py_UNICODE_ISNUMERIC(u'@')
for char in [0x0a, 0x0d, 0x1c, 0x1d, 0x1e, 0x85, 0x2028, 0x2029]:
assert api.Py_UNICODE_ISLINEBREAK(unichr(char))
@@ -251,6 +261,9 @@
assert not api.Py_UNICODE_ISUPPER(u'a')
assert not api.Py_UNICODE_ISLOWER(u'�')
assert api.Py_UNICODE_ISUPPER(u'�')
+ assert not api.Py_UNICODE_ISTITLE(u'A')
+ assert api.Py_UNICODE_ISTITLE(
+ u'\N{LATIN CAPITAL LETTER L WITH SMALL LETTER J}')
def test_TOLOWER(self, space, api):
assert api.Py_UNICODE_TOLOWER(u'�') == u'�'
@@ -472,3 +485,10 @@
api.PyUnicode_Replace(w_str, w_substr, w_replstr, 2))
assert u"zbzbzbzb" == space.unwrap(
api.PyUnicode_Replace(w_str, w_substr, w_replstr, -1))
+
+ def test_tailmatch(self, space, api):
+ w_str = space.wrap(u"abcdef")
+ assert api.PyUnicode_Tailmatch(w_str, space.wrap("cde"), 2, 10, 1) == 1
+ assert api.PyUnicode_Tailmatch(w_str, space.wrap("cde"), 1, 5, -1) == 1
+ self.raises(space, api, TypeError,
+ api.PyUnicode_Tailmatch, w_str, space.wrap(3), 2, 10, 1)
diff --git a/pypy/module/cpyext/unicodeobject.py
b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -11,7 +11,8 @@
PyObject, PyObjectP, Py_DecRef, make_ref, from_ref, track_reference,
make_typedescr, get_typedescr)
from pypy.module.cpyext.stringobject import PyString_Check
-from pypy.objspace.std import unicodeobject, unicodetype
+from pypy.module.sys.interp_encoding import setdefaultencoding
+from pypy.objspace.std import unicodeobject, unicodetype, stringtype
from pypy.rlib import runicode
from pypy.tool.sourcetools import func_renamer
import sys
@@ -91,6 +92,11 @@
return unicodedb.isspace(ord(ch))
@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
+def Py_UNICODE_ISALPHA(space, ch):
+ """Return 1 or 0 depending on whether ch is an alphabetic character."""
+ return unicodedb.isalpha(ord(ch))
+
+@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
def Py_UNICODE_ISALNUM(space, ch):
"""Return 1 or 0 depending on whether ch is an alphanumeric character."""
return unicodedb.isalnum(ord(ch))
@@ -106,6 +112,16 @@
return unicodedb.isdecimal(ord(ch))
@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
+def Py_UNICODE_ISDIGIT(space, ch):
+ """Return 1 or 0 depending on whether ch is a digit character."""
+ return unicodedb.isdigit(ord(ch))
+
+@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
+def Py_UNICODE_ISNUMERIC(space, ch):
+ """Return 1 or 0 depending on whether ch is a numeric character."""
+ return unicodedb.isnumeric(ord(ch))
+
+@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
def Py_UNICODE_ISLOWER(space, ch):
"""Return 1 or 0 depending on whether ch is a lowercase character."""
return unicodedb.islower(ord(ch))
@@ -115,6 +131,11 @@
"""Return 1 or 0 depending on whether ch is an uppercase character."""
return unicodedb.isupper(ord(ch))
+@cpython_api([Py_UNICODE], rffi.INT_real, error=CANNOT_FAIL)
+def Py_UNICODE_ISTITLE(space, ch):
+ """Return 1 or 0 depending on whether ch is a titlecase character."""
+ return unicodedb.istitle(ord(ch))
+
@cpython_api([Py_UNICODE], Py_UNICODE, error=CANNOT_FAIL)
def Py_UNICODE_TOLOWER(space, ch):
"""Return the character ch converted to lower case."""
@@ -157,6 +178,11 @@
except KeyError:
return -1.0
+@cpython_api([], Py_UNICODE, error=CANNOT_FAIL)
+def PyUnicode_GetMax(space):
+ """Get the maximum ordinal for a Unicode character."""
+ return unichr(runicode.MAXUNICODE)
+
@cpython_api([PyObject], rffi.CCHARP, error=CANNOT_FAIL)
def PyUnicode_AS_DATA(space, ref):
"""Return a pointer to the internal buffer of the object. o has to be a
@@ -564,3 +590,16 @@
return space.call_method(w_str, "replace", w_substr, w_replstr,
space.wrap(maxcount))
+@cpython_api([PyObject, PyObject, Py_ssize_t, Py_ssize_t, rffi.INT_real],
+ rffi.INT_real, error=-1)
+def PyUnicode_Tailmatch(space, w_str, w_substr, start, end, direction):
+ """Return 1 if substr matches str[start:end] at the given tail end
+ (direction == -1 means to do a prefix match, direction == 1 a
+ suffix match), 0 otherwise. Return -1 if an error occurred."""
+ str = space.unicode_w(w_str)
+ substr = space.unicode_w(w_substr)
+ if rffi.cast(lltype.Signed, direction) >= 0:
+ return stringtype.stringstartswith(str, substr, start, end)
+ else:
+ return stringtype.stringendswith(str, substr, start, end)
+
diff --git a/pypy/rlib/debug.py b/pypy/rlib/debug.py
--- a/pypy/rlib/debug.py
+++ b/pypy/rlib/debug.py
@@ -26,6 +26,7 @@
llop.debug_print_traceback(lltype.Void)
llop.debug_fatalerror(lltype.Void, msg)
fatalerror._dont_inline_ = True
+fatalerror._jit_look_inside_ = False
fatalerror._annenforceargs_ = [str]
def fatalerror_notb(msg):
@@ -34,6 +35,7 @@
from pypy.rpython.lltypesystem.lloperation import llop
llop.debug_fatalerror(lltype.Void, msg)
fatalerror_notb._dont_inline_ = True
+fatalerror_notb._jit_look_inside_ = False
fatalerror_notb._annenforceargs_ = [str]
diff --git a/pypy/translator/sandbox/test/test_sandbox.py
b/pypy/translator/sandbox/test/test_sandbox.py
--- a/pypy/translator/sandbox/test/test_sandbox.py
+++ b/pypy/translator/sandbox/test/test_sandbox.py
@@ -145,9 +145,9 @@
g = pipe.stdin
f = pipe.stdout
expect(f, g, "ll_os.ll_os_getenv", ("PYPY_GENERATIONGC_NURSERY",), None)
- if sys.platform.startswith('linux'): # on Mac, uses another (sandboxsafe)
approach
- expect(f, g, "ll_os.ll_os_open", ("/proc/cpuinfo", 0, 420),
- OSError(5232, "xyz"))
+ #if sys.platform.startswith('linux'):
+ # expect(f, g, "ll_os.ll_os_open", ("/proc/cpuinfo", 0, 420),
+ # OSError(5232, "xyz"))
expect(f, g, "ll_os.ll_os_getenv", ("PYPY_GC_DEBUG",), None)
g.close()
tail = f.read()
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit