Author: Matti Picus <matti.pi...@gmail.com> Branch: release-pypy2.7-5.x Changeset: r91449:34e9d2c7a2e1 Date: 2017-05-30 16:14 +0300 http://bitbucket.org/pypy/pypy/changeset/34e9d2c7a2e1/
Log: merge default into release diff too long, truncating to 2000 out of 52647 lines diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -49,6 +49,11 @@ ^rpython/translator/goal/target.+-c$ ^rpython/translator/goal/.+\.exe$ ^rpython/translator/goal/.+\.dll$ +^rpython/rlib/rvmprof/src/shared/libbacktrace/Makefile$ +^rpython/rlib/rvmprof/src/shared/libbacktrace/config.guess$ +^rpython/rlib/rvmprof/src/shared/libbacktrace/config.h$ +^rpython/rlib/rvmprof/src/shared/libbacktrace/config.log$ +^rpython/rlib/rvmprof/src/shared/libbacktrace/config.status$ ^pypy/goal/pypy-translation-snapshot$ ^pypy/goal/pypy-c ^pypy/goal/.+\.exe$ @@ -80,5 +85,8 @@ .hypothesis/ ^release/ ^rpython/_cache$ +^\.cache$ pypy/module/cppyy/.+/*\.pcm + + diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -34,3 +34,7 @@ 050d84dd78997f021acf0e133934275d63547cc0 release-pypy2.7-v5.4.1 0e2d9a73f5a1818d0245d75daccdbe21b2d5c3ef release-pypy2.7-v5.4.1 aff251e543859ce4508159dd9f1a82a2f553de00 release-pypy2.7-v5.6.0 +fa3249d55d15b9829e1be69cdf45b5a44cec902d release-pypy2.7-v5.7.0 +b16a4363e930f6401bceb499b9520955504c6cb0 release-pypy3.5-v5.7.0 +1aa2d8e03cdfab54b7121e93fda7e98ea88a30bf release-pypy2.7-v5.7.1 +2875f328eae2216a87f3d6f335092832eb031f56 release-pypy3.5-v5.7.1 diff --git a/include/README b/include/README --- a/include/README +++ b/include/README @@ -1,7 +1,11 @@ This directory contains all the include files needed to build cpython extensions with PyPy. Note that these are just copies of the original headers -that are in pypy/module/cpyext/include: they are automatically copied from -there during translation. +that are in pypy/module/cpyext/{include,parse}: they are automatically copied +from there during translation. -Moreover, pypy_decl.h and pypy_macros.h are automatically generated, also -during translation. +Moreover, some pypy-specific files are automatically generated, also during +translation. Currently they are: +* pypy_decl.h +* pypy_macros.h +* pypy_numpy.h +* pypy_structmember_decl.h diff --git a/lib-python/2.7/distutils/sysconfig_pypy.py b/lib-python/2.7/distutils/sysconfig_pypy.py --- a/lib-python/2.7/distutils/sysconfig_pypy.py +++ b/lib-python/2.7/distutils/sysconfig_pypy.py @@ -61,12 +61,12 @@ def _init_posix(): """Initialize the module as appropriate for POSIX systems.""" g = {} - g['CC'] = "gcc -pthread" - g['CXX'] = "g++ -pthread" + g['CC'] = "cc -pthread" + g['CXX'] = "c++ -pthread" g['OPT'] = "-DNDEBUG -O2" g['CFLAGS'] = "-DNDEBUG -O2" g['CCSHARED'] = "-fPIC" - g['LDSHARED'] = "gcc -pthread -shared" + g['LDSHARED'] = "cc -pthread -shared" g['SO'] = [s[0] for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION][0] g['AR'] = "ar" g['ARFLAGS'] = "rc" diff --git a/lib-python/2.7/weakref.py b/lib-python/2.7/weakref.py --- a/lib-python/2.7/weakref.py +++ b/lib-python/2.7/weakref.py @@ -36,9 +36,9 @@ except ImportError: def _delitem_if_value_is(d, key, value): try: - if self.data[key] is value: # fall-back: there is a potential + if d[key] is value: # fall-back: there is a potential # race condition in multithreaded programs HERE - del self.data[key] + del d[key] except KeyError: pass diff --git a/lib_pypy/_ctypes/array.py b/lib_pypy/_ctypes/array.py --- a/lib_pypy/_ctypes/array.py +++ b/lib_pypy/_ctypes/array.py @@ -85,8 +85,9 @@ res = self.__new__(self) ffiarray = self._ffiarray.fromaddress(resarray.buffer, self._length_) res._buffer = ffiarray - res._base = base - res._index = index + if base is not None: + res._base = base + res._index = index return res def _CData_retval(self, resbuffer): diff --git a/lib_pypy/_ctypes/basics.py b/lib_pypy/_ctypes/basics.py --- a/lib_pypy/_ctypes/basics.py +++ b/lib_pypy/_ctypes/basics.py @@ -64,8 +64,9 @@ res = object.__new__(self) res.__class__ = self res.__dict__['_buffer'] = resbuffer - res.__dict__['_base'] = base - res.__dict__['_index'] = index + if base is not None: + res.__dict__['_base'] = base + res.__dict__['_index'] = index return res def _CData_retval(self, resbuffer): diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py --- a/lib_pypy/_ctypes/function.py +++ b/lib_pypy/_ctypes/function.py @@ -1,4 +1,3 @@ - from _ctypes.basics import _CData, _CDataMeta, cdata_from_address from _ctypes.primitive import SimpleType, _SimpleCData from _ctypes.basics import ArgumentError, keepalive_key @@ -9,13 +8,16 @@ import sys import traceback -try: from __pypy__ import builtinify -except ImportError: builtinify = lambda f: f + +try: + from __pypy__ import builtinify +except ImportError: + builtinify = lambda f: f # XXX this file needs huge refactoring I fear -PARAMFLAG_FIN = 0x1 -PARAMFLAG_FOUT = 0x2 +PARAMFLAG_FIN = 0x1 +PARAMFLAG_FOUT = 0x2 PARAMFLAG_FLCID = 0x4 PARAMFLAG_COMBINED = PARAMFLAG_FIN | PARAMFLAG_FOUT | PARAMFLAG_FLCID @@ -24,9 +26,9 @@ PARAMFLAG_FIN, PARAMFLAG_FIN | PARAMFLAG_FOUT, PARAMFLAG_FIN | PARAMFLAG_FLCID - ) +) -WIN64 = sys.platform == 'win32' and sys.maxint == 2**63 - 1 +WIN64 = sys.platform == 'win32' and sys.maxint == 2 ** 63 - 1 def get_com_error(errcode, riid, pIunk): @@ -35,6 +37,7 @@ from _ctypes import COMError return COMError(errcode, None, None) + @builtinify def call_function(func, args): "Only for debugging so far: So that we can call CFunction instances" @@ -94,14 +97,9 @@ "item %d in _argtypes_ has no from_param method" % ( i + 1,)) self._argtypes_ = list(argtypes) - self._check_argtypes_for_fastpath() + argtypes = property(_getargtypes, _setargtypes) - def _check_argtypes_for_fastpath(self): - if all([hasattr(argtype, '_ffiargshape_') for argtype in self._argtypes_]): - fastpath_cls = make_fastpath_subclass(self.__class__) - fastpath_cls.enable_fastpath_maybe(self) - def _getparamflags(self): return self._paramflags @@ -126,27 +124,26 @@ raise TypeError( "paramflags must be a sequence of (int [,string [,value]]) " "tuples" - ) + ) if not isinstance(flag, int): raise TypeError( "paramflags must be a sequence of (int [,string [,value]]) " "tuples" - ) + ) _flag = flag & PARAMFLAG_COMBINED if _flag == PARAMFLAG_FOUT: typ = self._argtypes_[idx] if getattr(typ, '_ffiargshape_', None) not in ('P', 'z', 'Z'): raise TypeError( "'out' parameter %d must be a pointer type, not %s" - % (idx+1, type(typ).__name__) - ) + % (idx + 1, type(typ).__name__) + ) elif _flag not in VALID_PARAMFLAGS: raise TypeError("paramflag value %d not supported" % flag) self._paramflags = paramflags paramflags = property(_getparamflags, _setparamflags) - def _getrestype(self): return self._restype_ @@ -156,7 +153,7 @@ from ctypes import c_int restype = c_int if not (isinstance(restype, _CDataMeta) or restype is None or - callable(restype)): + callable(restype)): raise TypeError("restype must be a type, a callable, or None") self._restype_ = restype @@ -168,15 +165,18 @@ def _geterrcheck(self): return getattr(self, '_errcheck_', None) + def _seterrcheck(self, errcheck): if not callable(errcheck): raise TypeError("The errcheck attribute must be callable") self._errcheck_ = errcheck + def _delerrcheck(self): try: del self._errcheck_ except AttributeError: pass + errcheck = property(_geterrcheck, _seterrcheck, _delerrcheck) def _ffishapes(self, args, restype): @@ -188,7 +188,7 @@ raise TypeError("invalid result type for callback function") restype = restype._ffiargshape_ else: - restype = 'O' # void + restype = 'O' # void return argtypes, restype def _set_address(self, address): @@ -201,7 +201,7 @@ def __init__(self, *args): self.name = None - self._objects = {keepalive_key(0):self} + self._objects = {keepalive_key(0): self} self._needs_free = True # Empty function object -- this is needed for casts @@ -222,10 +222,8 @@ if self._argtypes_ is None: self._argtypes_ = [] self._ptr = self._getfuncptr_fromaddress(self._argtypes_, restype) - self._check_argtypes_for_fastpath() return - # A callback into python if callable(argument) and not argsl: self.callable = argument @@ -259,7 +257,7 @@ if (sys.platform == 'win32' and isinstance(argument, (int, long)) and argsl): ffiargs, ffires = self._ffishapes(self._argtypes_, self._restype_) - self._com_index = argument + 0x1000 + self._com_index = argument + 0x1000 self.name = argsl.pop(0) if argsl: self.paramflags = argsl.pop(0) @@ -281,6 +279,7 @@ except SystemExit as e: handle_system_exit(e) raise + return f def __call__(self, *args, **kwargs): @@ -317,7 +316,7 @@ except: exc_info = sys.exc_info() traceback.print_tb(exc_info[2], file=sys.stderr) - print >>sys.stderr, "%s: %s" % (exc_info[0].__name__, exc_info[1]) + print >> sys.stderr, "%s: %s" % (exc_info[0].__name__, exc_info[1]) return 0 if self._restype_ is not None: return res @@ -328,7 +327,7 @@ # really slow". Now we don't worry that much about slowness # of ctypes, and it's strange to get warnings for perfectly- # legal code. - #warnings.warn('C function without declared arguments called', + # warnings.warn('C function without declared arguments called', # RuntimeWarning, stacklevel=2) argtypes = [] @@ -337,7 +336,7 @@ if not args: raise ValueError( "native COM method call without 'this' parameter" - ) + ) thisvalue = args[0] thisarg = cast(thisvalue, POINTER(POINTER(c_void_p))) keepalives, newargs, argtypes, outargs, errcheckargs = ( @@ -366,7 +365,6 @@ return tuple(outargs) def _call_funcptr(self, funcptr, *newargs): - if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO: tmp = _rawffi.get_errno() _rawffi.set_errno(get_errno()) @@ -431,7 +429,7 @@ ffiargs = [argtype.get_ffi_argtype() for argtype in argtypes] ffires = restype.get_ffi_argtype() return _ffi.FuncPtr.fromaddr(ptr, '', ffiargs, ffires, self._flags_) - + cdll = self.dll._handle try: ffi_argtypes = [argtype.get_ffi_argtype() for argtype in argtypes] @@ -450,7 +448,7 @@ # funcname -> _funcname@<n> # where n is 0, 4, 8, 12, ..., 128 for i in range(33): - mangled_name = "_%s@%d" % (self.name, i*4) + mangled_name = "_%s@%d" % (self.name, i * 4) try: return cdll.getfunc(mangled_name, ffi_argtypes, ffi_restype, @@ -492,7 +490,7 @@ for argtype, arg in zip(argtypes, args): param = argtype.from_param(arg) _type_ = getattr(argtype, '_type_', None) - if _type_ == 'P': # special-case for c_void_p + if _type_ == 'P': # special-case for c_void_p param = param._get_buffer_value() elif self._is_primitive(argtype): param = param.value @@ -668,69 +666,11 @@ self._needs_free = False -def make_fastpath_subclass(CFuncPtr): - if CFuncPtr._is_fastpath: - return CFuncPtr - # - try: - return make_fastpath_subclass.memo[CFuncPtr] - except KeyError: - pass - - class CFuncPtrFast(CFuncPtr): - - _is_fastpath = True - _slowpath_allowed = True # set to False by tests - - @classmethod - def enable_fastpath_maybe(cls, obj): - if (obj.callable is None and - obj._com_index is None): - obj.__class__ = cls - - def __rollback(self): - assert self._slowpath_allowed - self.__class__ = CFuncPtr - - # disable the fast path if we reset argtypes - def _setargtypes(self, argtypes): - self.__rollback() - self._setargtypes(argtypes) - argtypes = property(CFuncPtr._getargtypes, _setargtypes) - - def _setcallable(self, func): - self.__rollback() - self.callable = func - callable = property(lambda x: None, _setcallable) - - def _setcom_index(self, idx): - self.__rollback() - self._com_index = idx - _com_index = property(lambda x: None, _setcom_index) - - def __call__(self, *args): - thisarg = None - argtypes = self._argtypes_ - restype = self._restype_ - funcptr = self._getfuncptr(argtypes, restype, thisarg) - try: - result = self._call_funcptr(funcptr, *args) - result, _ = self._do_errcheck(result, args) - except (TypeError, ArgumentError, UnicodeDecodeError): - assert self._slowpath_allowed - return CFuncPtr.__call__(self, *args) - return result - - make_fastpath_subclass.memo[CFuncPtr] = CFuncPtrFast - return CFuncPtrFast -make_fastpath_subclass.memo = {} - - def handle_system_exit(e): # issue #1194: if we get SystemExit here, then exit the interpreter. # Highly obscure imho but some people seem to depend on it. if sys.flags.inspect: - return # Don't exit if -i flag was given. + return # Don't exit if -i flag was given. else: code = e.code if isinstance(code, int): diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py --- a/lib_pypy/_ctypes/structure.py +++ b/lib_pypy/_ctypes/structure.py @@ -234,6 +234,9 @@ if ('_abstract_' in cls.__dict__ or cls is Structure or cls is union.Union): raise TypeError("abstract class") + if hasattr(cls, '_swappedbytes_'): + raise NotImplementedError("missing in PyPy: structure/union with " + "swapped (non-native) byte ordering") if hasattr(cls, '_ffistruct_'): self.__dict__['_buffer'] = self._ffistruct_(autofree=True) return self diff --git a/lib_pypy/_pypy_winbase_build.py b/lib_pypy/_pypy_winbase_build.py --- a/lib_pypy/_pypy_winbase_build.py +++ b/lib_pypy/_pypy_winbase_build.py @@ -79,10 +79,20 @@ BOOL WINAPI CreateProcessA(char *, char *, void *, void *, BOOL, DWORD, char *, char *, LPSTARTUPINFO, LPPROCESS_INFORMATION); +BOOL WINAPI CreateProcessW(wchar_t *, wchar_t *, void *, + void *, BOOL, DWORD, wchar_t *, + wchar_t *, LPSTARTUPINFO, LPPROCESS_INFORMATION); DWORD WINAPI WaitForSingleObject(HANDLE, DWORD); BOOL WINAPI GetExitCodeProcess(HANDLE, LPDWORD); BOOL WINAPI TerminateProcess(HANDLE, UINT); HANDLE WINAPI GetStdHandle(DWORD); +DWORD WINAPI GetModuleFileNameW(HANDLE, wchar_t *, DWORD); + +UINT WINAPI SetErrorMode(UINT); +#define SEM_FAILCRITICALERRORS 0x0001 +#define SEM_NOGPFAULTERRORBOX 0x0002 +#define SEM_NOALIGNMENTFAULTEXCEPT 0x0004 +#define SEM_NOOPENFILEERRORBOX 0x8000 """) # -------------------- diff --git a/lib_pypy/_pypy_winbase_cffi.py b/lib_pypy/_pypy_winbase_cffi.py --- a/lib_pypy/_pypy_winbase_cffi.py +++ b/lib_pypy/_pypy_winbase_cffi.py @@ -3,8 +3,8 @@ ffi = _cffi_backend.FFI('_pypy_winbase_cffi', _version = 0x2601, - _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x50\x03\x00\x00\x13\x11\x00\x00\x53\x03\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x13\x11\x00\x00\x13\x11\x00\x00\x4F\x03\x00\x00\x4E\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x03\x00\x00\x1F\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x18\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x1F\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x 00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x02\x0F\x00\x00\x42\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\x42\x0D\x00\x00\x00\x0F\x00\x00\x42\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x02\x0F\x00\x00\x00\x09\x00\x00\x01\x09\x00\x00\x02\x01\x00\x00\x52\x03\x00\x00\x04\x01\x00\x00\x00\x01', - _globals = (b'\x00\x00\x24\x23CloseHandle',0,b'\x00\x00\x1E\x23CreatePipe',0,b'\x00\x00\x12\x23CreateProcessA',0,b'\x00\x00\x2F\x23DuplicateHandle',0,b'\x00\x00\x4C\x23GetCurrentProcess',0,b'\x00\x00\x2B\x23GetExitCodeProcess',0,b'\x00\x00\x49\x23GetStdHandle',0,b'\x00\x00\x3F\x23GetVersion',0,b'\x00\x00\x27\x23TerminateProcess',0,b'\x00\x00\x3B\x23WaitForSingleObject',0,b'\x00\x00\x38\x23_get_osfhandle',0,b'\x00\x00\x10\x23_getch',0,b'\x00\x00\x10\x23_getche',0,b'\x00\x00\x44\x23_getwch',0,b'\x00\x00\x44\x23_getwche',0,b'\x00\x00\x10\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\x46\x23_putwch',0,b'\x00\x00\x03\x23_setmode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\x41\x23_ungetwch',0), - _struct_unions = ((b'\x00\x00\x00\x4E\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x15\x11hProcess',b'\x00\x00\x15\x11hThread',b'\x00\x00\x18\x11dwProcessId',b'\x00\x00\x18\x11dwThreadId'),(b'\x00\x00\x00\x4F\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x18\x11cb',b'\x00\x00\x13\x11lpReserved',b'\x00\x00\x13\x11lpDesktop',b'\x00\x00\x13\x11lpTitle',b'\x00\x00\x18\x11dwX',b'\x00\x00\x18\x11dwY',b'\x00\x00\x18\x11dwXSize',b'\x00\x00\x18\x11dwYSize',b'\x00\x00\x18\x11dwXCountChars',b'\x00\x00\x18\x11dwYCountChars',b'\x00\x00\x18\x11dwFillAttribute',b'\x00\x00\x18\x11dwFlags',b'\x00\x00\x42\x11wShowWindow',b'\x00\x00\x42\x11cbReserved2',b'\x00\x00\x51\x11lpReserved2',b'\x00\x00\x15\x11hStdInput',b'\x00\x00\x15\x11hStdOutput',b'\x00\x00\x15\x11hStdError')), - _typenames = (b'\x00\x00\x00\x1CLPPROCESS_INFORMATION',b'\x00\x00\x00\x1BLPSTARTUPINFO',b'\x00\x00\x00\x4EPROCESS_INFORMATION',b'\x00\x00\x00\x4FSTARTUPINFO',b'\x00\x00\x00\x42wint_t'), + _types = b'\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x07\x01\x00\x00\x07\x01\x00\x00\x09\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x19\x01\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x00\x0F\x00\x00\x01\x0D\x00\x00\x64\x03\x00\x00\x13\x11\x00\x00\x67\x03\x00\x00\x15\x11\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x13\x11\x00\x00\x13\x11\x00\x00\x63\x03\x00\x00\x62\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x03\x00\x00\x1F\x11\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x18\x03\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x00\x1F\x11\x00\x00\x0A\x01\x00\x00\x07\x01\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x01\x0D\x00\x00\x5B\x03\x00\x00\x39\x11\x00\x00\x15\x11\x00\x00\x15\x11\x00\x 00\x07\x01\x00\x00\x0A\x01\x00\x00\x39\x11\x00\x00\x39\x11\x00\x00\x1B\x11\x00\x00\x1C\x11\x00\x00\x02\x0F\x00\x00\x0D\x0D\x00\x00\x07\x01\x00\x00\x00\x0F\x00\x00\x29\x0D\x00\x00\x08\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x15\x11\x00\x00\x39\x11\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x18\x0D\x00\x00\x02\x0F\x00\x00\x56\x0D\x00\x00\x06\x01\x00\x00\x00\x0F\x00\x00\x56\x0D\x00\x00\x00\x0F\x00\x00\x56\x0D\x00\x00\x10\x01\x00\x00\x00\x0F\x00\x00\x15\x0D\x00\x00\x0A\x01\x00\x00\x02\x0F\x00\x00\x15\x0D\x00\x00\x02\x0F\x00\x00\x00\x09\x00\x00\x01\x09\x00\x00\x02\x01\x00\x00\x66\x03\x00\x00\x04\x01\x00\x00\x00\x01', + _globals = (b'\x00\x00\x24\x23CloseHandle',0,b'\x00\x00\x1E\x23CreatePipe',0,b'\x00\x00\x12\x23CreateProcessA',0,b'\x00\x00\x38\x23CreateProcessW',0,b'\x00\x00\x2F\x23DuplicateHandle',0,b'\x00\x00\x60\x23GetCurrentProcess',0,b'\x00\x00\x2B\x23GetExitCodeProcess',0,b'\x00\x00\x4E\x23GetModuleFileNameW',0,b'\x00\x00\x5D\x23GetStdHandle',0,b'\x00\x00\x53\x23GetVersion',0,b'\xFF\xFF\xFF\x1FSEM_FAILCRITICALERRORS',1,b'\xFF\xFF\xFF\x1FSEM_NOALIGNMENTFAULTEXCEPT',4,b'\xFF\xFF\xFF\x1FSEM_NOGPFAULTERRORBOX',2,b'\xFF\xFF\xFF\x1FSEM_NOOPENFILEERRORBOX',32768,b'\x00\x00\x47\x23SetErrorMode',0,b'\x00\x00\x27\x23TerminateProcess',0,b'\x00\x00\x4A\x23WaitForSingleObject',0,b'\x00\x00\x44\x23_get_osfhandle',0,b'\x00\x00\x10\x23_getch',0,b'\x00\x00\x10\x23_getche',0,b'\x00\x00\x58\x23_getwch',0,b'\x00\x00\x58\x23_getwche',0,b'\x00\x00\x10\x23_kbhit',0,b'\x00\x00\x07\x23_locking',0,b'\x00\x00\x0C\x23_open_osfhandle',0,b'\x00\x00\x00\x23_putch',0,b'\x00\x00\x5A\x23_putwch',0,b'\x00\x00\x03\x23_set mode',0,b'\x00\x00\x00\x23_ungetch',0,b'\x00\x00\x55\x23_ungetwch',0), + _struct_unions = ((b'\x00\x00\x00\x62\x00\x00\x00\x02$PROCESS_INFORMATION',b'\x00\x00\x15\x11hProcess',b'\x00\x00\x15\x11hThread',b'\x00\x00\x18\x11dwProcessId',b'\x00\x00\x18\x11dwThreadId'),(b'\x00\x00\x00\x63\x00\x00\x00\x02$STARTUPINFO',b'\x00\x00\x18\x11cb',b'\x00\x00\x13\x11lpReserved',b'\x00\x00\x13\x11lpDesktop',b'\x00\x00\x13\x11lpTitle',b'\x00\x00\x18\x11dwX',b'\x00\x00\x18\x11dwY',b'\x00\x00\x18\x11dwXSize',b'\x00\x00\x18\x11dwYSize',b'\x00\x00\x18\x11dwXCountChars',b'\x00\x00\x18\x11dwYCountChars',b'\x00\x00\x18\x11dwFillAttribute',b'\x00\x00\x18\x11dwFlags',b'\x00\x00\x56\x11wShowWindow',b'\x00\x00\x56\x11cbReserved2',b'\x00\x00\x65\x11lpReserved2',b'\x00\x00\x15\x11hStdInput',b'\x00\x00\x15\x11hStdOutput',b'\x00\x00\x15\x11hStdError')), + _typenames = (b'\x00\x00\x00\x1CLPPROCESS_INFORMATION',b'\x00\x00\x00\x1BLPSTARTUPINFO',b'\x00\x00\x00\x62PROCESS_INFORMATION',b'\x00\x00\x00\x63STARTUPINFO',b'\x00\x00\x00\x56wint_t'), ) diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -31,10 +31,11 @@ import weakref from threading import _get_ident as _thread_get_ident try: - from __pypy__ import newlist_hint + from __pypy__ import newlist_hint, add_memory_pressure except ImportError: assert '__pypy__' not in sys.builtin_module_names newlist_hint = lambda sizehint: [] + add_memory_pressure = lambda size: None if sys.version_info[0] >= 3: StandardError = Exception @@ -150,6 +151,9 @@ def connect(database, timeout=5.0, detect_types=0, isolation_level="", check_same_thread=True, factory=None, cached_statements=100): factory = Connection if not factory else factory + # an sqlite3 db seems to be around 100 KiB at least (doesn't matter if + # backed by :memory: or a file) + add_memory_pressure(100 * 1024) return factory(database, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements) diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -42,8 +42,9 @@ from rpython.jit.backend import detect_cpu try: if detect_cpu.autodetect().startswith('x86'): - working_modules.add('_vmprof') - working_modules.add('faulthandler') + if not sys.platform.startswith('openbsd'): + working_modules.add('_vmprof') + working_modules.add('faulthandler') except detect_cpu.ProcessorAutodetectError: pass @@ -219,9 +220,6 @@ BoolOption("withsmalllong", "use a version of 'long' in a C long long", default=False), - BoolOption("withstrbuf", "use strings optimized for addition (ver 2)", - default=False), - BoolOption("withspecialisedtuple", "use specialised tuples", default=False), diff --git a/pypy/doc/build.rst b/pypy/doc/build.rst --- a/pypy/doc/build.rst +++ b/pypy/doc/build.rst @@ -79,6 +79,9 @@ _ssl libssl +_vmprof + libunwind (optional, loaded dynamically at runtime) + Make sure to have these libraries (with development headers) installed before building PyPy, otherwise the resulting binary will not contain these modules. Furthermore, the following libraries should be present @@ -107,22 +110,22 @@ apt-get install gcc make libffi-dev pkg-config libz-dev libbz2-dev \ libsqlite3-dev libncurses-dev libexpat1-dev libssl-dev libgdbm-dev \ - tk-dev libgc-dev \ + tk-dev libgc-dev python-cffi \ liblzma-dev # For lzma on PyPy3. On Fedora:: dnf install gcc make libffi-devel pkgconfig zlib-devel bzip2-devel \ sqlite-devel ncurses-devel expat-devel openssl-devel tk-devel \ - gdbm-devel \ + gdbm-devel python-cffi\ xz-devel # For lzma on PyPy3. On SLES11:: zypper install gcc make python-devel pkg-config \ zlib-devel libopenssl-devel libbz2-devel sqlite3-devel \ - libexpat-devel libffi-devel python-curses \ - xz-devel # For lzma on PyPy3. + libexpat-devel libffi-devel python-curses python-cffi \ + xz-devel # For lzma on PyPy3. (XXX plus the SLES11 version of libgdbm-dev and tk-dev) On Mac OS X, most of these build-time dependencies are installed alongside @@ -185,7 +188,7 @@ :: cd pypy/tool/release - ./package.py pypy-VER-PLATFORM + ./package.py --archive-name=pypy-VER-PLATFORM This creates a clean and prepared hierarchy, as well as a ``.tar.bz2`` with the same content; both are found by default in diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -357,6 +357,24 @@ .. __: https://bitbucket.org/pypy/pypy/issue/1974/different-behaviour-for-collections-of +Performance Differences +------------------------- + +CPython has an optimization that can make repeated string concatenation not +quadratic. For example, this kind of code runs in O(n) time:: + + s = '' + for string in mylist: + s += string + +In PyPy, this code will always have quadratic complexity. Note also, that the +CPython optimization is brittle and can break by having slight variations in +your code anyway. So you should anyway replace the code with:: + + parts = [] + for string in mylist: + parts.append(string) + s = "".join(parts) Miscellaneous ------------- @@ -483,7 +501,14 @@ the rest is kept. If you return an unexpected string from ``__hex__()`` you get an exception (or a crash before CPython 2.7.13). -* PyPy3: ``__class__`` attritube assignment between heaptypes and non heaptypes. +* In PyPy, dictionaries passed as ``**kwargs`` can contain only string keys, + even for ``dict()`` and ``dict.update()``. CPython 2.7 allows non-string + keys in these two cases (and only there, as far as we know). E.g. this + code produces a ``TypeError``, on CPython 3.x as well as on any PyPy: + ``dict(**{1: 2})``. (Note that ``dict(**d1)`` is equivalent to + ``dict(d1)``.) + +* PyPy3: ``__class__`` attribute assignment between heaptypes and non heaptypes. CPython allows that for module subtypes, but not for e.g. ``int`` or ``float`` subtypes. Currently PyPy does not support the ``__class__`` attribute assignment for any non heaptype subtype. diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst --- a/pypy/doc/index-of-release-notes.rst +++ b/pypy/doc/index-of-release-notes.rst @@ -6,6 +6,7 @@ .. toctree:: + release-v5.7.1.rst release-v5.7.0.rst release-pypy2.7-v5.6.0.rst release-pypy2.7-v5.4.1.rst @@ -59,6 +60,7 @@ .. toctree:: + release-v5.7.1.rst release-v5.7.0.rst CPython 3.3 compatible versions diff --git a/pypy/doc/install.rst b/pypy/doc/install.rst --- a/pypy/doc/install.rst +++ b/pypy/doc/install.rst @@ -32,10 +32,10 @@ .. code-block:: console - $ tar xf pypy-2.1.tar.bz2 - $ ./pypy-2.1/bin/pypy - Python 2.7.3 (480845e6b1dd, Jul 31 2013, 11:05:31) - [PyPy 2.1.0 with GCC 4.4.3] on linux2 + $ tar xf pypy-x.y.z.tar.bz2 + $ ./pypy-x.y.z/bin/pypy + Python 2.7.x (xxxxxxxxxxxx, Date, Time) + [PyPy x.y.z with GCC x.y.z] on linux2 Type "help", "copyright", "credits" or "license" for more information. And now for something completely different: ``PyPy is an exciting technology that lets you to write fast, portable, multi-platform interpreters with less @@ -57,6 +57,7 @@ .. code-block:: console $ ./pypy-xxx/bin/pypy -m ensurepip + $ ./pypy-xxx/bin/pip install -U pip wheel # to upgrade to the latest versions $ ./pypy-xxx/bin/pip install pygments # for example Third party libraries will be installed in ``pypy-xxx/site-packages``, and @@ -77,7 +78,17 @@ # from the mercurial checkout $ virtualenv -p /path/to/pypy/pypy/translator/goal/pypy-c my-pypy-env -Note that bin/python is now a symlink to bin/pypy. + # in any case activate it + $ source my-pypy-env/bin/activate + +Note that my-pypy-env/bin/python is now a symlink to my-pypy-env/bin/pypy +so you should be able to run pypy simply by typing:: + + $ python + +You should still upgrade pip and wheel to the latest versions via:: + + $ my-pypy-env/bin/pip install -U pip wheel .. _pip: http://pypi.python.org/pypi/pip .. _ensurepip: https://docs.python.org/2.7/library/ensurepip.html diff --git a/pypy/doc/release-v5.7.0.rst b/pypy/doc/release-v5.7.0.rst --- a/pypy/doc/release-v5.7.0.rst +++ b/pypy/doc/release-v5.7.0.rst @@ -2,8 +2,11 @@ PyPy2.7 and PyPy3.5 v5.7 - two in one release ============================================= -We have released PyPy2.7 v5.7, and a beta-quality PyPy3.5 v5.7 (for -Linux 64bit only at first). +The PyPy team is proud to release both PyPy2.7 v5.7 (an interpreter supporting +Python v2.7 syntax), and a beta-quality PyPy3.5 v5.7 (an interpreter for Python +v3.5 syntax). The two releases are both based on much the same codebase, thus +the dual release. Note that PyPy3.5 supports Linux 64bit only for now. + This new PyPy2.7 release includes the upstream stdlib version 2.7.13, and PyPy3.5 (our first in the 3.5 series) includes the upstream stdlib version 3.5.3. @@ -88,14 +91,15 @@ * New features and cleanups * update the format of the PYPYLOG file and improvements to vmprof - * emit more sysconfig values for downstream cextension packages + * emit more sysconfig values for downstream cextension packages including + properly setting purelib and platlib to site-packages * add ``PyAnySet_Check``, ``PyModule_GetName``, ``PyWeakref_Check*``, ``_PyImport_{Acquire,Release}Lock``, ``PyGen_Check*``, ``PyOS_AfterFork``, * detect and raise on recreation of a PyPy object from a PyObject during tp_dealloc * refactor and clean up poor handling of unicode exposed in work on py3.5 * builtin module cppyy_ supports C++ 11, 14, etc. via cling (reflex has been removed) - * adapt ``weakref`` according to CPython issue #19542_, will be in CPython 2.7.14 + * adapt ``weakref`` according to CPython issue 19542_, will be in CPython 2.7.14 * support translations with cpyext and the Boehm GC (for special cases like RevDB_ * implement ``StringBuffer.get_raw_address`` for the buffer protocol, it is @@ -121,16 +125,18 @@ * disable ``clock_gettime()`` on OS/X, since we support 10.11 and it was only added in 10.12 * support ``HAVE_FSTATVFS`` which was unintentionally always false - * fix user-created C-API heaptype, issue #2434_ + * fix user-created C-API heaptype, issue 2434_ * fix ``PyDict_Update`` is not actually the same as ``dict.update`` * assign ``tp_doc`` on ``PyTypeObject`` and tie it to the app-level ``__doc__`` attribute - issue #2446_ + issue 2446_ * clean up memory leaks around ``PyObject_GetBuffer``, ``PyMemoryView_GET_BUFFER``, ``PyMemoryView_FromBuffer``, and ``PyBuffer_Release`` * improve support for creating C-extension objects from app-level classes, filling more slots, especially ``tp_new`` and ``tp_dealloc`` - * fix for ``ctypes.c_bool`` returning ``bool`` restype, issue #2475_ + * fix for ``ctypes.c_bool`` returning ``bool`` restype, issue 2475_ * fix in corner cases with the GIL and C-API functions + * allow overriding thread.local.__init__ in a subclass, issue 2501_ + * allow ``PyClass_New`` to be called with NULL as the first arguemnt, issue 2504_ * Performance improvements: @@ -183,21 +189,19 @@ * Performance improvements: * do not create a list whenever ``descr_new`` of a ``bytesobject`` is called - * - * - * * The following features of Python 3.5 are not implemented yet in PyPy: * PEP 442: Safe object finalization * PEP 489: Multi-phase extension module initialization - * XXX what else? .. _resolved: whatsnew-pypy2-5.7.0.html .. _19542: https://bugs.python.org/issue19542 .. _2434: https://bitbucket.org/pypy/pypy/issues/2434/support-pybind11-in-conjunction-with-pypys .. _2446: https://bitbucket.org/pypy/pypy/issues/2446/cpyext-tp_doc-field-not-reflected-on .. _2475: https://bitbucket.org/pypy/pypy/issues/2475 +.. _2501: https://bitbucket.org/pypy/pypy/issues/2501 +.. _2504: https://bitbucket.org/pypy/pypy/issues/2504 .. _RevDB: https://bitbucket.org/pypy/revdb .. _cryptography: https://cryptography.io .. _cppyy: cppyy.html diff --git a/pypy/doc/release-v5.7.1.rst b/pypy/doc/release-v5.7.1.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-v5.7.1.rst @@ -0,0 +1,50 @@ +========== +PyPy 5.7.1 +========== + +We have released a bugfix PyPy2.7-v5.7.1 and PyPy3.5-v5.7.1 beta (Linux 64bit), +due to the following issues: + + * correctly handle an edge case in dict.pop (issue 2508_) + + * fix a regression to correctly handle multiple inheritance in a C-API type + where the second base is an app-level class with a ``__new__`` function + + * fix a regression to fill a C-API type's ``tp_getattr`` slot from a + ``__getattr__`` method (issue 2523_) + +Thanks to those who reported the issues. + +.. _2508: https://bitbucket.org/pypy/pypy/issues/2508 +.. _2523: https://bitbucket.org/pypy/pypy/issues/2523 + +What is PyPy? +============= + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7 and CPython 3.5. It's fast (`PyPy and CPython 2.7.x`_ performance comparison) +due to its integrated tracing JIT compiler. + +We also welcome developers of other `dynamic languages`_ to see what RPython +can do for them. + +The PyPy 2.7 release supports: + + * **x86** machines on most common operating systems + (Linux 32/64 bits, Mac OS X 64 bits, Windows 32 bits, OpenBSD, FreeBSD) + + * newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux, + + * big- and little-endian variants of **PPC64** running Linux, + + * **s390x** running Linux + +.. _`PyPy and CPython 2.7.x`: http://speed.pypy.org +.. _`dynamic languages`: http://rpython.readthedocs.io/en/latest/examples.html + +Please update, and continue to help us make PyPy better. + +Cheers + +The PyPy Team + diff --git a/pypy/doc/test/test_whatsnew.py b/pypy/doc/test/test_whatsnew.py --- a/pypy/doc/test/test_whatsnew.py +++ b/pypy/doc/test/test_whatsnew.py @@ -101,6 +101,8 @@ assert not not_documented if branch == 'default': assert not not_merged + else: + assert branch in documented, 'Please document this branch before merging: %s' % branch def test_startrev_on_default(): doc = ROOT.join('pypy', 'doc') diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -2,7 +2,69 @@ What's new in PyPy2.7 5.8+ ========================== -.. this is a revision shortly after release-pypy2.7-v5.7 +.. this is a revision shortly after release-pypy2.7-v5.7.0 .. startrev: 44f31f6dd39f +Add cpyext interfaces for ``PyModule_New`` +Correctly handle `dict.pop`` where the ``pop`` +key is not the same type as the ``dict``'s and ``pop`` +is called with a default (will be part of release 5.7.1) + +.. branch: issue2522 + +Fix missing tp_new on w_object called through multiple inheritance +(will be part of release 5.7.1) + +.. branch: lstrip_to_empty_string + +.. branch: vmprof-native + +PyPy support to profile native frames in vmprof. + +.. branch: reusing-r11 +.. branch: branch-prediction + +Performance tweaks in the x86 JIT-generated machine code: rarely taken +blocks are moved off-line. Also, the temporary register used to contain +large constants is reused across instructions. + +.. branch: vmprof-0.4.4 + +.. branch: controller-refactor + +Refactor rpython.rtyper.controllerentry. + +.. branch: PyBuffer-backport + +Internal refactoring of buffers and memoryviews. Memoryviews will now be +accepted in a few more places, e.g. in compile(). + +.. branch: sthalik/fix-signed-integer-sizes-1494493539409 + +.. branch: cpyext-obj-stealing + +Redo much of the refcount semantics in PyList_{SG}etItem to closer match +CPython and ensure the same PyObject stored in the list can be later +retrieved + +.. branch: cpyext-recursionlimit + +Implement Py_EnterRecursiveCall and associated functions + +.. branch: pypy_ctypes_nosegfault_nofastpath + +Remove faulty fastpath from ctypes + +.. branch: sockopt_zero + +Passing a buffersize of 0 to socket.getsockopt + +.. branch: better-test-whatsnew + +.. branch: faster-rstruct-2 + +Improve the performance of struct.pack and struct.pack_into by using raw_store +or gc_store_indexed whenever possible. Moreover, enable the existing +struct.unpack fast path to all the existing buffer types, whereas previously +it was enabled only for strings diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst --- a/pypy/doc/windows.rst +++ b/pypy/doc/windows.rst @@ -11,7 +11,7 @@ To build pypy-c you need a working python environment, and a C compiler. It is possible to translate with a CPython 2.6 or later, but this is not -the preferred way, because it will take a lot longer to run – depending +the preferred way, because it will take a lot longer to run � depending on your architecture, between two and three times as long. So head to `our downloads`_ and get the latest stable version. @@ -23,11 +23,11 @@ Installing Visual Compiler v9 (for Python 2.7) ---------------------------------------------- -This compiler, while the standard one for Python 2.7, is depricated. Microsoft has +This compiler, while the standard one for Python 2.7, is deprecated. Microsoft has made it available as the `Microsoft Visual C++ Compiler for Python 2.7`_ (the link was checked in Nov 2016). Note that the compiler suite will be installed in ``C:\Users\<user name>\AppData\Local\Programs\Common\Microsoft\Visual C++ for Python``. -Using a current version of ``setuptools`` will be able to find it there. For +A current version of ``setuptools`` will be able to find it there. For Windows 10, you must right-click the download, and under ``Properties`` -> ``Compatibility`` mark it as ``Run run this program in comatibility mode for`` ``Previous version...``. Also, you must download and install the ``.Net Framework 3.5``, @@ -40,8 +40,9 @@ Translating PyPy with Visual Studio ----------------------------------- -We routinely test translation using Visual Studio 2008, Express -Edition. Other configurations may work as well. +We routinely test translation using v9, also known as Visual Studio 2008. +Our buildbot is still using the Express Edition, not the compiler noted above. +Other configurations may work as well. The translation scripts will set up the appropriate environment variables for the compiler, so you do not need to run vcvars before translation. @@ -117,6 +118,9 @@ ----------------------------------------------------------- Download the versions of all the external packages from +https://bitbucket.org/pypy/pypy/downloads/local_5.8.zip +(for post-5.7.1 builds) with sha256 checksum +``fbe769bf3a4ab6f5a8b0a05b61930fc7f37da2a9a85a8f609cf5a9bad06e2554`` or https://bitbucket.org/pypy/pypy/downloads/local_2.4.zip (for 2.4 release and later) or https://bitbucket.org/pypy/pypy/downloads/local.zip @@ -124,9 +128,9 @@ Then expand it into the base directory (base_dir) and modify your environment to reflect this:: - set PATH=<base_dir>\bin;<base_dir>\tcltk\bin;%PATH% - set INCLUDE=<base_dir>\include;<base_dir>\tcltk\include;%INCLUDE% - set LIB=<base_dir>\lib;<base_dir>\tcltk\lib;%LIB% + set PATH=<base_dir>\bin;%PATH% + set INCLUDE=<base_dir>\include;%INCLUDE% + set LIB=<base_dir>\lib;%LIB% Now you should be good to go. If you choose this method, you do not need to download/build anything else. @@ -173,13 +177,14 @@ The zlib compression library ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Download http://www.gzip.org/zlib/zlib-1.2.3.tar.gz and extract it in -the base directory. Then compile as a static library:: +Download http://www.gzip.org/zlib/zlib-1.2.11.tar.gz and extract it in +the base directory. Then compile:: - cd zlib-1.2.3 + cd zlib-1.2.11 nmake -f win32\Makefile.msc copy zlib.lib <somewhere in LIB> copy zlib.h zconf.h <somewhere in INCLUDE> + copy zlib1.dll <in PATH> # (needed for tests via ll2ctypes) The bz2 compression library @@ -198,22 +203,23 @@ PyPy uses cffi to interact with sqlite3.dll. Only the dll is needed, the cffi wrapper is compiled when the module is imported for the first time. -The sqlite3.dll should be version 3.6.21 for CPython2.7 compatablility. +The sqlite3.dll should be version 3.8.11 for CPython2.7 compatablility. The expat XML parser ~~~~~~~~~~~~~~~~~~~~ Download the source code of expat on sourceforge: -http://sourceforge.net/projects/expat/ and extract it in the base directory. -Version 2.1.0 is known to pass tests. Then open the project file ``expat.dsw`` +https://github.com/libexpat/libexpat/releases and extract it in the base directory. +Version 2.1.1 is known to pass tests. Then open the project file ``expat.dsw`` with Visual Studio; follow the instruction for converting the project files, switch to the "Release" configuration, use the ``expat_static`` project, -reconfigure the runtime for Multi-threaded DLL (/MD) and build. +reconfigure the runtime for Multi-threaded DLL (/MD) and build. Do the same for +the ``expat`` project to build the ``expat.dll`` (for tests via ll2ctypes) -Then, copy the file ``win32\bin\release\libexpat.lib`` somewhere in somewhere -in LIB, and both ``lib\expat.h`` and ``lib\expat_external.h`` somewhere in -INCLUDE. +Then, copy the file ``win32\bin\release\libexpat.lib`` into +LIB, and both ``lib\expat.h`` and ``lib\expat_external.h`` in +INCLUDE, and ``win32\bin\release\libexpat.dll`` into PATH. The OpenSSL library @@ -222,16 +228,17 @@ OpenSSL needs a Perl interpreter to configure its makefile. You may use the one distributed by ActiveState, or the one from cygwin.:: - svn export http://svn.python.org/projects/external/openssl-1.0.1i - cd openssl-1.0.1i + svn export http://svn.python.org/projects/external/openssl-1.0.2k + cd openssl-1.0.2k perl Configure VC-WIN32 no-idea no-mdc2 ms\do_ms.bat nmake -f ms\nt.mak install + copy out32\*.lib <somewhere in LIB> + xcopy /S include\openssl <somewhere in INCLUDE> -Then, copy the files ``out32\*.lib`` somewhere in -somewhere in LIB, and the entire ``include\openssl`` directory as-is somewhere -in INCLUDE. - +For tests you will also need the dlls:: + nmake -f ms\ntdll.mak install + copy out32dll\*.dll <somewhere in PATH> TkInter module support ~~~~~~~~~~~~~~~~~~~~~~ @@ -241,18 +248,17 @@ directory found for the release script, create the dlls, libs, headers and runtime by running:: - svn export http://svn.python.org/projects/external/tcl-8.5.2.1 tcl85 - svn export http://svn.python.org/projects/external/tk-8.5.2.0 tk85 - cd tcl85\win - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=0 INSTALLDIR=..\..\tcltk clean all - nmake -f makefile.vc DEBUG=0 INSTALLDIR=..\..\tcltk install - cd ..\..\tk85\win - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl85 clean all - nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl85 install - -Now you should have a tcktk\bin, tcltk\lib, and tcltk\include directory ready -for use. The release packaging script will pick up the tcltk runtime in the lib -directory and put it in the archive. + svn export http://svn.python.org/projects/external/tcl-8.5.2.1 tcl85 + svn export http://svn.python.org/projects/external/tk-8.5.2.0 tk85 + cd tcl85\win + nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 DEBUG=0 INSTALLDIR=..\..\tcltk clean all + nmake -f makefile.vc DEBUG=0 INSTALLDIR=..\..\tcltk install + cd ..\..\tk85\win + nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl85 clean all + nmake -f makefile.vc COMPILERFLAGS=-DWINVER=0x0500 OPTS=noxp DEBUG=1 INSTALLDIR=..\..\tcltk TCLDIR=..\..\tcl85 install + copy ..\..\tcltk\bin\* <somewhere in PATH> + copy ..\..\tcltk\lib\*.lib <somewhere in LIB> + xcopy /S ..\..\tcltk\include <somewhere in INCLUDE> The lzma compression library ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -263,6 +269,9 @@ http://tukaani.org/xz/xz-5.0.5-windows.zip, check the signature http://tukaani.org/xz/xz-5.0.5-windows.zip.sig +Then copy the headers to the include directory, rename ``liblzma.a`` to +``lzma.lib`` and copy it to the lib directory + Using the mingw compiler ------------------------ @@ -334,9 +343,9 @@ integer. The simplest fix is to make sure that it is so, but it will give the following incompatibility between CPython and PyPy on Win64: -CPython: ``sys.maxint == 2**32-1, sys.maxsize == 2**64-1`` +CPython: ``sys.maxint == 2**31-1, sys.maxsize == 2**63-1`` -PyPy: ``sys.maxint == sys.maxsize == 2**64-1`` +PyPy: ``sys.maxint == sys.maxsize == 2**63-1`` ...and, correspondingly, PyPy supports ints up to the larger value of sys.maxint before they are converted to ``long``. The first decision diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -264,11 +264,14 @@ raise Exception("Cannot use the --output option with PyPy " "when --shared is on (it is by default). " "See issue #1971.") - if (config.translation.profopt is not None - and not config.translation.noprofopt): - raise Exception("Cannot use the --profopt option " - "when --shared is on (it is by default). " - "See issue #2398.") + + # if both profopt and profoptpath are specified then we keep them as they are with no other changes + if config.translation.profopt: + if config.translation.profoptargs is None: + config.translation.profoptargs = "$(RPYDIR)/../lib-python/2.7/test/regrtest.py --pgo -x test_asyncore test_gdb test_multiprocessing test_subprocess || true" + elif config.translation.profoptargs is not None: + raise Exception("Cannot use --profoptargs without specifying --profopt as well") + if sys.platform == 'win32': libdir = thisdir.join('..', '..', 'libs') libdir.ensure(dir=1) @@ -307,6 +310,9 @@ config.translation.jit = True if config.translation.sandbox: + assert 0, ("--sandbox is not tested nor maintained. If you " + "really want to try it anyway, remove this line in " + "pypy/goal/targetpypystandalone.py.") config.objspace.lonepycfiles = False if config.objspace.usemodules.cpyext: diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -818,6 +818,11 @@ executable = sys.pypy_find_executable(executable) stdlib_path = sys.pypy_find_stdlib(executable) if stdlib_path is None: + for lib_path in sys.path: + stdlib_path = sys.pypy_find_stdlib(lib_path) + if stdlib_path is not None: + break + if stdlib_path is None: print >> sys.stderr, STDLIB_WARNING else: sys.path[:] = stdlib_path diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py --- a/pypy/interpreter/astcompiler/assemble.py +++ b/pypy/interpreter/astcompiler/assemble.py @@ -7,6 +7,7 @@ from pypy.interpreter.astcompiler import ast, misc, symtable from pypy.interpreter.error import OperationError from pypy.interpreter.pycode import PyCode +from pypy.interpreter.miscutils import string_sort from pypy.tool import stdlib_opcode as ops @@ -138,9 +139,12 @@ def _make_index_dict_filter(syms, flag): + names = syms.keys() + string_sort(names) # return cell vars in alphabetical order i = 0 result = {} - for name, scope in syms.iteritems(): + for name in names: + scope = syms[name] if scope == flag: result[name] = i i += 1 @@ -170,6 +174,7 @@ self.var_names = _list_to_dict(scope.varnames) self.cell_vars = _make_index_dict_filter(scope.symbols, symtable.SCOPE_CELL) + string_sort(scope.free_vars) # return free vars in alphabetical order self.free_vars = _list_to_dict(scope.free_vars, len(self.cell_vars)) self.w_consts = space.newdict() self.argcount = 0 diff --git a/pypy/interpreter/astcompiler/symtable.py b/pypy/interpreter/astcompiler/symtable.py --- a/pypy/interpreter/astcompiler/symtable.py +++ b/pypy/interpreter/astcompiler/symtable.py @@ -36,7 +36,7 @@ self.roles = {} self.varnames = [] self.children = [] - self.free_vars = [] + self.free_vars = [] # a bag of names: the order doesn't matter here self.temp_name_counter = 1 self.has_exec = False self.has_free = False diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -9,7 +9,9 @@ from rpython.rlib.signature import signature from rpython.rlib.rarithmetic import r_uint, SHRT_MIN, SHRT_MAX, \ INT_MIN, INT_MAX, UINT_MAX, USHRT_MAX +from rpython.rlib.buffer import StringBuffer +from pypy.interpreter.buffer import BufferInterfaceNotFound from pypy.interpreter.executioncontext import (ExecutionContext, ActionFlag, make_finalizer_queue) from pypy.interpreter.error import OperationError, new_exception_class, oefmt @@ -221,7 +223,8 @@ if w_impl is not None: w_result = space.get_and_call_function(w_impl, self, space.newint(flags)) - if space.isinstance_w(w_result, space.w_buffer): + if (space.isinstance_w(w_result, space.w_buffer) or + space.isinstance_w(w_result, space.w_memoryview)): return w_result.buffer_w(space, flags) raise BufferInterfaceNotFound @@ -233,7 +236,8 @@ if w_impl is not None: w_result = space.get_and_call_function(w_impl, self, space.newint(space.BUF_FULL_RO)) - if space.isinstance_w(w_result, space.w_buffer): + if (space.isinstance_w(w_result, space.w_buffer) or + space.isinstance_w(w_result, space.w_memoryview)): return w_result.readbuf_w(space) raise BufferInterfaceNotFound @@ -245,7 +249,8 @@ if w_impl is not None: w_result = space.get_and_call_function(w_impl, self, space.newint(space.BUF_FULL)) - if space.isinstance_w(w_result, space.w_buffer): + if (space.isinstance_w(w_result, space.w_buffer) or + space.isinstance_w(w_result, space.w_memoryview)): return w_result.writebuf_w(space) raise BufferInterfaceNotFound @@ -254,7 +259,8 @@ if w_impl is not None: w_result = space.get_and_call_function(w_impl, self, space.newint(space.BUF_FULL_RO)) - if space.isinstance_w(w_result, space.w_buffer): + if (space.isinstance_w(w_result, space.w_buffer) or + space.isinstance_w(w_result, space.w_memoryview)): return w_result.charbuf_w(space) raise BufferInterfaceNotFound @@ -392,9 +398,6 @@ class DescrMismatch(Exception): pass -class BufferInterfaceNotFound(Exception): - pass - @specialize.memo() def wrappable_class_name(Class): try: @@ -1501,18 +1504,28 @@ def readbuf_w(self, w_obj): # Old buffer interface, returns a readonly buffer (PyObject_AsReadBuffer) try: + return w_obj.buffer_w(self, self.BUF_SIMPLE).as_readbuf() + except OperationError: + self._getarg_error("convertible to a buffer", w_obj) + except BufferInterfaceNotFound: + pass + try: return w_obj.readbuf_w(self) except BufferInterfaceNotFound: - raise oefmt(self.w_TypeError, - "expected a readable buffer object") + self._getarg_error("convertible to a buffer", w_obj) def writebuf_w(self, w_obj): # Old buffer interface, returns a writeable buffer (PyObject_AsWriteBuffer) try: + return w_obj.buffer_w(self, self.BUF_WRITABLE).as_writebuf() + except OperationError: + self._getarg_error("read-write buffer", w_obj) + except BufferInterfaceNotFound: + pass + try: return w_obj.writebuf_w(self) except BufferInterfaceNotFound: - raise oefmt(self.w_TypeError, - "expected a writeable buffer object") + self._getarg_error("read-write buffer", w_obj) def charbuf_w(self, w_obj): # Old buffer interface, returns a character buffer (PyObject_AsCharBuffer) @@ -1541,12 +1554,10 @@ if self.isinstance_w(w_obj, self.w_unicode): return self.str(w_obj).readbuf_w(self) try: - return w_obj.buffer_w(self, 0) - except BufferInterfaceNotFound: - pass - try: - return w_obj.readbuf_w(self) - except BufferInterfaceNotFound: + return self.readbuf_w(w_obj) + except OperationError as e: + if not e.match(self, self.w_TypeError): + raise self._getarg_error("string or buffer", w_obj) elif code == 's#': if self.isinstance_w(w_obj, self.w_bytes): @@ -1558,16 +1569,7 @@ except BufferInterfaceNotFound: self._getarg_error("string or read-only buffer", w_obj) elif code == 'w*': - try: - return w_obj.buffer_w(self, self.BUF_WRITABLE) - except OperationError: - self._getarg_error("read-write buffer", w_obj) - except BufferInterfaceNotFound: - pass - try: - return w_obj.writebuf_w(self) - except BufferInterfaceNotFound: - self._getarg_error("read-write buffer", w_obj) + return self.writebuf_w(w_obj) elif code == 't#': try: return w_obj.charbuf_w(self) @@ -1654,6 +1656,23 @@ def fsencode_or_none_w(self, w_obj): return None if self.is_none(w_obj) else self.fsencode_w(w_obj) + def byte_w(self, w_obj): + """ + Convert an index-like object to an interp-level char + + Used for app-level code like "bytearray(b'abc')[0] = 42". + """ + if self.isinstance_w(w_obj, self.w_bytes): + string = self.bytes_w(w_obj) + if len(string) != 1: + raise oefmt(self.w_ValueError, "string must be of size 1") + return string[0] + value = self.getindex_w(w_obj, None) + if not 0 <= value < 256: + # this includes the OverflowError in case the long is too large + raise oefmt(self.w_ValueError, "byte must be in range(0, 256)") + return chr(value) + def int_w(self, w_obj, allow_conversion=True): """ Unwrap an app-level int object into an interpret-level int. diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py new file mode 100644 --- /dev/null +++ b/pypy/interpreter/buffer.py @@ -0,0 +1,295 @@ +from rpython.rlib.buffer import StringBuffer, SubBuffer + +from pypy.interpreter.error import oefmt + +class BufferInterfaceNotFound(Exception): + pass + + +class BufferView(object): + """Abstract base class for buffers.""" + _attrs_ = ['readonly'] + _immutable_ = True + + def getlength(self): + """Returns the size in bytes (even if getitemsize() > 1).""" + raise NotImplementedError + + def as_str(self): + "Returns an interp-level string with the whole content of the buffer." + return ''.join(self._copy_buffer()) + + def getbytes(self, start, size): + """Return `size` bytes starting at byte offset `start`. + + This is a low-level operation, it is up to the caller to ensure that + the data requested actually correspond to items accessible from the + BufferView. + Note that `start` may be negative, e.g. if the buffer is reversed. + """ + raise NotImplementedError + + def setbytes(self, start, string): + raise NotImplementedError + + def get_raw_address(self): + raise ValueError("no raw buffer") + + def as_readbuf(self): + # Inefficient. May be overridden. + return StringBuffer(self.as_str()) + + def as_writebuf(self): + """Return a writable Buffer sharing the same data as `self`.""" + raise BufferInterfaceNotFound + + def getformat(self): + raise NotImplementedError + + def getitemsize(self): + raise NotImplementedError + + def getndim(self): + raise NotImplementedError + + def getshape(self): + raise NotImplementedError + + def getstrides(self): + raise NotImplementedError + + def releasebuffer(self): + pass + + def value_from_bytes(self, space, s): + from pypy.module.struct.formatiterator import UnpackFormatIterator + buf = StringBuffer(s) + fmtiter = UnpackFormatIterator(space, buf) + fmtiter.interpret(self.getformat()) + return fmtiter.result_w[0] + + def _copy_buffer(self): + if self.getndim() == 0: + itemsize = self.getitemsize() + return [self.getbytes(0, itemsize)] + data = [] + self._copy_rec(0, data, 0) + return data + + def _copy_rec(self, idim, data, off): + shapes = self.getshape() + shape = shapes[idim] + strides = self.getstrides() + + if self.getndim() - 1 == idim: + self._copy_base(data, off) + return + + for i in range(shape): + self._copy_rec(idim + 1, data, off) + off += strides[idim] + + def _copy_base(self, data, off): + shapes = self.getshape() + step = shapes[0] + strides = self.getstrides() + itemsize = self.getitemsize() + bytesize = self.getlength() + copiedbytes = 0 + for i in range(step): + bytes = self.getbytes(off, itemsize) + data.append(bytes) + copiedbytes += len(bytes) + off += strides[0] + # do notcopy data if the sub buffer is out of bounds + if copiedbytes >= bytesize: + break + + def get_offset(self, space, dim, index): + "Convert index at dimension `dim` into a byte offset" + shape = self.getshape() + nitems = shape[dim] + if index < 0: + index += nitems + if index < 0 or index >= nitems: + raise oefmt(space.w_IndexError, + "index out of bounds on dimension %d", dim + 1) + # TODO suboffsets? + strides = self.getstrides() + return strides[dim] * index + + def w_getitem(self, space, idx): + offset = self.get_offset(space, 0, idx) + itemsize = self.getitemsize() + # TODO: this probably isn't very fast + data = self.getbytes(offset, itemsize) + return space.newbytes(data) + + def new_slice(self, start, step, slicelength): + return BufferSlice(self, start, step, slicelength) + + def w_tolist(self, space): + dim = self.getndim() + if dim == 0: + raise NotImplementedError + elif dim == 1: + n = self.getshape()[0] + values_w = [space.ord(self.w_getitem(space, i)) for i in range(n)] + return space.newlist(values_w) + else: + return self._tolist_rec(space, 0, 0) + + def _tolist_rec(self, space, start, idim): + strides = self.getstrides() + shape = self.getshape() + # + dim = idim + 1 + stride = strides[idim] + itemsize = self.getitemsize() + dimshape = shape[idim] + # + if dim >= self.getndim(): + bytecount = (stride * dimshape) + values_w = [ + self.value_from_bytes(space, self.getbytes(pos, itemsize)) + for pos in range(start, start + bytecount, stride)] + return space.newlist(values_w) + + items = [None] * dimshape + for i in range(dimshape): + item = self._tolist_rec(space, start, idim + 1) + items[i] = item + start += stride + + return space.newlist(items) + + def wrap(self, space): + return space.newmemoryview(self) + + +class SimpleView(BufferView): + _attrs_ = ['readonly', 'data'] + _immutable_ = True + + def __init__(self, data): + self.data = data + self.readonly = self.data.readonly + + def getlength(self): + return self.data.getlength() + + def as_str(self): + return self.data.as_str() + + def getbytes(self, start, size): + return self.data[start:start + size] + + def setbytes(self, offset, s): + self.data.setslice(offset, s) + + def get_raw_address(self): + return self.data.get_raw_address() + + def as_readbuf(self): + return self.data + + def as_writebuf(self): + assert not self.data.readonly + return self.data + + def getformat(self): + return 'B' + + def getitemsize(self): + return 1 + + def getndim(self): + return 1 + + def getshape(self): + return [self.getlength()] + + def getstrides(self): + return [1] + + def get_offset(self, space, dim, index): + "Convert index at dimension `dim` into a byte offset" + assert dim == 0 + nitems = self.getlength() + if index < 0: + index += nitems + if index < 0 or index >= nitems: + raise oefmt(space.w_IndexError, + "index out of bounds on dimension %d", dim + 1) + return index + + def w_getitem(self, space, idx): + idx = self.get_offset(space, 0, idx) + ch = self.data[idx] + return space.newbytes(ch) + + def new_slice(self, start, step, slicelength): + if step == 1: + return SimpleView(SubBuffer(self.data, start, slicelength)) + else: + return BufferSlice(self, start, step, slicelength) + + +class BufferSlice(BufferView): + _immutable_ = True + _attrs_ = ['parent', 'readonly', 'shape', 'strides', 'start', 'step'] + + def __init__(self, parent, start, step, length): + self.parent = parent + self.readonly = self.parent.readonly + self.strides = parent.getstrides()[:] + self.start = start + self.step = step + self.strides[0] *= step + self.shape = parent.getshape()[:] + self.shape[0] = length + + def getlength(self): + return self.shape[0] * self.getitemsize() + + def getbytes(self, start, size): + offset = self.start * self.parent.getstrides()[0] + return self.parent.getbytes(offset + start, size) + + def setbytes(self, start, string): + if len(string) == 0: + return # otherwise, adding self.offset might make 'start' + # out of bounds + offset = self.start * self.parent.getstrides()[0] + self.parent.setbytes(offset + start, string) + + def get_raw_address(self): + from rpython.rtyper.lltypesystem import rffi + offset = self.start * self.parent.getstrides()[0] + return rffi.ptradd(self.parent.get_raw_address(), offset) + + def getformat(self): + return self.parent.getformat() + + def getitemsize(self): + return self.parent.getitemsize() + + def getndim(self): + return self.parent.getndim() + + def getshape(self): + return self.shape + + def getstrides(self): + return self.strides + + def parent_index(self, idx): + return self.start + self.step * idx + + def w_getitem(self, space, idx): + return self.parent.w_getitem(space, self.parent_index(idx)) + + def new_slice(self, start, step, slicelength): + real_start = start + self.start + real_step = self.step * step + return BufferSlice(self.parent, real_start, real_step, slicelength) diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -2,6 +2,9 @@ Miscellaneous utilities. """ +from rpython.rlib.listsort import make_timsort_class + + class ThreadLocals: """Pseudo thread-local storage, for 'space.threadlocals'. This is not really thread-local at all; the intention is that the PyPy @@ -53,3 +56,15 @@ def set(self, key, value): self._dict[key] = value return FakeWeakValueDict() + + +_StringBaseTimSort = make_timsort_class() + +class StringSort(_StringBaseTimSort): + def lt(self, a, b): + return a < b + +def string_sort(lst): + """Sort a (resizable) list of strings.""" + sorter = StringSort(lst, len(lst)) + sorter.sort() diff --git a/pypy/interpreter/pyparser/future.py b/pypy/interpreter/pyparser/future.py --- a/pypy/interpreter/pyparser/future.py +++ b/pypy/interpreter/pyparser/future.py @@ -78,6 +78,7 @@ from pypy.interpreter.pyparser import pygram it = TokenIterator(tokens) result = 0 + last_position = (0, 0) # # The only things that can precede a future statement are another # future statement and a doc string (only one). This is a very @@ -92,6 +93,11 @@ it.skip_name("__future__") and it.skip_name("import")): it.skip(pygram.tokens.LPAR) # optionally + # return in 'last_position' any line-column pair that points + # somewhere inside the last __future__ import statement + # (at the start would be fine too, but it's easier to grab a + # random position inside) + last_position = (it.tok[2], it.tok[3]) result |= future_flags.get_compiler_feature(it.next_feature_name()) while it.skip(pygram.tokens.COMMA): result |= future_flags.get_compiler_feature(it.next_feature_name()) @@ -99,5 +105,4 @@ it.skip(pygram.tokens.SEMI) # optionally it.skip_newlines() - position = (it.tok[2], it.tok[3]) - return result, position + return result, last_position diff --git a/pypy/interpreter/pyparser/test/test_future.py b/pypy/interpreter/pyparser/test/test_future.py --- a/pypy/interpreter/pyparser/test/test_future.py +++ b/pypy/interpreter/pyparser/test/test_future.py @@ -2,10 +2,9 @@ from pypy.interpreter.pyparser import future, pytokenizer from pypy.tool import stdlib___future__ as fut -def run(s, expected_last_future=None): +def run(s, expected_last_future=(0, 0)): source_lines = s.splitlines(True) tokens = pytokenizer.generate_tokens(source_lines, 0) - expected_last_future = expected_last_future or tokens[-1][2:4] # flags, last_future_import = future.add_future_flags( future.futureFlags_2_7, tokens) @@ -14,7 +13,7 @@ def test_docstring(): s = '"Docstring\\" "\nfrom __future__ import division\n' - f = run(s) + f = run(s, (2, 24)) assert f == fut.CO_FUTURE_DIVISION def test_comment(): @@ -45,167 +44,167 @@ def test_from(): s = 'from __future__ import division\n' - f = run(s) + f = run(s, (1, 24)) assert f == fut.CO_FUTURE_DIVISION def test_froms(): s = 'from __future__ import division, generators, with_statement\n' - f = run(s) + f = run(s, (1, 24)) assert f == (fut.CO_FUTURE_DIVISION | fut.CO_GENERATOR_ALLOWED | fut.CO_FUTURE_WITH_STATEMENT) def test_from_as(): s = 'from __future__ import division as b\n' - f = run(s) + f = run(s, (1, 24)) assert f == fut.CO_FUTURE_DIVISION def test_froms_as(): s = 'from __future__ import division as b, generators as c\n' - f = run(s) + f = run(s, (1, 24)) assert f == (fut.CO_FUTURE_DIVISION | fut.CO_GENERATOR_ALLOWED) def test_from_paren(): s = 'from __future__ import (division)\n' - f = run(s) + f = run(s, (1, 25)) assert f == fut.CO_FUTURE_DIVISION def test_froms_paren(): s = 'from __future__ import (division, generators)\n' - f = run(s) + f = run(s, (1, 25)) assert f == (fut.CO_FUTURE_DIVISION | fut.CO_GENERATOR_ALLOWED) def test_froms_paren_as(): s = 'from __future__ import (division as b, generators,)\n' - f = run(s) + f = run(s, (1, 25)) assert f == (fut.CO_FUTURE_DIVISION | fut.CO_GENERATOR_ALLOWED) def test_paren_with_newline(): s = 'from __future__ import (division,\nabsolute_import)\n' - f = run(s) + f = run(s, (1, 24)) assert f == (fut.CO_FUTURE_DIVISION | fut.CO_FUTURE_ABSOLUTE_IMPORT) def test_paren_with_newline_2(): s = 'from __future__ import (\ndivision,\nabsolute_import)\n' - f = run(s) + f = run(s, (2, 0)) assert f == (fut.CO_FUTURE_DIVISION | fut.CO_FUTURE_ABSOLUTE_IMPORT) def test_multiline(): s = '"abc" #def\n #ghi\nfrom __future__ import (division as b, generators,)\nfrom __future__ import with_statement\n' - f = run(s) + f = run(s, (4, 23)) assert f == (fut.CO_FUTURE_DIVISION | fut.CO_GENERATOR_ALLOWED | fut.CO_FUTURE_WITH_STATEMENT) def test_windows_style_lineendings(): s = '"abc" #def\r\n #ghi\r\nfrom __future__ import (division as b, generators,)\r\nfrom __future__ import with_statement\r\n' - f = run(s) + f = run(s, (4, 23)) assert f == (fut.CO_FUTURE_DIVISION | fut.CO_GENERATOR_ALLOWED | fut.CO_FUTURE_WITH_STATEMENT) def test_mac_style_lineendings(): s = '"abc" #def\r #ghi\rfrom __future__ import (division as b, generators,)\rfrom __future__ import with_statement\r' - f = run(s) + f = run(s, (4, 23)) assert f == (fut.CO_FUTURE_DIVISION | fut.CO_GENERATOR_ALLOWED | fut.CO_FUTURE_WITH_STATEMENT) def test_semicolon(): s = '"abc" #def\n #ghi\nfrom __future__ import (division as b, generators,); from __future__ import with_statement\n' - f = run(s) + f = run(s, (3, 78)) assert f == (fut.CO_FUTURE_DIVISION | fut.CO_GENERATOR_ALLOWED | fut.CO_FUTURE_WITH_STATEMENT) def test_semicolon_2(): s = 'from __future__ import division; from foo import bar' - f = run(s, expected_last_future=(1, 39)) + f = run(s, expected_last_future=(1, 24)) assert f == fut.CO_FUTURE_DIVISION def test_full_chain(): s = '"abc" #def\n #ghi\nfrom __future__ import (division as b, generators,); from __future__ import with_statement\n' - f = run(s) + f = run(s, (3, 78)) assert f == (fut.CO_FUTURE_DIVISION | fut.CO_GENERATOR_ALLOWED | fut.CO_FUTURE_WITH_STATEMENT) def test_intervening_code(): s = 'from __future__ import (division as b, generators,)\nfrom sys import modules\nfrom __future__ import with_statement\n' - f = run(s, expected_last_future=(2, 5)) + f = run(s, expected_last_future=(1, 25)) assert f == (fut.CO_FUTURE_DIVISION | fut.CO_GENERATOR_ALLOWED) def test_nonexisting(): s = 'from __future__ import non_existing_feature\n' - f = run(s) + f = run(s, (1, 24)) assert f == 0 def test_nonexisting_2(): s = 'from __future__ import non_existing_feature, with_statement\n' - f = run(s) + f = run(s, (1, 24)) assert f == fut.CO_FUTURE_WITH_STATEMENT def test_from_import_abs_import(): s = 'from __future__ import absolute_import\n' - f = run(s) + f = run(s, (1, 24)) assert f == fut.CO_FUTURE_ABSOLUTE_IMPORT def test_raw_doc(): s = 'r"Doc"\nfrom __future__ import with_statement\n' - f = run(s) + f = run(s, (2, 23)) assert f == fut.CO_FUTURE_WITH_STATEMENT def test_unicode_doc(): s = 'u"Doc"\nfrom __future__ import with_statement\n' - f = run(s) + f = run(s, (2, 23)) assert f == fut.CO_FUTURE_WITH_STATEMENT def test_raw_unicode_doc(): s = 'ru"Doc"\nfrom __future__ import with_statement\n' - f = run(s) + f = run(s, (2, 23)) assert f == fut.CO_FUTURE_WITH_STATEMENT def test_continuation_line(): s = "\\\nfrom __future__ import with_statement\n" - f = run(s) + f = run(s, (2, 23)) assert f == fut.CO_FUTURE_WITH_STATEMENT def test_continuation_lines(): s = "\\\n \t\\\nfrom __future__ import with_statement\n" - f = run(s) + f = run(s, (3, 23)) assert f == fut.CO_FUTURE_WITH_STATEMENT def test_lots_of_continuation_lines(): s = "\\\n\\\n\\\n\\\n\\\n\\\n\nfrom __future__ import with_statement\n" - f = run(s) + f = run(s, (8, 23)) assert f == fut.CO_FUTURE_WITH_STATEMENT def test_continuation_lines_raise(): s = " \\\n \t\\\nfrom __future__ import with_statement\n" - f = run(s, expected_last_future=(1, 0)) + f = run(s) assert f == 0 # because of the INDENT def test_continuation_lines_in_docstring_single_quoted(): s = '"\\\n\\\n\\\n\\\n\\\n\\\n"\nfrom __future__ import division\n' - f = run(s) + f = run(s, (8, 24)) assert f == fut.CO_FUTURE_DIVISION def test_continuation_lines_in_docstring_triple_quoted(): s = '"""\\\n\\\n\\\n\\\n\\\n\\\n"""\nfrom __future__ import division\n' - f = run(s) + f = run(s, (8, 24)) assert f == fut.CO_FUTURE_DIVISION def test_blank_lines(): s = ('\n\t\n\nfrom __future__ import with_statement' ' \n \n \nfrom __future__ import division') - f = run(s) + f = run(s, (7, 23)) assert f == fut.CO_FUTURE_WITH_STATEMENT | fut.CO_FUTURE_DIVISION def test_dummy_semicolons(): s = ('from __future__ import division;\n' 'from __future__ import with_statement;') - f = run(s) + f = run(s, (2, 23)) assert f == fut.CO_FUTURE_DIVISION | fut.CO_FUTURE_WITH_STATEMENT diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py --- a/pypy/interpreter/test/test_compiler.py +++ b/pypy/interpreter/test/test_compiler.py @@ -787,6 +787,32 @@ else: assert l1 == l2 == l3 == l4 == [1, 3, 2, 4] + def test_freevars_order(self): + # co_cellvars and co_freevars are guaranteed to appear in + # alphabetical order. See CPython Issue #15368 (which does + # not come with tests). + source = """if 1: + def f1(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15): + def g1(): + return (x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15) + return g1 + def f2(x15,x14,x13,x12,x11,x10,x9,x8,x7,x6,x5,x4,x3,x2,x1): + def g2(): + return (x15,x14,x13,x12,x11,x10,x9,x8,x7,x6,x5,x4,x3,x2,x1) + return g2 + c1 = f1(*range(15)).__code__.co_freevars + c2 = f2(*range(15)).__code__.co_freevars + r1 = f1.__code__.co_cellvars + r2 = f2.__code__.co_cellvars + """ + d = {} + exec(source, d) + assert d['c1'] == d['c2'] + # the test above is important for a few bytecode hacks, + # but actually we get them in alphabetical order, so check that: + assert d['c1'] == tuple(sorted(d['c1'])) + assert d['r1'] == d['r2'] == d['c1'] + ##class TestPythonAstCompiler(BaseTestCompiler): ## def setup_method(self, method): diff --git a/pypy/interpreter/test/test_syntax.py b/pypy/interpreter/test/test_syntax.py --- a/pypy/interpreter/test/test_syntax.py +++ b/pypy/interpreter/test/test_syntax.py @@ -366,6 +366,15 @@ assert isinstance(ns["b"], str) assert isinstance(ns["c"], str) + def test_both_futures_with_semicolon(self): + # Issue #2526: a corner case which crashes only if the file + # contains *nothing more* than two __future__ imports separated + # by a semicolon. + s = """ +from __future__ import unicode_literals; from __future__ import print_function +""" + exec s in {} + class AppTestComprehensions: diff --git a/pypy/module/__builtin__/app_functional.py b/pypy/module/__builtin__/app_functional.py --- a/pypy/module/__builtin__/app_functional.py +++ b/pypy/module/__builtin__/app_functional.py @@ -2,7 +2,6 @@ Plain Python definition of the builtin functions oriented towards functional programming. """ -from __future__ import with_statement import operator from __pypy__ import resizelist_hint, newlist_hint from __pypy__ import specialized_zip_2_lists diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -38,6 +38,8 @@ "compile() arg 3 must be 'exec', 'eval' or 'single'") if space.isinstance_w(w_source, space.gettypeobject(ast.W_AST.typedef)): + if flags & consts.PyCF_ONLY_AST: + return w_source ast_node = ast.mod.from_object(space, w_source) return ec.compiler.compile_ast(ast_node, filename, mode, flags) diff --git a/pypy/module/__builtin__/test/test_compile.py b/pypy/module/__builtin__/test/test_compile.py --- a/pypy/module/__builtin__/test/test_compile.py _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit