[pypy-commit] pypy refactor-str-types: hg merge default
Manuel Jacob
noreply at buildbot.pypy.org
Sat Jul 27 03:44:14 CEST 2013
Author: Manuel Jacob
Branch: refactor-str-types
Changeset: r65700:1b8a81ea64cc
Date: 2013-07-26 22:47 +0200
http://bitbucket.org/pypy/pypy/changeset/1b8a81ea64cc/
Log: hg merge default
diff --git a/lib_pypy/_pypy_irc_topic.py b/lib_pypy/_pypy_irc_topic.py
--- a/lib_pypy/_pypy_irc_topic.py
+++ b/lib_pypy/_pypy_irc_topic.py
@@ -165,6 +165,63 @@
Nyy rkprcgoybpxf frrz fnar.
N cvax tyvggrel ebgngvat ynzoqn
"vg'f yvxryl grzcbenel hagvy sberire" nevtb
+"Lbh xabj jung'f avpr nobhg EClguba? Ybatre fjbeq svtugf."
+nccneragyl pbashfvba vf n srngher
+nccneragyl pbashfvba vf n srngher... be vf vg?
+ClCl 1.7 eryrnfrq
+vs lbh jnag gb or penml, lbh qba'g unir gb sbepr vg
+vs lbh jnag vg gb or iveghny, lbh fubhyq abg sbepr vg
+<Nyrk_Tnlabe> svwny: V whfg... fgnegrq pbqvat naq fhqqragyl... nobzvangvba
+fabj, fabj! :-)
+fabj, fabj, fabj, fabj
+clcl 1.8 eryrnfrq
+vg jnf srj lnxf gbb yngr
+ClCl vf n enpr orgjrra hf funivat lnxf, naq gur havirefr gelvat gb cebqhpr zber naq zber lnxf
+Jevgvat na SC7 nabalzbhf cebcbfny sbe ClCl vf yvxr znxvat n gi nq sbe n uvtu cresbeznapr fcbegf pne jvgubhg orvat noyr gb zragvba vgf zbqry be znahsnpghere
+Fabj, fabj (ntnva)
+Fgvyy fabjvat
+thrff jung, fabj
+"lbh haqrerfgvzngr gur vzcbegnapr bs zvpebnepuvgrpgher" "ab, vg'f zber gung jr ner fgvyy unccvyl va gur ynaq bs ernpunoyr sehvg"
+Jub nz V? Naq vs lrf, ubj znal?
+ClCl vf nyjnlf n cynfzn
+"genafyngvba gbbypunva" = "EClgure"? gb jevgr vagrEClguref va
+"sberire" va clcl grezf zrnaf yvxr srj zbaguf :)
+"Onu. PClguba bofphevgl. - Nezva Evtb"
+svwny: pna V vavgvngr lbh ba gur (rnfl ohg) aba-gevivny gbcvp bs jevgvat P shapgvba glcrf? :-)
+nyy fbsgjner vzcebirzragf unccra ol n ovg
+gur genprf qba'g yvr
+:-) be engure ":-/" bss-ol-bar-xrl reebe
+Be Nezva Evtb. V guvax ur'f noyr gb haqrefgnaq k86 gur jnl Plcure pna frr jbzra va gur zngevk.
+V zvtug, ohg abobql erfcrpgf zr
+cerohvyg vafgnapr Ryyvcfvf unf ab nggevohgr 'reeab'
+guvf frnfba'f svefg "fabj! fabj!" vf urer
+ClCl 2.0 orgn1 eryrnfrq - orggre yngr guna arire
+Fjvgreynaq 2012: zber fabj va Qrprzore guna rire fvapr clcl fgnegrq
+Fjvgmreynaq 2012: zber fabj va Qrprzore guna rire fvapr clcl fgnegrq
+<nevtngb> n sngny reebe, ol qrsvavgvba, vf sngny
+<nagbphav> V'z tynq gung jr cebtenz va Clguba naq jr qba'g qrny jvgu gubfr vffhrf rirel qnl. Ncneg gur snpg gung jr unir gb qrny jvgu gurz naljnl, vg frrzf
+unccl arj lrne!
+"zrffl" vf abg n whqtrzrag, ohg whfg n snpg bs pbzcyvpngrqarff
+n ybg bs fabj
+qb lbh xabj nobhg n gbnfgre jvgu 8XO bs ENZ naq 64XO bs EBZ?
+vg'f orra fabjvat rirelqnl sbe n juvyr, V pna'g whfg chg "fabj, fabj" hc urer rirel qnl
+fabjonyy svtugf!
+sbejneq pbzcngvovyvgl jvgu bcgvzvmngvbaf gung unira'g orra vairagrq lrg
+jr fgvyy unir gb jevgr fbsgjner jvgu n zrgnfcnpr ohooyr va vg
+cebonoyl gur ynfg gvzr va gur frnfba, ohg: fabj, fabj!
+ClCl 2.0-orgn2 eryrnfrq
+Gur ceboyrz vf gung sbe nyzbfg nal aba-gevivny cebtenz, vg'f abg pyrne jung 'pbeerpg' zrnaf.
+ClCl 2.0 nyzbfg eryrnfrq
+ClCl 2.0 eryrnfrq
+WVG pbzcvyref fubhyq or jevggra ol crbcyr jub npghnyyl unir snvgu va WVG pbzcvyref' novyvgl gb znxrf guvatf tb fpernzvat snfg
+ClCl 2.0.1 eryrnfrq
+arire haqrerfgvzngr gur vzcebonoyr jura lbh qb fbzrguvat ng 2TUm
+ClCl 2.0.2 eryrnfrq
+nyy jr arrq vf n angvir Cebybt znpuvar
+V haqrefgnaq ubj qravnyvfz vf n onq qrohttvat grpuavdhr
+rirel IZ fubhyq pbzr jvgu arheny argjbex genvarq gb erpbtavmr zvpeborapuznexf naq enaqbzyl syhpghngr gurz +/-9000%
+lbh qvq abg nccebnpu clcl sebz gur rnfl raq: fgz, gura wvg. vg'f n ovg gur Abegu snpr
+va ClCl orvat bayl zbqrengryl zntvp vf n tbbq guvat <psobym>
"""
from string import ascii_uppercase, ascii_lowercase
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
@@ -91,8 +91,8 @@
python ../../rpython/bin/rpython --opt=jit targetpypystandalone.py
possibly replacing ``--opt=jit`` with another `optimization level`_
- of your choice like ``--opt=2`` if you do not want to include the JIT
- compiler, which makes the Python interpreter much slower.
+ of your choice. Typical example: ``--opt=2`` gives a good (but of
+ course slower) Python interpreter without the JIT.
.. _`optimization level`: config/opt.html
diff --git a/pypy/doc/release-2.1.0-beta2.rst b/pypy/doc/release-2.1.0-beta2.rst
--- a/pypy/doc/release-2.1.0-beta2.rst
+++ b/pypy/doc/release-2.1.0-beta2.rst
@@ -3,14 +3,20 @@
===============
We're pleased to announce the second beta of the upcoming 2.1 release of PyPy.
-This beta does not add any new features to the 2.1 release, but contains several bugfixes listed below.
+This beta adds one new feature to the 2.1 release and contains several bugfixes listed below.
+
+You can download the PyPy 2.1 beta 1 release here:
+
+ http://pypy.org/download.html
Highlights
==========
+* Support for os.statvfs and os.fstatvfs on unix systems.
+
* Fixed issue `1533`_: fix an RPython-level OverflowError for space.float_w(w_big_long_number).
-* Fixed issue `1552`_: GreenletExit should inherit from BaseException
+* Fixed issue `1552`_: GreenletExit should inherit from BaseException.
* Fixed issue `1537`_: numpypy __array_interface__
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -31,3 +31,18 @@
more precise information about which functions can be called. Needed for Topaz.
.. branch: ssl_moving_write_buffer
+
+.. branch: pythoninspect-fix
+Make PyPy respect PYTHONINSPECT variable set via os.putenv in the same process
+to start interactive prompt when the script execution finishes. This adds
+new __pypy__.os.real_getenv call that bypasses Python cache and looksup env
+in the underlying OS. Translatorshell now works on PyPy.
+
+.. branch: add-statvfs
+Added os.statvfs and os.fstatvfs
+
+.. branch: statvfs_tests
+Added some addition tests for statvfs.
+
+.. branch: ndarray-subtypes
+Allow subclassing ndarray, i.e. matrix
diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py
--- a/pypy/interpreter/app_main.py
+++ b/pypy/interpreter/app_main.py
@@ -556,8 +556,15 @@
# or
# * PYTHONINSPECT is set and stdin is a tty.
#
+ try:
+ # we need a version of getenv that bypasses Python caching
+ from __pypy__.os import real_getenv
+ except ImportError:
+ # dont fail on CPython here
+ real_getenv = os.getenv
+
return (interactive or
- ((inspect or (readenv and os.getenv('PYTHONINSPECT')))
+ ((inspect or (readenv and real_getenv('PYTHONINSPECT')))
and sys.stdin.isatty()))
success = True
diff --git a/pypy/interpreter/test/test_app_main.py b/pypy/interpreter/test/test_app_main.py
--- a/pypy/interpreter/test/test_app_main.py
+++ b/pypy/interpreter/test/test_app_main.py
@@ -48,7 +48,7 @@
pdir = _get_next_path(ext='')
p = pdir.ensure(dir=1).join('__main__.py')
p.write(str(py.code.Source(source)))
- # return relative path for testing purposes
+ # return relative path for testing purposes
return py.path.local().bestrelpath(pdir)
demo_script = getscript("""
@@ -706,6 +706,20 @@
assert 'hello world\n' in data
assert '42\n' in data
+ def test_putenv_fires_interactive_within_process(self):
+ try:
+ import __pypy__
+ except ImportError:
+ py.test.skip("This can be only tested on PyPy with real_getenv")
+
+ # should be noninteractive when piped in
+ data = 'import os\nos.putenv("PYTHONINSPECT", "1")\n'
+ self.run('', senddata=data, expect_prompt=False)
+
+ # should go interactive with -c
+ data = data.replace('\n', ';')
+ self.run("-c '%s'" % data, expect_prompt=True)
+
def test_option_S_copyright(self):
data = self.run('-S -i', expect_prompt=True, expect_banner=True)
assert 'copyright' not in data
@@ -971,7 +985,7 @@
pypy_c = os.path.join(self.trunkdir, 'pypy', 'goal', 'pypy-c')
app_main.setup_bootstrap_path(pypy_c)
newpath = sys.path[:]
- # we get at least lib_pypy
+ # we get at least lib_pypy
# lib-python/X.Y.Z, and maybe more (e.g. plat-linux2)
assert len(newpath) >= 2
for p in newpath:
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -50,6 +50,13 @@
}
+class OsModule(MixedModule):
+ appleveldefs = {}
+ interpleveldefs = {
+ 'real_getenv': 'interp_os.real_getenv'
+ }
+
+
class Module(MixedModule):
appleveldefs = {
}
@@ -82,6 +89,7 @@
"time": TimeModule,
"thread": ThreadModule,
"intop": IntOpModule,
+ "os": OsModule,
}
def setup_after_space_initialization(self):
diff --git a/pypy/module/__pypy__/interp_os.py b/pypy/module/__pypy__/interp_os.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/interp_os.py
@@ -0,0 +1,9 @@
+import os
+
+from pypy.interpreter.gateway import unwrap_spec
+
+
+ at unwrap_spec(name='str0')
+def real_getenv(space, name):
+ """Get an OS environment value skipping Python cache"""
+ return space.wrap(os.environ.get(name))
diff --git a/pypy/module/__pypy__/test/test_os.py b/pypy/module/__pypy__/test/test_os.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/test/test_os.py
@@ -0,0 +1,16 @@
+class AppTestOs:
+ spaceconfig = dict(usemodules=['__pypy__'])
+
+ def test_real_getenv(self):
+ import __pypy__.os
+ import os
+
+ key = 'UNLIKELY_SET'
+ assert key not in os.environ
+ os.putenv(key, '42')
+ # this one skips Python cache
+ assert __pypy__.os.real_getenv(key) == '42'
+ # this one can only see things set on interpter start (cached)
+ assert os.getenv(key) is None
+ os.unsetenv(key)
+ assert __pypy__.os.real_getenv(key) is None
diff --git a/pypy/module/_cffi_backend/libraryobj.py b/pypy/module/_cffi_backend/libraryobj.py
--- a/pypy/module/_cffi_backend/libraryobj.py
+++ b/pypy/module/_cffi_backend/libraryobj.py
@@ -4,6 +4,7 @@
from pypy.interpreter.error import operationerrfmt
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef
+from pypy.module._rawffi.interp_rawffi import wrap_dlopenerror
from rpython.rtyper.lltypesystem import rffi
from rpython.rlib.rdynload import DLLHANDLE, dlopen, dlsym, dlclose, DLOpenError
@@ -24,9 +25,7 @@
try:
self.handle = dlopen(ll_libname, flags)
except DLOpenError, e:
- raise operationerrfmt(space.w_OSError,
- "cannot load library %s: %s",
- filename, e.msg)
+ raise wrap_dlopenerror(space, e, filename)
self.name = filename
def __del__(self):
diff --git a/pypy/module/_ffi/interp_funcptr.py b/pypy/module/_ffi/interp_funcptr.py
--- a/pypy/module/_ffi/interp_funcptr.py
+++ b/pypy/module/_ffi/interp_funcptr.py
@@ -14,7 +14,7 @@
from rpython.rlib.rarithmetic import r_uint
from rpython.rlib.objectmodel import we_are_translated
from pypy.module._ffi.type_converter import FromAppLevelConverter, ToAppLevelConverter
-from pypy.module._rawffi.interp_rawffi import got_libffi_error
+from pypy.module._rawffi.interp_rawffi import got_libffi_error, wrap_dlopenerror
import os
if os.name == 'nt':
@@ -324,8 +324,7 @@
try:
self.cdll = libffi.CDLL(name, mode)
except DLOpenError, e:
- raise operationerrfmt(space.w_OSError, '%s: %s', self.name,
- e.msg or 'unspecified error')
+ raise wrap_dlopenerror(space, e, self.name)
def getfunc(self, space, w_name, w_argtypes, w_restype):
return _getfunc(space, self, w_name, w_argtypes, w_restype)
diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py
--- a/pypy/module/_rawffi/interp_rawffi.py
+++ b/pypy/module/_rawffi/interp_rawffi.py
@@ -140,6 +140,11 @@
raise OperationError(space.w_SystemError,
space.wrap("not supported by libffi"))
+def wrap_dlopenerror(space, e, filename):
+ msg = e.msg if e.msg else 'unspecified error'
+ return operationerrfmt(space.w_OSError, 'Cannot load library %s: %s',
+ filename, msg)
+
class W_CDLL(W_Root):
def __init__(self, space, name, cdll):
@@ -219,8 +224,7 @@
try:
cdll = CDLL(name)
except DLOpenError, e:
- raise operationerrfmt(space.w_OSError, '%s: %s', name,
- e.msg or 'unspecified error')
+ raise wrap_dlopenerror(space, e, name)
except OSError, e:
raise wrap_oserror(space, e)
return space.wrap(W_CDLL(space, name, cdll))
diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py
--- a/pypy/module/_rawffi/test/test__rawffi.py
+++ b/pypy/module/_rawffi/test/test__rawffi.py
@@ -223,7 +223,8 @@
_rawffi.CDLL("xxxxx_this_name_does_not_exist_xxxxx")
except OSError, e:
print e
- assert str(e).startswith("xxxxx_this_name_does_not_exist_xxxxx: ")
+ assert str(e).startswith(
+ "Cannot load library xxxxx_this_name_does_not_exist_xxxxx: ")
else:
raise AssertionError("did not fail??")
diff --git a/pypy/module/micronumpy/arrayimpl/concrete.py b/pypy/module/micronumpy/arrayimpl/concrete.py
--- a/pypy/module/micronumpy/arrayimpl/concrete.py
+++ b/pypy/module/micronumpy/arrayimpl/concrete.py
@@ -229,7 +229,7 @@
except IndexError:
# not a single result
chunks = self._prepare_slice_args(space, w_index)
- return chunks.apply(orig_arr)
+ return chunks.apply(space, orig_arr)
def descr_setitem(self, space, orig_arr, w_index, w_value):
try:
@@ -238,7 +238,7 @@
except IndexError:
w_value = convert_to_array(space, w_value)
chunks = self._prepare_slice_args(space, w_index)
- view = chunks.apply(orig_arr)
+ view = chunks.apply(space, orig_arr)
view.implementation.setslice(space, w_value)
def transpose(self, orig_array):
@@ -269,14 +269,14 @@
shape, skip)
return iter.MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape)
- def swapaxes(self, orig_arr, axis1, axis2):
+ def swapaxes(self, space, orig_arr, axis1, axis2):
shape = self.get_shape()[:]
strides = self.get_strides()[:]
backstrides = self.get_backstrides()[:]
shape[axis1], shape[axis2] = shape[axis2], shape[axis1]
strides[axis1], strides[axis2] = strides[axis2], strides[axis1]
backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1]
- return W_NDimArray.new_slice(self.start, strides,
+ return W_NDimArray.new_slice(space, self.start, strides,
backstrides, shape, self, orig_arr)
def get_storage_as_int(self, space):
@@ -289,13 +289,16 @@
return ArrayBuffer(self)
def astype(self, space, dtype):
- new_arr = W_NDimArray.from_shape(self.get_shape(), dtype)
+ strides, backstrides = support.calc_strides(self.get_shape(), dtype,
+ self.order)
+ impl = ConcreteArray(self.get_shape(), dtype, self.order,
+ strides, backstrides)
if self.dtype.is_str_or_unicode() and not dtype.is_str_or_unicode():
raise OperationError(space.w_NotImplementedError, space.wrap(
"astype(%s) not implemented yet" % self.dtype))
else:
- loop.setslice(space, new_arr.get_shape(), new_arr.implementation, self)
- return new_arr
+ loop.setslice(space, impl.get_shape(), impl, self)
+ return impl
class ConcreteArrayNotOwning(BaseConcreteArray):
diff --git a/pypy/module/micronumpy/arrayimpl/scalar.py b/pypy/module/micronumpy/arrayimpl/scalar.py
--- a/pypy/module/micronumpy/arrayimpl/scalar.py
+++ b/pypy/module/micronumpy/arrayimpl/scalar.py
@@ -139,7 +139,7 @@
if not new_shape:
return self
if support.product(new_shape) == 1:
- arr = W_NDimArray.from_shape(new_shape, self.dtype)
+ arr = W_NDimArray.from_shape(space, new_shape, self.dtype)
arr_iter = arr.create_iter(new_shape)
arr_iter.setitem(self.value)
return arr.implementation
@@ -152,7 +152,7 @@
def create_axis_iter(self, shape, dim, cum):
raise Exception("axis iter should not happen on scalar")
- def swapaxes(self, orig_array, axis1, axis2):
+ def swapaxes(self, space, orig_array, axis1, axis2):
raise Exception("should not be called")
def fill(self, w_value):
@@ -166,7 +166,7 @@
return space.wrap(0)
def astype(self, space, dtype):
- return W_NDimArray.new_scalar(space, dtype, self.value)
+ raise Exception("should not be called")
def base(self):
return None
diff --git a/pypy/module/micronumpy/arrayimpl/sort.py b/pypy/module/micronumpy/arrayimpl/sort.py
--- a/pypy/module/micronumpy/arrayimpl/sort.py
+++ b/pypy/module/micronumpy/arrayimpl/sort.py
@@ -126,7 +126,7 @@
axis = space.int_w(w_axis)
# create array of indexes
dtype = interp_dtype.get_dtype_cache(space).w_longdtype
- index_arr = W_NDimArray.from_shape(arr.get_shape(), dtype)
+ index_arr = W_NDimArray.from_shape(space, arr.get_shape(), dtype)
storage = index_arr.implementation.get_storage()
if len(arr.get_shape()) == 1:
for i in range(arr.get_size()):
diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py
--- a/pypy/module/micronumpy/base.py
+++ b/pypy/module/micronumpy/base.py
@@ -10,6 +10,15 @@
space.isinstance_w(w_obj, space.w_list) or
isinstance(w_obj, W_NDimArray))
+def wrap_impl(space, w_cls, w_instance, impl):
+ if w_cls is None or space.is_w(w_cls, space.gettypefor(W_NDimArray)):
+ w_ret = W_NDimArray(impl)
+ else:
+ w_ret = space.allocate_instance(W_NDimArray, w_cls)
+ W_NDimArray.__init__(w_ret, impl)
+ assert isinstance(w_ret, W_NDimArray)
+ space.call_method(w_ret, '__array_finalize__', w_instance)
+ return w_ret
class ArrayArgumentException(Exception):
pass
@@ -20,10 +29,11 @@
def __init__(self, implementation):
assert isinstance(implementation, BaseArrayImplementation)
+ assert isinstance(self, W_NDimArray)
self.implementation = implementation
@staticmethod
- def from_shape(shape, dtype, order='C'):
+ def from_shape(space, shape, dtype, order='C', w_instance=None):
from pypy.module.micronumpy.arrayimpl import concrete, scalar
if not shape:
@@ -32,10 +42,12 @@
strides, backstrides = calc_strides(shape, dtype.base, order)
impl = concrete.ConcreteArray(shape, dtype.base, order, strides,
backstrides)
+ if w_instance:
+ return wrap_impl(space, space.type(w_instance), w_instance, impl)
return W_NDimArray(impl)
@staticmethod
- def from_shape_and_storage(shape, storage, dtype, order='C', owning=False):
+ def from_shape_and_storage(space, shape, storage, dtype, order='C', owning=False, w_subtype=None):
from pypy.module.micronumpy.arrayimpl import concrete
assert shape
strides, backstrides = calc_strides(shape, dtype, order)
@@ -46,15 +58,20 @@
else:
impl = concrete.ConcreteArrayNotOwning(shape, dtype, order, strides,
backstrides, storage)
+ if w_subtype:
+ w_ret = space.allocate_instance(W_NDimArray, w_subtype)
+ W_NDimArray.__init__(w_ret, impl)
+ space.call_method(w_ret, '__array_finalize__', w_subtype)
+ return w_ret
return W_NDimArray(impl)
@staticmethod
- def new_slice(offset, strides, backstrides, shape, parent, orig_arr, dtype=None):
+ def new_slice(space, offset, strides, backstrides, shape, parent, orig_arr, dtype=None):
from pypy.module.micronumpy.arrayimpl import concrete
impl = concrete.SliceArray(offset, strides, backstrides, shape, parent,
orig_arr, dtype)
- return W_NDimArray(impl)
+ return wrap_impl(space, space.type(orig_arr), orig_arr, impl)
@staticmethod
def new_scalar(space, dtype, w_val=None):
diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -35,10 +35,12 @@
class BadToken(Exception):
pass
+
SINGLE_ARG_FUNCTIONS = ["sum", "prod", "max", "min", "all", "any",
"unegative", "flat", "tostring","count_nonzero",
"argsort"]
TWO_ARG_FUNCTIONS = ["dot", 'take']
+TWO_ARG_FUNCTIONS_OR_NONE = ['view']
THREE_ARG_FUNCTIONS = ['where']
class W_TypeObject(W_Root):
@@ -184,14 +186,23 @@
def is_true(self, w_obj):
assert isinstance(w_obj, BoolObject)
- return False
- #return w_obj.boolval
+ return w_obj.boolval
def is_w(self, w_obj, w_what):
return w_obj is w_what
+ def issubtype(self, w_type1, w_type2):
+ return BoolObject(True)
+
def type(self, w_obj):
- return w_obj.tp
+ if self.is_none(w_obj):
+ return self.w_None
+ try:
+ return w_obj.tp
+ except AttributeError:
+ if isinstance(w_obj, W_NDimArray):
+ return W_NDimArray
+ return self.w_None
def gettypefor(self, w_obj):
return None
@@ -199,6 +210,11 @@
def call_function(self, tp, w_dtype):
return w_dtype
+ def call_method(self, w_obj, s, *args):
+ # XXX even the hacks have hacks
+ return None
+ #return getattr(w_obj, 'descr_' + s)(self, *args)
+
@specialize.arg(1)
def interp_w(self, tp, what):
assert isinstance(what, tp)
@@ -329,6 +345,8 @@
self.name = name.strip(" ")
def execute(self, interp):
+ if self.name == 'None':
+ return None
return interp.variables[self.name]
def __repr__(self):
@@ -451,6 +469,32 @@
def __repr__(self):
return 'slice(%s,%s,%s)' % (self.start, self.stop, self.step)
+class ArrayClass(Node):
+ def __init__(self):
+ self.v = W_NDimArray
+
+ def execute(self, interp):
+ return self.v
+
+ def __repr__(self):
+ return '<class W_NDimArray>'
+
+class DtypeClass(Node):
+ def __init__(self, dt):
+ self.v = dt
+
+ def execute(self, interp):
+ if self.v == 'int':
+ dtype = get_dtype_cache(interp.space).w_int64dtype
+ elif self.v == 'float':
+ dtype = get_dtype_cache(interp.space).w_float64dtype
+ else:
+ raise BadToken('unknown v to dtype "%s"' % self.v)
+ return dtype
+
+ def __repr__(self):
+ return '<class %s dtype>' % self.v
+
class Execute(Node):
def __init__(self, expr):
self.expr = expr
@@ -533,6 +577,14 @@
w_res = where(interp.space, arr, arg1, arg2)
else:
assert False
+ elif self.name in TWO_ARG_FUNCTIONS_OR_NONE:
+ if len(self.args) != 2:
+ raise ArgumentMismatch
+ arg = self.args[1].execute(interp)
+ if self.name == 'view':
+ w_res = arr.descr_view(interp.space, arg)
+ else:
+ assert False
else:
raise WrongFunctionName
if isinstance(w_res, W_NDimArray):
@@ -652,8 +704,14 @@
if token.name == 'identifier':
if tokens.remaining() and tokens.get(0).name == 'paren_left':
stack.append(self.parse_function_call(token.v, tokens))
+ elif token.v.strip(' ') == 'ndarray':
+ stack.append(ArrayClass())
+ elif token.v.strip(' ') == 'int':
+ stack.append(DtypeClass('int'))
+ elif token.v.strip(' ') == 'float':
+ stack.append(DtypeClass('float'))
else:
- stack.append(Variable(token.v))
+ stack.append(Variable(token.v.strip(' ')))
elif token.name == 'array_left':
stack.append(ArrayConstant(self.parse_array_const(tokens)))
elif token.name == 'operator':
diff --git a/pypy/module/micronumpy/interp_arrayops.py b/pypy/module/micronumpy/interp_arrayops.py
--- a/pypy/module/micronumpy/interp_arrayops.py
+++ b/pypy/module/micronumpy/interp_arrayops.py
@@ -88,7 +88,7 @@
y.get_dtype())
shape = shape_agreement(space, arr.get_shape(), x)
shape = shape_agreement(space, shape, y)
- out = W_NDimArray.from_shape(shape, dtype)
+ out = W_NDimArray.from_shape(space, shape, dtype)
return loop.where(out, shape, arr, x, y, dtype)
def dot(space, w_obj1, w_obj2):
@@ -131,7 +131,8 @@
arr.get_dtype())
if _axis < 0 or len(arr.get_shape()) <= _axis:
raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape))
- res = W_NDimArray.from_shape(shape, dtype, 'C')
+ # concatenate does not handle ndarray subtypes, it always returns a ndarray
+ res = W_NDimArray.from_shape(space, shape, dtype, 'C')
chunks = [Chunk(0, i, 1, i) for i in shape]
axis_start = 0
for arr in args_w:
@@ -139,7 +140,7 @@
continue
chunks[_axis] = Chunk(axis_start, axis_start + arr.get_shape()[_axis], 1,
arr.get_shape()[_axis])
- Chunks(chunks).apply(res).implementation.setslice(space, arr)
+ Chunks(chunks).apply(space, res).implementation.setslice(space, arr)
axis_start += arr.get_shape()[_axis]
return res
@@ -150,22 +151,22 @@
arr = arr.descr_flatten(space)
orig_size = arr.get_shape()[0]
shape = [arr.get_shape()[0] * repeats]
- res = W_NDimArray.from_shape(shape, arr.get_dtype())
+ w_res = W_NDimArray.from_shape(space, shape, arr.get_dtype(), w_instance=arr)
for i in range(repeats):
Chunks([Chunk(i, shape[0] - repeats + i, repeats,
- orig_size)]).apply(res).implementation.setslice(space, arr)
+ orig_size)]).apply(space, w_res).implementation.setslice(space, arr)
else:
axis = space.int_w(w_axis)
shape = arr.get_shape()[:]
chunks = [Chunk(0, i, 1, i) for i in shape]
orig_size = shape[axis]
shape[axis] *= repeats
- res = W_NDimArray.from_shape(shape, arr.get_dtype())
+ w_res = W_NDimArray.from_shape(space, shape, arr.get_dtype(), w_instance=arr)
for i in range(repeats):
chunks[axis] = Chunk(i, shape[axis] - repeats + i, repeats,
orig_size)
- Chunks(chunks).apply(res).implementation.setslice(space, arr)
- return res
+ Chunks(chunks).apply(space, w_res).implementation.setslice(space, arr)
+ return w_res
def count_nonzero(space, w_obj):
return space.wrap(loop.count_all_true(convert_to_array(space, w_obj)))
@@ -261,7 +262,7 @@
else:
shape = (shape[:axis2] + shape[axis2 + 1:axis1] +
shape[axis1 + 1:] + [size])
- out = W_NDimArray.from_shape(shape, dtype)
+ out = W_NDimArray.from_shape(space, shape, dtype)
if size == 0:
return out
if shapelen == 2:
diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -41,7 +41,7 @@
dtype = w_arr_list[0].get_dtype()
for w_arr in w_arr_list[1:]:
dtype = find_binop_result_dtype(space, dtype, w_arr.get_dtype())
- out = base.W_NDimArray.from_shape(shape, dtype)
+ out = base.W_NDimArray.from_shape(space, shape, dtype)
return out
diff --git a/pypy/module/micronumpy/interp_flatiter.py b/pypy/module/micronumpy/interp_flatiter.py
--- a/pypy/module/micronumpy/interp_flatiter.py
+++ b/pypy/module/micronumpy/interp_flatiter.py
@@ -64,8 +64,8 @@
base_iter.next_skip_x(start)
if length == 1:
return base_iter.getitem()
- res = W_NDimArray.from_shape([length], base.get_dtype(),
- base.get_order())
+ res = W_NDimArray.from_shape(space, [length], base.get_dtype(),
+ base.get_order(), w_instance=base)
return loop.flatiter_getitem(res, base_iter, step)
def descr_setitem(self, space, w_idx, w_value):
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
@@ -3,7 +3,7 @@
from pypy.interpreter.typedef import TypeDef, GetSetProperty, make_weakref_descr
from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
from pypy.module.micronumpy.base import W_NDimArray, convert_to_array,\
- ArrayArgumentException, issequence_w
+ ArrayArgumentException, issequence_w, wrap_impl
from pypy.module.micronumpy import interp_dtype, interp_ufuncs, interp_boxes,\
interp_arrayops
from pypy.module.micronumpy.strides import find_shape_and_elems,\
@@ -85,8 +85,8 @@
res_shape = [size] + self.get_shape()[1:]
else:
res_shape = [size]
- res = W_NDimArray.from_shape(res_shape, self.get_dtype())
- return loop.getitem_filter(res, self, arr)
+ w_res = W_NDimArray.from_shape(space, res_shape, self.get_dtype(), w_instance=self)
+ return loop.getitem_filter(w_res, self, arr)
def setitem_filter(self, space, idx, val):
if len(idx.get_shape()) > 1 and idx.get_shape() != self.get_shape():
@@ -145,12 +145,13 @@
if iter_shape is None:
# w_index is a list of slices, return a view
chunks = self.implementation._prepare_slice_args(space, w_index)
- return chunks.apply(self)
+ return chunks.apply(space, self)
shape = res_shape + self.get_shape()[len(indexes):]
- res = W_NDimArray.from_shape(shape, self.get_dtype(), self.get_order())
- if not res.get_size():
- return res
- return loop.getitem_array_int(space, self, res, iter_shape, indexes,
+ w_res = W_NDimArray.from_shape(space, shape, self.get_dtype(),
+ self.get_order(), w_instance=self)
+ if not w_res.get_size():
+ return w_res
+ return loop.getitem_array_int(space, self, w_res, iter_shape, indexes,
prefix)
def setitem_array_int(self, space, w_index, w_value):
@@ -161,7 +162,7 @@
# w_index is a list of slices
w_value = convert_to_array(space, w_value)
chunks = self.implementation._prepare_slice_args(space, w_index)
- view = chunks.apply(self)
+ view = chunks.apply(space, self)
view.implementation.setslice(space, w_value)
return
loop.setitem_array_int(space, self, iter_shape, indexes, val_arr,
@@ -259,14 +260,17 @@
return self.implementation.get_scalar_value()
def descr_copy(self, space):
- return W_NDimArray(self.implementation.copy(space))
+ copy = self.implementation.copy(space)
+ w_subtype = space.type(self)
+ return wrap_impl(space, w_subtype, self, copy)
def descr_get_real(self, space):
- return W_NDimArray(self.implementation.get_real(self))
+ return wrap_impl(space, space.type(self), self,
+ self.implementation.get_real(self))
def descr_get_imag(self, space):
ret = self.implementation.get_imag(self)
- return W_NDimArray(ret)
+ return wrap_impl(space, space.type(self), self, ret)
def descr_set_real(self, space, w_value):
# copy (broadcast) values into self
@@ -298,7 +302,7 @@
new_shape = get_shape_from_iterable(space, self.get_size(), w_shape)
new_impl = self.implementation.reshape(space, self, new_shape)
if new_impl is not None:
- return W_NDimArray(new_impl)
+ return wrap_impl(space, space.type(self), self, new_impl)
# Create copy with contiguous data
arr = self.descr_copy(space)
if arr.get_size() > 0:
@@ -326,7 +330,7 @@
"""
if self.is_scalar():
return self
- return self.implementation.swapaxes(self, axis1, axis2)
+ return self.implementation.swapaxes(space, self, axis1, axis2)
def descr_tolist(self, space):
if len(self.get_shape()) == 0:
@@ -446,17 +450,24 @@
# we must do that, because we need a working set. otherwise
# we would modify the array in-place. Use this to our advantage
# by converting nonnative byte order.
+ if self.is_scalar():
+ return space.wrap(0)
s = self.get_dtype().name
if not self.get_dtype().native:
s = s[1:]
dtype = interp_dtype.get_dtype_cache(space).dtypes_by_name[s]
contig = self.implementation.astype(space, dtype)
- return contig.implementation.argsort(space, w_axis)
+ return contig.argsort(space, w_axis)
def descr_astype(self, space, w_dtype):
dtype = space.interp_w(interp_dtype.W_Dtype,
space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype))
- return self.implementation.astype(space, dtype)
+ impl = self.implementation
+ if isinstance(impl, scalar.Scalar):
+ return W_NDimArray.new_scalar(space, dtype, impl.value)
+ else:
+ new_impl = impl.astype(space, dtype)
+ return wrap_impl(space, space.type(self), self, new_impl)
def descr_get_base(self, space):
impl = self.implementation
@@ -471,9 +482,9 @@
loop.byteswap(self.implementation, self.implementation)
return self
else:
- res = W_NDimArray.from_shape(self.get_shape(), self.get_dtype())
- loop.byteswap(self.implementation, res.implementation)
- return res
+ w_res = W_NDimArray.from_shape(space, self.get_shape(), self.get_dtype(), w_instance=self)
+ loop.byteswap(self.implementation, w_res.implementation)
+ return w_res
@unwrap_spec(mode=str)
def descr_choose(self, space, w_choices, w_out=None, mode='raise'):
@@ -564,7 +575,7 @@
if space.is_none(w_out):
if self.get_dtype().is_bool_type():
#numpy promotes bool.round() to float16. Go figure.
- w_out = W_NDimArray.from_shape(self.get_shape(),
+ w_out = W_NDimArray.from_shape(space, self.get_shape(),
interp_dtype.get_dtype_cache(space).w_float16dtype)
else:
w_out = None
@@ -578,6 +589,8 @@
else:
calc_dtype = out.get_dtype()
+ if decimals == 0:
+ out = out.descr_view(space,space.type(self))
loop.round(space, self, calc_dtype, self.get_shape(), decimals, out)
return out
@@ -619,9 +632,13 @@
"trace not implemented yet"))
def descr_view(self, space, w_dtype=None, w_type=None) :
- if w_type is not None:
- raise OperationError(space.w_NotImplementedError, space.wrap(
- "view(... type=<class>) not implemented yet"))
+ if not w_type and w_dtype:
+ try:
+ if space.is_true(space.issubtype(w_dtype, space.gettypefor(W_NDimArray))):
+ w_type = w_dtype
+ w_dtype = None
+ except (OperationError, TypeError):
+ pass
if w_dtype:
dtype = space.interp_w(interp_dtype.W_Dtype,
space.call_function(space.gettypefor(interp_dtype.W_Dtype),
@@ -651,8 +668,9 @@
raise OperationError(space.w_ValueError, space.wrap(
"new type not compatible with array."))
new_shape[-1] = new_shape[-1] * old_itemsize / new_itemsize
- return W_NDimArray(impl.get_view(self, dtype, new_shape))
-
+ v = impl.get_view(self, dtype, new_shape)
+ w_ret = wrap_impl(space, w_type, self, v)
+ return w_ret
# --------------------- operations ----------------------------
@@ -760,9 +778,9 @@
return W_NDimArray.new_scalar(space, dtype, space.wrap(0))
# Do the dims match?
out_shape, other_critical_dim = match_dot_shapes(space, self, other)
- result = W_NDimArray.from_shape(out_shape, dtype)
+ w_res = W_NDimArray.from_shape(space, out_shape, dtype, w_instance=self)
# This is the place to add fpypy and blas
- return loop.multidim_dot(space, self, other, result, dtype,
+ return loop.multidim_dot(space, self, other, w_res, dtype,
other_critical_dim)
@unwrap_spec(w_axis = WrappedDefault(None))
@@ -884,14 +902,20 @@
isfortran = space.getitem(w_state, space.wrap(3))
storage = space.getitem(w_state, space.wrap(4))
- self.implementation = W_NDimArray.from_shape_and_storage([space.int_w(i) for i in space.listview(shape)], rffi.str2charp(space.str_w(storage), track_allocation=False), dtype, owning=True).implementation
+ self.implementation = W_NDimArray.from_shape_and_storage(space,
+ [space.int_w(i) for i in space.listview(shape)],
+ rffi.str2charp(space.str_w(storage), track_allocation=False),
+ dtype, owning=True).implementation
+ def descr___array_finalize__(self, space, w_obj):
+ pass
- at unwrap_spec(offset=int)
+ at unwrap_spec(offset=int, order=str)
def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None,
- offset=0, w_strides=None, w_order=None):
+ offset=0, w_strides=None, order='C'):
+ from pypy.module.micronumpy.arrayimpl.concrete import ConcreteArray
+ from pypy.module.micronumpy.support import calc_strides
if (offset != 0 or not space.is_none(w_strides) or
- not space.is_none(w_order) or
not space.is_none(w_buffer)):
raise OperationError(space.w_NotImplementedError,
space.wrap("unsupported param"))
@@ -900,10 +924,19 @@
shape = _find_shape(space, w_shape, dtype)
if not shape:
return W_NDimArray.new_scalar(space, dtype)
- return W_NDimArray.from_shape(shape, dtype)
+ if space.is_w(w_subtype, space.gettypefor(W_NDimArray)):
+ return W_NDimArray.from_shape(space, shape, dtype, order)
+ strides, backstrides = calc_strides(shape, dtype.base, order)
+ impl = ConcreteArray(shape, dtype.base, order, strides,
+ backstrides)
+ w_ret = space.allocate_instance(W_NDimArray, w_subtype)
+ W_NDimArray.__init__(w_ret, impl)
+ space.call_function(space.getattr(w_ret,
+ space.wrap('__array_finalize__')), w_subtype)
+ return w_ret
@unwrap_spec(addr=int)
-def descr__from_shape_and_storage(space, w_cls, w_shape, addr, w_dtype):
+def descr__from_shape_and_storage(space, w_cls, w_shape, addr, w_dtype, w_subtype=None):
"""
Create an array from an existing buffer, given its address as int.
PyPy-only implementation detail.
@@ -912,9 +945,17 @@
from rpython.rlib.rawstorage import RAW_STORAGE_PTR
storage = rffi.cast(RAW_STORAGE_PTR, addr)
dtype = space.interp_w(interp_dtype.W_Dtype,
- space.call_function(space.gettypefor(interp_dtype.W_Dtype), w_dtype))
+ space.call_function(space.gettypefor(interp_dtype.W_Dtype),
+ w_dtype))
shape = _find_shape(space, w_shape, dtype)
- return W_NDimArray.from_shape_and_storage(shape, storage, dtype)
+ if w_subtype:
+ if not space.isinstance_w(w_subtype, space.w_type):
+ raise OperationError(space.w_ValueError, space.wrap(
+ "subtype must be a subtype of ndarray, not a class instance"))
+ return W_NDimArray.from_shape_and_storage(space, shape, storage, dtype,
+ 'C', False, w_subtype)
+ else:
+ return W_NDimArray.from_shape_and_storage(space, shape, storage, dtype)
W_NDimArray.typedef = TypeDef(
"ndarray",
@@ -1042,6 +1083,7 @@
W_NDimArray.fdel___pypy_data__),
__reduce__ = interp2app(W_NDimArray.descr_reduce),
__setstate__ = interp2app(W_NDimArray.descr_setstate),
+ __array_finalize__ = interp2app(W_NDimArray.descr___array_finalize__),
)
@unwrap_spec(ndmin=int, copy=bool, subok=bool)
@@ -1094,12 +1136,12 @@
dtype = interp_dtype.variable_dtype(space, dtype.char + '1')
if ndmin > len(shape):
shape = [1] * (ndmin - len(shape)) + shape
- arr = W_NDimArray.from_shape(shape, dtype, order=order)
- arr_iter = arr.create_iter()
+ w_arr = W_NDimArray.from_shape(space, shape, dtype, order=order)
+ arr_iter = w_arr.create_iter()
for w_elem in elems_w:
arr_iter.setitem(dtype.coerce(space, w_elem))
arr_iter.next()
- return arr
+ return w_arr
@unwrap_spec(order=str)
def zeros(space, w_shape, w_dtype=None, order='C'):
@@ -1109,7 +1151,7 @@
shape = _find_shape(space, w_shape, dtype)
if not shape:
return W_NDimArray.new_scalar(space, dtype, space.wrap(0))
- return space.wrap(W_NDimArray.from_shape(shape, dtype=dtype, order=order))
+ return space.wrap(W_NDimArray.from_shape(space, shape, dtype=dtype, order=order))
@unwrap_spec(order=str)
def ones(space, w_shape, w_dtype=None, order='C'):
@@ -1119,10 +1161,10 @@
shape = _find_shape(space, w_shape, dtype)
if not shape:
return W_NDimArray.new_scalar(space, dtype, space.wrap(0))
- arr = W_NDimArray.from_shape(shape, dtype=dtype, order=order)
+ w_arr = W_NDimArray.from_shape(space, shape, dtype=dtype, order=order)
one = dtype.box(1)
- arr.fill(one)
- return space.wrap(arr)
+ w_arr.fill(one)
+ return space.wrap(w_arr)
def _reconstruct(space, w_subtype, w_shape, w_dtype):
return descr_new_array(space, w_subtype, w_shape, w_dtype)
diff --git a/pypy/module/micronumpy/interp_support.py b/pypy/module/micronumpy/interp_support.py
--- a/pypy/module/micronumpy/interp_support.py
+++ b/pypy/module/micronumpy/interp_support.py
@@ -50,7 +50,7 @@
raise OperationError(space.w_ValueError, space.wrap(
"string is smaller than requested size"))
- a = W_NDimArray.from_shape([num_items], dtype=dtype)
+ a = W_NDimArray.from_shape(space, [num_items], dtype=dtype)
ai = a.create_iter()
for val in items:
ai.setitem(val)
@@ -71,7 +71,7 @@
raise OperationError(space.w_ValueError, space.wrap(
"string is smaller than requested size"))
- a = W_NDimArray.from_shape([count], dtype=dtype)
+ a = W_NDimArray.from_shape(space, [count], dtype=dtype)
loop.fromstring_loop(a, dtype, itemsize, s)
return space.wrap(a)
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
@@ -181,7 +181,8 @@
temp_shape = obj_shape[:axis] + obj_shape[axis + 1:]
if out:
dtype = out.get_dtype()
- temp = W_NDimArray.from_shape(temp_shape, dtype)
+ temp = W_NDimArray.from_shape(space, temp_shape, dtype,
+ w_instance=obj)
elif keepdims:
shape = obj_shape[:axis] + [1] + obj_shape[axis + 1:]
else:
@@ -207,7 +208,7 @@
)
dtype = out.get_dtype()
else:
- out = W_NDimArray.from_shape(shape, dtype)
+ out = W_NDimArray.from_shape(space, shape, dtype, w_instance=obj)
return loop.do_axis_reduce(shape, self.func, obj, dtype, axis, out,
self.identity, cumultative, temp)
if cumultative:
@@ -216,7 +217,7 @@
raise OperationError(space.w_ValueError, space.wrap(
"out of incompatible size"))
else:
- out = W_NDimArray.from_shape([obj.get_size()], dtype)
+ out = W_NDimArray.from_shape(space, [obj.get_size()], dtype, w_instance=obj)
loop.compute_reduce_cumultative(obj, out, dtype, self.func,
self.identity)
return out
@@ -295,7 +296,7 @@
return out
shape = shape_agreement(space, w_obj.get_shape(), out,
broadcast_down=False)
- return loop.call1(shape, self.func, calc_dtype, res_dtype,
+ return loop.call1(space, shape, self.func, calc_dtype, res_dtype,
w_obj, out)
@@ -370,7 +371,7 @@
return out
new_shape = shape_agreement(space, w_lhs.get_shape(), w_rhs)
new_shape = shape_agreement(space, new_shape, out, broadcast_down=False)
- return loop.call2(new_shape, self.func, calc_dtype,
+ return loop.call2(space, new_shape, self.func, calc_dtype,
res_dtype, w_lhs, w_rhs, out)
@@ -450,7 +451,7 @@
return dt2
return dt1
return dt2
- else:
+ else:
# increase to the next signed type
dtypenum = dt2.num + 1
newdtype = interp_dtype.get_dtype_cache(space).dtypes_by_num[dtypenum]
@@ -537,7 +538,13 @@
return current_guess
if current_guess is complex_type:
return complex_type
- return interp_dtype.get_dtype_cache(space).w_float64dtype
+ if space.isinstance_w(w_obj, space.w_float):
+ return float_type
+ elif space.isinstance_w(w_obj, space.w_slice):
+ return long_dtype
+ raise operationerrfmt(space.w_NotImplementedError,
+ 'unable to create dtype from objects, ' '"%T" instance not supported',
+ w_obj)
def ufunc_dtype_caller(space, ufunc_name, op_name, argcount, comparison_func,
diff --git a/pypy/module/micronumpy/iter.py b/pypy/module/micronumpy/iter.py
--- a/pypy/module/micronumpy/iter.py
+++ b/pypy/module/micronumpy/iter.py
@@ -58,11 +58,11 @@
def __init__(self, name):
self.name = name
- def apply(self, orig_arr):
+ def apply(self, space, orig_arr):
arr = orig_arr.implementation
ofs, subdtype = arr.dtype.fields[self.name]
# strides backstrides are identical, ofs only changes start
- return W_NDimArray.new_slice(arr.start + ofs, arr.get_strides(),
+ return W_NDimArray.new_slice(space, arr.start + ofs, arr.get_strides(),
arr.get_backstrides(),
arr.shape, arr, orig_arr, subdtype)
@@ -81,13 +81,13 @@
assert s >= 0
return shape[:] + old_shape[s:]
- def apply(self, orig_arr):
+ def apply(self, space, orig_arr):
arr = orig_arr.implementation
shape = self.extend_shape(arr.shape)
r = calculate_slice_strides(arr.shape, arr.start, arr.get_strides(),
arr.get_backstrides(), self.l)
_, start, strides, backstrides = r
- return W_NDimArray.new_slice(start, strides[:], backstrides[:],
+ return W_NDimArray.new_slice(space, start, strides[:], backstrides[:],
shape[:], arr, orig_arr)
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -19,9 +19,34 @@
reds = ['shape', 'w_lhs', 'w_rhs', 'out',
'left_iter', 'right_iter', 'out_iter'])
-def call2(shape, func, calc_dtype, res_dtype, w_lhs, w_rhs, out):
+def call2(space, shape, func, calc_dtype, res_dtype, w_lhs, w_rhs, out):
+ # handle array_priority
+ # w_lhs and w_rhs could be of different ndarray subtypes. Numpy does:
+ # 1. if __array_priorities__ are equal and one is an ndarray and the
+ # other is a subtype, flip the order
+ # 2. elif rhs.__array_priority__ is higher, flip the order
+ # Now return the subtype of the first one
+
+ w_ndarray = space.gettypefor(W_NDimArray)
+ lhs_type = space.type(w_lhs)
+ rhs_type = space.type(w_rhs)
+ lhs_for_subtype = w_lhs
+ rhs_for_subtype = w_rhs
+ #it may be something like a FlatIter, which is not an ndarray
+ if not space.is_true(space.issubtype(lhs_type, w_ndarray)):
+ lhs_type = space.type(w_lhs.base)
+ lhs_for_subtype = w_lhs.base
+ if not space.is_true(space.issubtype(rhs_type, w_ndarray)):
+ rhs_type = space.type(w_rhs.base)
+ rhs_for_subtype = w_rhs.base
+ if space.is_w(lhs_type, w_ndarray) and not space.is_w(rhs_type, w_ndarray):
+ lhs_for_subtype = rhs_for_subtype
+
+ # TODO handle __array_priorities__ and maybe flip the order
+
if out is None:
- out = W_NDimArray.from_shape(shape, res_dtype)
+ out = W_NDimArray.from_shape(space, shape, res_dtype,
+ w_instance=lhs_for_subtype)
left_iter = w_lhs.create_iter(shape)
right_iter = w_rhs.create_iter(shape)
out_iter = out.create_iter(shape)
@@ -48,9 +73,9 @@
reds = ['shape', 'w_obj', 'out', 'obj_iter',
'out_iter'])
-def call1(shape, func, calc_dtype, res_dtype, w_obj, out):
+def call1(space, shape, func, calc_dtype, res_dtype, w_obj, out):
if out is None:
- out = W_NDimArray.from_shape(shape, res_dtype)
+ out = W_NDimArray.from_shape(space, shape, res_dtype, w_instance=w_obj)
obj_iter = w_obj.create_iter(shape)
out_iter = out.create_iter(shape)
shapelen = len(shape)
@@ -437,12 +462,12 @@
def tostring(space, arr):
builder = StringBuilder()
iter = arr.create_iter()
- res_str = W_NDimArray.from_shape([1], arr.get_dtype(), order='C')
+ w_res_str = W_NDimArray.from_shape(space, [1], arr.get_dtype(), order='C')
itemsize = arr.get_dtype().itemtype.get_element_size()
res_str_casted = rffi.cast(rffi.CArrayPtr(lltype.Char),
- res_str.implementation.get_storage_as_int(space))
+ w_res_str.implementation.get_storage_as_int(space))
while not iter.done():
- res_str.implementation.setitem(0, iter.getitem())
+ w_res_str.implementation.setitem(0, iter.getitem())
for i in range(itemsize):
builder.append(res_str_casted[i])
iter.next()
diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py
--- a/pypy/module/micronumpy/test/test_compile.py
+++ b/pypy/module/micronumpy/test/test_compile.py
@@ -2,7 +2,7 @@
import py
from pypy.module.micronumpy.compile import (numpy_compile, Assignment,
ArrayConstant, FloatConstant, Operator, Variable, RangeConstant, Execute,
- FunctionCall, FakeSpace)
+ FunctionCall, FakeSpace, W_NDimArray)
class TestCompiler(object):
@@ -84,6 +84,7 @@
assert interp.code.statements[0] == Assignment(
'a', Operator(Variable('b'), "+", FloatConstant(3)))
+
class TestRunner(object):
def run(self, code):
interp = numpy_compile(code)
@@ -290,4 +291,32 @@
''')
assert interp.results[0].real == 0
assert interp.results[0].imag == 1
-
+
+ def test_view_none(self):
+ interp = self.run('''
+ a = [1, 0, 3, 0]
+ b = None
+ c = view(a, b)
+ c -> 0
+ ''')
+ assert interp.results[0].value == 1
+
+ def test_view_ndarray(self):
+ interp = self.run('''
+ a = [1, 0, 3, 0]
+ b = ndarray
+ c = view(a, b)
+ c
+ ''')
+ results = interp.results[0]
+ assert isinstance(results, W_NDimArray)
+
+ def test_view_dtype(self):
+ interp = self.run('''
+ a = [1, 0, 3, 0]
+ b = int
+ c = view(a, b)
+ c
+ ''')
+ results = interp.results[0]
+ assert isinstance(results, W_NDimArray)
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
@@ -976,3 +976,16 @@
assert a[0] == 1
assert (a + a)[1] == 4
+class AppTestObjectDtypes(BaseNumpyAppTest):
+ def test_scalar_from_object(self):
+ from numpypy import array
+ class Polynomial(object):
+ pass
+ try:
+ a = array(Polynomial())
+ assert a.shape == ()
+ except NotImplementedError, e:
+ if e.message.find('unable to create dtype from objects')>=0:
+ skip('creating ojbect dtype not supported yet')
+
+
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
@@ -24,8 +24,8 @@
def get_size(self):
return 1
-def create_slice(a, chunks):
- return Chunks(chunks).apply(W_NDimArray(a)).implementation
+def create_slice(space, a, chunks):
+ return Chunks(chunks).apply(space, W_NDimArray(a)).implementation
def create_array(*args, **kwargs):
@@ -46,100 +46,100 @@
return self.space.newtuple(args_w)
def test_strides_f(self):
- a = create_array([10, 5, 3], MockDtype(), order='F')
+ a = create_array(self.space, [10, 5, 3], MockDtype(), order='F')
assert a.strides == [1, 10, 50]
assert a.backstrides == [9, 40, 100]
def test_strides_c(self):
- a = create_array([10, 5, 3], MockDtype(), order='C')
+ a = create_array(self.space, [10, 5, 3], MockDtype(), order='C')
assert a.strides == [15, 3, 1]
assert a.backstrides == [135, 12, 2]
- a = create_array([1, 0, 7], MockDtype(), order='C')
+ a = create_array(self.space, [1, 0, 7], MockDtype(), order='C')
assert a.strides == [7, 7, 1]
assert a.backstrides == [0, 0, 6]
def test_create_slice_f(self):
- a = create_array([10, 5, 3], MockDtype(), order='F')
- s = create_slice(a, [Chunk(3, 0, 0, 1)])
+ a = create_array(self.space, [10, 5, 3], MockDtype(), order='F')
+ s = create_slice(self.space, a, [Chunk(3, 0, 0, 1)])
assert s.start == 3
assert s.strides == [10, 50]
assert s.backstrides == [40, 100]
- s = create_slice(a, [Chunk(1, 9, 2, 4)])
+ s = create_slice(self.space, a, [Chunk(1, 9, 2, 4)])
assert s.start == 1
assert s.strides == [2, 10, 50]
assert s.backstrides == [6, 40, 100]
- s = create_slice(a, [Chunk(1, 5, 3, 2), Chunk(1, 2, 1, 1), Chunk(1, 0, 0, 1)])
+ s = create_slice(self.space, a, [Chunk(1, 5, 3, 2), Chunk(1, 2, 1, 1), Chunk(1, 0, 0, 1)])
assert s.shape == [2, 1]
assert s.strides == [3, 10]
assert s.backstrides == [3, 0]
- s = create_slice(a, [Chunk(0, 10, 1, 10), Chunk(2, 0, 0, 1)])
+ s = create_slice(self.space, a, [Chunk(0, 10, 1, 10), Chunk(2, 0, 0, 1)])
assert s.start == 20
assert s.shape == [10, 3]
def test_create_slice_c(self):
- a = create_array([10, 5, 3], MockDtype(), order='C')
- s = create_slice(a, [Chunk(3, 0, 0, 1)])
+ a = create_array(self.space, [10, 5, 3], MockDtype(), order='C')
+ s = create_slice(self.space, a, [Chunk(3, 0, 0, 1)])
assert s.start == 45
assert s.strides == [3, 1]
assert s.backstrides == [12, 2]
- s = create_slice(a, [Chunk(1, 9, 2, 4)])
+ s = create_slice(self.space, a, [Chunk(1, 9, 2, 4)])
assert s.start == 15
assert s.strides == [30, 3, 1]
assert s.backstrides == [90, 12, 2]
- s = create_slice(a, [Chunk(1, 5, 3, 2), Chunk(1, 2, 1, 1),
+ s = create_slice(self.space, a, [Chunk(1, 5, 3, 2), Chunk(1, 2, 1, 1),
Chunk(1, 0, 0, 1)])
assert s.start == 19
assert s.shape == [2, 1]
assert s.strides == [45, 3]
assert s.backstrides == [45, 0]
- s = create_slice(a, [Chunk(0, 10, 1, 10), Chunk(2, 0, 0, 1)])
+ s = create_slice(self.space, a, [Chunk(0, 10, 1, 10), Chunk(2, 0, 0, 1)])
assert s.start == 6
assert s.shape == [10, 3]
def test_slice_of_slice_f(self):
- a = create_array([10, 5, 3], MockDtype(), order='F')
- s = create_slice(a, [Chunk(5, 0, 0, 1)])
+ a = create_array(self.space, [10, 5, 3], MockDtype(), order='F')
+ s = create_slice(self.space, a, [Chunk(5, 0, 0, 1)])
assert s.start == 5
- s2 = create_slice(s, [Chunk(3, 0, 0, 1)])
+ s2 = create_slice(self.space, s, [Chunk(3, 0, 0, 1)])
assert s2.shape == [3]
assert s2.strides == [50]
assert s2.parent is a
assert s2.backstrides == [100]
assert s2.start == 35
- s = create_slice(a, [Chunk(1, 5, 3, 2)])
- s2 = create_slice(s, [Chunk(0, 2, 1, 2), Chunk(2, 0, 0, 1)])
+ s = create_slice(self.space, a, [Chunk(1, 5, 3, 2)])
+ s2 = create_slice(self.space, s, [Chunk(0, 2, 1, 2), Chunk(2, 0, 0, 1)])
assert s2.shape == [2, 3]
assert s2.strides == [3, 50]
assert s2.backstrides == [3, 100]
assert s2.start == 1 * 15 + 2 * 3
def test_slice_of_slice_c(self):
- a = create_array([10, 5, 3], MockDtype(), order='C')
- s = create_slice(a, [Chunk(5, 0, 0, 1)])
+ a = create_array(self.space, [10, 5, 3], MockDtype(), order='C')
+ s = create_slice(self.space, a, [Chunk(5, 0, 0, 1)])
assert s.start == 15 * 5
- s2 = create_slice(s, [Chunk(3, 0, 0, 1)])
+ s2 = create_slice(self.space, s, [Chunk(3, 0, 0, 1)])
assert s2.shape == [3]
assert s2.strides == [1]
assert s2.parent is a
assert s2.backstrides == [2]
assert s2.start == 5 * 15 + 3 * 3
- s = create_slice(a, [Chunk(1, 5, 3, 2)])
- s2 = create_slice(s, [Chunk(0, 2, 1, 2), Chunk(2, 0, 0, 1)])
+ s = create_slice(self.space, a, [Chunk(1, 5, 3, 2)])
+ s2 = create_slice(self.space, s, [Chunk(0, 2, 1, 2), Chunk(2, 0, 0, 1)])
assert s2.shape == [2, 3]
assert s2.strides == [45, 1]
assert s2.backstrides == [45, 2]
assert s2.start == 1 * 15 + 2 * 3
def test_negative_step_f(self):
- a = create_array([10, 5, 3], MockDtype(), order='F')
- s = create_slice(a, [Chunk(9, -1, -2, 5)])
+ a = create_array(self.space, [10, 5, 3], MockDtype(), order='F')
+ s = create_slice(self.space, a, [Chunk(9, -1, -2, 5)])
assert s.start == 9
assert s.strides == [-2, 10, 50]
assert s.backstrides == [-8, 40, 100]
def test_negative_step_c(self):
- a = create_array([10, 5, 3], MockDtype(), order='C')
- s = create_slice(a, [Chunk(9, -1, -2, 5)])
+ a = create_array(self.space, [10, 5, 3], MockDtype(), order='C')
+ s = create_slice(self.space, a, [Chunk(9, -1, -2, 5)])
assert s.start == 135
assert s.strides == [-30, 3, 1]
assert s.backstrides == [-120, 12, 2]
@@ -207,7 +207,8 @@
raw_storage_setitem(storage, i, rffi.cast(rffi.UCHAR, i))
#
dtypes = get_dtype_cache(self.space)
- w_array = W_NDimArray.from_shape_and_storage([2, 2], storage, dtypes.w_int8dtype)
+ w_array = W_NDimArray.from_shape_and_storage(self.space, [2, 2],
+ storage, dtypes.w_int8dtype)
def get(i, j):
return w_array.getitem(self.space, [i, j]).value
assert get(0, 0) == 0
@@ -1442,7 +1443,7 @@
assert x.view('int8').shape == (10, 3)
def test_ndarray_view_empty(self):
- from numpypy import array, int8, int16, dtype
+ from numpypy import array, int8, int16
x = array([], dtype=[('a', int8), ('b', int8)])
y = x.view(dtype=int16)
@@ -2876,6 +2877,12 @@
assert y[0, 1] == 2
y[0, 1] = 42
assert x[1] == 42
+ class C(ndarray):
+ pass
+ z = ndarray._from_shape_and_storage([4, 1], addr, x.dtype, C)
+ assert isinstance(z, C)
+ assert z.shape == (4, 1)
+ assert z[1, 0] == 42
def test___pypy_data__(self):
from numpypy import array
@@ -2890,7 +2897,7 @@
class AppTestLongDoubleDtypes(BaseNumpyAppTest):
def setup_class(cls):
from pypy.module.micronumpy import Module
- print dir(Module.interpleveldefs)
+ #print dir(Module.interpleveldefs)
if not Module.interpleveldefs.get('longfloat', None):
py.test.skip('no longdouble types yet')
BaseNumpyAppTest.setup_class.im_func(cls)
diff --git a/pypy/module/micronumpy/test/test_subtype.py b/pypy/module/micronumpy/test/test_subtype.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/micronumpy/test/test_subtype.py
@@ -0,0 +1,223 @@
+import py
+from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
+
+
+class AppTestSupport(BaseNumpyAppTest):
+ def setup_class(cls):
+ BaseNumpyAppTest.setup_class.im_func(cls)
+ cls.w_NoNew = cls.space.appexec([], '''():
+ from numpypy import ndarray
+ class NoNew(ndarray):
+ def __new__(cls, subtype):
+ raise ValueError('should not call __new__')
+ def __array_finalize__(self, obj):
+
+ self.called_finalize = True
+ return NoNew ''')
+ cls.w_SubType = cls.space.appexec([], '''():
+ from numpypy import ndarray, asarray
+ class SubType(ndarray):
+ def __new__(obj, input_array):
+ obj = asarray(input_array).view(obj)
+ obj.called_new = True
+ return obj
+ def __array_finalize__(self, obj):
+ self.called_finalize = True
+ return SubType ''')
+
+ def test_subtype_base(self):
+ from numpypy import ndarray, dtype
+ class C(ndarray):
+ def __new__(subtype, shape, dtype):
+ self = ndarray.__new__(subtype, shape, dtype)
+ self.id = 'subtype'
+ return self
+ a = C([2, 2], int)
+ assert isinstance(a, C)
+ assert isinstance(a, ndarray)
+ assert a.shape == (2, 2)
+ assert a.dtype is dtype(int)
+ assert a.id == 'subtype'
+ a = a.reshape(1, 4)
+ b = a.reshape(4, 1)
+ assert isinstance(b, C)
+ #make sure __new__ was not called
+ assert not getattr(b, 'id', None)
+ a.fill(3)
+ b = a[0]
+ assert isinstance(b, C)
+ assert (b == 3).all()
+ b[0]=100
+ assert a[0,0] == 100
+
+ def test_subtype_view(self):
+ from numpypy import ndarray, array
+ class matrix(ndarray):
+ def __new__(subtype, data, dtype=None, copy=True):
+ if isinstance(data, matrix):
+ return data
+ return data.view(subtype)
+ a = array(range(5))
+ b = matrix(a)
+ assert isinstance(b, matrix)
+ assert (b == a).all()
+
+
+ def test_finalize(self):
+ #taken from http://docs.scipy.org/doc/numpy/user/basics.subclassing.html#simple-example-adding-an-extra-attribute-to-ndarray
+ import numpypy as np
+ class InfoArray(np.ndarray):
+ def __new__(subtype, shape, dtype=float, buffer=None, offset=0,
+ strides=None, order='C', info=None):
+ obj = np.ndarray.__new__(subtype, shape, dtype, buffer,
+ offset, strides, order)
+ obj.info = info
+ return obj
+
+ def __array_finalize__(self, obj):
+ if obj is None:
+ print 'finalize with None'
+ return
+ # printing the object itself will crash the test
+ print 'finalize with something',type(obj)
+ self.info = getattr(obj, 'info', None)
+ obj = InfoArray(shape=(3,))
+ assert isinstance(obj, InfoArray)
+ assert obj.info is None
+ obj = InfoArray(shape=(3,), info='information')
+ assert obj.info == 'information'
+ v = obj[1:]
+ assert isinstance(v, InfoArray)
+ assert v.base is obj
+ assert v.info == 'information'
+ arr = np.arange(10)
+ cast_arr = arr.view(InfoArray)
+ assert isinstance(cast_arr, InfoArray)
+ assert cast_arr.base is arr
+ assert cast_arr.info is None
+
+ def test_sub_where(self):
+ from numpypy import where, ones, zeros, array
+ a = array([1, 2, 3, 0, -3])
+ v = a.view(self.NoNew)
+ b = where(array(v) > 0, ones(5), zeros(5))
+ assert (b == [1, 1, 1, 0, 0]).all()
+ # where returns an ndarray irregardless of the subtype of v
+ assert not isinstance(b, self.NoNew)
+
+ def test_sub_repeat(self):
+ from numpypy import repeat, array
+ a = self.SubType(array([[1, 2], [3, 4]]))
+ b = repeat(a, 3)
+ assert (b == [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]).all()
+ assert isinstance(b, self.SubType)
+
+ def test_sub_flatiter(self):
+ from numpypy import array
+ a = array(range(9)).reshape(3, 3).view(self.NoNew)
+ c = array(range(9)).reshape(3, 3)
+ assert isinstance(a.flat[:] + a.flat[:], self.NoNew)
+ assert isinstance(a.flat[:] + c.flat[:], self.NoNew)
+ assert isinstance(c.flat[:] + a.flat[:], self.NoNew)
+ assert not isinstance(c.flat[:] + c.flat[:], self.NoNew)
+
+ def test_sub_getitem_filter(self):
+ from numpypy import array
+ a = array(range(5))
+ b = self.SubType(a)
+ c = b[array([False, True, False, True, False])]
+ assert c.shape == (2,)
+ assert (c == [1, 3]).all()
+ assert isinstance(c, self.SubType)
+ assert b.called_new
+ assert not getattr(c, 'called_new', False)
+ assert c.called_finalize
+
+ def test_sub_getitem_array_int(self):
+ from numpypy import array
+ a = array(range(5))
+ b = self.SubType(a)
+ assert b.called_new
+ c = b[array([3, 2, 1, 4])]
+ assert (c == [3, 2, 1, 4]).all()
+ assert isinstance(c, self.SubType)
+ assert not getattr(c, 'called_new', False)
+ assert c.called_finalize
+
+ def test_sub_round(self):
+ from numpypy import array
+ a = array(range(10), dtype=float).view(self.NoNew)
+ # numpy compatibility
+ b = a.round(decimals=0)
+ assert isinstance(b, self.NoNew)
+ b = a.round(decimals=1)
+ assert not isinstance(b, self.NoNew)
+ b = a.round(decimals=-1)
+ assert not isinstance(b, self.NoNew)
+
+ def test_sub_dot(self):
+ # the returned type is that of the first argument
+ from numpypy import array
+ a = array(range(12)).reshape(3,4)
+ b = self.SubType(a)
+ c = array(range(12)).reshape(4,3).view(self.SubType)
+ d = c.dot(a)
+ assert isinstance(d, self.SubType)
+ assert not getattr(d, 'called_new', False)
+ assert d.called_finalize
+ d = a.dot(c)
+ assert not isinstance(d, self.SubType)
+ assert not getattr(d, 'called_new', False)
+ assert not getattr(d, 'called_finalize', False)
+
+ def test_sub_reduce(self):
+ # i.e. sum, max
+ # test for out as well
+ from numpypy import array
+ a = array(range(12)).reshape(3,4)
+ b = self.SubType(a)
+ c = b.sum(axis=0)
+ assert (c == [12, 15, 18, 21]).all()
+ assert isinstance(c, self.SubType)
+ assert not getattr(c, 'called_new', False)
+ assert c.called_finalize
+ d = array(range(4))
+ c = b.sum(axis=0, out=d)
+ assert c is d
+ assert not isinstance(c, self.SubType)
+ d = array(range(4)).view(self.NoNew)
+ c = b.sum(axis=0, out=d)
+ assert c is d
+ assert isinstance(c, self.NoNew)
+
+ def test_sub_call2(self):
+ # c + a vs. a + c, what about array priority?
+ from numpypy import array
+ a = array(range(12)).view(self.NoNew)
+ b = self.SubType(range(12))
+ c = b + a
+ assert isinstance(c, self.SubType)
+ c = a + b
+ assert isinstance(c, self.NoNew)
+ d = range(12)
+ e = a - d
+ assert isinstance(e, self.NoNew)
+
+ def test_sub_call1(self):
+ from numpypy import array, sqrt
+ a = array(range(12)).view(self.NoNew)
+ b = sqrt(a)
+ assert b.called_finalize == True
+
+ def test_sub_astype(self):
+ from numpypy import array
+ a = array(range(12)).view(self.NoNew)
+ b = a.astype(float)
+ assert b.called_finalize == True
+
+ def test_sub_reshape(self):
+ from numpypy import array
+ a = array(range(12)).view(self.NoNew)
+ b = a.reshape(3, 4)
+ assert b.called_finalize == True
+
diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -184,14 +184,15 @@
assert isinstance(e, WindowsError)
assert e.winerror == 3
- def test_statvfs(self):
- st = self.posix.statvfs(".")
- assert isinstance(st, self.posix.statvfs_result)
- for field in [
- 'f_bsize', 'f_frsize', 'f_blocks', 'f_bfree', 'f_bavail',
- 'f_files', 'f_ffree', 'f_favail', 'f_flag', 'f_namemax',
- ]:
- assert hasattr(st, field)
+ if hasattr(__import__(os.name), "statvfs"):
+ def test_statvfs(self):
+ st = self.posix.statvfs(".")
+ assert isinstance(st, self.posix.statvfs_result)
+ for field in [
+ 'f_bsize', 'f_frsize', 'f_blocks', 'f_bfree', 'f_bavail',
+ 'f_files', 'f_ffree', 'f_favail', 'f_flag', 'f_namemax',
+ ]:
+ assert hasattr(st, field)
def test_pickle(self):
import pickle, os
diff --git a/pypy/module/pypyjit/interp_resop.py b/pypy/module/pypyjit/interp_resop.py
--- a/pypy/module/pypyjit/interp_resop.py
+++ b/pypy/module/pypyjit/interp_resop.py
@@ -125,12 +125,10 @@
self.llbox = llbox
def descr_getint(self, space):
- try:
- value = jit_hooks.box_getint(self.llbox)
- except NotImplementedError:
+ if not jit_hooks.box_isint(self.llbox):
raise OperationError(space.w_NotImplementedError,
space.wrap("Box has no int value"))
- return space.wrap(value)
+ return space.wrap(jit_hooks.box_getint(self.llbox))
@unwrap_spec(no=int)
def descr_new_box(space, w_tp, no):
diff --git a/rpython/jit/tool/test/f.pypylog.bz2 b/rpython/jit/tool/test/f.pypylog.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..a982e459b1daa33547576733ccc0b560f99a3f79
GIT binary patch
[cut]
diff --git a/rpython/jit/tool/test/test_traceviewer.py b/rpython/jit/tool/test/test_traceviewer.py
--- a/rpython/jit/tool/test/test_traceviewer.py
+++ b/rpython/jit/tool/test/test_traceviewer.py
@@ -1,7 +1,7 @@
import math
import py
from rpython.jit.tool.traceviewer import splitloops, FinalBlock, Block,\
- split_one_loop, postprocess, main, get_gradient_color
+ split_one_loop, postprocess, main, get_gradient_color, guard_number
def test_gradient_color():
@@ -30,6 +30,20 @@
loops = splitloops(data)
assert len(loops) == 2
+ def test_no_of_loops_hexguards(self):
+ data = [preparse("""
+ # Loop 0 : loop with 39 ops
+ debug_merge_point('', 0)
+ guard_class(p4, 141310752, descr=<Guard0x10abcdef0>) [p0, p1]
+ p60 = getfield_gc(p4, descr=<GcPtrFieldDescr 16>)
+ guard_nonnull(p60, descr=<Guard0x10abcdef1>) [p0, p1]
+ """), preparse("""
+ # Loop 1 : loop with 46 ops
+ p21 = getfield_gc(p4, descr=<GcPtrFieldDescr 16>)
+ """)]
+ loops = splitloops(data)
+ assert len(loops) == 2
+
def test_split_one_loop(self):
real_loops = [FinalBlock(preparse("""
p21 = getfield_gc(p4, descr=<GcPtrFieldDescr 16>)
@@ -50,12 +64,42 @@
assert loop.left.content == ''
assert loop.right.content == 'extra'
+ def test_split_one_loop_hexguards(self):
+ real_loops = [FinalBlock(preparse("""
+ p21 = getfield_gc(p4, descr=<GcPtrFieldDescr 16>)
+ guard_class(p4, 141310752, descr=<Guard0x10abcdef2>) [p0, p1]
+ """), None), FinalBlock(preparse("""
+ p60 = getfield_gc(p4, descr=<GcPtrFieldDescr 16>)
+ guard_nonnull(p60, descr=<Guard0x10abcdef0>) [p0, p1]
+ """), None)]
+ real_loops[0].loop_no = 0
+ real_loops[1].loop_no = 1
+ allloops = real_loops[:]
+ split_one_loop(real_loops, 'Guard0x10abcdef0', 'extra', 1, guard_number(("0x10abcdef0", "0x")), allloops)
+ loop = real_loops[1]
+ assert isinstance(loop, Block)
+ assert loop.content.endswith('p1]')
+ loop.left = allloops[loop.left]
+ loop.right = allloops[loop.right]
+ assert loop.left.content == ''
+ assert loop.right.content == 'extra'
+
def test_postparse(self):
real_loops = [FinalBlock("debug_merge_point('<code object _runCallbacks, file '/tmp/x/twisted-trunk/twisted/internet/defer.py', line 357> #40 POP_TOP', 0)", None)]
postprocess(real_loops, real_loops[:], {})
assert real_loops[0].header.startswith("_runCallbacks, file '/tmp/x/twisted-trunk/twisted/internet/defer.py', line 357")
+ def test_postparse_new(self):
+ real_loops = [FinalBlock("debug_merge_point(0, 0, '<code object _optimize_charset. file '/usr/local/Cellar/pypy/2.0-beta2/lib-python/2.7/sre_compile.py'. line 207> #351 LOAD_FAST')", None)]
+ postprocess(real_loops, real_loops[:], {})
+ assert real_loops[0].header.startswith("_optimize_charset. file '/usr/local/Cellar/pypy/2.0-beta2/lib-python/2.7/sre_compile.py'. line 207")
+
def test_load_actual(self):
fname = py.path.local(__file__).join('..', 'data.log.bz2')
main(str(fname), False, view=False)
# assert did not explode
+
+ def test_load_actual_f(self):
+ fname = py.path.local(__file__).join('..', 'f.pypylog.bz2')
+ main(str(fname), False, view=False)
+ # assert did not explode
diff --git a/rpython/jit/tool/traceviewer.py b/rpython/jit/tool/traceviewer.py
--- a/rpython/jit/tool/traceviewer.py
+++ b/rpython/jit/tool/traceviewer.py
@@ -56,6 +56,18 @@
BOX_COLOR = (128, 0, 96)
+GUARDNO_RE = "((0x)?[\da-f]+)"
+def guard_number(guardno_match):
+ if (len(guardno_match) == 1 # ("12354",)
+ or guardno_match[1] != "0x" # ("12345", None)
+ ):
+ return int(guardno_match[0])
+ else: # ("0x12ef", "0x")
+ return int(guardno_match[0], 16)
+
+def guard_number_string(guardno_match):
+ return guardno_match[0] # its always the first group
+
class BasicBlock(object):
counter = 0
startlineno = 0
@@ -85,13 +97,15 @@
def set_content(self, content):
self._content = content
- groups = re.findall('Guard(\d+)', content)
+ groups = re.findall('Guard' + GUARDNO_RE, content)
if not groups:
self.first_guard = -1
self.last_guard = -1
else:
- self.first_guard = int(groups[0])
- self.last_guard = int(groups[-1])
+ # guards can be out of order nowadays
+ groups = sorted(groups)
+ self.first_guard = guard_number(groups[0])
+ self.last_guard = guard_number(groups[-1])
content = property(get_content, set_content)
@@ -197,11 +211,11 @@
_loop.loop_no = no
allloops.append(_loop)
else:
- m = re.search("bridge out of Guard (\d+)", firstline)
+ m = re.search("bridge out of Guard " + GUARDNO_RE, firstline)
assert m
- guard_s = 'Guard' + m.group(1)
+ guard_s = 'Guard' + guard_number_string(m.groups())
split_one_loop(real_loops, guard_s, loop, counter,
- int(m.group(1)), allloops)
+ guard_number(m.groups()), allloops)
counter += loop.count("\n") + 2
return real_loops, allloops
@@ -211,7 +225,7 @@
memo.add(loop)
if loop is None:
return
- m = re.search("debug_merge_point\('(<code object (.*?)> (.*?))'", loop.content)
+ m = re.search("debug_merge_point\((?:\d+,\ )*'(<code object (.*?)> (.*?))'", loop.content)
if m is None:
name = '?'
loop.key = '?'
@@ -236,7 +250,7 @@
content = loop.content
loop.content = "Logfile at %d\n" % loop.startlineno + content
loop.postprocess(loops, memo, counts)
-
+
def postprocess(loops, allloops, counts):
for loop in allloops:
if isinstance(loop, Block):
diff --git a/rpython/rlib/jit_hooks.py b/rpython/rlib/jit_hooks.py
--- a/rpython/rlib/jit_hooks.py
+++ b/rpython/rlib/jit_hooks.py
@@ -111,6 +111,11 @@
from rpython.jit.metainterp.history import Const
return isinstance(_cast_to_box(llbox), Const)
+ at register_helper(annmodel.SomeBool())
+def box_isint(llbox):
+ from rpython.jit.metainterp.history import INT
+ return _cast_to_box(llbox).type == INT
+
# ------------------------- stats interface ---------------------------
@register_helper(annmodel.SomeBool())
diff --git a/rpython/rtyper/module/test/test_ll_os.py b/rpython/rtyper/module/test/test_ll_os.py
--- a/rpython/rtyper/module/test/test_ll_os.py
+++ b/rpython/rtyper/module/test/test_ll_os.py
@@ -46,6 +46,26 @@
data = getllimpl(os.getlogin)()
assert data == expected
+def test_statvfs():
+ if not hasattr(os, 'statvfs'):
+ py.test.skip('posix specific function')
+ try:
+ expected = os.statvfs('.')
+ except OSError, e:
+ py.test.skip("the underlying os.statvfs() failed: %s" % e)
+ data = getllimpl(os.statvfs)('.')
+ assert data == expected
+
+def test_fstatvfs():
+ if not hasattr(os, 'fstatvfs'):
+ py.test.skip('posix specific function')
+ try:
+ expected = os.fstatvfs(0)
+ except OSError, e:
+ py.test.skip("the underlying os.fstatvfs() failed: %s" % e)
+ data = getllimpl(os.fstatvfs)(0)
+ assert data == expected
+
def test_utimes():
if os.name != 'nt':
py.test.skip('Windows specific feature')
More information about the pypy-commit
mailing list