FAQ

[pypy-commit] pypy arm-backend-2: merge default

Bivab
Feb 15, 2012 at 5:35 pm
Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r52517:72c916028806
Date: 2012-02-15 10:01 +0100
http://bitbucket.org/pypy/pypy/changeset/72c916028806/

Log: merge default

diff --git a/ctypes_configure/cbuild.py b/ctypes_configure/cbuild.py
--- a/ctypes_configure/cbuild.py
+++ b/ctypes_configure/cbuild.py
@@ -206,8 +206,9 @@
cfiles += eci.separate_module_files
include_dirs = list(eci.include_dirs)
library_dirs = list(eci.library_dirs)
- if sys.platform == 'darwin': # support Fink & Darwinports
- for s in ('/sw/', '/opt/local/'):
+ if (sys.platform == 'darwin' or # support Fink & Darwinports
+ sys.platform.startswith('freebsd')):
+ for s in ('/sw/', '/opt/local/', '/usr/local/'):
if s + 'include' not in include_dirs and \
os.path.exists(s + 'include'):
include_dirs.append(s + 'include')
@@ -380,9 +381,9 @@
self.link_extra += ['-pthread']
if sys.platform == 'win32':
self.link_extra += ['/DEBUG'] # generate .pdb file
- if sys.platform == 'darwin':
- # support Fink & Darwinports
- for s in ('/sw/', '/opt/local/'):
+ if (sys.platform == 'darwin' or # support Fink & Darwinports
+ sys.platform.startswith('freebsd')):
+ for s in ('/sw/', '/opt/local/', '/usr/local/'):
if s + 'include' not in self.include_dirs and \
os.path.exists(s + 'include'):
self.include_dirs.append(s + 'include')
@@ -395,7 +396,6 @@
self.outputfilename = py.path.local(cfilenames[0]).new(ext=ext)
else:
self.outputfilename = py.path.local(outputfilename)
- self.eci = eci

def build(self, noerrúlse):
basename = self.outputfilename.new(ext='')
@@ -436,7 +436,7 @@
old = cfile.dirpath().chdir()
try:
res = compiler.compile([cfile.basename],
- include_dirs=self.eci.include_dirs,
+ include_dirs=self.include_dirs,
extra_preargs=self.compile_extra)
assert len(res) == 1
cobjfile = py.path.local(res[0])
@@ -445,9 +445,9 @@
finally:
old.chdir()
compiler.link_executable(objects, str(self.outputfilename),
- libraries=self.eci.libraries,
+ libraries=self.libraries,
extra_preargs=self.link_extra,
- library_dirs=self.eci.library_dirs)
+ library_dirs=self.library_dirs)

def build_executable(*args, **kwds):
noerr = kwds.pop('noerr', False)
diff --git a/lib-python/modified-2.7/UserDict.py b/lib-python/modified-2.7/UserDict.py
--- a/lib-python/modified-2.7/UserDict.py
+++ b/lib-python/modified-2.7/UserDict.py
@@ -85,8 +85,12 @@
def __iter__(self):
return iter(self.data)

-import _abcoll
-_abcoll.MutableMapping.register(IterableUserDict)
+try:
+ import _abcoll
+except ImportError:
+ pass # e.g. no '_weakref' module on this pypy
+else:
+ _abcoll.MutableMapping.register(IterableUserDict)


class DictMixin:
diff --git a/lib_pypy/_subprocess.py b/lib_pypy/_subprocess.py
--- a/lib_pypy/_subprocess.py
+++ b/lib_pypy/_subprocess.py
@@ -87,7 +87,7 @@

# Now the _subprocess module implementation

-from ctypes import c_int as _c_int, byref as _byref
+from ctypes import c_int as _c_int, byref as _byref, WinError as _WinError

class _handle:
def __init__(self, handle):
@@ -116,7 +116,7 @@
res = _CreatePipe(_byref(read), _byref(write), None, size)

if not res:
- raise WindowsError("Error")
+ raise _WinError()

return _handle(read.value), _handle(write.value)

@@ -132,7 +132,7 @@
access, inherit, options)

if not res:
- raise WindowsError("Error")
+ raise _WinError()

return _handle(target.value)
DUPLICATE_SAME_ACCESS = 2
@@ -165,7 +165,7 @@
start_dir, _byref(si), _byref(pi))

if not res:
- raise WindowsError("Error")
+ raise _WinError()

return _handle(pi.hProcess), _handle(pi.hThread), pi.dwProcessID, pi.dwThreadID
STARTF_USESHOWWINDOW = 0x001
@@ -178,7 +178,7 @@
res = _WaitForSingleObject(int(handle), milliseconds)

if res < 0:
- raise WindowsError("Error")
+ raise _WinError()

return res
INFINITE = 0xffffffff
@@ -190,7 +190,7 @@
res = _GetExitCodeProcess(int(handle), _byref(code))

if not res:
- raise WindowsError("Error")
+ raise _WinError()

return code.value

@@ -198,7 +198,7 @@
res = _TerminateProcess(int(handle), exitcode)

if not res:
- raise WindowsError("Error")
+ raise _WinError()

def GetStdHandle(stdhandle):
res = _GetStdHandle(stdhandle)
diff --git a/lib_pypy/ctypes_config_cache/pyexpat.ctc.py b/lib_pypy/ctypes_config_cache/pyexpat.ctc.py
deleted file mode 100644
--- a/lib_pypy/ctypes_config_cache/pyexpat.ctc.py
+++ /dev/null
@@ -1,45 +0,0 @@
-"""
-'ctypes_configure' source for pyexpat.py.
-Run this to rebuild _pyexpat_cache.py.
-"""
-
-import ctypes
-from ctypes import c_char_p, c_int, c_void_p, c_char
-from ctypes_configure import configure
-import dumpcache
-
-
-class CConfigure:
- _compilation_info_ = configure.ExternalCompilationInfo(
- includes = ['expat.h'],
- libraries = ['expat'],
- pre_include_lines = [
- '#define XML_COMBINED_VERSION (10000*XML_MAJOR_VERSION+100*XML_MINOR_VERSION+XML_MICRO_VERSION)'],
- )
-
- XML_Char = configure.SimpleType('XML_Char', c_char)
- XML_COMBINED_VERSION = configure.ConstantInteger('XML_COMBINED_VERSION')
- for name in ['XML_PARAM_ENTITY_PARSING_NEVER',
- 'XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE',
- 'XML_PARAM_ENTITY_PARSING_ALWAYS']:
- locals()[name] = configure.ConstantInteger(name)
-
- XML_Encoding = configure.Struct('XML_Encoding',[
- ('data', c_void_p),
- ('convert', c_void_p),
- ('release', c_void_p),
- ('map', c_int * 256)])
- XML_Content = configure.Struct('XML_Content',[
- ('numchildren', c_int),
- ('children', c_void_p),
- ('name', c_char_p),
- ('type', c_int),
- ('quant', c_int),
- ])
- # this is insanely stupid
- XML_FALSE = configure.ConstantInteger('XML_FALSE')
- XML_TRUE = configure.ConstantInteger('XML_TRUE')
-
-config = configure.configure(CConfigure)
-
-dumpcache.dumpcache2('pyexpat', config)
diff --git a/lib_pypy/ctypes_config_cache/test/test_cache.py b/lib_pypy/ctypes_config_cache/test/test_cache.py
--- a/lib_pypy/ctypes_config_cache/test/test_cache.py
+++ b/lib_pypy/ctypes_config_cache/test/test_cache.py
@@ -39,10 +39,6 @@
d = run('resource.ctc.py', '_resource_cache.py')
assert 'RLIM_NLIMITS' in d

-def test_pyexpat():
- d = run('pyexpat.ctc.py', '_pyexpat_cache.py')
- assert 'XML_COMBINED_VERSION' in d
-
def test_locale():
d = run('locale.ctc.py', '_locale_cache.py')
assert 'LC_ALL' in d
diff --git a/lib_pypy/datetime.py b/lib_pypy/datetime.py
--- a/lib_pypy/datetime.py
+++ b/lib_pypy/datetime.py
@@ -271,8 +271,9 @@
raise ValueError("%s()=%d, must be in -1439..1439" % (name, offset))

def _check_date_fields(year, month, day):
- if not isinstance(year, (int, long)):
- raise TypeError('int expected')
+ for value in [year, day]:
+ if not isinstance(value, (int, long)):
+ raise TypeError('int expected')
if not MINYEAR <= year <= MAXYEAR:
raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year)
if not 1 <= month <= 12:
@@ -282,8 +283,9 @@
raise ValueError('day must be in 1..%d' % dim, day)

def _check_time_fields(hour, minute, second, microsecond):
- if not isinstance(hour, (int, long)):
- raise TypeError('int expected')
+ for value in [hour, minute, second, microsecond]:
+ if not isinstance(value, (int, long)):
+ raise TypeError('int expected')
if not 0 <= hour <= 23:
raise ValueError('hour must be in 0..23', hour)
if not 0 <= minute <= 59:
@@ -1520,7 +1522,7 @@
def utcfromtimestamp(cls, t):
"Construct a UTC datetime from a POSIX timestamp (like time.time())."
t, frac = divmod(t, 1.0)
- us = round(frac * 1e6)
+ us = int(round(frac * 1e6))

# If timestamp is less than one microsecond smaller than a
# full second, us can be rounded up to 1000000. In this case,
diff --git a/lib_pypy/pyexpat.py b/lib_pypy/pyexpat.py
deleted file mode 100644
--- a/lib_pypy/pyexpat.py
+++ /dev/null
@@ -1,448 +0,0 @@
-
-import ctypes
-import ctypes.util
-from ctypes import c_char_p, c_int, c_void_p, POINTER, c_char, c_wchar_p
-import sys
-
-# load the platform-specific cache made by running pyexpat.ctc.py
-from ctypes_config_cache._pyexpat_cache import *
-
-try: from __pypy__ import builtinify
-except ImportError: builtinify = lambda f: f
-
-
-lib = ctypes.CDLL(ctypes.util.find_library('expat'))
-
-
-XML_Content.children = POINTER(XML_Content)
-XML_Parser = ctypes.c_void_p # an opaque pointer
-assert XML_Char is ctypes.c_char # this assumption is everywhere in
-# cpython's expat, let's explode
-
-def declare_external(name, args, res):
- func = getattr(lib, name)
- func.args = args
- func.restype = res
- globals()[name] = func
-
-declare_external('XML_ParserCreate', [c_char_p], XML_Parser)
-declare_external('XML_ParserCreateNS', [c_char_p, c_char], XML_Parser)
-declare_external('XML_Parse', [XML_Parser, c_char_p, c_int, c_int], c_int)
-currents = ['CurrentLineNumber', 'CurrentColumnNumber',
- 'CurrentByteIndex']
-for name in currents:
- func = getattr(lib, 'XML_Get' + name)
- func.args = [XML_Parser]
- func.restype = c_int
-
-declare_external('XML_SetReturnNSTriplet', [XML_Parser, c_int], None)
-declare_external('XML_GetSpecifiedAttributeCount', [XML_Parser], c_int)
-declare_external('XML_SetParamEntityParsing', [XML_Parser, c_int], None)
-declare_external('XML_GetErrorCode', [XML_Parser], c_int)
-declare_external('XML_StopParser', [XML_Parser, c_int], None)
-declare_external('XML_ErrorString', [c_int], c_char_p)
-declare_external('XML_SetBase', [XML_Parser, c_char_p], None)
-if XML_COMBINED_VERSION >= 19505:
- declare_external('XML_UseForeignDTD', [XML_Parser, c_int], None)
-
-declare_external('XML_SetUnknownEncodingHandler', [XML_Parser, c_void_p,
- c_void_p], None)
-declare_external('XML_FreeContentModel', [XML_Parser, POINTER(XML_Content)],
- None)
-declare_external('XML_ExternalEntityParserCreate', [XML_Parser,c_char_p,
- c_char_p],
- XML_Parser)
-
-handler_names = [
- 'StartElement',
- 'EndElement',
- 'ProcessingInstruction',
- 'CharacterData',
- 'UnparsedEntityDecl',
- 'NotationDecl',
- 'StartNamespaceDecl',
- 'EndNamespaceDecl',
- 'Comment',
- 'StartCdataSection',
- 'EndCdataSection',
- 'Default',
- 'DefaultHandlerExpand',
- 'NotStandalone',
- 'ExternalEntityRef',
- 'StartDoctypeDecl',
- 'EndDoctypeDecl',
- 'EntityDecl',
- 'XmlDecl',
- 'ElementDecl',
- 'AttlistDecl',
- ]
-if XML_COMBINED_VERSION >= 19504:
- handler_names.append('SkippedEntity')
-setters = {}
-
-for name in handler_names:
- if name == 'DefaultHandlerExpand':
- newname = 'XML_SetDefaultHandlerExpand'
- else:
- name += 'Handler'
- newname = 'XML_Set' + name
- cfunc = getattr(lib, newname)
- cfunc.args = [XML_Parser, ctypes.c_void_p]
- cfunc.result = ctypes.c_int
- setters[name] = cfunc
-
-class ExpatError(Exception):
- def __str__(self):
- return self.s
-
-error = ExpatError
-
-class XMLParserType(object):
- specified_attributes = 0
- ordered_attributes = 0
- returns_unicode = 1
- encoding = 'utf-8'
- def __init__(self, encoding, namespace_separator, _hook_external_entityúlse):
- self.returns_unicode = 1
- if encoding:
- self.encoding = encoding
- if not _hook_external_entity:
- if namespace_separator is None:
- self.itself = XML_ParserCreate(encoding)
- else:
- self.itself = XML_ParserCreateNS(encoding, ord(namespace_separator))
- if not self.itself:
- raise RuntimeError("Creating parser failed")
- self._set_unknown_encoding_handler()
- self.storage = {}
- self.buffer = None
- self.buffer_size = 8192
- self.character_data_handler = None
- self.intern = {}
- self.__exc_info = None
-
- def _flush_character_buffer(self):
- if not self.buffer:
- return
- res = self._call_character_handler(''.join(self.buffer))
- self.buffer = []
- return res
-
- def _call_character_handler(self, buf):
- if self.character_data_handler:
- self.character_data_handler(buf)
-
- def _set_unknown_encoding_handler(self):
- def UnknownEncoding(encodingData, name, info_p):
- info = info_p.contents
- s = ''.join([chr(i) for i in range(256)])
- u = s.decode(self.encoding, 'replace')
- for i in range(len(u)):
- if u[i] == u'\xfffd':
- info.map[i] = -1
- else:
- info.map[i] = ord(u[i])
- info.data = None
- info.convert = None
- info.release = None
- return 1
-
- CB = ctypes.CFUNCTYPE(c_int, c_void_p, c_char_p, POINTER(XML_Encoding))
- cb = CB(UnknownEncoding)
- self._unknown_encoding_handler = (cb, UnknownEncoding)
- XML_SetUnknownEncodingHandler(self.itself, cb, None)
-
- def _set_error(self, code):
- e = ExpatError()
- e.code = code
- lineno = lib.XML_GetCurrentLineNumber(self.itself)
- colno = lib.XML_GetCurrentColumnNumber(self.itself)
- e.offset = colno
- e.lineno = lineno
- err = XML_ErrorString(code)[:200]
- e.s = "%s: line: %d, column: %d" % (err, lineno, colno)
- e.message = e.s
- self._error = e
-
- def Parse(self, data, is_final=0):
- res = XML_Parse(self.itself, data, len(data), is_final)
- if res == 0:
- self._set_error(XML_GetErrorCode(self.itself))
- if self.__exc_info:
- exc_info = self.__exc_info
- self.__exc_info = None
- raise exc_info[0], exc_info[1], exc_info[2]
- else:
- raise self._error
- self._flush_character_buffer()
- return res
-
- def _sethandler(self, name, real_cb):
- setter = setters[name]
- try:
- cb = self.storage[(name, real_cb)]
- except KeyError:
- cb = getattr(self, 'get_cb_for_%s' % name)(real_cb)
- self.storage[(name, real_cb)] = cb
- except TypeError:
- # weellll...
- cb = getattr(self, 'get_cb_for_%s' % name)(real_cb)
- setter(self.itself, cb)
-
- def _wrap_cb(self, cb):
- def f(*args):
- try:
- return cb(*args)
- except:
- self.__exc_info = sys.exc_info()
- XML_StopParser(self.itself, XML_FALSE)
- return f
-
- def get_cb_for_StartElementHandler(self, real_cb):
- def StartElement(unused, name, attrs):
- # unpack name and attrs
- conv = self.conv
- self._flush_character_buffer()
- if self.specified_attributes:
- max = XML_GetSpecifiedAttributeCount(self.itself)
- else:
- max = 0
- while attrs[max]:
- max += 2 # copied
- if self.ordered_attributes:
- res = [attrs[i] for i in range(max)]
- else:
- res = {}
- for i in range(0, max, 2):
- res[conv(attrs[i])] = conv(attrs[i + 1])
- real_cb(conv(name), res)
- StartElement = self._wrap_cb(StartElement)
- CB = ctypes.CFUNCTYPE(None, c_void_p, c_char_p, POINTER(c_char_p))
- return CB(StartElement)
-
- def get_cb_for_ExternalEntityRefHandler(self, real_cb):
- def ExternalEntity(unused, context, base, sysId, pubId):
- self._flush_character_buffer()
- conv = self.conv
- res = real_cb(conv(context), conv(base), conv(sysId),
- conv(pubId))
- if res is None:
- return 0
- return res
- ExternalEntity = self._wrap_cb(ExternalEntity)
- CB = ctypes.CFUNCTYPE(c_int, c_void_p, *([c_char_p] * 4))
- return CB(ExternalEntity)
-
- def get_cb_for_CharacterDataHandler(self, real_cb):
- def CharacterData(unused, s, lgt):
- if self.buffer is None:
- self._call_character_handler(self.conv(s[:lgt]))
- else:
- if len(self.buffer) + lgt > self.buffer_size:
- self._flush_character_buffer()
- if self.character_data_handler is None:
- return
- if lgt >= self.buffer_size:
- self._call_character_handler(s[:lgt])
- self.buffer = []
- else:
- self.buffer.append(s[:lgt])
- CharacterData = self._wrap_cb(CharacterData)
- CB = ctypes.CFUNCTYPE(None, c_void_p, POINTER(c_char), c_int)
- return CB(CharacterData)
-
- def get_cb_for_NotStandaloneHandler(self, real_cb):
- def NotStandaloneHandler(unused):
- return real_cb()
- NotStandaloneHandler = self._wrap_cb(NotStandaloneHandler)
- CB = ctypes.CFUNCTYPE(c_int, c_void_p)
- return CB(NotStandaloneHandler)
-
- def get_cb_for_EntityDeclHandler(self, real_cb):
- def EntityDecl(unused, ename, is_param, value, value_len, base,
- system_id, pub_id, not_name):
- self._flush_character_buffer()
- if not value:
- value = None
- else:
- value = value[:value_len]
- args = [ename, is_param, value, base, system_id,
- pub_id, not_name]
- args = [self.conv(arg) for arg in args]
- real_cb(*args)
- EntityDecl = self._wrap_cb(EntityDecl)
- CB = ctypes.CFUNCTYPE(None, c_void_p, c_char_p, c_int, c_char_p,
- c_int, c_char_p, c_char_p, c_char_p, c_char_p)
- return CB(EntityDecl)
-
- def _conv_content_model(self, model):
- children = tuple([self._conv_content_model(model.children[i])
- for i in range(model.numchildren)])
- return (model.type, model.quant, self.conv(model.name),
- children)
-
- def get_cb_for_ElementDeclHandler(self, real_cb):
- def ElementDecl(unused, name, model):
- self._flush_character_buffer()
- modelobj = self._conv_content_model(model[0])
- real_cb(name, modelobj)
- XML_FreeContentModel(self.itself, model)
-
- ElementDecl = self._wrap_cb(ElementDecl)
- CB = ctypes.CFUNCTYPE(None, c_void_p, c_char_p, POINTER(XML_Content))
- return CB(ElementDecl)
-
- def _new_callback_for_string_len(name, sign):
- def get_callback_for_(self, real_cb):
- def func(unused, s, len):
- self._flush_character_buffer()
- arg = self.conv(s[:len])
- real_cb(arg)
- func.func_name = name
- func = self._wrap_cb(func)
- CB = ctypes.CFUNCTYPE(*sign)
- return CB(func)
- get_callback_for_.func_name = 'get_cb_for_' + name
- return get_callback_for_
-
- for name in ['DefaultHandlerExpand',
- 'DefaultHandler']:
- sign = [None, c_void_p, POINTER(c_char), c_int]
- name = 'get_cb_for_' + name
- locals()[name] = _new_callback_for_string_len(name, sign)
-
- def _new_callback_for_starargs(name, sign):
- def get_callback_for_(self, real_cb):
- def func(unused, *args):
- self._flush_character_buffer()
- args = [self.conv(arg) for arg in args]
- real_cb(*args)
- func.func_name = name
- func = self._wrap_cb(func)
- CB = ctypes.CFUNCTYPE(*sign)
- return CB(func)
- get_callback_for_.func_name = 'get_cb_for_' + name
- return get_callback_for_
-
- for name, num_or_sign in [
- ('EndElementHandler', 1),
- ('ProcessingInstructionHandler', 2),
- ('UnparsedEntityDeclHandler', 5),
- ('NotationDeclHandler', 4),
- ('StartNamespaceDeclHandler', 2),
- ('EndNamespaceDeclHandler', 1),
- ('CommentHandler', 1),
- ('StartCdataSectionHandler', 0),
- ('EndCdataSectionHandler', 0),
- ('StartDoctypeDeclHandler', [None, c_void_p] + [c_char_p] * 3 + [c_int]),
- ('XmlDeclHandler', [None, c_void_p, c_char_p, c_char_p, c_int]),
- ('AttlistDeclHandler', [None, c_void_p] + [c_char_p] * 4 + [c_int]),
- ('EndDoctypeDeclHandler', 0),
- ('SkippedEntityHandler', [None, c_void_p, c_char_p, c_int]),
- ]:
- if isinstance(num_or_sign, int):
- sign = [None, c_void_p] + [c_char_p] * num_or_sign
- else:
- sign = num_or_sign
- name = 'get_cb_for_' + name
- locals()[name] = _new_callback_for_starargs(name, sign)
-
- def conv_unicode(self, s):
- if s is None or isinstance(s, int):
- return s
- return s.decode(self.encoding, "strict")
-
- def __setattr__(self, name, value):
- # forest of ifs...
- if name in ['ordered_attributes',
- 'returns_unicode', 'specified_attributes']:
- if value:
- if name == 'returns_unicode':
- self.conv = self.conv_unicode
- self.__dict__[name] = 1
- else:
- if name == 'returns_unicode':
- self.conv = lambda s: s
- self.__dict__[name] = 0
- elif name == 'buffer_text':
- if value:
- self.buffer = []
- else:
- self._flush_character_buffer()
- self.buffer = None
- elif name == 'buffer_size':
- if not isinstance(value, int):
- raise TypeError("Expected int")
- if value <= 0:
- raise ValueError("Expected positive int")
- self.__dict__[name] = value
- elif name == 'namespace_prefixes':
- XML_SetReturnNSTriplet(self.itself, int(bool(value)))
- elif name in setters:
- if name == 'CharacterDataHandler':
- # XXX we need to flush buffer here
- self._flush_character_buffer()
- self.character_data_handler = value
- #print name
- #print value
- #print
- self._sethandler(name, value)
- else:
- self.__dict__[name] = value
-
- def SetParamEntityParsing(self, arg):
- XML_SetParamEntityParsing(self.itself, arg)
-
- if XML_COMBINED_VERSION >= 19505:
- def UseForeignDTD(self, arg=True):
- if arg:
- flag = XML_TRUE
- else:
- flag = XML_FALSE
- XML_UseForeignDTD(self.itself, flag)
-
- def __getattr__(self, name):
- if name == 'buffer_text':
- return self.buffer is not None
- elif name in currents:
- return getattr(lib, 'XML_Get' + name)(self.itself)
- elif name == 'ErrorColumnNumber':
- return lib.XML_GetCurrentColumnNumber(self.itself)
- elif name == 'ErrorLineNumber':
- return lib.XML_GetCurrentLineNumber(self.itself)
- return self.__dict__[name]
-
- def ParseFile(self, file):
- return self.Parse(file.read(), False)
-
- def SetBase(self, base):
- XML_SetBase(self.itself, base)
-
- def ExternalEntityParserCreate(self, context, encoding=None):
- """ExternalEntityParserCreate(context[, encoding])
- Create a parser for parsing an external entity based on the
- information passed to the ExternalEntityRefHandler."""
- new_parser = XMLParserType(encoding, None, True)
- new_parser.itself = XML_ExternalEntityParserCreate(self.itself,
- context, encoding)
- new_parser._set_unknown_encoding_handler()
- return new_parser
-
- at builtinify
-def ErrorString(errno):
- return XML_ErrorString(errno)[:200]
-
- at builtinify
-def ParserCreate(encoding=None, namespace_separator=None, intern=None):
- if (not isinstance(encoding, str) and
- not encoding is None):
- raise TypeError("ParserCreate() argument 1 must be string or None, not %s" % encoding.__class__.__name__)
- if (not isinstance(namespace_separator, str) and
- not namespace_separator is None):
- raise TypeError("ParserCreate() argument 2 must be string or None, not %s" % namespace_separator.__class__.__name__)
- if namespace_separator is not None:
- if len(namespace_separator) > 1:
- raise ValueError('namespace_separator must be at most one character, omitted, or None')
- if len(namespace_separator) == 0:
- namespace_separator = None
- return XMLParserType(encoding, namespace_separator)
diff --git a/lib_pypy/pypy_test/test_pyexpat.py b/lib_pypy/pypy_test/test_pyexpat.py
deleted file mode 100644
--- a/lib_pypy/pypy_test/test_pyexpat.py
+++ /dev/null
@@ -1,665 +0,0 @@
-# XXX TypeErrors on calling handlers, or on bad return values from a
-# handler, are obscure and unhelpful.
-
-from __future__ import absolute_import
-import StringIO, sys
-import unittest, py
-
-from lib_pypy.ctypes_config_cache import rebuild
-rebuild.rebuild_one('pyexpat.ctc.py')
-
-from lib_pypy import pyexpat
-#from xml.parsers import expat
-expat = pyexpat
-
-from test.test_support import sortdict, run_unittest
-
-
-class TestSetAttribute:
- def setup_method(self, meth):
- self.parser = expat.ParserCreate(namespace_separator='!')
- self.set_get_pairs = [
- [0, 0],
- [1, 1],
- [2, 1],
- [0, 0],
- ]
-
- def test_returns_unicode(self):
- for x, y in self.set_get_pairs:
- self.parser.returns_unicode = x
- assert self.parser.returns_unicode == y
-
- def test_ordered_attributes(self):
- for x, y in self.set_get_pairs:
- self.parser.ordered_attributes = x
- assert self.parser.ordered_attributes == y
-
- def test_specified_attributes(self):
- for x, y in self.set_get_pairs:
- self.parser.specified_attributes = x
- assert self.parser.specified_attributes == y
-
-
-data = '''\
-<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
-<?xml-stylesheet href="stylesheet.css"?>
-<!-- comment data -->
-<!DOCTYPE quotations SYSTEM "quotations.dtd" [
-<!ELEMENT root ANY>
-<!ATTLIST root attr1 CDATA #REQUIRED attr2 CDATA #IMPLIED>
-<!NOTATION notation SYSTEM "notation.jpeg">
-<!ENTITY acirc "&#226;">
-<!ENTITY external_entity SYSTEM "entity.file">
-<!ENTITY unparsed_entity SYSTEM "entity.file" NDATA notation>
-%unparsed_entity;
-]>
-
-<root attr1="value1" attr2="value2&#8000;">
-<myns:subelement xmlns:myns="http://www.python.org/namespace">
- Contents of subelements
-</myns:subelement>
-<sub2><![CDATA[contents of CDATA section]]></sub2>
-&external_entity;
-&skipped_entity;
-</root>
-'''
-
-
-# Produce UTF-8 output
-class TestParse:
- class Outputter:
- def __init__(self):
- self.out = []
-
- def StartElementHandler(self, name, attrs):
- self.out.append('Start element: ' + repr(name) + ' ' +
- sortdict(attrs))
-
- def EndElementHandler(self, name):
- self.out.append('End element: ' + repr(name))
-
- def CharacterDataHandler(self, data):
- data = data.strip()
- if data:
- self.out.append('Character data: ' + repr(data))
-
- def ProcessingInstructionHandler(self, target, data):
- self.out.append('PI: ' + repr(target) + ' ' + repr(data))
-
- def StartNamespaceDeclHandler(self, prefix, uri):
- self.out.append('NS decl: ' + repr(prefix) + ' ' + repr(uri))
-
- def EndNamespaceDeclHandler(self, prefix):
- self.out.append('End of NS decl: ' + repr(prefix))
-
- def StartCdataSectionHandler(self):
- self.out.append('Start of CDATA section')
-
- def EndCdataSectionHandler(self):
- self.out.append('End of CDATA section')
-
- def CommentHandler(self, text):
- self.out.append('Comment: ' + repr(text))
-
- def NotationDeclHandler(self, *args):
- name, base, sysid, pubid = args
- self.out.append('Notation declared: %s' %(args,))
-
- def UnparsedEntityDeclHandler(self, *args):
- entityName, base, systemId, publicId, notationName = args
- self.out.append('Unparsed entity decl: %s' %(args,))
-
- def NotStandaloneHandler(self):
- self.out.append('Not standalone')
- return 1
-
- def ExternalEntityRefHandler(self, *args):
- context, base, sysId, pubId = args
- self.out.append('External entity ref: %s' %(args[1:],))
- return 1
-
- def StartDoctypeDeclHandler(self, *args):
- self.out.append(('Start doctype', args))
- return 1
-
- def EndDoctypeDeclHandler(self):
- self.out.append("End doctype")
- return 1
-
- def EntityDeclHandler(self, *args):
- self.out.append(('Entity declaration', args))
- return 1
-
- def XmlDeclHandler(self, *args):
- self.out.append(('XML declaration', args))
- return 1
-
- def ElementDeclHandler(self, *args):
- self.out.append(('Element declaration', args))
- return 1
-
- def AttlistDeclHandler(self, *args):
- self.out.append(('Attribute list declaration', args))
- return 1
-
- def SkippedEntityHandler(self, *args):
- self.out.append(("Skipped entity", args))
- return 1
-
- def DefaultHandler(self, userData):
- pass
-
- def DefaultHandlerExpand(self, userData):
- pass
-
- handler_names = [
- 'StartElementHandler', 'EndElementHandler', 'CharacterDataHandler',
- 'ProcessingInstructionHandler', 'UnparsedEntityDeclHandler',
- 'NotationDeclHandler', 'StartNamespaceDeclHandler',
- 'EndNamespaceDeclHandler', 'CommentHandler',
- 'StartCdataSectionHandler', 'EndCdataSectionHandler', 'DefaultHandler',
- 'DefaultHandlerExpand', 'NotStandaloneHandler',
- 'ExternalEntityRefHandler', 'StartDoctypeDeclHandler',
- 'EndDoctypeDeclHandler', 'EntityDeclHandler', 'XmlDeclHandler',
- 'ElementDeclHandler', 'AttlistDeclHandler', 'SkippedEntityHandler',
- ]
-
- def test_utf8(self):
-
- out = self.Outputter()
- parser = expat.ParserCreate(namespace_separator='!')
- for name in self.handler_names:
- setattr(parser, name, getattr(out, name))
- parser.returns_unicode = 0
- parser.Parse(data, 1)
-
- # Verify output
- operations = out.out
- expected_operations = [
- ('XML declaration', (u'1.0', u'iso-8859-1', 0)),
- 'PI: \'xml-stylesheet\' \'href="stylesheet.css"\'',
- "Comment: ' comment data '",
- "Not standalone",
- ("Start doctype", ('quotations', 'quotations.dtd', None, 1)),
- ('Element declaration', (u'root', (2, 0, None, ()))),
- ('Attribute list declaration', ('root', 'attr1', 'CDATA', None,
- 1)),
- ('Attribute list declaration', ('root', 'attr2', 'CDATA', None,
- 0)),
- "Notation declared: ('notation', None, 'notation.jpeg', None)",
- ('Entity declaration', ('acirc', 0, '\xc3\xa2', None, None, None, None)),
- ('Entity declaration', ('external_entity', 0, None, None,
- 'entity.file', None, None)),
- "Unparsed entity decl: ('unparsed_entity', None, 'entity.file', None, 'notation')",
- "Not standalone",
- "End doctype",
- "Start element: 'root' {'attr1': 'value1', 'attr2': 'value2\\xe1\\xbd\\x80'}",
- "NS decl: 'myns' 'http://www.python.org/namespace'",
- "Start element: 'http://www.python.org/namespace!subelement' {}",
- "Character data: 'Contents of subelements'",
- "End element: 'http://www.python.org/namespace!subelement'",
- "End of NS decl: 'myns'",
- "Start element: 'sub2' {}",
- 'Start of CDATA section',
- "Character data: 'contents of CDATA section'",
- 'End of CDATA section',
- "End element: 'sub2'",
- "External entity ref: (None, 'entity.file', None)",
- ('Skipped entity', ('skipped_entity', 0)),
- "End element: 'root'",
- ]
- for operation, expected_operation in zip(operations, expected_operations):
- assert operation == expected_operation
-
- def test_unicode(self):
- # Try the parse again, this time producing Unicode output
- out = self.Outputter()
- parser = expat.ParserCreate(namespace_separator='!')
- parser.returns_unicode = 1
- for name in self.handler_names:
- setattr(parser, name, getattr(out, name))
-
- parser.Parse(data, 1)
-
- operations = out.out
- expected_operations = [
- ('XML declaration', (u'1.0', u'iso-8859-1', 0)),
- 'PI: u\'xml-stylesheet\' u\'href="stylesheet.css"\'',
- "Comment: u' comment data '",
- "Not standalone",
- ("Start doctype", ('quotations', 'quotations.dtd', None, 1)),
- ('Element declaration', (u'root', (2, 0, None, ()))),
- ('Attribute list declaration', ('root', 'attr1', 'CDATA', None,
- 1)),
- ('Attribute list declaration', ('root', 'attr2', 'CDATA', None,
- 0)),
- "Notation declared: (u'notation', None, u'notation.jpeg', None)",
- ('Entity declaration', (u'acirc', 0, u'\xe2', None, None, None,
- None)),
- ('Entity declaration', (u'external_entity', 0, None, None,
- u'entity.file', None, None)),
- "Unparsed entity decl: (u'unparsed_entity', None, u'entity.file', None, u'notation')",
- "Not standalone",
- "End doctype",
- "Start element: u'root' {u'attr1': u'value1', u'attr2': u'value2\\u1f40'}",
- "NS decl: u'myns' u'http://www.python.org/namespace'",
- "Start element: u'http://www.python.org/namespace!subelement' {}",
- "Character data: u'Contents of subelements'",
- "End element: u'http://www.python.org/namespace!subelement'",
- "End of NS decl: u'myns'",
- "Start element: u'sub2' {}",
- 'Start of CDATA section',
- "Character data: u'contents of CDATA section'",
- 'End of CDATA section',
- "End element: u'sub2'",
- "External entity ref: (None, u'entity.file', None)",
- ('Skipped entity', ('skipped_entity', 0)),
- "End element: u'root'",
- ]
- for operation, expected_operation in zip(operations, expected_operations):
- assert operation == expected_operation
-
- def test_parse_file(self):
- # Try parsing a file
- out = self.Outputter()
- parser = expat.ParserCreate(namespace_separator='!')
- parser.returns_unicode = 1
- for name in self.handler_names:
- setattr(parser, name, getattr(out, name))
- file = StringIO.StringIO(data)
-
- parser.ParseFile(file)
-
- operations = out.out
- expected_operations = [
- ('XML declaration', (u'1.0', u'iso-8859-1', 0)),
- 'PI: u\'xml-stylesheet\' u\'href="stylesheet.css"\'',
- "Comment: u' comment data '",
- "Not standalone",
- ("Start doctype", ('quotations', 'quotations.dtd', None, 1)),
- ('Element declaration', (u'root', (2, 0, None, ()))),
- ('Attribute list declaration', ('root', 'attr1', 'CDATA', None,
- 1)),
- ('Attribute list declaration', ('root', 'attr2', 'CDATA', None,
- 0)),
- "Notation declared: (u'notation', None, u'notation.jpeg', None)",
- ('Entity declaration', ('acirc', 0, u'\xe2', None, None, None, None)),
- ('Entity declaration', (u'external_entity', 0, None, None, u'entity.file', None, None)),
- "Unparsed entity decl: (u'unparsed_entity', None, u'entity.file', None, u'notation')",
- "Not standalone",
- "End doctype",
- "Start element: u'root' {u'attr1': u'value1', u'attr2': u'value2\\u1f40'}",
- "NS decl: u'myns' u'http://www.python.org/namespace'",
- "Start element: u'http://www.python.org/namespace!subelement' {}",
- "Character data: u'Contents of subelements'",
- "End element: u'http://www.python.org/namespace!subelement'",
- "End of NS decl: u'myns'",
- "Start element: u'sub2' {}",
- 'Start of CDATA section',
- "Character data: u'contents of CDATA section'",
- 'End of CDATA section',
- "End element: u'sub2'",
- "External entity ref: (None, u'entity.file', None)",
- ('Skipped entity', ('skipped_entity', 0)),
- "End element: u'root'",
- ]
- for operation, expected_operation in zip(operations, expected_operations):
- assert operation == expected_operation
-
-
-class TestNamespaceSeparator:
- def test_legal(self):
- # Tests that make sure we get errors when the namespace_separator value
- # is illegal, and that we don't for good values:
- expat.ParserCreate()
- expat.ParserCreate(namespace_separator=None)
- expat.ParserCreate(namespace_separator=' ')
-
- def test_illegal(self):
- try:
- expat.ParserCreate(namespace_separatorB)
- raise AssertionError
- except TypeError, e:
- assert str(e) == (
- 'ParserCreate() argument 2 must be string or None, not int')
-
- try:
- expat.ParserCreate(namespace_separator='too long')
- raise AssertionError
- except ValueError, e:
- assert str(e) == (
- 'namespace_separator must be at most one character, omitted, or None')
-
- def test_zero_length(self):
- # ParserCreate() needs to accept a namespace_separator of zero length
- # to satisfy the requirements of RDF applications that are required
- # to simply glue together the namespace URI and the localname. Though
- # considered a wart of the RDF specifications, it needs to be supported.
- #
- # See XML-SIG mailing list thread starting with
- # http://mail.python.org/pipermail/xml-sig/2001-April/005202.html
- #
- expat.ParserCreate(namespace_separator='') # too short
-
-
-class TestInterning:
- def test(self):
- py.test.skip("Not working")
- # Test the interning machinery.
- p = expat.ParserCreate()
- L = []
- def collector(name, *args):
- L.append(name)
- p.StartElementHandler = collector
- p.EndElementHandler = collector
- p.Parse("<e> <e/> <e></e> </e>", 1)
- tag = L[0]
- assert len(L) == 6
- for entry in L:
- # L should have the same string repeated over and over.
- assert tag is entry
-
-
-class TestBufferText:
- def setup_method(self, meth):
- self.stuff = []
- self.parser = expat.ParserCreate()
- self.parser.buffer_text = 1
- self.parser.CharacterDataHandler = self.CharacterDataHandler
-
- def check(self, expected, label):
- assert self.stuff == expected, (
- "%s\nstuff = %r\nexpected = %r"
- % (label, self.stuff, map(unicode, expected)))
-
- def CharacterDataHandler(self, text):
- self.stuff.append(text)
-
- def StartElementHandler(self, name, attrs):
- self.stuff.append("<%s>" % name)
- bt = attrs.get("buffer-text")
- if bt == "yes":
- self.parser.buffer_text = 1
- elif bt == "no":
- self.parser.buffer_text = 0
-
- def EndElementHandler(self, name):
- self.stuff.append("</%s>" % name)
-
- def CommentHandler(self, data):
- self.stuff.append("<!--%s-->" % data)
-
- def setHandlers(self, handlers=[]):
- for name in handlers:
- setattr(self.parser, name, getattr(self, name))
-
- def test_default_to_disabled(self):
- parser = expat.ParserCreate()
- assert not parser.buffer_text
-
- def test_buffering_enabled(self):
- # Make sure buffering is turned on
- assert self.parser.buffer_text
- self.parser.Parse("<a>1<b/>2<c/>3</a>", 1)
- assert self.stuff == ['123'], (
- "buffered text not properly collapsed")
-
- def test1(self):
- # XXX This test exposes more detail of Expat's text chunking than we
- # XXX like, but it tests what we need to concisely.
- self.setHandlers(["StartElementHandler"])
- self.parser.Parse("<a>1<b buffer-text='no'/>2\n3<c buffer-text='yes'/>4\n5</a>", 1)
- assert self.stuff == (
- ["<a>", "1", "<b>", "2", "\n", "3", "<c>", "4\n5"]), (
- "buffering control not reacting as expected")
-
- def test2(self):
- self.parser.Parse("<a>1<b/>&lt;2&gt;<c/>&#32;\n&#x20;3</a>", 1)
- assert self.stuff == ["1<2> \n 3"], (
- "buffered text not properly collapsed")
-
- def test3(self):
- self.setHandlers(["StartElementHandler"])
- self.parser.Parse("<a>1<b/>2<c/>3</a>", 1)
- assert self.stuff == ["<a>", "1", "<b>", "2", "<c>", "3"], (
- "buffered text not properly split")
-
- def test4(self):
- self.setHandlers(["StartElementHandler", "EndElementHandler"])
- self.parser.CharacterDataHandler = None
- self.parser.Parse("<a>1<b/>2<c/>3</a>", 1)
- assert self.stuff == (
- ["<a>", "<b>", "</b>", "<c>", "</c>", "</a>"])
-
- def test5(self):
- self.setHandlers(["StartElementHandler", "EndElementHandler"])
- self.parser.Parse("<a>1<b></b>2<c/>3</a>", 1)
- assert self.stuff == (
- ["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "3", "</a>"])
-
- def test6(self):
- self.setHandlers(["CommentHandler", "EndElementHandler",
- "StartElementHandler"])
- self.parser.Parse("<a>1<b/>2<c></c>345</a> ", 1)
- assert self.stuff == (
- ["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "345", "</a>"]), (
- "buffered text not properly split")
-
- def test7(self):
- self.setHandlers(["CommentHandler", "EndElementHandler",
- "StartElementHandler"])
- self.parser.Parse("<a>1<b/>2<c></c>3<!--abc-->4<!--def-->5</a> ", 1)
- assert self.stuff == (
- ["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "3",
- "<!--abc-->", "4", "<!--def-->", "5", "</a>"]), (
- "buffered text not properly split")
-
-
-# Test handling of exception from callback:
-class TestHandlerException:
- def StartElementHandler(self, name, attrs):
- raise RuntimeError(name)
-
- def test(self):
- parser = expat.ParserCreate()
- parser.StartElementHandler = self.StartElementHandler
- try:
- parser.Parse("<a><b><c/></b></a>", 1)
- raise AssertionError
- except RuntimeError, e:
- assert e.args[0] == 'a', (
- "Expected RuntimeError for element 'a', but" + \
- " found %r" % e.args[0])
-
-
-# Test Current* members:
-class TestPosition:
- def StartElementHandler(self, name, attrs):
- self.check_pos('s')
-
- def EndElementHandler(self, name):
- self.check_pos('e')
-
- def check_pos(self, event):
- pos = (event,
- self.parser.CurrentByteIndex,
- self.parser.CurrentLineNumber,
- self.parser.CurrentColumnNumber)
- assert self.upto < len(self.expected_list)
- expected = self.expected_list[self.upto]
- assert pos == expected, (
- 'Expected position %s, got position %s' %(pos, expected))
- self.upto += 1
-
- def test(self):
- self.parser = expat.ParserCreate()
- self.parser.StartElementHandler = self.StartElementHandler
- self.parser.EndElementHandler = self.EndElementHandler
- self.upto = 0
- self.expected_list = [('s', 0, 1, 0), ('s', 5, 2, 1), ('s', 11, 3, 2),
- ('e', 15, 3, 6), ('e', 17, 4, 1), ('e', 22, 5, 0)]
-
- xml = '<a>\n <b>\n <c/>\n </b>\n</a>'
- self.parser.Parse(xml, 1)
-
-
-class Testsf1296433:
- def test_parse_only_xml_data(self):
- # http://python.org/sf/1296433
- #
- xml = "<?xml version='1.0' encoding='iso8859'?><s>%s</s>" % ('a' * 1025)
- # this one doesn't crash
- #xml = "<?xml version='1.0'?><s>%s</s>" % ('a' * 10000)
-
- class SpecificException(Exception):
- pass
-
- def handler(text):
- raise SpecificException
-
- parser = expat.ParserCreate()
- parser.CharacterDataHandler = handler
-
- py.test.raises(Exception, parser.Parse, xml)
-
-class TestChardataBuffer:
- """
- test setting of chardata buffer size
- """
-
- def test_1025_bytes(self):
- assert self.small_buffer_test(1025) == 2
-
- def test_1000_bytes(self):
- assert self.small_buffer_test(1000) == 1
-
- def test_wrong_size(self):
- parser = expat.ParserCreate()
- parser.buffer_text = 1
- def f(size):
- parser.buffer_size = size
-
- py.test.raises(TypeError, f, sys.maxint+1)
- py.test.raises(ValueError, f, -1)
- py.test.raises(ValueError, f, 0)
-
- def test_unchanged_size(self):
- xml1 = ("<?xml version='1.0' encoding='iso8859'?><s>%s" % ('a' * 512))
- xml2 = 'a'*512 + '</s>'
- parser = expat.ParserCreate()
- parser.CharacterDataHandler = self.counting_handler
- parser.buffer_size = 512
- parser.buffer_text = 1
-
- # Feed 512 bytes of character data: the handler should be called
- # once.
- self.n = 0
- parser.Parse(xml1)
- assert self.n == 1
-
- # Reassign to buffer_size, but assign the same size.
- parser.buffer_size = parser.buffer_size
- assert self.n == 1
-
- # Try parsing rest of the document
- parser.Parse(xml2)
- assert self.n == 2
-
-
- def test_disabling_buffer(self):
- xml1 = "<?xml version='1.0' encoding='iso8859'?><a>%s" % ('a' * 512)
- xml2 = ('b' * 1024)
- xml3 = "%s</a>" % ('c' * 1024)
- parser = expat.ParserCreate()
- parser.CharacterDataHandler = self.counting_handler
- parser.buffer_text = 1
- parser.buffer_size = 1024
- assert parser.buffer_size == 1024
-
- # Parse one chunk of XML
- self.n = 0
- parser.Parse(xml1, 0)
- assert parser.buffer_size == 1024
- assert self.n == 1
-
- # Turn off buffering and parse the next chunk.
- parser.buffer_text = 0
- assert not parser.buffer_text
- assert parser.buffer_size == 1024
- for i in range(10):
- parser.Parse(xml2, 0)
- assert self.n == 11
-
- parser.buffer_text = 1
- assert parser.buffer_text
- assert parser.buffer_size == 1024
- parser.Parse(xml3, 1)
- assert self.n == 12
-
-
-
- def make_document(self, bytes):
- return ("<?xml version='1.0'?><tag>" + bytes * 'a' + '</tag>')
-
- def counting_handler(self, text):
- self.n += 1
-
- def small_buffer_test(self, buffer_len):
- xml = "<?xml version='1.0' encoding='iso8859'?><s>%s</s>" % ('a' * buffer_len)
- parser = expat.ParserCreate()
- parser.CharacterDataHandler = self.counting_handler
- parser.buffer_size = 1024
- parser.buffer_text = 1
-
- self.n = 0
- parser.Parse(xml)
- return self.n
-
- def test_change_size_1(self):
- xml1 = "<?xml version='1.0' encoding='iso8859'?><a><s>%s" % ('a' * 1024)
- xml2 = "aaa</s><s>%s</s></a>" % ('a' * 1025)
- parser = expat.ParserCreate()
- parser.CharacterDataHandler = self.counting_handler
- parser.buffer_text = 1
- parser.buffer_size = 1024
- assert parser.buffer_size == 1024
-
- self.n = 0
- parser.Parse(xml1, 0)
- parser.buffer_size *= 2
- assert parser.buffer_size == 2048
- parser.Parse(xml2, 1)
- assert self.n == 2
-
- def test_change_size_2(self):
- xml1 = "<?xml version='1.0' encoding='iso8859'?><a>a<s>%s" % ('a' * 1023)
- xml2 = "aaa</s><s>%s</s></a>" % ('a' * 1025)
- parser = expat.ParserCreate()
- parser.CharacterDataHandler = self.counting_handler
- parser.buffer_text = 1
- parser.buffer_size = 2048
- assert parser.buffer_size == 2048
-
- self.n=0
- parser.Parse(xml1, 0)
- parser.buffer_size /= 2
- assert parser.buffer_size == 1024
- parser.Parse(xml2, 1)
- assert self.n == 4
-
- def test_segfault(self):
- py.test.raises(TypeError, expat.ParserCreate, 1234123123)
-
-def test_invalid_data():
- parser = expat.ParserCreate()
- parser.Parse('invalid.xml', 0)
- try:
- parser.Parse("", 1)
- except expat.ExpatError, e:
- assert e.code == 2 # XXX is this reliable?
- assert e.lineno == 1
- assert e.message.startswith('syntax error')
- else:
- py.test.fail("Did not raise")
-
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -106,7 +106,8 @@
BoolOption("sandbox", "Produce a fully-sandboxed executable",
defaultúlse, cmdline="--sandbox",
requires=[("translation.thread", False)],
- suggests=[("translation.gc", "generation")]),
+ suggests=[("translation.gc", "generation"),
+ ("translation.gcrootfinder", "shadowstack")]),
BoolOption("rweakref", "The backend supports RPython-level weakrefs",
default=True),

diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst
--- a/pypy/doc/coding-guide.rst
+++ b/pypy/doc/coding-guide.rst
@@ -388,7 +388,9 @@
In a few cases (e.g. hash table manipulation), we need machine-sized unsigned
arithmetic. For these cases there is the r_uint class, which is a pure
Python implementation of word-sized unsigned integers that silently wrap
- around. The purpose of this class (as opposed to helper functions as above)
+ around. ("word-sized" and "machine-sized" are used equivalently and mean
+ the native size, which you get using "unsigned long" in C.)
+ The purpose of this class (as opposed to helper functions as above)
is consistent typing: both Python and the annotator will propagate r_uint
instances in the program and interpret all the operations between them as
unsigned. Instances of r_uint are special-cased by the code generators to
diff --git a/pypy/doc/config/objspace.usemodules.pyexpat.txt b/pypy/doc/config/objspace.usemodules.pyexpat.txt
--- a/pypy/doc/config/objspace.usemodules.pyexpat.txt
+++ b/pypy/doc/config/objspace.usemodules.pyexpat.txt
@@ -1,2 +1,1 @@
-Use (experimental) pyexpat module written in RPython, instead of CTypes
-version which is used by default.
+Use the pyexpat module, written in RPython.
diff --git a/pypy/doc/getting-started-python.rst b/pypy/doc/getting-started-python.rst
--- a/pypy/doc/getting-started-python.rst
+++ b/pypy/doc/getting-started-python.rst
@@ -103,18 +103,22 @@
executable. The executable behaves mostly like a normal Python interpreter::

$ ./pypy-c
- Python 2.7.0 (61ef2a11b56a, Mar 02 2011, 03:00:11)
- [PyPy 1.6.0 with GCC 4.4.3] on linux2
+ Python 2.7.2 (0e28b379d8b3, Feb 09 2012, 19:41:03)
+ [PyPy 1.8.0 with GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
And now for something completely different: ``this sentence is false''
46 - 4
42
from test import pystone
pystone.main()
- Pystone(1.1) time for 50000 passes = 0.280017
- This machine benchmarks at 178561 pystones/second
- >>>>
+ Pystone(1.1) time for 50000 passes = 0.220015
+ This machine benchmarks at 227257 pystones/second
+ >>>> pystone.main()
+ Pystone(1.1) time for 50000 passes = 0.060004
+ This machine benchmarks at 833278 pystones/second
+ >>>>

+Note that pystone gets faster as the JIT kicks in.
This executable can be moved around or copied on other machines; see
Installation_ below.

diff --git a/pypy/doc/getting-started.rst b/pypy/doc/getting-started.rst
--- a/pypy/doc/getting-started.rst
+++ b/pypy/doc/getting-started.rst
@@ -53,14 +53,15 @@
PyPy is ready to be executed as soon as you unpack the tarball or the zip
file, with no need to install it in any specific location::

- $ tar xf pypy-1.7-linux.tar.bz2
-
- $ ./pypy-1.7/bin/pypy
- Python 2.7.1 (?, Apr 27 2011, 12:44:21)
- [PyPy 1.7.0 with GCC 4.4.3] on linux2
+ $ tar xf pypy-1.8-linux.tar.bz2
+ $ ./pypy-1.8/bin/pypy
+ Python 2.7.2 (0e28b379d8b3, Feb 09 2012, 19:41:03)
+ [PyPy 1.8.0 with GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
- And now for something completely different: ``implementing LOGO in LOGO:
- "turtles all the way down"''
+ And now for something completely different: ``it seems to me that once you
+ settle on an execution / object model and / or bytecode format, you've already
+ decided what languages (where the 's' seems superfluous) support is going to be
+ first class for''
>>>>

If you want to make PyPy available system-wide, you can put a symlink to the
@@ -75,14 +76,14 @@

$ curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py

- $ ./pypy-1.7/bin/pypy distribute_setup.py
+ $ ./pypy-1.8/bin/pypy distribute_setup.py

- $ ./pypy-1.7/bin/pypy get-pip.py
+ $ ./pypy-1.8/bin/pypy get-pip.py

- $ ./pypy-1.7/bin/pip install pygments # for example
+ $ ./pypy-1.8/bin/pip install pygments # for example

-3rd party libraries will be installed in ``pypy-1.7/site-packages``, and
-the scripts in ``pypy-1.7/bin``.
+3rd party libraries will be installed in ``pypy-1.8/site-packages``, and
+the scripts in ``pypy-1.8/bin``.

Installing using virtualenv
---------------------------
diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst
--- a/pypy/doc/index.rst
+++ b/pypy/doc/index.rst
@@ -15,7 +15,7 @@

* `FAQ`_: some frequently asked questions.

-* `Release 1.7`_: the latest official release
+* `Release 1.8`_: the latest official release

* `PyPy Blog`_: news and status info about PyPy

@@ -75,7 +75,7 @@
.. _`Getting Started`: getting-started.html
.. _`Papers`: extradoc.html
.. _`Videos`: video-index.html
-.. _`Release 1.7`: http://pypy.org/download.html
+.. _`Release 1.8`: http://pypy.org/download.html
.. _`speed.pypy.org`: http://speed.pypy.org
.. _`RPython toolchain`: translation.html
.. _`potential project ideas`: project-ideas.html
@@ -120,9 +120,9 @@
Windows, on top of .NET, and on top of Java.
To dig into PyPy it is recommended to try out the current
Mercurial default branch, which is always working or mostly working,
-instead of the latest release, which is `1.7`__.
+instead of the latest release, which is `1.8`__.

-.. __: release-1.7.0.html
+.. __: release-1.8.0.html

PyPy is mainly developed on Linux and Mac OS X. Windows is supported,
but platform-specific bugs tend to take longer before we notice and fix
diff --git a/pypy/doc/release-1.8.0.rst b/pypy/doc/release-1.8.0.rst
--- a/pypy/doc/release-1.8.0.rst
+++ b/pypy/doc/release-1.8.0.rst
@@ -2,16 +2,21 @@
PyPy 1.8 - business as usual
===========================
-We're pleased to announce the 1.8 release of PyPy. As has become a habit, this
-release brings a lot of bugfixes, and performance and memory improvements over
-the 1.7 release. The main highlight of the release is the introduction of
-list strategies which makes homogenous lists more efficient both in terms
-of performance and memory. This release also upgrades us from Python 2.7.1 compatibility to 2.7.2. Otherwise it's "business as usual" in the sense
-that performance improved roughly 10% on average since the previous release.
-You can download the PyPy 1.8 release here:
+We're pleased to announce the 1.8 release of PyPy. As habitual this
+release brings a lot of bugfixes, together with performance and memory
+improvements over the 1.7 release. The main highlight of the release
+is the introduction of `list strategies`_ which makes homogenous lists
+more efficient both in terms of performance and memory. This release
+also upgrades us from Python 2.7.1 compatibility to 2.7.2. Otherwise
+it's "business as usual" in the sense that performance improved
+roughly 10% on average since the previous release.
+
+you can download the PyPy 1.8 release here:

http://pypy.org/download.html

+.. _`list strategies`: http://morepypy.blogspot.com/2011/10/more-compact-lists-with-list-strategies.html
+
What is PyPy?
============
@@ -60,13 +65,6 @@
* New JIT hooks that allow you to hook into the JIT process from your python
program. There is a `brief overview`_ of what they offer.

-* Since the last release there was a significant breakthrough in PyPy's
- fundraising. We now have enough funds to work on first stages of `numpypy`_
- and `py3k`_. We would like to thank again to everyone who donated.
-
- It's also probably worth noting, we're considering donations for the STM
- project.
-
* Standard library upgrade from 2.7.1 to 2.7.2.

Ongoing work
@@ -82,7 +80,15 @@

* More numpy work

-* Software Transactional Memory, you can read more about `our plans`_
+* Since the last release there was a significant breakthrough in PyPy's
+ fundraising. We now have enough funds to work on first stages of `numpypy`_
+ and `py3k`_. We would like to thank again to everyone who donated.
+
+* It's also probably worth noting, we're considering donations for the
+ Software Transactional Memory project. You can read more about `our plans`_
+
+Cheers,
+The PyPy Team

.. _`brief overview`: http://doc.pypy.org/en/latest/jit-hooks.html
.. _`numpy status page`: http://buildbot.pypy.org/numpy-status/latest.html
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
@@ -134,7 +134,10 @@
assert a == 'a\nbxxxxxxx'

def test_nonblocking_read(self):
- import os, fcntl
+ try:
+ import os, fcntl
+ except ImportError:
+ skip("need fcntl to set nonblocking mode")
r_fd, w_fd = os.pipe()
# set nonblocking
fcntl.fcntl(r_fd, fcntl.F_SETFL, os.O_NONBLOCK)
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
@@ -23,6 +23,7 @@
from pypy.interpreter.function import StaticMethod
from pypy.objspace.std.sliceobject import W_SliceObject
from pypy.module.__builtin__.descriptor import W_Property
+from pypy.module.__builtin__.interp_classobj import W_ClassObject
from pypy.module.__builtin__.interp_memoryview import W_MemoryView
from pypy.rlib.entrypoint import entrypoint
from pypy.rlib.unroll import unrolling_iterable
@@ -397,6 +398,7 @@
'Module': 'space.gettypeobject(Module.typedef)',
'Property': 'space.gettypeobject(W_Property.typedef)',
'Slice': 'space.gettypeobject(W_SliceObject.typedef)',
+ 'Class': 'space.gettypeobject(W_ClassObject.typedef)',
'StaticMethod': 'space.gettypeobject(StaticMethod.typedef)',
'CFunction': 'space.gettypeobject(cpyext.methodobject.W_PyCFunctionObject.typedef)',
'WrapperDescr': 'space.gettypeobject(cpyext.methodobject.W_PyCMethodObject.typedef)'
diff --git a/pypy/module/cpyext/include/methodobject.h b/pypy/module/cpyext/include/methodobject.h
--- a/pypy/module/cpyext/include/methodobject.h
+++ b/pypy/module/cpyext/include/methodobject.h
@@ -26,6 +26,7 @@
PyObject_HEAD
PyMethodDef *m_ml; /* Description of the C function to call */
PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */
+ PyObject *m_module; /* The __module__ attribute, can be anything */
} PyCFunctionObject;

/* Flag passed to newmethodobject */
diff --git a/pypy/module/cpyext/include/patchlevel.h b/pypy/module/cpyext/include/patchlevel.h
--- a/pypy/module/cpyext/include/patchlevel.h
+++ b/pypy/module/cpyext/include/patchlevel.h
@@ -21,12 +21,12 @@
/* Version parsed out into numeric values */
#define PY_MAJOR_VERSION 2
#define PY_MINOR_VERSION 7
-#define PY_MICRO_VERSION 1
+#define PY_MICRO_VERSION 2
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL
#define PY_RELEASE_SERIAL 0

/* Version as a string */
-#define PY_VERSION "2.7.1"
+#define PY_VERSION "2.7.2"

/* PyPy version as a string */
#define PYPY_VERSION "1.8.1"
diff --git a/pypy/module/cpyext/include/pystate.h b/pypy/module/cpyext/include/pystate.h
--- a/pypy/module/cpyext/include/pystate.h
+++ b/pypy/module/cpyext/include/pystate.h
@@ -24,4 +24,6 @@
enum {PyGILState_LOCKED, PyGILState_UNLOCKED}
PyGILState_STATE;

+#define PyThreadState_GET() PyThreadState_Get()
+
#endif /* !Py_PYSTATE_H */
diff --git a/pypy/module/cpyext/include/structmember.h b/pypy/module/cpyext/include/structmember.h
--- a/pypy/module/cpyext/include/structmember.h
+++ b/pypy/module/cpyext/include/structmember.h
@@ -20,7 +20,7 @@
} PyMemberDef;


-/* Types */
+/* Types. These constants are also in structmemberdefs.py. */
#define T_SHORT 0
#define T_INT 1
#define T_LONG 2
@@ -42,9 +42,12 @@
#define T_LONGLONG 17
#define T_ULONGLONG 18

-/* Flags */
+/* Flags. These constants are also in structmemberdefs.py. */
#define READONLY 1
#define RO READONLY /* Shorthand */
+#define READ_RESTRICTED 2
+#define PY_WRITE_RESTRICTED 4
+#define RESTRICTED (READ_RESTRICTED | PY_WRITE_RESTRICTED)


#ifdef __cplusplus
diff --git a/pypy/module/cpyext/methodobject.py b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -32,6 +32,7 @@
PyObjectFields + (
('m_ml', lltype.Ptr(PyMethodDef)),
('m_self', PyObject),
+ ('m_module', PyObject),
))
PyCFunctionObject = lltype.Ptr(PyCFunctionObjectStruct)

@@ -47,11 +48,13 @@
assert isinstance(w_obj, W_PyCFunctionObject)
py_func.c_m_ml = w_obj.ml
py_func.c_m_self = make_ref(space, w_obj.w_self)
+ py_func.c_m_module = make_ref(space, w_obj.w_module)

@cpython_api([PyObject], lltype.Void, externalúlse)
def cfunction_dealloc(space, py_obj):
py_func = rffi.cast(PyCFunctionObject, py_obj)
Py_DecRef(space, py_func.c_m_self)
+ Py_DecRef(space, py_func.c_m_module)
from pypy.module.cpyext.object import PyObject_dealloc
PyObject_dealloc(space, py_obj)

diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -381,6 +381,15 @@
This is the equivalent of the Python expression hash(o)."""
return space.int_w(space.hash(w_obj))

+ at cpython_api([PyObject], PyObject)
+def PyObject_Dir(space, w_o):
+ """This is equivalent to the Python expression dir(o), returning a (possibly
+ empty) list of strings appropriate for the object argument, or NULL if there
+ was an error. If the argument is NULL, this is like the Python dir(),
+ returning the names of the current locals; in this case, if no execution frame
+ is active then NULL is returned but PyErr_Occurred() will return false."""
+ return space.call_function(space.builtin.get('dir'), w_o)
+
@cpython_api([PyObject, rffi.CCHARPP, Py_ssize_tP], rffi.INT_real, error=-1)
def PyObject_AsCharBuffer(space, obj, bufferp, sizep):
"""Returns a pointer to a read-only memory location usable as
diff --git a/pypy/module/cpyext/pyfile.py b/pypy/module/cpyext/pyfile.py
--- a/pypy/module/cpyext/pyfile.py
+++ b/pypy/module/cpyext/pyfile.py
@@ -1,7 +1,8 @@
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.module.cpyext.api import (
- cpython_api, CONST_STRING, FILEP, build_type_checkers)
+ cpython_api, CANNOT_FAIL, CONST_STRING, FILEP, build_type_checkers)
from pypy.module.cpyext.pyobject import PyObject, borrow_from
+from pypy.module.cpyext.object import Py_PRINT_RAW
from pypy.interpreter.error import OperationError
from pypy.module._file.interp_file import W_File

@@ -61,11 +62,49 @@
def PyFile_WriteString(space, s, w_p):
"""Write string s to file object p. Return 0 on success or -1 on
failure; the appropriate exception will be set."""
- w_s = space.wrap(rffi.charp2str(s))
- space.call_method(w_p, "write", w_s)
+ w_str = space.wrap(rffi.charp2str(s))
+ space.call_method(w_p, "write", w_str)
+ return 0
+
+ at cpython_api([PyObject, PyObject, rffi.INT_real], rffi.INT_real, error=-1)
+def PyFile_WriteObject(space, w_obj, w_p, flags):
+ """
+ Write object obj to file object p. The only supported flag for flags is
+ Py_PRINT_RAW; if given, the str() of the object is written
+ instead of the repr(). Return 0 on success or -1 on failure; the
+ appropriate exception will be set."""
+ if rffi.cast(lltype.Signed, flags) & Py_PRINT_RAW:
+ w_str = space.str(w_obj)
+ else:
+ w_str = space.repr(w_obj)
+ space.call_method(w_p, "write", w_str)
return 0

@cpython_api([PyObject], PyObject)
def PyFile_Name(space, w_p):
"""Return the name of the file specified by p as a string object."""
- return borrow_from(w_p, space.getattr(w_p, space.wrap("name")))
\ No newline at end of file
+ return borrow_from(w_p, space.getattr(w_p, space.wrap("name")))
+
+ at cpython_api([PyObject, rffi.INT_real], rffi.INT_real, errorÊNNOT_FAIL)
+def PyFile_SoftSpace(space, w_p, newflag):
+ """
+ This function exists for internal use by the interpreter. Set the
+ softspace attribute of p to newflag and return the previous value.
+ p does not have to be a file object for this function to work
+ properly; any object is supported (thought its only interesting if
+ the softspace attribute can be set). This function clears any
+ errors, and will return 0 as the previous value if the attribute
+ either does not exist or if there were errors in retrieving it.
+ There is no way to detect errors from this function, but doing so
+ should not be needed."""
+ try:
+ if rffi.cast(lltype.Signed, newflag):
+ w_newflag = space.w_True
+ else:
+ w_newflag = space.w_False
+ oldflag = space.int_w(space.getattr(w_p, space.wrap("softspace")))
+ space.setattr(w_p, space.wrap("softspace"), w_newflag)
+ return oldflag
+ except OperationError, e:
+ return 0
+
diff --git a/pypy/module/cpyext/pythonrun.py b/pypy/module/cpyext/pythonrun.py
--- a/pypy/module/cpyext/pythonrun.py
+++ b/pypy/module/cpyext/pythonrun.py
@@ -14,6 +14,20 @@
value."""
return space.fromcache(State).get_programname()

+ at cpython_api([], rffi.CCHARP)
+def Py_GetVersion(space):
+ """Return the version of this Python interpreter. This is a
+ string that looks something like
+
+ "1.5 (\#67, Dec 31 1997, 22:34:28) [GCC 2.7.2.2]"
+
+ The first word (up to the first space character) is the current
+ Python version; the first three characters are the major and minor
+ version separated by a period. The returned string points into
+ static storage; the caller should not modify its value. The value
+ is available to Python code as sys.version."""
+ return space.fromcache(State).get_version()
+
@cpython_api([lltype.Ptr(lltype.FuncType([], lltype.Void))], rffi.INT_real, error=-1)
def Py_AtExit(space, func_ptr):
"""Register a cleanup function to be called by Py_Finalize(). The cleanup
diff --git a/pypy/module/cpyext/state.py b/pypy/module/cpyext/state.py
--- a/pypy/module/cpyext/state.py
+++ b/pypy/module/cpyext/state.py
@@ -10,6 +10,7 @@
self.space = space
self.reset()
self.programname = lltype.nullptr(rffi.CCHARP.TO)
+ self.version = lltype.nullptr(rffi.CCHARP.TO)

def reset(self):
from pypy.module.cpyext.modsupport import PyMethodDef
@@ -102,6 +103,15 @@
lltype.render_immortal(self.programname)
return self.programname

+ def get_version(self):
+ if not self.version:
+ space = self.space
+ w_version = space.sys.get('version')
+ version = space.str_w(w_version)
+ self.version = rffi.str2charp(version)
+ lltype.render_immortal(self.version)
+ return self.version
+
def find_extension(self, name, path):
from pypy.module.cpyext.modsupport import PyImport_AddModule
from pypy.interpreter.module import Module
diff --git a/pypy/module/cpyext/stringobject.py b/pypy/module/cpyext/stringobject.py
--- a/pypy/module/cpyext/stringobject.py
+++ b/pypy/module/cpyext/stringobject.py
@@ -250,6 +250,26 @@
s = rffi.charp2str(string)
return space.new_interned_str(s)

+ at cpython_api([PyObjectP], lltype.Void)
+def PyString_InternInPlace(space, string):
+ """Intern the argument *string in place. The argument must be the
+ address of a pointer variable pointing to a Python string object.
+ If there is an existing interned string that is the same as
+ *string, it sets *string to it (decrementing the reference count
+ of the old string object and incrementing the reference count of
+ the interned string object), otherwise it leaves *string alone and
+ interns it (incrementing its reference count). (Clarification:
+ even though there is a lot of talk about reference counts, think
+ of this function as reference-count-neutral; you own the object
+ after the call if and only if you owned it before the call.)
+
+ This function is not available in 3.x and does not have a PyBytes
+ alias."""
+ w_str = from_ref(space, string[0])
+ w_str = space.new_interned_w_str(w_str)
+ Py_DecRef(space, string[0])
+ string[0] = make_ref(space, w_str)
+
@cpython_api([PyObject, rffi.CCHARP, rffi.CCHARP], PyObject)
def PyString_AsEncodedObject(space, w_str, encoding, errors):
"""Encode a string object using the codec registered for encoding and return
diff --git a/pypy/module/cpyext/structmemberdefs.py b/pypy/module/cpyext/structmemberdefs.py
--- a/pypy/module/cpyext/structmemberdefs.py
+++ b/pypy/module/cpyext/structmemberdefs.py
@@ -1,3 +1,5 @@
+# These constants are also in include/structmember.h
+
T_SHORT = 0
T_INT = 1
T_LONG = 2
@@ -18,3 +20,6 @@
T_ULONGLONG = 18

READONLY = RO = 1
+READ_RESTRICTED = 2
+WRITE_RESTRICTED = 4
+RESTRICTED = READ_RESTRICTED | WRITE_RESTRICTED
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
@@ -1,5 +1,5 @@
from pypy.module.cpyext.api import (
- cpython_api, PyObject, PyObjectP, CANNOT_FAIL, Py_buffer
+ cpython_api, PyObject, PyObjectP, CANNOT_FAIL
)
from pypy.module.cpyext.complexobject import Py_complex_ptr as Py_complex
from pypy.rpython.lltypesystem import rffi, lltype
@@ -10,6 +10,7 @@
PyMethodDef = rffi.VOIDP
PyGetSetDef = rffi.VOIDP
PyMemberDef = rffi.VOIDP
+Py_buffer = rffi.VOIDP
va_list = rffi.VOIDP
PyDateTime_Date = rffi.VOIDP
PyDateTime_DateTime = rffi.VOIDP
@@ -32,10 +33,6 @@
def _PyObject_Del(space, op):
raise NotImplementedError

- at cpython_api([PyObject], rffi.INT_real, errorÊNNOT_FAIL)
-def PyObject_CheckBuffer(space, obj):
- raise NotImplementedError
-
@cpython_api([rffi.CCHARP], Py_ssize_t, errorÊNNOT_FAIL)
def PyBuffer_SizeFromFormat(space, format):
"""Return the implied ~Py_buffer.itemsize from the struct-stype
@@ -684,28 +681,6 @@
"""
raise NotImplementedError

- at cpython_api([PyObject, rffi.INT_real], rffi.INT_real, errorÊNNOT_FAIL)
-def PyFile_SoftSpace(space, p, newflag):
- """
- This function exists for internal use by the interpreter. Set the
- softspace attribute of p to newflag and return the previous value.
- p does not have to be a file object for this function to work properly; any
- object is supported (thought its only interesting if the softspace
- attribute can be set). This function clears any errors, and will return 0
- as the previous value if the attribute either does not exist or if there were
- errors in retrieving it. There is no way to detect errors from this function,
- but doing so should not be needed."""
- raise NotImplementedError
-
- at cpython_api([PyObject, PyObject, rffi.INT_real], rffi.INT_real, error=-1)
-def PyFile_WriteObject(space, obj, p, flags):
- """
- Write object obj to file object p. The only supported flag for flags is
- Py_PRINT_RAW; if given, the str() of the object is written
- instead of the repr(). Return 0 on success or -1 on failure; the
- appropriate exception will be set."""
- raise NotImplementedError
-
@cpython_api([], PyObject)
def PyFloat_GetInfo(space):
"""Return a structseq instance which contains information about the
@@ -1097,19 +1072,6 @@
raise NotImplementedError

@cpython_api([], rffi.CCHARP)
-def Py_GetVersion(space):
- """Return the version of this Python interpreter. This is a string that looks
- something like
-
- "1.5 (\#67, Dec 31 1997, 22:34:28) [GCC 2.7.2.2]"
-
- The first word (up to the first space character) is the current Python version;
- the first three characters are the major and minor version separated by a
- period. The returned string points into static storage; the caller should not
- modify its value. The value is available to Python code as sys.version."""
- raise NotImplementedError
-
- at cpython_api([], rffi.CCHARP)
def Py_GetPlatform(space):
"""Return the platform identifier for the current platform. On Unix, this
is formed from the"official" name of the operating system, converted to lower
@@ -1685,15 +1647,6 @@
"""
raise NotImplementedError

- at cpython_api([PyObject], PyObject)
-def PyObject_Dir(space, o):
- """This is equivalent to the Python expression dir(o), returning a (possibly
- empty) list of strings appropriate for the object argument, or NULL if there
- was an error. If the argument is NULL, this is like the Python dir(),
- returning the names of the current locals; in this case, if no execution frame
- is active then NULL is returned but PyErr_Occurred() will return false."""
- raise NotImplementedError
-
@cpython_api([], PyFrameObject)
def PyEval_GetFrame(space):
"""Return the current thread state's frame, which is NULL if no frame is
@@ -1815,21 +1768,6 @@
"""Empty an existing set of all elements."""
raise NotImplementedError

- at cpython_api([PyObjectP], lltype.Void)
-def PyString_InternInPlace(space, string):
- """Intern the argument *string in place. The argument must be the address of a
- pointer variable pointing to a Python string object. If there is an existing
- interned string that is the same as *string, it sets *string to it
- (decrementing the reference count of the old string object and incrementing the
- reference count of the interned string object), otherwise it leaves *string
- alone and interns it (incrementing its reference count). (Clarification: even
- though there is a lot of talk about reference counts, think of this function as
- reference-count-neutral; you own the object after the call if and only if you
- owned it before the call.)
-
- This function is not available in 3.x and does not have a PyBytes alias."""
- raise NotImplementedError
-
@cpython_api([rffi.CCHARP, Py_ssize_t, rffi.CCHARP, rffi.CCHARP], PyObject)
def PyString_Decode(space, s, size, encoding, errors):
"""Create an object by decoding size bytes of the encoded buffer s using the
diff --git a/pypy/module/cpyext/test/test_classobject.py b/pypy/module/cpyext/test/test_classobject.py
--- a/pypy/module/cpyext/test/test_classobject.py
+++ b/pypy/module/cpyext/test/test_classobject.py
@@ -1,4 +1,5 @@
from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
from pypy.interpreter.function import Function, Method

class TestClassObject(BaseApiTest):
@@ -51,3 +52,14 @@
assert api.PyInstance_Check(w_instance)
assert space.is_true(space.call_method(space.builtin, "isinstance",
w_instance, w_class))
+
+class AppTestStringObject(AppTestCpythonExtensionBase):
+ def test_class_type(self):
+ module = self.import_extension('foo', [
+ ("get_classtype", "METH_NOARGS",
+ """
+ Py_INCREF(&PyClass_Type);
+ return &PyClass_Type;
+ """)])
+ class C: pass
+ assert module.get_classtype() is type(C)
diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -744,6 +744,22 @@
print p
assert 'py' in p

+ def test_get_version(self):
+ mod = self.import_extension('foo', [
+ ('get_version', 'METH_NOARGS',
+ '''
+ char* name1 = Py_GetVersion();
+ char* name2 = Py_GetVersion();
+ if (name1 != name2)
+ Py_RETURN_FALSE;
+ return PyString_FromString(name1);
+ '''
+ ),
+ ])
+ p = mod.get_version()
+ print p
+ assert 'PyPy' in p
+
def test_no_double_imports(self):
import sys, os
try:
diff --git a/pypy/module/cpyext/test/test_methodobject.py b/pypy/module/cpyext/test/test_methodobject.py
--- a/pypy/module/cpyext/test/test_methodobject.py
+++ b/pypy/module/cpyext/test/test_methodobject.py
@@ -9,7 +9,7 @@

class AppTestMethodObject(AppTestCpythonExtensionBase):
def test_call_METH(self):
- mod = self.import_extension('foo', [
+ mod = self.import_extension('MyModule', [
('getarg_O', 'METH_O',
'''
Py_INCREF(args);
@@ -51,11 +51,23 @@
}
'''
),
+ ('getModule', 'METH_O',
+ '''
+ if(PyCFunction_Check(args)) {
+ PyCFunctionObject* func = (PyCFunctionObject*)args;
+ Py_INCREF(func->m_module);
+ return func->m_module;
+ }
+ else {
+ Py_RETURN_FALSE;
+ }
+ '''
+ ),
('isSameFunction', 'METH_O',
'''
PyCFunction ptr = PyCFunction_GetFunction(args);
if (!ptr) return NULL;
- if (ptr == foo_getarg_O)
+ if (ptr == MyModule_getarg_O)
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
@@ -76,6 +88,7 @@
assert mod.getarg_OLD(1, 2) == (1, 2)

assert mod.isCFunction(mod.getarg_O) == "getarg_O"
+ assert mod.getModule(mod.getarg_O) == 'MyModule'
assert mod.isSameFunction(mod.getarg_O)
raises(TypeError, mod.isSameFunction, 1)

diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py
--- a/pypy/module/cpyext/test/test_object.py
+++ b/pypy/module/cpyext/test/test_object.py
@@ -191,6 +191,11 @@
assert api.PyObject_Unicode(space.wrap("\xe9")) is None
api.PyErr_Clear()

+ def test_dir(self, space, api):
+ w_dir = api.PyObject_Dir(space.sys)
+ assert space.isinstance_w(w_dir, space.w_list)
+ assert space.is_true(space.contains(w_dir, space.wrap('modules')))
+
class AppTestObject(AppTestCpythonExtensionBase):
def setup_class(cls):
AppTestCpythonExtensionBase.setup_class.im_func(cls)
diff --git a/pypy/module/cpyext/test/test_pyfile.py b/pypy/module/cpyext/test/test_pyfile.py
--- a/pypy/module/cpyext/test/test_pyfile.py
+++ b/pypy/module/cpyext/test/test_pyfile.py
@@ -1,5 +1,6 @@
from pypy.module.cpyext.api import fopen, fclose, fwrite
from pypy.module.cpyext.test.test_api import BaseApiTest
+from pypy.module.cpyext.object import Py_PRINT_RAW
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.tool.udir import udir
import pytest
@@ -77,3 +78,28 @@
out = out.replace('\r\n', '\n')
assert out == "test\n"

+ def test_file_writeobject(self, space, api, capfd):
+ w_obj = space.wrap("test\n")
+ w_stdout = space.sys.get("stdout")
+ api.PyFile_WriteObject(w_obj, w_stdout, Py_PRINT_RAW)
+ api.PyFile_WriteObject(w_obj, w_stdout, 0)
+ space.call_method(w_stdout, "flush")
+ out, err = capfd.readouterr()
+ out = out.replace('\r\n', '\n')
+ assert out == "test\n'test\\n'"
+
+ def test_file_softspace(self, space, api, capfd):
+ w_stdout = space.sys.get("stdout")
+ assert api.PyFile_SoftSpace(w_stdout, 1) == 0
+ assert api.PyFile_SoftSpace(w_stdout, 0) == 1
+
+ api.PyFile_SoftSpace(w_stdout, 1)
+ w_ns = space.newdict()
+ space.exec_("print 1,", w_ns, w_ns)
+ space.exec_("print 2,", w_ns, w_ns)
+ api.PyFile_SoftSpace(w_stdout, 0)
+ space.exec_("print 3", w_ns, w_ns)
+ space.call_method(w_stdout, "flush")
+ out, err = capfd.readouterr()
+ out = out.replace('\r\n', '\n')
+ assert out == " 1 23\n"
diff --git a/pypy/module/cpyext/test/test_stringobject.py b/pypy/module/cpyext/test/test_stringobject.py
--- a/pypy/module/cpyext/test/test_stringobject.py
+++ b/pypy/module/cpyext/test/test_stringobject.py
@@ -166,6 +166,20 @@
res = module.test_string_format(1, "xyz")
assert res == "bla 1 ble xyz\n"

+ def test_intern_inplace(self):
+ module = self.import_extension('foo', [
+ ("test_intern_inplace", "METH_O",
+ '''
+ PyObject *s = args;
+ Py_INCREF(s);
+ PyString_InternInPlace(&s);
+ return s;
+ '''
+ )
+ ])
+ # This does not test much, but at least the refcounts are checked.
+ assert module.test_intern_inplace('s') == 's'
+
class TestString(BaseApiTest):
def test_string_resize(self, space, api):
py_str = new_empty_str(space, 10)
diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -95,6 +95,7 @@
("tan", "tan"),
('bitwise_and', 'bitwise_and'),
('bitwise_or', 'bitwise_or'),
+ ('bitwise_xor', 'bitwise_xor'),
('bitwise_not', 'invert'),
('isnan', 'isnan'),
('isinf', 'isinf'),
diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -83,6 +83,8 @@
descr_truediv = _binop_impl("true_divide")
descr_mod = _binop_impl("mod")
descr_pow = _binop_impl("power")
+ descr_lshift = _binop_impl("left_shift")
+ descr_rshift = _binop_impl("right_shift")
descr_and = _binop_impl("bitwise_and")
descr_or = _binop_impl("bitwise_or")
descr_xor = _binop_impl("bitwise_xor")
@@ -97,13 +99,31 @@
descr_radd = _binop_right_impl("add")
descr_rsub = _binop_right_impl("subtract")
descr_rmul = _binop_right_impl("multiply")
+ descr_rdiv = _binop_right_impl("divide")
+ descr_rtruediv = _binop_right_impl("true_divide")
+ descr_rmod = _binop_right_impl("mod")
descr_rpow = _binop_right_impl("power")
+ descr_rlshift = _binop_right_impl("left_shift")
+ descr_rrshift = _binop_right_impl("right_shift")
+ descr_rand = _binop_right_impl("bitwise_and")
+ descr_ror = _binop_right_impl("bitwise_or")
+ descr_rxor = _binop_right_impl("bitwise_xor")

descr_pos = _unaryop_impl("positive")
descr_neg = _unaryop_impl("negative")
descr_abs = _unaryop_impl("absolute")
descr_invert = _unaryop_impl("invert")

+ def descr_divmod(self, space, w_other):
+ w_quotient = self.descr_div(space, w_other)
+ w_remainder = self.descr_mod(space, w_other)
+ return space.newtuple([w_quotient, w_remainder])
+
+ def descr_rdivmod(self, space, w_other):
+ w_quotient = self.descr_rdiv(space, w_other)
+ w_remainder = self.descr_rmod(space, w_other)
+ return space.newtuple([w_quotient, w_remainder])
+
def item(self, space):
return self.get_dtype(space).itemtype.to_builtin_type(space, self)

@@ -185,7 +205,10 @@
__div__ = interp2app(W_GenericBox.descr_div),
__truediv__ = interp2app(W_GenericBox.descr_truediv),
__mod__ = interp2app(W_GenericBox.descr_mod),
+ __divmod__ = interp2app(W_GenericBox.descr_divmod),
__pow__ = interp2app(W_GenericBox.descr_pow),
+ __lshift__ = interp2app(W_GenericBox.descr_lshift),
+ __rshift__ = interp2app(W_GenericBox.descr_rshift),
__and__ = interp2app(W_GenericBox.descr_and),
__or__ = interp2app(W_GenericBox.descr_or),
__xor__ = interp2app(W_GenericBox.descr_xor),
@@ -193,7 +216,16 @@
__radd__ = interp2app(W_GenericBox.descr_radd),
__rsub__ = interp2app(W_GenericBox.descr_rsub),
__rmul__ = interp2app(W_GenericBox.descr_rmul),
+ __rdiv__ = interp2app(W_GenericBox.descr_rdiv),
+ __rtruediv__ = interp2app(W_GenericBox.descr_rtruediv),
+ __rmod__ = interp2app(W_GenericBox.descr_rmod),
+ __rdivmod__ = interp2app(W_GenericBox.descr_rdivmod),
__rpow__ = interp2app(W_GenericBox.descr_rpow),
+ __rlshift__ = interp2app(W_GenericBox.descr_rlshift),
+ __rrshift__ = interp2app(W_GenericBox.descr_rrshift),
+ __rand__ = interp2app(W_GenericBox.descr_rand),
+ __ror__ = interp2app(W_GenericBox.descr_ror),
+ __rxor__ = interp2app(W_GenericBox.descr_rxor),

__eq__ = interp2app(W_GenericBox.descr_eq),
__ne__ = interp2app(W_GenericBox.descr_ne),
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -4,17 +4,17 @@
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.module.micronumpy import (interp_ufuncs, interp_dtype, interp_boxes,
signature, support, loop)
+from pypy.module.micronumpy.appbridge import get_appbridge_cache
+from pypy.module.micronumpy.dot import multidim_dot, match_dot_shapes
+from pypy.module.micronumpy.interp_iter import (ArrayIterator,
+ SkipLastAxisIterator, Chunk, ViewIterator)
from pypy.module.micronumpy.strides import (calculate_slice_strides,
shape_agreement, find_shape_and_elems, get_shape_from_iterable,
calc_new_strides, to_coords)
-from dot import multidim_dot, match_dot_shapes
from pypy.rlib import jit
+from pypy.rlib.rstring import StringBuilder
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.tool.sourcetools import func_with_new_name
-from pypy.rlib.rstring import StringBuilder
-from pypy.module.micronumpy.interp_iter import (ArrayIterator,
- SkipLastAxisIterator, Chunk, ViewIterator)
-from pypy.module.micronumpy.appbridge import get_appbridge_cache


count_driver = jit.JitDriver(
@@ -101,8 +101,14 @@
descr_sub = _binop_impl("subtract")
descr_mul = _binop_impl("multiply")
descr_div = _binop_impl("divide")
+ descr_truediv = _binop_impl("true_divide")
+ descr_mod = _binop_impl("mod")
descr_pow = _binop_impl("power")
- descr_mod = _binop_impl("mod")
+ descr_lshift = _binop_impl("left_shift")
+ descr_rshift = _binop_impl("right_shift")
+ descr_and = _binop_impl("bitwise_and")
+ descr_or = _binop_impl("bitwise_or")
+ descr_xor = _binop_impl("bitwise_xor")

descr_eq = _binop_impl("equal")
descr_ne = _binop_impl("not_equal")
@@ -111,8 +117,10 @@
descr_gt = _binop_impl("greater")
descr_ge = _binop_impl("greater_equal")

- descr_and = _binop_impl("bitwise_and")
- descr_or = _binop_impl("bitwise_or")
+ def descr_divmod(self, space, w_other):
+ w_quotient = self.descr_div(space, w_other)
+ w_remainder = self.descr_mod(space, w_other)
+ return space.newtuple([w_quotient, w_remainder])

def _binop_right_impl(ufunc_name):
def impl(self, space, w_other):
@@ -127,8 +135,19 @@
descr_rsub = _binop_right_impl("subtract")
descr_rmul = _binop_right_impl("multiply")
descr_rdiv = _binop_right_impl("divide")
+ descr_rtruediv = _binop_right_impl("true_divide")
+ descr_rmod = _binop_right_impl("mod")
descr_rpow = _binop_right_impl("power")
- descr_rmod = _binop_right_impl("mod")
+ descr_rlshift = _binop_right_impl("left_shift")
+ descr_rrshift = _binop_right_impl("right_shift")
+ descr_rand = _binop_right_impl("bitwise_and")
+ descr_ror = _binop_right_impl("bitwise_or")
+ descr_rxor = _binop_right_impl("bitwise_xor")
+
+ def descr_rdivmod(self, space, w_other):
+ w_quotient = self.descr_rdiv(space, w_other)
+ w_remainder = self.descr_rmod(space, w_other)
+ return space.newtuple([w_quotient, w_remainder])

def _reduce_ufunc_impl(ufunc_name, promote_to_largestúlse):
def impl(self, space, w_axis=None):
@@ -1227,21 +1246,36 @@
__pos__ = interp2app(BaseArray.descr_pos),
__neg__ = interp2app(BaseArray.descr_neg),
__abs__ = interp2app(BaseArray.descr_abs),
+ __invert__ = interp2app(BaseArray.descr_invert),
__nonzero__ = interp2app(BaseArray.descr_nonzero),

__add__ = interp2app(BaseArray.descr_add),
__sub__ = interp2app(BaseArray.descr_sub),
__mul__ = interp2app(BaseArray.descr_mul),
__div__ = interp2app(BaseArray.descr_div),
+ __truediv__ = interp2app(BaseArray.descr_truediv),
+ __mod__ = interp2app(BaseArray.descr_mod),
+ __divmod__ = interp2app(BaseArray.descr_divmod),
__pow__ = interp2app(BaseArray.descr_pow),
- __mod__ = interp2app(BaseArray.descr_mod),
+ __lshift__ = interp2app(BaseArray.descr_lshift),
+ __rshift__ = interp2app(BaseArray.descr_rshift),
+ __and__ = interp2app(BaseArray.descr_and),
+ __or__ = interp2app(BaseArray.descr_or),
+ __xor__ = interp2app(BaseArray.descr_xor),

__radd__ = interp2app(BaseArray.descr_radd),
__rsub__ = interp2app(BaseArray.descr_rsub),
__rmul__ = interp2app(BaseArray.descr_rmul),
__rdiv__ = interp2app(BaseArray.descr_rdiv),
+ __rtruediv__ = interp2app(BaseArray.descr_rtruediv),
+ __rmod__ = interp2app(BaseArray.descr_rmod),
+ __rdivmod__ = interp2app(BaseArray.descr_rdivmod),
__rpow__ = interp2app(BaseArray.descr_rpow),
- __rmod__ = interp2app(BaseArray.descr_rmod),
+ __rlshift__ = interp2app(BaseArray.descr_rlshift),
+ __rrshift__ = interp2app(BaseArray.descr_rrshift),
+ __rand__ = interp2app(BaseArray.descr_rand),
+ __ror__ = interp2app(BaseArray.descr_ror),
+ __rxor__ = interp2app(BaseArray.descr_rxor),

__eq__ = interp2app(BaseArray.descr_eq),
__ne__ = interp2app(BaseArray.descr_ne),
@@ -1250,10 +1284,6 @@
__gt__ = interp2app(BaseArray.descr_gt),
__ge__ = interp2app(BaseArray.descr_ge),

- __and__ = interp2app(BaseArray.descr_and),
- __or__ = interp2app(BaseArray.descr_or),
- __invert__ = interp2app(BaseArray.descr_invert),
-
__repr__ = interp2app(BaseArray.descr_repr),
__str__ = interp2app(BaseArray.descr_str),
__array_interface__ = GetSetProperty(BaseArray.descr_array_iface),
@@ -1267,6 +1297,7 @@
nbytes = GetSetProperty(BaseArray.descr_get_nbytes),

T = GetSetProperty(BaseArray.descr_get_transpose),
+ transpose = interp2app(BaseArray.descr_get_transpose),
flat = GetSetProperty(BaseArray.descr_get_flatiter),
ravel = interp2app(BaseArray.descr_ravel),
item = interp2app(BaseArray.descr_item),
diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -392,6 +392,8 @@
("true_divide", "div", 2, {"promote_to_float": True}),
("mod", "mod", 2, {"promote_bools": True}),
("power", "pow", 2, {"promote_bools": True}),
+ ("left_shift", "lshift", 2, {"int_only": True}),
+ ("right_shift", "rshift", 2, {"int_only": True}),

("equal", "eq", 2, {"comparison_func": True}),
("not_equal", "ne", 2, {"comparison_func": True}),
diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -406,15 +406,28 @@
from operator import truediv
from _numpypy import float64, int_, True_, False_

+ assert 5 / int_(2) == int_(2)
assert truediv(int_(3), int_(2)) == float64(1.5)
+ assert truediv(3, int_(2)) == float64(1.5)
+ assert int_(8) % int_(3) == int_(2)
+ assert 8 % int_(3) == int_(2)
+ assert divmod(int_(8), int_(3)) == (int_(2), int_(2))
+ assert divmod(8, int_(3)) == (int_(2), int_(2))
assert 2 ** int_(3) == int_(8)
+ assert int_(3) << int_(2) == int_(12)
+ assert 3 << int_(2) == int_(12)
+ assert int_(8) >> int_(2) == int_(2)
+ assert 8 >> int_(2) == int_(2)
assert int_(3) & int_(1) == int_(1)
- raises(TypeError, lambda: float64(3) & 1)
- assert int_(8) % int_(3) == int_(2)
+ assert 2 & int_(3) == int_(2)
assert int_(2) | int_(1) == int_(3)
+ assert 2 | int_(1) == int_(3)
assert int_(3) ^ int_(5) == int_(6)
assert True_ ^ False_ is True_
+ assert 5 ^ int_(3) == int_(6)

assert +int_(3) == int_(3)
assert ~int_(3) == int_(-4)

+ raises(TypeError, lambda: float64(3) & 1)
+
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -625,6 +625,59 @@
for i in range(5):
assert b[i] == i / 5.0

+ def test_truediv(self):
+ from operator import truediv
+ from _numpypy import arange
+
+ assert (truediv(arange(5), 2) == [0., .5, 1., 1.5, 2.]).all()
+ assert (truediv(2, arange(3)) == [float("inf"), 2., 1.]).all()
+
+ def test_divmod(self):
+ from _numpypy import arange
+
+ a, b = divmod(arange(10), 3)
+ assert (a == [0, 0, 0, 1, 1, 1, 2, 2, 2, 3]).all()
+ assert (b == [0, 1, 2, 0, 1, 2, 0, 1, 2, 0]).all()
+
+ def test_rdivmod(self):
+ from _numpypy import arange
+
+ a, b = divmod(3, arange(1, 5))
+ assert (a == [3, 1, 1, 0]).all()
+ assert (b == [0, 1, 0, 3]).all()
+
+ def test_lshift(self):
+ from _numpypy import array
+
+ a = array([0, 1, 2, 3])
+ assert (a << 2 == [0, 4, 8, 12]).all()
+ a = array([True, False])
+ assert (a << 2 == [4, 0]).all()
+ a = array([1.0])
+ raises(TypeError, lambda: a << 2)
+
+ def test_rlshift(self):
+ from _numpypy import arange
+
+ a = arange(3)
+ assert (2 << a == [2, 4, 8]).all()
+
+ def test_rshift(self):
+ from _numpypy import arange, array
+
+ a = arange(10)
+ assert (a >> 2 == [0, 0, 0, 0, 1, 1, 1, 1, 2, 2]).all()
+ a = array([True, False])
+ assert (a >> 1 == [0, 0]).all()
+ a = arange(3, dtype=float)
+ raises(TypeError, lambda: a >> 1)
+
+ def test_rrshift(self):
+ from _numpypy import arange
+
+ a = arange(5)
+ assert (2 >> a == [2, 1, 0, 0, 0]).all()
+
def test_pow(self):
from _numpypy import array
a = array(range(5), float)
@@ -678,6 +731,30 @@
for i in range(5):
assert b[i] == i % 2

+ def test_rand(self):
+ from _numpypy import arange
+
+ a = arange(5)
+ assert (3 & a == [0, 1, 2, 3, 0]).all()
+
+ def test_ror(self):
+ from _numpypy import arange
+
+ a = arange(5)
+ assert (3 | a == [3, 3, 3, 3, 7]).all()
+
+ def test_xor(self):
+ from _numpypy import arange
+
+ a = arange(5)
+ assert (a ^ 3 == [3, 2, 1, 0, 7]).all()
+
+ def test_rxor(self):
+ from _numpypy import arange
+
+ a = arange(5)
+ assert (3 ^ a == [3, 2, 1, 0, 7]).all()
+
def test_pos(self):
from _numpypy import array
a = array([1., -2., 3., -4., -5.])
@@ -1410,6 +1487,7 @@
a = array((range(10), range(20, 30)))
b = a.T
assert(b[:, 0] == a[0, :]).all()
+ assert (a.transpose() == b).all()

def test_flatiter(self):
from _numpypy import array, flatiter, arange
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -368,14 +368,14 @@
assert b.shape == (1, 4)
assert (add.reduce(a, 0, keepdims=True) == [12, 15, 18, 21]).all()

-
def test_bitwise(self):
- from _numpypy import bitwise_and, bitwise_or, arange, array
+ from _numpypy import bitwise_and, bitwise_or, bitwise_xor, arange, array
a = arange(6).reshape(2, 3)
assert (a & 1 == [[0, 1, 0], [1, 0, 1]]).all()
assert (a & 1 == bitwise_and(a, 1)).all()
assert (a | 1 == [[1, 1, 3], [3, 5, 5]]).all()
assert (a | 1 == bitwise_or(a, 1)).all()
+ assert (a ^ 3 == bitwise_xor(a, 3)).all()
raises(TypeError, 'array([1.0]) & 1')

def test_unary_bitops(self):
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -295,6 +295,14 @@
v1 *= v1
return res

+ @simple_binary_op
+ def lshift(self, v1, v2):
+ return v1 << v2
+
+ @simple_binary_op
+ def rshift(self, v1, v2):
+ return v1 >> v2
+
@simple_unary_op
def sign(self, v):
if v > 0:
diff --git a/pypy/module/pypyjit/__init__.py b/pypy/module/pypyjit/__init__.py
--- a/pypy/module/pypyjit/__init__.py
+++ b/pypy/module/pypyjit/__init__.py
@@ -13,6 +13,7 @@
'ResOperation': 'interp_resop.WrappedOp',
'DebugMergePoint': 'interp_resop.DebugMergePoint',
'Box': 'interp_resop.WrappedBox',
+ 'PARAMETER_DOCS': 'space.wrap(pypy.rlib.jit.PARAMETER_DOCS)',
}

def setup_after_space_initialization(self):
diff --git a/pypy/module/pypyjit/test/test_jit_setup.py b/pypy/module/pypyjit/test/test_jit_setup.py
--- a/pypy/module/pypyjit/test/test_jit_setup.py
+++ b/pypy/module/pypyjit/test/test_jit_setup.py
@@ -45,6 +45,12 @@
pypyjit.set_compile_hook(None)
pypyjit.set_param('default')

+ def test_doc(self):
+ import pypyjit
+ d = pypyjit.PARAMETER_DOCS
+ assert type(d) is dict
+ assert 'threshold' in d
+

def test_interface_residual_call():
space = gettestobjspace(usemodules=['pypyjit'])
diff --git a/pypy/module/sys/version.py b/pypy/module/sys/version.py
--- a/pypy/module/sys/version.py
+++ b/pypy/module/sys/version.py
@@ -7,7 +7,7 @@
from pypy.interpreter import gateway

#XXX # the release serial 42 is not in range(16)
-CPYTHON_VERSION = (2, 7, 1, "final", 42) #XXX # sync patchlevel.h
+CPYTHON_VERSION = (2, 7, 2, "final", 42) #XXX # sync patchlevel.h
CPYTHON_API_VERSION = 1013 #XXX # sync with include/modsupport.h

PYPY_VERSION = (1, 8, 1, "dev", 0) #XXX # sync patchlevel.h
diff --git a/pypy/module/test_lib_pypy/test_datetime.py b/pypy/module/test_lib_pypy/test_datetime.py
--- a/pypy/module/test_lib_pypy/test_datetime.py
+++ b/pypy/module/test_lib_pypy/test_datetime.py
@@ -1,7 +1,10 @@
"""Additional tests for datetime."""

+import py
+
import time
import datetime
+import copy
import os

def test_utcfromtimestamp():
@@ -22,3 +25,22 @@
del os.environ["TZ"]
else:
os.environ["TZ"] = prev_tz
+
+def test_utcfromtimestamp_microsecond():
+ dt = datetime.datetime.utcfromtimestamp(0)
+ assert isinstance(dt.microsecond, int)
+
+
+def test_integer_args():
+ with py.test.raises(TypeError):
+ datetime.datetime(10, 10, 10.)
+ with py.test.raises(TypeError):
+ datetime.datetime(10, 10, 10, 10, 10.)
+ with py.test.raises(TypeError):
+ datetime.datetime(10, 10, 10, 10, 10, 10.)
+
+def test_utcnow_microsecond():
+ dt = datetime.datetime.utcnow()
+ assert type(dt.microsecond) is int
+
+ copy.copy(dt)
\ No newline at end of file
diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py
--- a/pypy/rlib/libffi.py
+++ b/pypy/rlib/libffi.py
@@ -238,7 +238,7 @@
self = jit.promote(self)
if argchain.numargs != len(self.argtypes):
raise TypeError, 'Wrong number of arguments: %d expected, got %d' %\
- (argchain.numargs, len(self.argtypes))
+ (len(self.argtypes), argchain.numargs)
ll_args = self._prepare()
i = 0
arg = argchain.first
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -60,7 +60,8 @@
if sys.platform == 'win32':
# Can't rename a DLL: it is always called 'libpypy-c.dll'
for extra in ['libpypy-c.dll',
- 'libexpat.dll', 'sqlite3.dll', 'msvcr90.dll']:
+ 'libexpat.dll', 'sqlite3.dll', 'msvcr90.dll',
+ 'libeay32.dll', 'ssleay32.dll']:
p = pypy_c.dirpath().join(extra)
if not p.check():
p = py.path.local.sysfind(extra)
@@ -125,7 +126,7 @@
zf.close()
else:
archive = str(builddir.join(name + '.tar.bz2'))
- if sys.platform == 'darwin':
+ if sys.platform == 'darwin' or sys.platform.startswith('freebsd'):
e = os.system('tar --numeric-owner -cvjf ' + archive + " " + name)
else:
e = os.system('tar --owner=root --group=root --numeric-owner -cvjf ' + archive + " " + name)
diff --git a/pypy/translator/c/database.py b/pypy/translator/c/database.py
--- a/pypy/translator/c/database.py
+++ b/pypy/translator/c/database.py
@@ -28,11 +28,13 @@
gctransformer = None

def __init__(self, translator=None, standaloneúlse,
+ cpython_extensionúlse,
gcpolicyclass=None,
thread_enabledúlse,
sandboxúlse):
self.translator = translator
self.standalone = standalone
+ self.cpython_extension = cpython_extension
self.sandbox = sandbox
if gcpolicyclass is None:
gcpolicyclass = gc.RefcountingGcPolicy
diff --git a/pypy/translator/c/dlltool.py b/pypy/translator/c/dlltool.py
--- a/pypy/translator/c/dlltool.py
+++ b/pypy/translator/c/dlltool.py
@@ -14,11 +14,14 @@
CBuilder.__init__(self, *args, **kwds)

def getentrypointptr(self):
+ entrypoints = []
bk = self.translator.annotator.bookkeeper
- graphs = [bk.getdesc(f).cachedgraph(None) for f, _ in self.functions]
- return [getfunctionptr(graph) for graph in graphs]
+ for f, _ in self.functions:
+ graph = bk.getdesc(f).getuniquegraph()
+ entrypoints.append(getfunctionptr(graph))
+ return entrypoints

- def gen_makefile(self, targetdir):
+ def gen_makefile(self, targetdir, exe_name=None):
pass # XXX finish

def compile(self):
diff --git a/pypy/translator/c/extfunc.py b/pypy/translator/c/extfunc.py
--- a/pypy/translator/c/extfunc.py
+++ b/pypy/translator/c/extfunc.py
@@ -106,7 +106,7 @@
yield ('RPYTHON_EXCEPTION_MATCH', exceptiondata.fn_exception_match)
yield ('RPYTHON_TYPE_OF_EXC_INST', exceptiondata.fn_type_of_exc_inst)
yield ('RPYTHON_RAISE_OSERROR', exceptiondata.fn_raise_OSError)
- if not db.standalone:
+ if db.cpython_extension:
yield ('RPYTHON_PYEXCCLASS2EXC', exceptiondata.fn_pyexcclass2exc)

yield ('RPyExceptionOccurred1', exctransformer.rpyexc_occured_ptr.value)
diff --git a/pypy/translator/c/gcc/trackgcroot.py b/pypy/translator/c/gcc/trackgcroot.py
--- a/pypy/translator/c/gcc/trackgcroot.py
+++ b/pypy/translator/c/gcc/trackgcroot.py
@@ -471,19 +471,22 @@
return []

IGNORE_OPS_WITH_PREFIXES = dict.fromkeys([
- 'cmp', 'test', 'set', 'sahf', 'lahf', 'cltd', 'cld', 'std',
- 'rep', 'movs', 'lods', 'stos', 'scas', 'cwtl', 'cwde', 'prefetch',
+ 'cmp', 'test', 'set', 'sahf', 'lahf', 'cld', 'std',
+ 'rep', 'movs', 'lods', 'stos', 'scas', 'cwde', 'prefetch',
# floating-point operations cannot produce GC pointers
'f',
'cvt', 'ucomi', 'comi', 'subs', 'subp' , 'adds', 'addp', 'xorp',
'movap', 'movd', 'movlp', 'sqrtsd', 'movhpd',
'mins', 'minp', 'maxs', 'maxp', 'unpck', 'pxor', 'por', # sse2
+ 'shufps', 'shufpd',
# arithmetic operations should not produce GC pointers
'inc', 'dec', 'not', 'neg', 'or', 'and', 'sbb', 'adc',
'shl', 'shr', 'sal', 'sar', 'rol', 'ror', 'mul', 'imul', 'div', 'idiv',
'bswap', 'bt', 'rdtsc',
'punpck', 'pshufd', 'pcmp', 'pand', 'psllw', 'pslld', 'psllq',
'paddq', 'pinsr',
+ # sign-extending moves should not produce GC pointers
+ 'cbtw', 'cwtl', 'cwtd', 'cltd', 'cltq', 'cqto',
# zero-extending moves should not produce GC pointers
'movz',
# locked operations should not move GC pointers, at least so far
diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -111,6 +111,7 @@
_compiled = False
modulename = None
split = False
+ cpython_extension = False

def __init__(self, translator, entrypoint, config, gcpolicy=None,
secondary_entrypoints=()):
@@ -138,6 +139,7 @@
raise NotImplementedError("--gcrootfinder=asmgcc requires standalone")

db = LowLevelDatabase(translator, standalone=self.standalone,
+ cpython_extension=self.cpython_extension,
gcpolicyclass=gcpolicyclass,
thread_enabled=self.config.translation.thread,
sandbox=self.config.translation.sandbox)
@@ -236,6 +238,8 @@
CBuilder.have___thread = self.translator.platform.check___thread()
if not self.standalone:
assert not self.config.translation.instrument
+ if self.cpython_extension:
+ defines['PYPY_CPYTHON_EXTENSION'] = 1
else:
defines['PYPY_STANDALONE'] = db.get(pf)
if self.config.translation.instrument:
@@ -307,13 +311,18 @@

class CExtModuleBuilder(CBuilder):
standalone = False
+ cpython_extension = True
_module = None
_wrapper = None

def get_eci(self):
from distutils import sysconfig
python_inc = sysconfig.get_python_inc()
- eci = ExternalCompilationInfo(include_dirs=[python_inc])
+ eci = ExternalCompilationInfo(
+ include_dirs=[python_inc],
+ includes=["Python.h",
+ ],
+ )
return eci.merge(CBuilder.get_eci(self))

def getentrypointptr(self): # xxx
diff --git a/pypy/translator/c/src/exception.h b/pypy/translator/c/src/exception.h
--- a/pypy/translator/c/src/exception.h
+++ b/pypy/translator/c/src/exception.h
@@ -2,7 +2,7 @@
/************************************************************/
/*** C header subsection: exceptions ***/

-#if !defined(PYPY_STANDALONE) && !defined(PYPY_NOT_MAIN_FILE)
+#if defined(PYPY_CPYTHON_EXTENSION) && !defined(PYPY_NOT_MAIN_FILE)
PyObject *RPythonError;
#endif

@@ -74,7 +74,7 @@
RPyRaiseException(RPYTHON_TYPE_OF_EXC_INST(rexc), rexc);
}

-#ifndef PYPY_STANDALONE
+#ifdef PYPY_CPYTHON_EXTENSION
void RPyConvertExceptionFromCPython(void)
{
/* convert the CPython exception to an RPython one */
diff --git a/pypy/translator/c/src/g_include.h b/pypy/translator/c/src/g_include.h
--- a/pypy/translator/c/src/g_include.h
+++ b/pypy/translator/c/src/g_include.h
@@ -2,7 +2,7 @@
/************************************************************/
/*** C header file for code produced by genc.py ***/

-#ifndef PYPY_STANDALONE
+#ifdef PYPY_CPYTHON_EXTENSION
# include "Python.h"
# include "compile.h"
# include "frameobject.h"
diff --git a/pypy/translator/c/src/g_prerequisite.h b/pypy/translator/c/src/g_prerequisite.h
--- a/pypy/translator/c/src/g_prerequisite.h
+++ b/pypy/translator/c/src/g_prerequisite.h
@@ -5,8 +5,6 @@

#ifdef PYPY_STANDALONE
# include "src/commondefs.h"
-#else
-# include "Python.h"
#endif

#ifdef _WIN32
diff --git a/pypy/translator/c/src/pyobj.h b/pypy/translator/c/src/pyobj.h
--- a/pypy/translator/c/src/pyobj.h
+++ b/pypy/translator/c/src/pyobj.h
@@ -2,7 +2,7 @@
/************************************************************/
/*** C header subsection: untyped operations ***/
/*** as OP_XXX() macros calling the CPython API ***/
-
+#ifdef PYPY_CPYTHON_EXTENSION

#define op_bool(r,what) { \
int _retval = what; \
@@ -261,3 +261,5 @@
}

#endif
+
+#endif /* PYPY_CPYTHON_EXTENSION */
diff --git a/pypy/translator/c/src/support.h b/pypy/translator/c/src/support.h
--- a/pypy/translator/c/src/support.h
+++ b/pypy/translator/c/src/support.h
@@ -104,7 +104,7 @@
# define RPyBareItem(array, index) ((array)[index])
#endif

-#ifndef PYPY_STANDALONE
+#ifdef PYPY_CPYTHON_EXTENSION

/* prototypes */

diff --git a/pypy/translator/c/test/test_dlltool.py b/pypy/translator/c/test/test_dlltool.py
--- a/pypy/translator/c/test/test_dlltool.py
+++ b/pypy/translator/c/test/test_dlltool.py
@@ -2,7 +2,6 @@
from pypy.translator.c.dlltool import DLLDef
from ctypes import CDLL
import py
-py.test.skip("fix this if needed")

class TestDLLTool(object):
def test_basic(self):
@@ -16,8 +15,8 @@
d = DLLDef('lib', [(f, [int]), (b, [int])])
so = d.compile()
dll = CDLL(str(so))
- assert dll.f(3) == 3
- assert dll.b(10) == 12
+ assert dll.pypy_g_f(3) == 3
+ assert dll.pypy_g_b(10) == 12

def test_split_criteria(self):
def f(x):
@@ -28,4 +27,5 @@

d = DLLDef('lib', [(f, [int]), (b, [int])])
so = d.compile()
- assert py.path.local(so).dirpath().join('implement.c').check()
+ dirpath = py.path.local(so).dirpath()
+ assert dirpath.join('translator_c_test_test_dlltool.c').check()
diff --git a/pypy/translator/driver.py b/pypy/translator/driver.py
--- a/pypy/translator/driver.py
+++ b/pypy/translator/driver.py
@@ -331,6 +331,7 @@
raise Exception("stand-alone program entry point must return an "
"int (and not, e.g., None or always raise an "
"exception).")
+ annotator.complete()
annotator.simplify()
return s

diff --git a/pypy/translator/goal/app_main.py b/pypy/translator/goal/app_main.py
--- a/pypy/translator/goal/app_main.py
+++ b/pypy/translator/goal/app_main.py
@@ -139,8 +139,14 @@
items = pypyjit.defaults.items()
items.sort()
for key, value in items:
- print ' --jit %s=N %s%s (default %s)' % (
- key, ' '*(18-len(key)), pypyjit.PARAMETER_DOCS[key], value)
+ prefix = ' --jit %s=N %s' % (key, ' '*(18-len(key)))
+ doc = '%s (default %s)' % (pypyjit.PARAMETER_DOCS[key], value)
+ while len(doc) > 51:
+ i = doc[:51].rfind(' ')
+ print prefix + doc[:i]
+ doc = doc[i+1:]
+ prefix = ' '*len(prefix)
+ print prefix + doc
print ' --jit off turn off the JIT'

def print_version(*args):
reply

Search Discussions

Discussion Posts

Previous

Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 2 of 4 | next ›

1 user in discussion

Bivab: 4 posts