[pypy-commit] pypy py3.3: merge py3k
pjenvey
noreply at buildbot.pypy.org
Fri Oct 24 22:57:23 CEST 2014
Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3.3
Changeset: r74191:3820173e81e3
Date: 2014-10-24 13:48 -0700
http://bitbucket.org/pypy/pypy/changeset/3820173e81e3/
Log: merge py3k
diff too long, truncating to 2000 out of 5270 lines
diff --git a/lib_pypy/_tkinter/app.py b/lib_pypy/_tkinter/app.py
--- a/lib_pypy/_tkinter/app.py
+++ b/lib_pypy/_tkinter/app.py
@@ -439,7 +439,7 @@
if isinstance(s, int):
return s
s = s.encode('utf-8')
- if '\x00' in s:
+ if b'\x00' in s:
raise TypeError
v = tkffi.new("int*")
res = tklib.Tcl_GetBoolean(self.interp, s, v)
@@ -451,7 +451,7 @@
if isinstance(s, int):
return s
s = s.encode('utf-8')
- if '\x00' in s:
+ if b'\x00' in s:
raise TypeError
v = tkffi.new("int*")
res = tklib.Tcl_GetInt(self.interp, s, v)
@@ -463,7 +463,7 @@
if isinstance(s, float):
return s
s = s.encode('utf-8')
- if '\x00' in s:
+ if b'\x00' in s:
raise TypeError
v = tkffi.new("double*")
res = tklib.Tcl_GetDouble(self.interp, s, v)
@@ -472,7 +472,7 @@
return v[0]
def exprboolean(self, s):
- if '\x00' in s:
+ if b'\x00' in s:
raise TypeError
v = tkffi.new("int*")
res = tklib.Tcl_ExprBoolean(self.interp, s, v)
@@ -481,7 +481,7 @@
return v[0]
def exprlong(self, s):
- if '\x00' in s:
+ if b'\x00' in s:
raise TypeError
v = tkffi.new("long*")
res = tklib.Tcl_ExprLong(self.interp, s, v)
@@ -490,7 +490,7 @@
return v[0]
def exprdouble(self, s):
- if '\x00' in s:
+ if b'\x00' in s:
raise TypeError
v = tkffi.new("double*")
res = tklib.Tcl_ExprDouble(self.interp, s, v)
@@ -499,7 +499,7 @@
return v[0]
def exprstring(self, s):
- if '\x00' in s:
+ if b'\x00' in s:
raise TypeError
res = tklib.Tcl_ExprString(self.interp, s)
if res == tklib.TCL_ERROR:
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
@@ -22,3 +22,6 @@
.. branch: ClassRepr
Refactor ClassRepr and make normalizecalls independent of the rtyper.
+
+.. branch: remove-remaining-smm
+Remove all remaining multimethods.
diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -310,7 +310,8 @@
return self.get_entry_point(config)
def jitpolicy(self, driver):
- from pypy.module.pypyjit.policy import PyPyJitPolicy, pypy_hooks
+ from pypy.module.pypyjit.policy import PyPyJitPolicy
+ from pypy.module.pypyjit.hooks import pypy_hooks
return PyPyJitPolicy(pypy_hooks)
def get_entry_point(self, config):
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1902,5 +1902,4 @@
'newdict',
'newslice',
'call_args',
- 'marshal_w',
]
diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -644,6 +644,17 @@
elif unwrap_spec == [ObjSpace, W_Root, Arguments]:
self.__class__ = BuiltinCodePassThroughArguments1
self.func__args__ = func
+ elif unwrap_spec == [self_type, ObjSpace, Arguments]:
+ self.__class__ = BuiltinCodePassThroughArguments1
+ miniglobals = {'func': func, 'self_type': self_type}
+ d = {}
+ source = """if 1:
+ def _call(space, w_obj, args):
+ self = space.descr_self_interp_w(self_type, w_obj)
+ return func(self, space, args)
+ \n"""
+ exec compile2(source) in miniglobals, d
+ self.func__args__ = d['_call']
else:
self.__class__ = globals()['BuiltinCode%d' % arity]
setattr(self, 'fastfunc_%d' % arity, fastfunc)
diff --git a/pypy/interpreter/test/test_gateway.py b/pypy/interpreter/test/test_gateway.py
--- a/pypy/interpreter/test/test_gateway.py
+++ b/pypy/interpreter/test/test_gateway.py
@@ -906,11 +906,33 @@
assert len(called) == 1
assert isinstance(called[0], argument.Arguments)
+ def test_pass_trough_arguments_method(self):
+ space = self.space
+
+ called = []
+
+ class W_Something(W_Root):
+ def f(self, space, __args__):
+ called.append(__args__)
+ a_w, _ = __args__.unpack()
+ return space.newtuple([space.wrap('f')]+a_w)
+
+ w_f = space.wrap(gateway.interp2app_temp(W_Something.f))
+
+ w_self = space.wrap(W_Something())
+ args = argument.Arguments(space, [space.wrap(7)])
+
+ w_res = space.call_obj_args(w_f, w_self, args)
+ assert space.is_true(space.eq(w_res, space.wrap(('f', 7))))
+
+ # white-box check for opt
+ assert called[0] is args
+
class AppTestKeywordsToBuiltinSanity(object):
def test_type(self):
class X(object):
- def __init__(self, **kw):
+ def __init__(myself, **kw):
pass
clash = type.__call__.__code__.co_varnames[0]
@@ -926,7 +948,6 @@
X(**{clash: 33})
object.__new__(X, **{clash: 33})
-
def test_dict_new(self):
clash = dict.__new__.__code__.co_varnames[0]
diff --git a/pypy/module/marshal/interp_marshal.py b/pypy/module/marshal/interp_marshal.py
--- a/pypy/module/marshal/interp_marshal.py
+++ b/pypy/module/marshal/interp_marshal.py
@@ -2,6 +2,7 @@
from pypy.interpreter.gateway import WrappedDefault, unwrap_spec
from rpython.rlib.rarithmetic import intmask
from rpython.rlib import rstackovf
+from pypy.objspace.std.marshal_impl import marshal, get_unmarshallers
Py_MARSHAL_VERSION = 2
@@ -139,6 +140,26 @@
raise OperationError(space.w_ValueError, space.wrap(msg))
class Marshaller(_Base):
+ """
+ atomic types including typecode:
+
+ atom(tc) puts single typecode
+ atom_int(tc, int) puts code and int
+ atom_int64(tc, int64) puts code and int64
+ atom_str(tc, str) puts code, len and string
+ atom_strlist(tc, strlist) puts code, len and list of strings
+
+ building blocks for compound types:
+
+ start(typecode) sets the type character
+ put(s) puts a string with fixed length
+ put_short(int) puts a short integer
+ put_int(int) puts an integer
+ put_pascal(s) puts a short string
+ put_w_obj(w_obj) puts a wrapped object
+ put_tuple_w(TYPE, tuple_w) puts tuple_w, an unwrapped list of wrapped objects
+ """
+
# _annspecialcase_ = "specialize:ctr_location" # polymorphic
# does not work with subclassing
@@ -217,7 +238,7 @@
self.put(x)
def put_w_obj(self, w_obj):
- self.space.marshal_w(w_obj, self)
+ marshal(self.space, w_obj, self)
def dump_w_obj(self, w_obj):
space = self.space
@@ -243,7 +264,7 @@
idx = 0
while idx < lng:
w_obj = lst_w[idx]
- self.space.marshal_w(w_obj, self)
+ marshal(self.space, w_obj, self)
idx += 1
def _overflow(self):
@@ -333,14 +354,11 @@
u.raise_exc("bad marshal data (unknown type code)")
-def register(codes, func):
- """NOT_RPYTHON"""
- for code in codes:
- Unmarshaller._dispatch[ord(code)] = func
-
class Unmarshaller(_Base):
_dispatch = [invalid_typecode] * 256
+ for tc, func in get_unmarshallers():
+ _dispatch[ord(tc)] = func
def __init__(self, space, reader):
self.space = space
diff --git a/pypy/module/marshal/test/test_marshalimpl.py b/pypy/module/marshal/test/test_marshalimpl.py
--- a/pypy/module/marshal/test/test_marshalimpl.py
+++ b/pypy/module/marshal/test/test_marshalimpl.py
@@ -72,7 +72,7 @@
expected = marshal.dumps(long(x))
w_obj = space.wraplong(x)
m = FakeM()
- space.marshal_w(w_obj, m)
+ interp_marshal.marshal(space, w_obj, m)
assert ''.join(m.seen) == expected
#
u = interp_marshal.StringUnmarshaller(space, space.wrapbytes(expected))
diff --git a/pypy/module/micronumpy/boxes.py b/pypy/module/micronumpy/boxes.py
--- a/pypy/module/micronumpy/boxes.py
+++ b/pypy/module/micronumpy/boxes.py
@@ -3,8 +3,8 @@
from pypy.interpreter.mixedmodule import MixedModule
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.objspace.std.bytesobject import W_BytesObject
-from pypy.objspace.std.complextype import complex_typedef
-from pypy.objspace.std.floattype import float_typedef
+from pypy.objspace.std.complexobject import W_ComplexObject
+from pypy.objspace.std.floatobject import W_FloatObject
from pypy.objspace.std.intobject import W_IntObject
from pypy.objspace.std.unicodeobject import W_UnicodeObject
from rpython.rlib.rarithmetic import LONG_BIT
@@ -784,7 +784,7 @@
__reduce__ = interp2app(W_Float32Box.descr_reduce),
)
-W_Float64Box.typedef = TypeDef("numpy.float64", (W_FloatingBox.typedef, float_typedef),
+W_Float64Box.typedef = TypeDef("numpy.float64", (W_FloatingBox.typedef, W_FloatObject.typedef),
__new__ = interp2app(W_Float64Box.descr__new__.im_func),
__reduce__ = interp2app(W_Float64Box.descr_reduce),
as_integer_ratio = interp2app(W_Float64Box.descr_as_integer_ratio),
@@ -799,7 +799,7 @@
__complex__ = interp2app(W_GenericBox.item),
)
-W_Complex128Box.typedef = TypeDef("numpy.complex128", (W_ComplexFloatingBox.typedef, complex_typedef),
+W_Complex128Box.typedef = TypeDef("numpy.complex128", (W_ComplexFloatingBox.typedef, W_ComplexObject.typedef),
__new__ = interp2app(W_Complex128Box.descr__new__.im_func),
__reduce__ = interp2app(W_Complex128Box.descr_reduce),
)
@@ -810,7 +810,7 @@
__reduce__ = interp2app(W_FloatLongBox.descr_reduce),
)
- W_ComplexLongBox.typedef = TypeDef("numpy.complex%d" % (long_double_size * 16), (W_ComplexFloatingBox.typedef, complex_typedef),
+ W_ComplexLongBox.typedef = TypeDef("numpy.complex%d" % (long_double_size * 16), (W_ComplexFloatingBox.typedef, W_ComplexObject.typedef),
__new__ = interp2app(W_ComplexLongBox.descr__new__.im_func),
__reduce__ = interp2app(W_ComplexLongBox.descr_reduce),
__complex__ = interp2app(W_GenericBox.item),
diff --git a/pypy/module/posix/interp_nt.py b/pypy/module/posix/interp_nt.py
--- a/pypy/module/posix/interp_nt.py
+++ b/pypy/module/posix/interp_nt.py
@@ -21,6 +21,9 @@
"""
eci = ExternalCompilationInfo(
includes=['windows.h'],
+ post_include_bits=[
+ "DWORD "
+ "pypy_GetFinalPathNameByHandle(FARPROC, HANDLE, LPTSTR, DWORD, DWORD);"],
separate_module_sources=[separate_module_source],
export_symbols=['pypy_GetFinalPathNameByHandle']
)
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
@@ -24,7 +24,7 @@
def setup_after_space_initialization(self):
# force the __extend__ hacks to occur early
from pypy.module.pypyjit.interp_jit import pypyjitdriver
- from pypy.module.pypyjit.policy import pypy_hooks
+ from pypy.module.pypyjit.hooks import pypy_hooks
# add the 'defaults' attribute
from rpython.rlib.jit import PARAMETERS
space = self.space
diff --git a/pypy/module/pypyjit/hooks.py b/pypy/module/pypyjit/hooks.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/pypyjit/hooks.py
@@ -0,0 +1,89 @@
+
+from rpython.rlib import jit_hooks
+from rpython.rlib.jit import JitHookInterface, Counters
+
+from pypy.interpreter.error import OperationError
+from pypy.module.pypyjit.interp_resop import (Cache, wrap_greenkey,
+ WrappedOp, W_JitLoopInfo, wrap_oplist)
+
+class PyPyJitIface(JitHookInterface):
+ def on_abort(self, reason, jitdriver, greenkey, greenkey_repr, logops, operations):
+ space = self.space
+ cache = space.fromcache(Cache)
+ if cache.in_recursion:
+ return
+ if space.is_true(cache.w_abort_hook):
+ cache.in_recursion = True
+ oplist_w = wrap_oplist(space, logops, operations)
+ try:
+ try:
+ space.call_function(cache.w_abort_hook,
+ space.wrap(jitdriver.name),
+ wrap_greenkey(space, jitdriver, greenkey, greenkey_repr),
+ space.wrap(Counters.counter_names[reason]),
+ space.newlist(oplist_w)
+ )
+ except OperationError, e:
+ e.write_unraisable(space, "jit hook ", cache.w_abort_hook)
+ finally:
+ cache.in_recursion = False
+
+ def after_compile(self, debug_info):
+ self._compile_hook(debug_info, is_bridge=False)
+
+ def after_compile_bridge(self, debug_info):
+ self._compile_hook(debug_info, is_bridge=True)
+
+ def before_compile(self, debug_info):
+ self._optimize_hook(debug_info, is_bridge=False)
+
+ def before_compile_bridge(self, debug_info):
+ self._optimize_hook(debug_info, is_bridge=True)
+
+ def _compile_hook(self, debug_info, is_bridge):
+ space = self.space
+ cache = space.fromcache(Cache)
+ if cache.in_recursion:
+ return
+ if space.is_true(cache.w_compile_hook):
+ w_debug_info = W_JitLoopInfo(space, debug_info, is_bridge)
+ cache.in_recursion = True
+ try:
+ try:
+ space.call_function(cache.w_compile_hook,
+ space.wrap(w_debug_info))
+ except OperationError, e:
+ e.write_unraisable(space, "jit hook ", cache.w_compile_hook)
+ finally:
+ cache.in_recursion = False
+
+ def _optimize_hook(self, debug_info, is_bridge=False):
+ space = self.space
+ cache = space.fromcache(Cache)
+ if cache.in_recursion:
+ return
+ if space.is_true(cache.w_optimize_hook):
+ w_debug_info = W_JitLoopInfo(space, debug_info, is_bridge)
+ cache.in_recursion = True
+ try:
+ try:
+ w_res = space.call_function(cache.w_optimize_hook,
+ space.wrap(w_debug_info))
+ if space.is_w(w_res, space.w_None):
+ return
+ l = []
+ for w_item in space.listview(w_res):
+ item = space.interp_w(WrappedOp, w_item)
+ l.append(jit_hooks._cast_to_resop(item.op))
+ del debug_info.operations[:] # modifying operations above is
+ # probably not a great idea since types may not work
+ # and we'll end up with half-working list and
+ # a segfault/fatal RPython error
+ for elem in l:
+ debug_info.operations.append(elem)
+ except OperationError, e:
+ e.write_unraisable(space, "jit hook ", cache.w_compile_hook)
+ finally:
+ cache.in_recursion = False
+
+pypy_hooks = PyPyJitIface()
diff --git a/pypy/module/pypyjit/policy.py b/pypy/module/pypyjit/policy.py
--- a/pypy/module/pypyjit/policy.py
+++ b/pypy/module/pypyjit/policy.py
@@ -1,93 +1,4 @@
from rpython.jit.codewriter.policy import JitPolicy
-from rpython.rlib import jit_hooks
-from rpython.rlib.jit import JitHookInterface, Counters
-
-from pypy.interpreter.error import OperationError
-from pypy.module.pypyjit.interp_resop import (Cache, wrap_greenkey,
- WrappedOp, W_JitLoopInfo, wrap_oplist)
-
-
-class PyPyJitIface(JitHookInterface):
- def on_abort(self, reason, jitdriver, greenkey, greenkey_repr, logops, operations):
- space = self.space
- cache = space.fromcache(Cache)
- if cache.in_recursion:
- return
- if space.is_true(cache.w_abort_hook):
- cache.in_recursion = True
- oplist_w = wrap_oplist(space, logops, operations)
- try:
- try:
- space.call_function(cache.w_abort_hook,
- space.wrap(jitdriver.name),
- wrap_greenkey(space, jitdriver, greenkey, greenkey_repr),
- space.wrap(Counters.counter_names[reason]),
- space.newlist(oplist_w)
- )
- except OperationError, e:
- e.write_unraisable(space, "jit hook ", cache.w_abort_hook)
- finally:
- cache.in_recursion = False
-
- def after_compile(self, debug_info):
- self._compile_hook(debug_info, is_bridge=False)
-
- def after_compile_bridge(self, debug_info):
- self._compile_hook(debug_info, is_bridge=True)
-
- def before_compile(self, debug_info):
- self._optimize_hook(debug_info, is_bridge=False)
-
- def before_compile_bridge(self, debug_info):
- self._optimize_hook(debug_info, is_bridge=True)
-
- def _compile_hook(self, debug_info, is_bridge):
- space = self.space
- cache = space.fromcache(Cache)
- if cache.in_recursion:
- return
- if space.is_true(cache.w_compile_hook):
- w_debug_info = W_JitLoopInfo(space, debug_info, is_bridge)
- cache.in_recursion = True
- try:
- try:
- space.call_function(cache.w_compile_hook,
- space.wrap(w_debug_info))
- except OperationError, e:
- e.write_unraisable(space, "jit hook ", cache.w_compile_hook)
- finally:
- cache.in_recursion = False
-
- def _optimize_hook(self, debug_info, is_bridge=False):
- space = self.space
- cache = space.fromcache(Cache)
- if cache.in_recursion:
- return
- if space.is_true(cache.w_optimize_hook):
- w_debug_info = W_JitLoopInfo(space, debug_info, is_bridge)
- cache.in_recursion = True
- try:
- try:
- w_res = space.call_function(cache.w_optimize_hook,
- space.wrap(w_debug_info))
- if space.is_w(w_res, space.w_None):
- return
- l = []
- for w_item in space.listview(w_res):
- item = space.interp_w(WrappedOp, w_item)
- l.append(jit_hooks._cast_to_resop(item.op))
- del debug_info.operations[:] # modifying operations above is
- # probably not a great idea since types may not work
- # and we'll end up with half-working list and
- # a segfault/fatal RPython error
- for elem in l:
- debug_info.operations.append(elem)
- except OperationError, e:
- e.write_unraisable(space, "jit hook ", cache.w_compile_hook)
- finally:
- cache.in_recursion = False
-
-pypy_hooks = PyPyJitIface()
class PyPyJitPolicy(JitPolicy):
@@ -103,19 +14,13 @@
return True
if '.' in modname:
modname, rest = modname.split('.', 1)
+ if modname in ['unicodedata', 'gc', '_minimal_curses', 'cpyext']:
+ return False
else:
rest = ''
- if modname in ['pypyjit', 'signal', 'micronumpy', 'math', 'exceptions',
- 'imp', 'sys', 'array', 'itertools', 'operator',
- 'posix', '_socket', '_sre', '_lsprof', '_weakref',
- '__pypy__', 'cStringIO', '_collections', 'struct',
- 'mmap', 'marshal', '_codecs', 'rctime', 'cppyy',
- '_cffi_backend', 'pyexpat', '_continuation', '_io',
- 'thread', 'select', '_random']:
- if modname == 'pypyjit' and 'interp_resop' in rest:
- return False
- return True
- return False
+ if modname == 'pypyjit' and 'interp_resop' in rest:
+ return False
+ return True
def look_inside_function(self, func):
mod = func.__module__ or '?'
diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py b/pypy/module/pypyjit/test_pypy_c/test_string.py
--- a/pypy/module/pypyjit/test_pypy_c/test_string.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_string.py
@@ -85,7 +85,7 @@
i95 = getfield_gc_pure(p93, descr=<FieldS rpython.rlib.rbigint.rbigint.inst_size .*>)
i96 = int_gt(i95, .*)
guard_false(i96, descr=...)
- i94 = call(ConstClass(rbigint._toint_helper), p93, descr=<Calli 8 r EF=3>)
+ i94 = call(ConstClass(rbigint._toint_helper), p93, descr=<Calli . r EF=3>)
guard_no_exception(descr=...)
i95 = int_add_ovf(i6, i94)
guard_no_overflow(descr=...)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_thread.py b/pypy/module/pypyjit/test_pypy_c/test_thread.py
--- a/pypy/module/pypyjit/test_pypy_c/test_thread.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_thread.py
@@ -70,7 +70,6 @@
i59 = int_is_true(i58)
guard_true(i59, descr=...)
i60 = int_sub(i44, 1)
- guard_not_invalidated(descr=...)
p62 = force_token()
setfield_gc(p0, p62, descr=<FieldP pypy.interpreter.pyframe.PyFrame.vable_token 8>)
i63 = call_release_gil(..., i37, 0, descr=<Calli 4 ii EF=6>)
diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py
--- a/pypy/objspace/std/complexobject.py
+++ b/pypy/objspace/std/complexobject.py
@@ -1,57 +1,181 @@
import math
-from pypy.interpreter.error import OperationError
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
from pypy.objspace.std import newformat
-from pypy.objspace.std.intobject import W_IntObject
-from pypy.objspace.std.model import registerimplementation, W_Object
-from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.floatobject import W_FloatObject, _hash_float
-from pypy.objspace.std.longobject import W_LongObject
+from pypy.objspace.std.floatobject import _hash_float
+from pypy.objspace.std.stdtypedef import GetSetProperty, StdTypeDef
+from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
+from rpython.rlib import jit, rcomplex
+from rpython.rlib.rarithmetic import intmask, r_ulonglong
from rpython.rlib.rbigint import rbigint
from rpython.rlib.rfloat import (
- formatd, DTSF_STR_PRECISION, isinf, isnan, copysign)
-from rpython.rlib import jit, rcomplex
-from rpython.rlib.rarithmetic import intmask, r_ulonglong
+ formatd, DTSF_STR_PRECISION, isinf, isnan, copysign, string_to_float)
+from rpython.rlib.rstring import ParseStringError
+from rpython.tool.sourcetools import func_with_new_name
HASH_IMAG = 1000003
-class W_AbstractComplexObject(W_Object):
- __slots__ = ()
+def _split_complex(s):
+ slen = len(s)
+ if slen == 0:
+ raise ValueError
+ realstart = 0
+ realstop = 0
+ imagstart = 0
+ imagstop = 0
+ imagsign = ' '
+ i = 0
+ # ignore whitespace at beginning and end
+ while i < slen and s[i] == ' ':
+ i += 1
+ while slen > 0 and s[slen-1] == ' ':
+ slen -= 1
- def is_w(self, space, w_other):
- from rpython.rlib.longlong2float import float2longlong
- if not isinstance(w_other, W_AbstractComplexObject):
- return False
- if self.user_overridden_class or w_other.user_overridden_class:
- return self is w_other
- real1 = space.float_w(space.getattr(self, space.wrap("real")))
- real2 = space.float_w(space.getattr(w_other, space.wrap("real")))
- imag1 = space.float_w(space.getattr(self, space.wrap("imag")))
- imag2 = space.float_w(space.getattr(w_other, space.wrap("imag")))
- real1 = float2longlong(real1)
- real2 = float2longlong(real2)
- imag1 = float2longlong(imag1)
- imag2 = float2longlong(imag2)
- return real1 == real2 and imag1 == imag2
+ if s[i] == '(' and s[slen-1] == ')':
+ i += 1
+ slen -= 1
+ # ignore whitespace after bracket
+ while i < slen and s[i] == ' ':
+ i += 1
+ while slen > 0 and s[slen-1] == ' ':
+ slen -= 1
- def immutable_unique_id(self, space):
- if self.user_overridden_class:
- return None
- from rpython.rlib.longlong2float import float2longlong
- from pypy.objspace.std.model import IDTAG_COMPLEX as tag
- real = space.float_w(space.getattr(self, space.wrap("real")))
- imag = space.float_w(space.getattr(self, space.wrap("imag")))
- real_b = rbigint.fromrarith_int(float2longlong(real))
- imag_b = rbigint.fromrarith_int(r_ulonglong(float2longlong(imag)))
- val = real_b.lshift(64).or_(imag_b).lshift(3).or_(rbigint.fromint(tag))
- return space.newlong_from_rbigint(val)
+ # extract first number
+ realstart = i
+ pc = s[i]
+ while i < slen and s[i] != ' ':
+ if s[i] in ('+', '-') and pc not in ('e', 'E') and i != realstart:
+ break
+ pc = s[i]
+ i += 1
+ realstop = i
-class W_ComplexObject(W_AbstractComplexObject):
- """This is a reimplementation of the CPython "PyComplexObject"
+ # return appropriate strings is only one number is there
+ if i >= slen:
+ newstop = realstop - 1
+ if newstop < 0:
+ raise ValueError
+ if s[newstop] in ('j', 'J'):
+ if realstart == newstop:
+ imagpart = '1.0'
+ elif realstart == newstop-1 and s[realstart] == '+':
+ imagpart = '1.0'
+ elif realstart == newstop-1 and s[realstart] == '-':
+ imagpart = '-1.0'
+ else:
+ imagpart = s[realstart:newstop]
+ return '0.0', imagpart
+ else:
+ return s[realstart:realstop], '0.0'
+
+ # find sign for imaginary part
+ if s[i] == '-' or s[i] == '+':
+ imagsign = s[i]
+ else:
+ raise ValueError
+
+ i += 1
+ if i >= slen:
+ raise ValueError
+
+ imagstart = i
+ pc = s[i]
+ while i < slen and s[i] != ' ':
+ if s[i] in ('+', '-') and pc not in ('e', 'E'):
+ break
+ pc = s[i]
+ i += 1
+
+ imagstop = i - 1
+ if imagstop < 0:
+ raise ValueError
+ if s[imagstop] not in ('j', 'J'):
+ raise ValueError
+ if imagstop < imagstart:
+ raise ValueError
+
+ if i < slen:
+ raise ValueError
+
+ realpart = s[realstart:realstop]
+ if imagstart == imagstop:
+ imagpart = '1.0'
+ else:
+ imagpart = s[imagstart:imagstop]
+ if imagsign == '-':
+ imagpart = imagsign + imagpart
+
+ return realpart, imagpart
+
+
+def format_float(x, code, precision):
+ # like float2string, except that the ".0" is not necessary
+ if isinf(x):
+ if x > 0.0:
+ return "inf"
+ else:
+ return "-inf"
+ elif isnan(x):
+ return "nan"
+ else:
+ return formatd(x, code, precision)
+
+def repr_format(x):
+ return format_float(x, 'r', 0)
+
+def str_format(x):
+ return format_float(x, 'g', DTSF_STR_PRECISION)
+
+
+def unpackcomplex(space, w_complex, strict_typing=True):
"""
- from pypy.objspace.std.complextype import complex_typedef as typedef
+ convert w_complex into a complex and return the unwrapped (real, imag)
+ tuple. If strict_typing==True, we also typecheck the value returned by
+ __complex__ to actually be a complex (and not e.g. a float).
+ See test___complex___returning_non_complex.
+ """
+ if type(w_complex) is W_ComplexObject:
+ return (w_complex.realval, w_complex.imagval)
+ #
+ # test for a '__complex__' method, and call it if found.
+ w_z = None
+ w_method = space.lookup(w_complex, '__complex__')
+ if w_method is not None:
+ w_z = space.get_and_call_function(w_method, w_complex)
+ #
+ if w_z is not None:
+ # __complex__() must return a complex or (float,int,long) object
+ # (XXX should not use isinstance here)
+ if not strict_typing and (space.isinstance_w(w_z, space.w_int) or
+ space.isinstance_w(w_z, space.w_float)):
+ return (space.float_w(w_z), 0.0)
+ elif isinstance(w_z, W_ComplexObject):
+ return (w_z.realval, w_z.imagval)
+ raise oefmt(space.w_TypeError,
+ "__complex__() must return a complex number")
+
+ #
+ # no '__complex__' method, so we assume it is a float,
+ # unless it is an instance of some subclass of complex.
+ if space.isinstance_w(w_complex, space.gettypefor(W_ComplexObject)):
+ real = space.float(space.getattr(w_complex, space.wrap("real")))
+ imag = space.float(space.getattr(w_complex, space.wrap("imag")))
+ return (space.float_w(real), space.float_w(imag))
+ #
+ # Check that it is not a string (on which space.float() would succeed).
+ if (space.isinstance_w(w_complex, space.w_str) or
+ space.isinstance_w(w_complex, space.w_unicode)):
+ raise oefmt(space.w_TypeError,
+ "complex number expected, got '%T'", w_complex)
+ #
+ return (space.float_w(space.float(w_complex)), 0.0)
+
+
+class W_ComplexObject(W_Root):
_immutable_fields_ = ['realval', 'imagval']
def __init__(self, realval=0.0, imgval=0.0):
@@ -63,7 +187,7 @@
def __repr__(self):
""" representation for debugging purposes """
- return "<W_ComplexObject(%f,%f)>" % (self.realval, self.imagval)
+ return "<W_ComplexObject(%f, %f)>" % (self.realval, self.imagval)
def as_tuple(self):
return (self.realval, self.imagval)
@@ -104,162 +228,331 @@
return w_result
+ def is_w(self, space, w_other):
+ from rpython.rlib.longlong2float import float2longlong
+ if not isinstance(w_other, W_ComplexObject):
+ return False
+ if self.user_overridden_class or w_other.user_overridden_class:
+ return self is w_other
+ real1 = space.float_w(space.getattr(self, space.wrap("real")))
+ real2 = space.float_w(space.getattr(w_other, space.wrap("real")))
+ imag1 = space.float_w(space.getattr(self, space.wrap("imag")))
+ imag2 = space.float_w(space.getattr(w_other, space.wrap("imag")))
+ real1 = float2longlong(real1)
+ real2 = float2longlong(real2)
+ imag1 = float2longlong(imag1)
+ imag2 = float2longlong(imag2)
+ return real1 == real2 and imag1 == imag2
+
+ def immutable_unique_id(self, space):
+ if self.user_overridden_class:
+ return None
+ from rpython.rlib.longlong2float import float2longlong
+ from pypy.objspace.std.model import IDTAG_COMPLEX as tag
+ real = space.float_w(space.getattr(self, space.wrap("real")))
+ imag = space.float_w(space.getattr(self, space.wrap("imag")))
+ real_b = rbigint.fromrarith_int(float2longlong(real))
+ imag_b = rbigint.fromrarith_int(r_ulonglong(float2longlong(imag)))
+ val = real_b.lshift(64).or_(imag_b).lshift(3).or_(rbigint.fromint(tag))
+ return space.newlong_from_rbigint(val)
+
def int(self, space):
- raise OperationError(space.w_TypeError, space.wrap("can't convert complex to int; use int(abs(z))"))
+ raise oefmt(space.w_TypeError,
+ "can't convert complex to int; use int(abs(z))")
-registerimplementation(W_ComplexObject)
+ def _to_complex(self, space, w_obj):
+ if isinstance(w_obj, W_ComplexObject):
+ return w_obj
+ if space.isinstance_w(w_obj, space.w_int):
+ w_float = space.float_w(w_obj)
+ return W_ComplexObject(w_float, 0.0)
+ if space.isinstance_w(w_obj, space.w_float):
+ return W_ComplexObject(space.float_w(w_obj), 0.0)
+
+ @staticmethod
+ @unwrap_spec(w_real=WrappedDefault(0.0))
+ def descr__new__(space, w_complextype, w_real, w_imag=None):
+ # if w_real is already a complex number and there is no second
+ # argument, return it. Note that we cannot return w_real if
+ # it is an instance of a *subclass* of complex, or if w_complextype
+ # is itself a subclass of complex.
+ noarg2 = w_imag is None
+ if (noarg2 and space.is_w(w_complextype, space.w_complex)
+ and space.is_w(space.type(w_real), space.w_complex)):
+ return w_real
+
+ if space.isinstance_w(w_real, space.w_unicode):
+ # a string argument
+ if not noarg2:
+ raise oefmt(space.w_TypeError, "complex() can't take second"
+ " arg if first is a string")
+ unistr = unicode_to_decimal_w(space, w_real)
+ try:
+ realstr, imagstr = _split_complex(unistr)
+ except ValueError:
+ raise oefmt(space.w_ValueError,
+ "complex() arg is a malformed string")
+ try:
+ realval = string_to_float(realstr)
+ imagval = string_to_float(imagstr)
+ except ParseStringError:
+ raise oefmt(space.w_ValueError,
+ "complex() arg is a malformed string")
+
+ else:
+ # non-string arguments
+ realval, imagval = unpackcomplex(space, w_real,
+ strict_typing=False)
+
+ # now take w_imag into account
+ if not noarg2:
+ # complex(x, y) == x+y*j, even if 'y' is already a complex.
+ realval2, imagval2 = unpackcomplex(space, w_imag,
+ strict_typing=False)
+
+ # try to preserve the signs of zeroes of realval and realval2
+ if imagval2 != 0.0:
+ realval -= imagval2
+
+ if imagval != 0.0:
+ imagval += realval2
+ else:
+ imagval = realval2
+ # done
+ w_obj = space.allocate_instance(W_ComplexObject, w_complextype)
+ W_ComplexObject.__init__(w_obj, realval, imagval)
+ return w_obj
+
+ def descr___getnewargs__(self, space):
+ return space.newtuple([space.newfloat(self.realval),
+ space.newfloat(self.imagval)])
+
+ def descr_repr(self, space):
+ if self.realval == 0 and copysign(1., self.realval) == 1.:
+ return space.wrap(repr_format(self.imagval) + 'j')
+ sign = (copysign(1., self.imagval) == 1. or
+ isnan(self.imagval)) and '+' or ''
+ return space.wrap('(' + repr_format(self.realval)
+ + sign + repr_format(self.imagval) + 'j)')
+
+ def descr_str(self, space):
+ if self.realval == 0 and copysign(1., self.realval) == 1.:
+ return space.wrap(str_format(self.imagval) + 'j')
+ sign = (copysign(1., self.imagval) == 1. or
+ isnan(self.imagval)) and '+' or ''
+ return space.wrap('(' + str_format(self.realval)
+ + sign + str_format(self.imagval) + 'j)')
+
+ def descr_hash(self, space):
+ hashreal = _hash_float(space, self.realval)
+ hashimg = _hash_float(space, self.imagval)
+ combined = intmask(hashreal + HASH_IMAG * hashimg)
+ return space.newint(-2 if combined == -1 else combined)
+
+ def descr_format(self, space, w_format_spec):
+ return newformat.run_formatter(space, w_format_spec, "format_complex",
+ self)
+
+ def descr_bool(self, space):
+ return space.newbool((self.realval != 0.0) or (self.imagval != 0.0))
+
+ def descr_float(self, space):
+ raise oefmt(space.w_TypeError,
+ "can't convert complex to float; use abs(z)")
+
+ def descr_neg(self, space):
+ return W_ComplexObject(-self.realval, -self.imagval)
+
+ def descr_pos(self, space):
+ return W_ComplexObject(self.realval, self.imagval)
+
+ def descr_abs(self, space):
+ try:
+ return space.newfloat(math.hypot(self.realval, self.imagval))
+ except OverflowError, e:
+ raise OperationError(space.w_OverflowError, space.wrap(str(e)))
+
+ def descr_eq(self, space, w_other):
+ if isinstance(w_other, W_ComplexObject):
+ return space.newbool((self.realval == w_other.realval) and
+ (self.imagval == w_other.imagval))
+ if (space.isinstance_w(w_other, space.w_int) or
+ space.isinstance_w(w_other, space.w_float)):
+ if self.imagval:
+ return space.w_False
+ return space.eq(space.newfloat(self.realval), w_other)
+ return space.w_NotImplemented
+
+ def descr_ne(self, space, w_other):
+ if isinstance(w_other, W_ComplexObject):
+ return space.newbool((self.realval != w_other.realval) or
+ (self.imagval != w_other.imagval))
+ if (space.isinstance_w(w_other, space.w_int)):
+ if self.imagval:
+ return space.w_True
+ return space.ne(space.newfloat(self.realval), w_other)
+ return space.w_NotImplemented
+
+ def _fail_cmp(self, space, w_other):
+ return space.w_NotImplemented
+
+ def descr_add(self, space, w_rhs):
+ w_rhs = self._to_complex(space, w_rhs)
+ if w_rhs is None:
+ return space.w_NotImplemented
+ return W_ComplexObject(self.realval + w_rhs.realval,
+ self.imagval + w_rhs.imagval)
+
+ def descr_radd(self, space, w_lhs):
+ w_lhs = self._to_complex(space, w_lhs)
+ if w_lhs is None:
+ return space.w_NotImplemented
+ return W_ComplexObject(w_lhs.realval + self.realval,
+ w_lhs.imagval + self.imagval)
+
+ def descr_sub(self, space, w_rhs):
+ w_rhs = self._to_complex(space, w_rhs)
+ if w_rhs is None:
+ return space.w_NotImplemented
+ return W_ComplexObject(self.realval - w_rhs.realval,
+ self.imagval - w_rhs.imagval)
+
+ def descr_rsub(self, space, w_lhs):
+ w_lhs = self._to_complex(space, w_lhs)
+ if w_lhs is None:
+ return space.w_NotImplemented
+ return W_ComplexObject(w_lhs.realval - self.realval,
+ w_lhs.imagval - self.imagval)
+
+ def descr_mul(self, space, w_rhs):
+ w_rhs = self._to_complex(space, w_rhs)
+ if w_rhs is None:
+ return space.w_NotImplemented
+ return self.mul(w_rhs)
+
+ def descr_rmul(self, space, w_lhs):
+ w_lhs = self._to_complex(space, w_lhs)
+ if w_lhs is None:
+ return space.w_NotImplemented
+ return w_lhs.mul(self)
+
+ def descr_truediv(self, space, w_rhs):
+ w_rhs = self._to_complex(space, w_rhs)
+ if w_rhs is None:
+ return space.w_NotImplemented
+ try:
+ return self.div(w_rhs)
+ except ZeroDivisionError, e:
+ raise OperationError(space.w_ZeroDivisionError, space.wrap(str(e)))
+
+ def descr_rtruediv(self, space, w_lhs):
+ w_lhs = self._to_complex(space, w_lhs)
+ if w_lhs is None:
+ return space.w_NotImplemented
+ try:
+ return w_lhs.div(self)
+ except ZeroDivisionError, e:
+ raise OperationError(space.w_ZeroDivisionError, space.wrap(str(e)))
+
+ def descr_floordiv(self, space, w_rhs):
+ raise oefmt(space.w_TypeError, "can't take floor of complex number.")
+ descr_rfloordiv = func_with_new_name(descr_floordiv, 'descr_rfloordiv')
+
+ def descr_mod(self, space, w_rhs):
+ raise oefmt(space.w_TypeError, "can't mod complex numbers.")
+ descr_rmod = func_with_new_name(descr_mod, 'descr_rmod')
+
+ def descr_divmod(self, space, w_rhs):
+ raise oefmt(space.w_TypeError,
+ "can't take floor or mod of complex number.")
+ descr_rdivmod = func_with_new_name(descr_divmod, 'descr_rdivmod')
+
+ @unwrap_spec(w_third_arg=WrappedDefault(None))
+ def descr_pow(self, space, w_exponent, w_third_arg):
+ w_exponent = self._to_complex(space, w_exponent)
+ if w_exponent is None:
+ return space.w_NotImplemented
+ if not space.is_w(w_third_arg, space.w_None):
+ raise oefmt(space.w_ValueError, 'complex modulo')
+ try:
+ r = w_exponent.realval
+ if (w_exponent.imagval == 0.0 and -100.0 <= r <= 100.0 and
+ r == int(r)):
+ w_p = self.pow_small_int(int(r))
+ else:
+ w_p = self.pow(w_exponent)
+ except ZeroDivisionError:
+ raise oefmt(space.w_ZeroDivisionError,
+ "0.0 to a negative or complex power")
+ except OverflowError:
+ raise oefmt(space.w_OverflowError, "complex exponentiation")
+ return w_p
+
+ @unwrap_spec(w_third_arg=WrappedDefault(None))
+ def descr_rpow(self, space, w_lhs, w_third_arg):
+ w_lhs = self._to_complex(space, w_lhs)
+ if w_lhs is None:
+ return space.w_NotImplemented
+ return w_lhs.descr_pow(space, self, w_third_arg)
+
+ def descr_conjugate(self, space):
+ """(A+Bj).conjugate() -> A-Bj"""
+ return space.newcomplex(self.realval, -self.imagval)
+
w_one = W_ComplexObject(1, 0)
-def delegate_Bool2Complex(space, w_bool):
- return W_ComplexObject(w_bool.intval, 0.0)
+def complexwprop(name, doc):
+ def fget(space, w_obj):
+ if not isinstance(w_obj, W_ComplexObject):
+ raise oefmt(space.w_TypeError, "descriptor is for 'complex'")
+ return space.newfloat(getattr(w_obj, name))
+ return GetSetProperty(fget, doc=doc)
-def delegate_Int2Complex(space, w_int):
- return W_ComplexObject(w_int.intval, 0.0)
+W_ComplexObject.typedef = StdTypeDef("complex",
+ __doc__ = """complex(real[, imag]) -> complex number
-def delegate_Long2Complex(space, w_long):
- dval = w_long.tofloat(space)
- return W_ComplexObject(dval, 0.0)
+Create a complex number from a real part and an optional imaginary part.
+This is equivalent to (real + imag*1j) where imag defaults to 0.""",
+ __new__ = interp2app(W_ComplexObject.descr__new__),
+ __getnewargs__ = interp2app(W_ComplexObject.descr___getnewargs__),
+ real = complexwprop('realval', doc="the real part of a complex number"),
+ imag = complexwprop('imagval',
+ doc="the imaginary part of a complex number"),
+ __repr__ = interp2app(W_ComplexObject.descr_repr),
+ __str__ = interp2app(W_ComplexObject.descr_str),
+ __hash__ = interp2app(W_ComplexObject.descr_hash),
+ __format__ = interp2app(W_ComplexObject.descr_format),
+ __bool__ = interp2app(W_ComplexObject.descr_bool),
+ __float__ = interp2app(W_ComplexObject.descr_float),
+ __neg__ = interp2app(W_ComplexObject.descr_neg),
+ __pos__ = interp2app(W_ComplexObject.descr_pos),
+ __abs__ = interp2app(W_ComplexObject.descr_abs),
-def delegate_Float2Complex(space, w_float):
- return W_ComplexObject(w_float.floatval, 0.0)
+ __eq__ = interp2app(W_ComplexObject.descr_eq),
+ __ne__ = interp2app(W_ComplexObject.descr_ne),
+ __lt__ = interp2app(W_ComplexObject._fail_cmp),
+ __le__ = interp2app(W_ComplexObject._fail_cmp),
+ __gt__ = interp2app(W_ComplexObject._fail_cmp),
+ __ge__ = interp2app(W_ComplexObject._fail_cmp),
-def hash__Complex(space, w_value):
- hashreal = _hash_float(space, w_value.realval)
- hashimg = _hash_float(space, w_value.imagval)
- combined = intmask(hashreal + HASH_IMAG * hashimg)
- return space.newint(-2 if combined == -1 else combined)
+ __add__ = interp2app(W_ComplexObject.descr_add),
+ __radd__ = interp2app(W_ComplexObject.descr_radd),
+ __sub__ = interp2app(W_ComplexObject.descr_sub),
+ __rsub__ = interp2app(W_ComplexObject.descr_rsub),
+ __mul__ = interp2app(W_ComplexObject.descr_mul),
+ __rmul__ = interp2app(W_ComplexObject.descr_rmul),
+ __truediv__ = interp2app(W_ComplexObject.descr_truediv),
+ __rtruediv__ = interp2app(W_ComplexObject.descr_rtruediv),
+ __floordiv__ = interp2app(W_ComplexObject.descr_floordiv),
+ __rfloordiv__ = interp2app(W_ComplexObject.descr_rfloordiv),
+ __mod__ = interp2app(W_ComplexObject.descr_mod),
+ __rmod__ = interp2app(W_ComplexObject.descr_rmod),
+ __divmod__ = interp2app(W_ComplexObject.descr_divmod),
+ __rdivmod__ = interp2app(W_ComplexObject.descr_rdivmod),
+ __pow__ = interp2app(W_ComplexObject.descr_pow),
+ __rpow__ = interp2app(W_ComplexObject.descr_rpow),
-def add__Complex_Complex(space, w_complex1, w_complex2):
- return W_ComplexObject(w_complex1.realval + w_complex2.realval,
- w_complex1.imagval + w_complex2.imagval)
-
-def sub__Complex_Complex(space, w_complex1, w_complex2):
- return W_ComplexObject(w_complex1.realval - w_complex2.realval,
- w_complex1.imagval - w_complex2.imagval)
-
-def mul__Complex_Complex(space, w_complex1, w_complex2):
- return w_complex1.mul(w_complex2)
-
-def div__Complex_Complex(space, w_complex1, w_complex2):
- try:
- return w_complex1.div(w_complex2)
- except ZeroDivisionError, e:
- raise OperationError(space.w_ZeroDivisionError, space.wrap(str(e)))
-
-truediv__Complex_Complex = div__Complex_Complex
-
-def pow__Complex_Complex_ANY(space, w_complex, w_exponent, thirdArg):
- if not space.is_w(thirdArg, space.w_None):
- raise OperationError(space.w_ValueError, space.wrap('complex modulo'))
- try:
- r = w_exponent.realval
- if w_exponent.imagval == 0.0 and -100.0 <= r <= 100.0 and r == int(r):
- w_p = w_complex.pow_small_int(int(r))
- else:
- w_p = w_complex.pow(w_exponent)
- except ZeroDivisionError:
- raise OperationError(space.w_ZeroDivisionError, space.wrap("0.0 to a negative or complex power"))
- except OverflowError:
- raise OperationError(space.w_OverflowError, space.wrap("complex exponentiation"))
- return w_p
-
-def neg__Complex(space, w_complex):
- return W_ComplexObject(-w_complex.realval, -w_complex.imagval)
-
-def pos__Complex(space, w_complex):
- return W_ComplexObject(w_complex.realval, w_complex.imagval)
-
-def abs__Complex(space, w_complex):
- try:
- return space.newfloat(math.hypot(w_complex.realval, w_complex.imagval))
- except OverflowError, e:
- raise OperationError(space.w_OverflowError, space.wrap(str(e)))
-
-def eq__Complex_Complex(space, w_complex1, w_complex2):
- return space.newbool((w_complex1.realval == w_complex2.realval) and
- (w_complex1.imagval == w_complex2.imagval))
-
-def ne__Complex_Complex(space, w_complex1, w_complex2):
- return space.newbool((w_complex1.realval != w_complex2.realval) or
- (w_complex1.imagval != w_complex2.imagval))
-
-def eq__Complex_Long(space, w_complex1, w_long2):
- if w_complex1.imagval:
- return space.w_False
- return space.eq(space.newfloat(w_complex1.realval), w_long2)
-eq__Complex_Int = eq__Complex_Long
-
-def eq__Long_Complex(space, w_long1, w_complex2):
- return eq__Complex_Long(space, w_complex2, w_long1)
-eq__Int_Complex = eq__Long_Complex
-
-def ne__Complex_Long(space, w_complex1, w_long2):
- if w_complex1.imagval:
- return space.w_True
- return space.ne(space.newfloat(w_complex1.realval), w_long2)
-ne__Complex_Int = ne__Complex_Long
-
-def ne__Long_Complex(space, w_long1, w_complex2):
- return ne__Complex_Long(space, w_complex2, w_long1)
-ne__Int_Complex = ne__Long_Complex
-
-def lt__Complex_Complex(space, w_complex1, w_complex2):
- from pypy.objspace.std.model import FailedToImplement
- raise FailedToImplement
-
-gt__Complex_Complex = lt__Complex_Complex
-ge__Complex_Complex = lt__Complex_Complex
-le__Complex_Complex = lt__Complex_Complex
-
-def nonzero__Complex(space, w_complex):
- return space.newbool((w_complex.realval != 0.0) or
- (w_complex.imagval != 0.0))
-
-def float__Complex(space, w_complex):
- raise OperationError(space.w_TypeError, space.wrap("can't convert complex to float; use abs(z)"))
-
-def complex_conjugate__Complex(space, w_self):
- #w_real = space.call_function(space.w_float,space.wrap(w_self.realval))
- #w_imag = space.call_function(space.w_float,space.wrap(-w_self.imagval))
- return space.newcomplex(w_self.realval,-w_self.imagval)
-
-def format_float(x, code, precision):
- # like float2string, except that the ".0" is not necessary
- if isinf(x):
- if x > 0.0:
- return "inf"
- else:
- return "-inf"
- elif isnan(x):
- return "nan"
- else:
- return formatd(x, code, precision)
-
-def repr_format(x):
- return format_float(x, 'r', 0)
-def str_format(x):
- return format_float(x, 'g', DTSF_STR_PRECISION)
-
-def repr__Complex(space, w_complex):
- if w_complex.realval == 0 and copysign(1., w_complex.realval) == 1.:
- return space.wrap(repr_format(w_complex.imagval) + 'j')
- sign = (copysign(1., w_complex.imagval) == 1. or
- isnan(w_complex.imagval)) and '+' or ''
- return space.wrap('(' + repr_format(w_complex.realval)
- + sign + repr_format(w_complex.imagval) + 'j)')
-
-def str__Complex(space, w_complex):
- if w_complex.realval == 0 and copysign(1., w_complex.realval) == 1.:
- return space.wrap(str_format(w_complex.imagval) + 'j')
- sign = (copysign(1., w_complex.imagval) == 1. or
- isnan(w_complex.imagval)) and '+' or ''
- return space.wrap('(' + str_format(w_complex.realval)
- + sign + str_format(w_complex.imagval) + 'j)')
-
-def format__Complex_ANY(space, w_complex, w_format_spec):
- return newformat.run_formatter(space, w_format_spec, "format_complex", w_complex)
-
-from pypy.objspace.std import complextype
-register_all(vars(), complextype)
+ conjugate = interp2app(W_ComplexObject.descr_conjugate),
+)
diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py
deleted file mode 100644
--- a/pypy/objspace/std/complextype.py
+++ /dev/null
@@ -1,240 +0,0 @@
-from pypy.interpreter.error import OperationError, oefmt
-from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
-from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.stdtypedef import GetSetProperty, StdTypeDef
-from pypy.objspace.std.stdtypedef import StdObjSpaceMultiMethod
-from pypy.objspace.std.unicodeobject import unicode_to_decimal_w
-from rpython.rlib.rfloat import string_to_float
-from rpython.rlib.rstring import ParseStringError
-
-# ERRORCODES
-
-ERR_WRONG_SECOND = "complex() can't take second arg if first is a string"
-ERR_MALFORMED = "complex() arg is a malformed string"
-
-complex_conjugate = StdObjSpaceMultiMethod('conjugate', 1,
- doc="(A+Bj).conjugate() -> A-Bj")
-
-register_all(vars(),globals())
-
-def _split_complex(s):
- slen = len(s)
- if slen == 0:
- raise ValueError
- realstart = 0
- realstop = 0
- imagstart = 0
- imagstop = 0
- imagsign = ' '
- i = 0
- # ignore whitespace at beginning and end
- while i < slen and s[i] == ' ':
- i += 1
- while slen > 0 and s[slen-1] == ' ':
- slen -= 1
-
- if s[i] == '(' and s[slen-1] == ')':
- i += 1
- slen -= 1
- # ignore whitespace after bracket
- while i < slen and s[i] == ' ':
- i += 1
- while slen > 0 and s[slen-1] == ' ':
- slen -= 1
-
- # extract first number
- realstart = i
- pc = s[i]
- while i < slen and s[i] != ' ':
- if s[i] in ('+', '-') and pc not in ('e', 'E') and i != realstart:
- break
- pc = s[i]
- i += 1
-
- realstop = i
-
- # return appropriate strings is only one number is there
- if i >= slen:
- newstop = realstop - 1
- if newstop < 0:
- raise ValueError
- if s[newstop] in ('j', 'J'):
- if realstart == newstop:
- imagpart = '1.0'
- elif realstart == newstop-1 and s[realstart] == '+':
- imagpart = '1.0'
- elif realstart == newstop-1 and s[realstart] == '-':
- imagpart = '-1.0'
- else:
- imagpart = s[realstart:newstop]
- return '0.0', imagpart
- else:
- return s[realstart:realstop], '0.0'
-
- # find sign for imaginary part
- if s[i] == '-' or s[i] == '+':
- imagsign = s[i]
- else:
- raise ValueError
-
- i += 1
- if i >= slen:
- raise ValueError
-
- imagstart = i
- pc = s[i]
- while i < slen and s[i] != ' ':
- if s[i] in ('+', '-') and pc not in ('e', 'E'):
- break
- pc = s[i]
- i += 1
-
- imagstop = i - 1
- if imagstop < 0:
- raise ValueError
- if s[imagstop] not in ('j', 'J'):
- raise ValueError
- if imagstop < imagstart:
- raise ValueError
-
- if i < slen:
- raise ValueError
-
- realpart = s[realstart:realstop]
- if imagstart == imagstop:
- imagpart = '1.0'
- else:
- imagpart = s[imagstart:imagstop]
- if imagsign == '-':
- imagpart = imagsign + imagpart
-
- return realpart, imagpart
-
-
- at unwrap_spec(w_real = WrappedDefault(0.0))
-def descr__new__(space, w_complextype, w_real, w_imag=None):
- from pypy.objspace.std.complexobject import W_ComplexObject
-
- # if w_real is already a complex number and there is no second
- # argument, return it. Note that we cannot return w_real if
- # it is an instance of a *subclass* of complex, or if w_complextype
- # is itself a subclass of complex.
- noarg2 = w_imag is None
- if (noarg2 and space.is_w(w_complextype, space.w_complex)
- and space.is_w(space.type(w_real), space.w_complex)):
- return w_real
-
- if space.isinstance_w(w_real, space.w_unicode):
- # a string argument
- if not noarg2:
- raise OperationError(space.w_TypeError,
- space.wrap("complex() can't take second arg"
- " if first is a string"))
- unistr = unicode_to_decimal_w(space, w_real)
- try:
- realstr, imagstr = _split_complex(unistr)
- except ValueError:
- raise OperationError(space.w_ValueError, space.wrap(ERR_MALFORMED))
- try:
- realval = string_to_float(realstr)
- imagval = string_to_float(imagstr)
- except ParseStringError:
- raise OperationError(space.w_ValueError, space.wrap(ERR_MALFORMED))
-
- else:
- # non-string arguments
- realval, imagval = unpackcomplex(space, w_real, strict_typing=False)
-
- # now take w_imag into account
- if not noarg2:
- # complex(x, y) == x+y*j, even if 'y' is already a complex.
- realval2, imagval2 = unpackcomplex(space, w_imag, strict_typing=False)
-
- # try to preserve the signs of zeroes of realval and realval2
- if imagval2 != 0.0:
- realval -= imagval2
-
- if imagval != 0.0:
- imagval += realval2
- else:
- imagval = realval2
- # done
- w_obj = space.allocate_instance(W_ComplexObject, w_complextype)
- W_ComplexObject.__init__(w_obj, realval, imagval)
- return w_obj
-
-
-def unpackcomplex(space, w_complex, strict_typing=True):
- """
- convert w_complex into a complex and return the unwrapped (real, imag)
- tuple. If strict_typing==True, we also typecheck the value returned by
- __complex__ to actually be a complex (and not e.g. a float).
- See test___complex___returning_non_complex.
- """
- from pypy.objspace.std.complexobject import W_ComplexObject
- if type(w_complex) is W_ComplexObject:
- return (w_complex.realval, w_complex.imagval)
- #
- # test for a '__complex__' method, and call it if found.
- w_z = None
- w_method = space.lookup(w_complex, '__complex__')
- if w_method is not None:
- w_z = space.get_and_call_function(w_method, w_complex)
- #
- if w_z is not None:
- # __complex__() must return a complex or (float,int,long) object
- # (XXX should not use isinstance here)
- if not strict_typing and (space.isinstance_w(w_z, space.w_int) or
- space.isinstance_w(w_z, space.w_float)):
- return (space.float_w(w_z), 0.0)
- elif isinstance(w_z, W_ComplexObject):
- return (w_z.realval, w_z.imagval)
- raise OperationError(space.w_TypeError,
- space.wrap("__complex__() must return"
- " a complex number"))
-
- #
- # no '__complex__' method, so we assume it is a float,
- # unless it is an instance of some subclass of complex.
- if space.isinstance_w(w_complex, space.gettypefor(W_ComplexObject)):
- real = space.float(space.getattr(w_complex, space.wrap("real")))
- imag = space.float(space.getattr(w_complex, space.wrap("imag")))
- return (space.float_w(real), space.float_w(imag))
- #
- # Check that it is not a string (on which space.float() would succeed).
- if (space.isinstance_w(w_complex, space.w_str) or
- space.isinstance_w(w_complex, space.w_unicode)):
- raise oefmt(space.w_TypeError,
- "complex number expected, got '%T'", w_complex)
- #
- return (space.float_w(space.float(w_complex)), 0.0)
-
-
-def complexwprop(name, doc):
- def fget(space, w_obj):
- from pypy.objspace.std.complexobject import W_ComplexObject
- if not isinstance(w_obj, W_ComplexObject):
- raise OperationError(space.w_TypeError,
- space.wrap("descriptor is for 'complex'"))
- return space.newfloat(getattr(w_obj, name))
- return GetSetProperty(fget, doc=doc)
-
-def descr___getnewargs__(space, w_self):
- from pypy.objspace.std.complexobject import W_ComplexObject
- assert isinstance(w_self, W_ComplexObject)
- return space.newtuple([space.newfloat(w_self.realval),
- space.newfloat(w_self.imagval)])
-
-complex_typedef = StdTypeDef("complex",
- __doc__ = """complex(real[, imag]) -> complex number
-
-Create a complex number from a real part and an optional imaginary part.
-This is equivalent to (real + imag*1j) where imag defaults to 0.""",
- __new__ = interp2app(descr__new__),
- __getnewargs__ = interp2app(descr___getnewargs__),
- real = complexwprop('realval', doc="the real part of a complex number"),
- imag = complexwprop('imagval',
- doc="the imaginary part of a complex number"),
- )
-
-complex_typedef.registermethods(globals())
diff --git a/pypy/objspace/std/default.py b/pypy/objspace/std/default.py
deleted file mode 100644
--- a/pypy/objspace/std/default.py
+++ /dev/null
@@ -1,11 +0,0 @@
-"""Default implementation for some operation."""
-
-from pypy.objspace.std.register_all import register_all
-
-
-# __init__ should succeed if called internally as a multimethod
-
-def init__ANY(space, w_obj, __args__):
- pass
-
-register_all(vars())
diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py
--- a/pypy/objspace/std/dictproxyobject.py
+++ b/pypy/objspace/std/dictproxyobject.py
@@ -1,5 +1,3 @@
-#from pypy.objspace.std.model import registerimplementation, W_Object
-#from pypy.objspace.std.register_all import register_all
from pypy.objspace.std.dictmultiobject import DictStrategy, create_iterator_classes
from pypy.objspace.std.typeobject import unwrap_cell
from pypy.interpreter.error import OperationError, oefmt
diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py
--- a/pypy/objspace/std/floatobject.py
+++ b/pypy/objspace/std/floatobject.py
@@ -1,139 +1,35 @@
import math
import operator
+import sys
+from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
+from pypy.interpreter.typedef import GetSetProperty
from pypy.objspace.std import newformat
-from pypy.objspace.std.floattype import float_typedef, W_AbstractFloatObject
-from pypy.objspace.std.intobject import HASH_BITS, HASH_MODULUS
-from pypy.objspace.std.multimethod import FailedToImplementArgs
-from pypy.objspace.std.model import registerimplementation, W_Object
-from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.longobject import W_LongObject, newlong_from_float
-from pypy.objspace.std.noneobject import W_NoneObject
+from pypy.objspace.std.intobject import HASH_BITS, HASH_MODULUS, W_IntObject
+from pypy.objspace.std.longobject import (
+ W_AbstractLongObject, newlong_from_float)
from rpython.rlib.rarithmetic import (
LONG_BIT, intmask, ovfcheck_float_to_int, r_uint)
+from pypy.objspace.std.stdtypedef import StdTypeDef
+from pypy.objspace.std.util import wrap_parsestringerror
+from rpython.rlib import rarithmetic, rfloat
+from rpython.rlib.rbigint import rbigint
from rpython.rlib.rfloat import (
isinf, isnan, isfinite, INFINITY, NAN, copysign, formatd,
DTSF_ADD_DOT_0, float_as_rbigint_ratio)
-from rpython.rlib.rbigint import rbigint
-from rpython.rlib import rfloat
+from rpython.rlib.rstring import ParseStringError
from rpython.tool.sourcetools import func_with_new_name
+from rpython.rlib.unroll import unrolling_iterable
from rpython.rtyper.lltypesystem.module.ll_math import math_fmod
-from pypy.objspace.std.intobject import W_IntObject
-
HASH_INF = 314159
HASH_NAN = 0
-class W_FloatObject(W_AbstractFloatObject):
- """This is a implementation of the app-level 'float' type.
- The constructor takes an RPython float as an argument."""
- _immutable_fields_ = ['floatval']
-
- typedef = float_typedef
-
- def __init__(self, floatval):
- self.floatval = floatval
-
- def unwrap(self, space):
- return self.floatval
-
- def int_w(self, space, allow_conversion=True):
- self._typed_unwrap_error(space, "integer")
-
- def bigint_w(self, space, allow_conversion=True):
- self._typed_unwrap_error(space, "integer")
-
- def float_w(self, space, allow_conversion=True):
- return self.floatval
-
- def _float_w(self, space):
- return self.floatval
-
- def int(self, space):
- if (type(self) is not W_FloatObject and
- space.is_overloaded(self, space.w_float, '__int__')):
- return W_Object.int(self, space)
- try:
- value = ovfcheck_float_to_int(self.floatval)
- except OverflowError:
- return newlong_from_float(space, self.floatval)
- else:
- return space.newint(value)
-
- def __repr__(self):
- return "<W_FloatObject(%f)>" % self.floatval
-
-registerimplementation(W_FloatObject)
-
-# bool-to-float delegation
-def delegate_Bool2Float(space, w_bool):
- return W_FloatObject(float(w_bool.intval))
-
-# int-to-float delegation
-def delegate_Int2Float(space, w_intobj):
- return W_FloatObject(float(w_intobj.intval))
-
-# long-to-float delegation
-def delegate_Long2Float(space, w_longobj):
- return W_FloatObject(w_longobj.tofloat(space))
-
-
-# float__Float is supposed to do nothing, unless it has
-# a derived float object, where it should return
-# an exact one.
-def float__Float(space, w_float1):
- if space.is_w(space.type(w_float1), space.w_float):
- return w_float1
- a = w_float1.floatval
- return W_FloatObject(a)
-
-def trunc__Float(space, w_floatobj):
- whole = math.modf(w_floatobj.floatval)[1]
- try:
- value = ovfcheck_float_to_int(whole)
- except OverflowError:
- return newlong_from_float(space, whole)
- else:
- return space.newint(value)
-
-def _char_from_hex(number):
- return "0123456789abcdef"[number]
-
-TOHEX_NBITS = rfloat.DBL_MANT_DIG + 3 - (rfloat.DBL_MANT_DIG + 2) % 4
-
-def float_hex__Float(space, w_float):
- value = w_float.floatval
- if not isfinite(value):
- return str__Float(space, w_float)
- if value == 0.0:
- if copysign(1., value) == -1.:
- return space.wrap("-0x0.0p+0")
- else:
- return space.wrap("0x0.0p+0")
- mant, exp = math.frexp(value)
- shift = 1 - max(rfloat.DBL_MIN_EXP - exp, 0)
- mant = math.ldexp(mant, shift)
- mant = abs(mant)
- exp -= shift
- result = ['\0'] * ((TOHEX_NBITS - 1) // 4 + 2)
- result[0] = _char_from_hex(int(mant))
- mant -= int(mant)
- result[1] = "."
- for i in range((TOHEX_NBITS - 1) // 4):
- mant *= 16.0
- result[i + 2] = _char_from_hex(int(mant))
- mant -= int(mant)
- if exp < 0:
- sign = "-"
- else:
- sign = "+"
- exp = abs(exp)
- s = ''.join(result)
- if value < 0.0:
- return space.wrap("-0x%sp%s%d" % (s, sign, exp))
- else:
- return space.wrap("0x%sp%s%d" % (s, sign, exp))
+# Here 0.30103 is an upper bound for log10(2)
+NDIGITS_MAX = int((rfloat.DBL_MANT_DIG - rfloat.DBL_MIN_EXP) * 0.30103)
+NDIGITS_MIN = -int((rfloat.DBL_MAX_EXP + 1) * 0.30103)
def float2string(x, code, precision):
# we special-case explicitly inf and nan here
@@ -148,34 +44,60 @@
s = "nan"
return s
-def repr__Float(space, w_float):
- return space.wrap(float2string(w_float.floatval, 'r', 0))
-str__Float = repr__Float
+def detect_floatformat():
+ from rpython.rtyper.lltypesystem import rffi, lltype
+ buf = lltype.malloc(rffi.CCHARP.TO, 8, flavor='raw')
+ rffi.cast(rffi.DOUBLEP, buf)[0] = 9006104071832581.0
+ packed = rffi.charpsize2str(buf, 8)
+ if packed == "\x43\x3f\xff\x01\x02\x03\x04\x05":
+ double_format = 'IEEE, big-endian'
+ elif packed == "\x05\x04\x03\x02\x01\xff\x3f\x43":
+ double_format = 'IEEE, little-endian'
+ else:
+ double_format = 'unknown'
+ lltype.free(buf, flavor='raw')
+ #
+ buf = lltype.malloc(rffi.CCHARP.TO, 4, flavor='raw')
+ rffi.cast(rffi.FLOATP, buf)[0] = rarithmetic.r_singlefloat(16711938.0)
+ packed = rffi.charpsize2str(buf, 4)
+ if packed == "\x4b\x7f\x01\x02":
+ float_format = 'IEEE, big-endian'
+ elif packed == "\x02\x01\x7f\x4b":
+ float_format = 'IEEE, little-endian'
+ else:
+ float_format = 'unknown'
+ lltype.free(buf, flavor='raw')
-def format__Float_ANY(space, w_float, w_spec):
- return newformat.run_formatter(space, w_spec, "format_float", w_float)
+ return double_format, float_format
-# ____________________________________________________________
-# A mess to handle all cases of float comparison without relying
-# on delegation, which can unfortunately loose precision when
-# casting an int or a long to a float.
+_double_format, _float_format = detect_floatformat()
-def list_compare_funcs(declarator):
- for op in ['lt', 'le', 'eq', 'ne', 'gt', 'ge']:
- func, name = declarator(op)
- globals()[name] = func_with_new_name(func, name)
-def _reverse(opname):
- if opname[0] == 'l': return 'g' + opname[1:]
- elif opname[0] == 'g': return 'l' + opname[1:]
- else: return opname
+_alpha = zip("abcdef", range(10, 16)) + zip("ABCDEF", range(10, 16))
+_hex_to_int = zip("0123456789", range(10)) + _alpha
+_hex_to_int_iterable = unrolling_iterable(_hex_to_int)
+def _hex_from_char(c):
+ for h, v in _hex_to_int_iterable:
+ if h == c:
+ return v
+ return -1
-def declare_compare_bigint(opname):
- """Return a helper function that implements a float-bigint comparison."""
+def _hex_digit(s, j, co_end, float_digits):
+ if j < float_digits:
+ i = co_end - j
+ else:
+ i = co_end - 1 - j
+ return _hex_from_char(s[i])
+
+def _char_from_hex(number):
+ return "0123456789abcdef"[number]
+
+
+def make_compare_func(opname):
op = getattr(operator, opname)
- #
+
if opname == 'eq' or opname == 'ne':
def do_compare_bigint(f1, b2):
"""f1 is a float. b2 is a bigint."""
@@ -201,73 +123,578 @@
f1 = math.floor(f1)
b1 = rbigint.fromfloat(f1)
return getattr(b1, opname)(b2)
- #
- return do_compare_bigint, 'compare_bigint_' + opname
-list_compare_funcs(declare_compare_bigint)
+ def _compare(self, space, w_other):
+ if isinstance(w_other, W_FloatObject):
+ return space.newbool(op(self.floatval, w_other.floatval))
+ if isinstance(w_other, W_IntObject):
+ f1 = self.floatval
+ i2 = space.int_w(w_other)
+ f2 = float(i2)
+ if LONG_BIT > 32 and int(f2) != i2:
+ res = do_compare_bigint(f1, rbigint.fromint(i2))
+ else:
+ res = op(f1, f2)
+ return space.newbool(res)
+ if isinstance(w_other, W_AbstractLongObject):
+ return space.newbool(do_compare_bigint(self.floatval,
+ space.bigint_w(w_other)))
+ return space.w_NotImplemented
+ return func_with_new_name(_compare, 'descr_' + opname)
-def declare_cmp_float_float(opname):
- op = getattr(operator, opname)
- def f(space, w_float1, w_float2):
- f1 = w_float1.floatval
- f2 = w_float2.floatval
- return space.newbool(op(f1, f2))
- return f, opname + "__Float_Float"
-list_compare_funcs(declare_cmp_float_float)
-def declare_cmp_float_int(opname):
- op = getattr(operator, opname)
- compare = globals()['compare_bigint_' + opname]
- def f(space, w_float1, w_int2):
- f1 = w_float1.floatval
- i2 = w_int2.intval
- f2 = float(i2)
- if LONG_BIT > 32 and int(f2) != i2:
- res = compare(f1, rbigint.fromint(i2))
+class W_FloatObject(W_Root):
+ """This is a implementation of the app-level 'float' type.
+ The constructor takes an RPython float as an argument."""
+ _immutable_fields_ = ['floatval']
+
+ def __init__(self, floatval):
+ self.floatval = floatval
+
+ def unwrap(self, space):
+ return self.floatval
+
+ def int_w(self, space, allow_conversion=True):
+ self._typed_unwrap_error(space, "integer")
+
+ def bigint_w(self, space, allow_conversion=True):
+ self._typed_unwrap_error(space, "integer")
+
+ def float_w(self, space, allow_conversion=True):
+ return self.floatval
+
+ def _float_w(self, space):
+ return self.floatval
+
+ def int(self, space):
+ if (type(self) is not W_FloatObject and
+ space.is_overloaded(self, space.w_float, '__int__')):
+ return W_Root.int(self, space)
+ try:
+ value = ovfcheck_float_to_int(self.floatval)
+ except OverflowError:
+ return newlong_from_float(space, self.floatval)
else:
- res = op(f1, f2)
- return space.newbool(res)
- return f, opname + "__Float_Int"
-list_compare_funcs(declare_cmp_float_int)
+ return space.newint(value)
-def declare_cmp_float_long(opname):
- compare = globals()['compare_bigint_' + opname]
- def f(space, w_float1, w_long2):
- f1 = w_float1.floatval
- b2 = w_long2.num
- return space.newbool(compare(f1, b2))
- return f, opname + "__Float_Long"
-list_compare_funcs(declare_cmp_float_long)
+ def is_w(self, space, w_other):
+ from rpython.rlib.longlong2float import float2longlong
+ if not isinstance(w_other, W_FloatObject):
+ return False
+ if self.user_overridden_class or w_other.user_overridden_class:
+ return self is w_other
+ one = float2longlong(space.float_w(self))
+ two = float2longlong(space.float_w(w_other))
+ return one == two
-def declare_cmp_int_float(opname):
- op = getattr(operator, opname)
- revcompare = globals()['compare_bigint_' + _reverse(opname)]
- def f(space, w_int1, w_float2):
- f2 = w_float2.floatval
- i1 = w_int1.intval
- f1 = float(i1)
- if LONG_BIT > 32 and int(f1) != i1:
- res = revcompare(f2, rbigint.fromint(i1))
+ def immutable_unique_id(self, space):
+ if self.user_overridden_class:
+ return None
+ from rpython.rlib.longlong2float import float2longlong
+ from pypy.objspace.std.model import IDTAG_FLOAT as tag
+ val = float2longlong(space.float_w(self))
+ b = rbigint.fromrarith_int(val)
+ b = b.lshift(3).or_(rbigint.fromint(tag))
+ return space.newlong_from_rbigint(b)
+
+ def __repr__(self):
+ return "<W_FloatObject(%f)>" % self.floatval
+
+ @staticmethod
+ @unwrap_spec(w_x=WrappedDefault(0.0))
+ def descr__new__(space, w_floattype, w_x):
+ def _string_to_float(space, w_source, string):
+ try:
+ return rfloat.string_to_float(string)
+ except ParseStringError as e:
+ raise wrap_parsestringerror(space, e, w_source)
+
+ w_value = w_x # 'x' is the keyword argument name in CPython
+ if space.lookup(w_value, "__float__") is not None:
+ w_obj = space.float(w_value)
+ if space.is_w(w_floattype, space.w_float):
+ return w_obj
+ value = space.float_w(w_obj)
+ elif space.isinstance_w(w_value, space.w_unicode):
+ from unicodeobject import unicode_to_decimal_w
+ value = _string_to_float(space, w_value,
+ unicode_to_decimal_w(space, w_value))
else:
- res = op(f1, f2)
- return space.newbool(res)
- return f, opname + "__Int_Float"
-list_compare_funcs(declare_cmp_int_float)
+ try:
+ value = space.charbuf_w(w_value)
+ except OperationError as e:
+ if e.match(space, space.w_TypeError):
+ raise oefmt(
+ space.w_TypeError,
+ "float() argument must be a string or a number")
+ raise
+ value = _string_to_float(space, w_value, value)
+ w_obj = space.allocate_instance(W_FloatObject, w_floattype)
+ W_FloatObject.__init__(w_obj, value)
+ return w_obj
-def declare_cmp_long_float(opname):
- revcompare = globals()['compare_bigint_' + _reverse(opname)]
- def f(space, w_long1, w_float2):
- f2 = w_float2.floatval
- b1 = w_long1.num
- return space.newbool(revcompare(f2, b1))
- return f, opname + "__Long_Float"
-list_compare_funcs(declare_cmp_long_float)
+ @staticmethod
+ @unwrap_spec(kind=str)
+ def descr___getformat__(space, w_cls, kind):
+ if kind == "float":
+ return space.wrap(_float_format)
+ elif kind == "double":
+ return space.wrap(_double_format)
+ raise oefmt(space.w_ValueError, "only float and double are valid")
+ @staticmethod
+ @unwrap_spec(s=str)
+ def descr_fromhex(space, w_cls, s):
+ length = len(s)
+ i = 0
+ value = 0.0
+ while i < length and s[i].isspace():
+ i += 1
+ if i == length:
+ raise oefmt(space.w_ValueError, "invalid hex string")
+ sign = 1
+ if s[i] == "-":
+ sign = -1
+ i += 1
+ elif s[i] == "+":
+ i += 1
+ if length == i:
+ raise oefmt(space.w_ValueError, "invalid hex string")
+ if s[i] == "i" or s[i] == "I":
+ i += 1
+ if length - i >= 2 and s[i:i + 2].lower() == "nf":
+ i += 2
+ value = rfloat.INFINITY
+ if length - i >= 5 and s[i:i + 5].lower() == "inity":
+ i += 5
+ elif s[i] == "n" or s[i] == "N":
+ i += 1
+ if length - i >= 2 and s[i:i + 2].lower() == "an":
+ i += 2
+ value = rfloat.NAN
+ else:
+ if (s[i] == "0" and length - i > 1 and
+ (s[i + 1] == "x" or s[i + 1] == "X")):
+ i += 2
+ co_start = i
+ while i < length and _hex_from_char(s[i]) >= 0:
+ i += 1
+ whole_end = i
+ if i < length and s[i] == ".":
+ i += 1
+ while i < length and _hex_from_char(s[i]) >= 0:
+ i += 1
+ co_end = i - 1
+ else:
+ co_end = i
More information about the pypy-commit
mailing list