Author: Ronan Lamy <[email protected]>
Branch: multiphase
Changeset: r92152:4babb75613f0
Date: 2017-08-14 20:53 +0200
http://bitbucket.org/pypy/pypy/changeset/4babb75613f0/
Log: hg merge py3.5
diff --git a/lib-python/3/distutils/sysconfig_pypy.py
b/lib-python/3/distutils/sysconfig_pypy.py
--- a/lib-python/3/distutils/sysconfig_pypy.py
+++ b/lib-python/3/distutils/sysconfig_pypy.py
@@ -81,6 +81,19 @@
g['LIBDIR'] = os.path.join(sys.prefix, 'lib')
g['VERSION'] = get_python_version()
+ if sys.platform[:6] == "darwin":
+ import platform
+ if platform.machine() == 'i386':
+ if platform.architecture()[0] == '32bit':
+ arch = 'i386'
+ else:
+ arch = 'x86_64'
+ else:
+ # just a guess
+ arch = platform.machine()
+ g['LDSHARED'] += ' -undefined dynamic_lookup'
+ g['CC'] += ' -arch %s' % (arch,)
+
global _config_vars
_config_vars = g
diff --git a/lib-python/3/test/test_pyexpat.py
b/lib-python/3/test/test_pyexpat.py
--- a/lib-python/3/test/test_pyexpat.py
+++ b/lib-python/3/test/test_pyexpat.py
@@ -11,7 +11,7 @@
from xml.parsers import expat
from xml.parsers.expat import errors
-from test.support import sortdict
+from test.support import sortdict, impl_detail
class SetAttributeTest(unittest.TestCase):
@@ -446,6 +446,7 @@
self.assertEqual(os.path.basename(entry[0]), filename)
self.assertEqual(entry[2], funcname)
+ @impl_detail("PyPy does not have pyexpat.c", pypy=False)
def test_exception(self):
parser = expat.ParserCreate()
parser.StartElementHandler = self.StartElementHandler
diff --git a/lib_pypy/pyrepl/readline.py b/lib_pypy/pyrepl/readline.py
--- a/lib_pypy/pyrepl/readline.py
+++ b/lib_pypy/pyrepl/readline.py
@@ -297,10 +297,7 @@
line = line.rstrip('\n')
if isinstance(line, unicode):
return line # on py3k
- try:
- return unicode(line, ENCODING)
- except UnicodeDecodeError: # bah, silently fall back...
- return unicode(line, 'utf-8', 'replace')
+ return unicode(line, 'utf-8', 'replace')
def get_history_length(self):
return self.saved_history_length
@@ -317,7 +314,7 @@
# history item: we use \r\n instead of just \n. If the history
# file is passed to GNU readline, the extra \r are just ignored.
history = self.get_reader().history
- f = open(os.path.expanduser(filename), 'r')
+ f = open(os.path.expanduser(filename), 'r', encoding='utf-8')
buffer = []
for line in f:
if line.endswith('\r\n'):
@@ -334,15 +331,12 @@
def write_history_file(self, filename='~/.history'):
maxlength = self.saved_history_length
history = self.get_reader().get_trimmed_history(maxlength)
- f = open(os.path.expanduser(filename), 'w')
+ f = open(os.path.expanduser(filename), 'w', encoding='utf-8')
for entry in history:
# if we are on py3k, we don't need to encode strings before
# writing it to a file
if isinstance(entry, unicode) and sys.version_info < (3,):
- try:
- entry = entry.encode(ENCODING)
- except UnicodeEncodeError: # bah, silently fall back...
- entry = entry.encode('utf-8')
+ entry = entry.encode('utf-8')
entry = entry.replace('\n', '\r\n') # multiline history support
f.write(entry + '\n')
f.close()
diff --git a/pypy/module/__builtin__/descriptor.py
b/pypy/module/__builtin__/descriptor.py
--- a/pypy/module/__builtin__/descriptor.py
+++ b/pypy/module/__builtin__/descriptor.py
@@ -21,24 +21,31 @@
if space.is_none(w_obj_or_type):
w_type = None # unbound super object
- w_obj_or_type = space.w_None
+ w_obj_or_type = None
else:
w_type = _super_check(space, w_starttype, w_obj_or_type)
self.w_starttype = w_starttype
self.w_objtype = w_type
- self.w_self = w_obj_or_type
+ self.w_self = w_obj_or_type # may be None
def descr_repr(self, space):
if self.w_objtype is not None:
objtype_name = u"<%s object>" % self.w_objtype.getname(space)
else:
objtype_name = u'NULL'
+ if self.w_starttype is not None:
+ starttype_name = self.w_starttype.getname(space)
+ else:
+ starttype_name = u'NULL'
return space.newunicode(u"<super: <class '%s'>, %s>" % (
- self.w_starttype.getname(space), objtype_name))
+ starttype_name, objtype_name))
def get(self, space, w_obj, w_type=None):
- if self.w_self is None or space.is_w(w_obj, space.w_None):
+ if self.w_self is not None or space.is_w(w_obj, space.w_None):
return self
+ if self.w_starttype is None:
+ raise oefmt(space.w_TypeError,
+ "__get__(x) is invalid on an uninitialized instance of
'super'")
else:
# if type(self) is W_Super:
# XXX write a fast path for this common case
@@ -50,6 +57,7 @@
# only use a special logic for bound super objects and not for
# getting the __class__ of the super object itself.
if self.w_objtype is not None and name != '__class__':
+ assert self.w_starttype is not None
w_value = space.lookup_in_type_starting_at(self.w_objtype,
self.w_starttype,
name)
@@ -59,10 +67,9 @@
return w_value
# Only pass 'obj' param if this is instance-mode super
# (see CPython sourceforge id #743627)
- if self.w_self is self.w_objtype:
+ w_obj = self.w_self
+ if w_obj is None or w_obj is self.w_objtype:
w_obj = space.w_None
- else:
- w_obj = self.w_self
return space.get_and_call_function(w_get, w_value,
w_obj, self.w_objtype)
# fallback to object.__getattribute__()
@@ -160,7 +167,11 @@
_immutable_fields_ = ["w_fget", "w_fset", "w_fdel"]
def __init__(self, space):
- pass
+ self.w_fget = space.w_None
+ self.w_fset = space.w_None
+ self.w_fdel = space.w_None
+ self.w_doc = space.w_None
+ self.getter_doc = False
@unwrap_spec(w_fget=WrappedDefault(None),
w_fset=WrappedDefault(None),
diff --git a/pypy/module/__builtin__/test/test_descriptor.py
b/pypy/module/__builtin__/test/test_descriptor.py
--- a/pypy/module/__builtin__/test/test_descriptor.py
+++ b/pypy/module/__builtin__/test/test_descriptor.py
@@ -333,6 +333,22 @@
assert repr(A()).endswith('>!')
assert repr(super(A, A())) == "<super: <class 'A'>, <A object>>"
+ def test_super_get_corner_case(self):
+ class A(object):
+ pass
+ s1 = super(A, A())
+ assert s1.__get__(42) is s1
+ assert s1.__get__(42, int) is s1
+ s2 = super(A)
+ assert s2.__get__(None, "anything") is s2
+ #
+ assert s1.__get__(None, "anything") is s1
+ raises(TypeError, s2.__get__, 42)
+ raises(TypeError, s2.__get__, 42, int)
+ a = A()
+ assert s2.__get__(a).__self__ is a
+ assert s1.__get__(a) is s1
+
def test_property_docstring(self):
assert property.__doc__.startswith('property')
@@ -520,3 +536,35 @@
super()
raises(RuntimeError, X().f)
"""
+
+ def test_uninitialized_property(self):
+ p = property.__new__(property)
+ raises(AttributeError, p.__get__, 42)
+ raises(AttributeError, p.__set__, 42, None)
+ raises(AttributeError, p.__delete__, 42)
+ assert repr(p).startswith("<property object at ")
+ assert p.fget is p.fset is p.fdel is p.__doc__ is None
+ #
+ lst = []
+ p.deleter(lst.append).__delete__(42)
+ assert lst == [42]
+ #
+ lst = []
+ p.getter(lst.append).__get__(43)
+ assert lst == [43]
+ #
+ lst = []
+ p.setter(lambda x, y: lst.append((x, y))).__set__(44, 45)
+ assert lst == [(44, 45)]
+
+ def test_uninitialized_super(self):
+ s = super.__new__(super)
+ assert repr(s) == "<super: <class 'NULL'>, NULL>"
+ assert s.__thisclass__ is s.__self__ is s.__self_class__ is None
+ assert s.__get__(None, "anything") is s
+ raises(TypeError, s.__get__, 42)
+ raises(TypeError, s.__get__, int)
+ raises(TypeError, s.__get__, type(None))
+ raises(AttributeError, "s.abcde")
+ raises(AttributeError, "s.abcde = 42")
+ raises(AttributeError, "del s.abcde")
diff --git a/pypy/module/cpyext/src/modsupport.c
b/pypy/module/cpyext/src/modsupport.c
--- a/pypy/module/cpyext/src/modsupport.c
+++ b/pypy/module/cpyext/src/modsupport.c
@@ -523,12 +523,10 @@
return res;
}
-/* returns -1 in case of error, 0 if a new key was added, 1 if the key
- was already there (and replaced) */
-static int
-_PyModule_AddObject_NoConsumeRef(PyObject *m, const char *name, PyObject *o)
+int
+PyModule_AddObject(PyObject *m, const char *name, PyObject *o)
{
- PyObject *dict, *prev;
+ PyObject *dict;
if (!PyModule_Check(m)) {
PyErr_SetString(PyExc_TypeError,
"PyModule_AddObject() needs module as first arg");
@@ -548,49 +546,34 @@
PyModule_GetName(m));
return -1;
}
- prev = PyDict_GetItemString(dict, name);
if (PyDict_SetItemString(dict, name, o))
return -1;
- return prev != NULL;
-}
-
-int
-PyModule_AddObject(PyObject *m, const char *name, PyObject *o)
-{
- int result = _PyModule_AddObject_NoConsumeRef(m, name, o);
- /* XXX WORKAROUND for a common misusage of PyModule_AddObject:
- for the common case of adding a new key, we don't consume a
- reference, but instead just leak it away. The issue is that
- people generally don't realize that this function consumes a
- reference, because on CPython the reference is still stored
- on the dictionary. */
- if (result != 0)
- Py_DECREF(o);
- return result < 0 ? -1 : 0;
+ Py_DECREF(o);
+ return 0;
}
int
PyModule_AddIntConstant(PyObject *m, const char *name, long value)
{
- int result;
PyObject *o = PyLong_FromLong(value);
if (!o)
return -1;
- result = _PyModule_AddObject_NoConsumeRef(m, name, o);
+ if (PyModule_AddObject(m, name, o) == 0)
+ return 0;
Py_DECREF(o);
- return result < 0 ? -1 : 0;
+ return -1;
}
int
PyModule_AddStringConstant(PyObject *m, const char *name, const char *value)
{
- int result;
PyObject *o = PyUnicode_FromString(value);
if (!o)
return -1;
- result = _PyModule_AddObject_NoConsumeRef(m, name, o);
+ if (PyModule_AddObject(m, name, o) == 0)
+ return 0;
Py_DECREF(o);
- return result < 0 ? -1 : 0;
+ return -1;
}
PyModuleDef*
diff --git a/pypy/module/cpyext/test/test_capsule.py
b/pypy/module/cpyext/test/test_capsule.py
--- a/pypy/module/cpyext/test/test_capsule.py
+++ b/pypy/module/cpyext/test/test_capsule.py
@@ -12,9 +12,6 @@
if (PyErr_Occurred()) return NULL;
module = PyImport_ImportModule("foo");
PyModule_AddObject(module, "_ptr", capsule);
- #ifdef PYPY_VERSION
- Py_DECREF(capsule); /* XXX <--- anti-workaround */
- #endif
Py_DECREF(module);
if (PyErr_Occurred()) return NULL;
Py_RETURN_NONE;
diff --git a/pypy/module/pyexpat/test/test_parser.py
b/pypy/module/pyexpat/test/test_parser.py
--- a/pypy/module/pyexpat/test/test_parser.py
+++ b/pypy/module/pyexpat/test/test_parser.py
@@ -210,6 +210,30 @@
p.ParseFile(fake_reader)
assert fake_reader.read_count == 4
+
+ def test_exception(self):
+ """
+ lib-python/3/test_pyexpat.py:HandlerExceptionTest.test_exception port
+ without the fragile traceback inspection.
+ """
+ import pyexpat as expat
+
+ def StartElementHandler(name, attrs):
+ raise RuntimeError(name)
+
+ parser = expat.ParserCreate()
+ parser.StartElementHandler = StartElementHandler
+
+ try:
+ parser.Parse(b"<a><b><c/></b></a>", 1)
+ self.fail()
+ except RuntimeError as e:
+ assert e.args[0] == 'a', (
+ "Expected RuntimeError for element 'a', but" + \
+ " found %r" % e.args[0]
+ )
+
+
class AppTestPyexpat2:
spaceconfig = dict(usemodules=['_rawffi', 'pyexpat', 'itertools',
'_socket', 'time', 'struct', 'binascii',
diff --git a/pypy/module/readline/test/test_readline.py
b/pypy/module/readline/test/test_readline.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/readline/test/test_readline.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+
+class AppTestReadline:
+ spaceconfig = dict(usemodules={
+ 'unicodedata', 'termios', 'select', 'signal', 'fcntl',
+ '_minimal_curses', 'faulthandler', '_socket', 'binascii',
+ '_posixsubprocess',
+ })
+
+ def test_nonascii_history(self):
+ import os, readline
+ TESTFN = "{}_{}_tmp".format("@test", os.getpid())
+
+ is_editline = readline.__doc__ and "libedit" in readline.__doc__
+
+ readline.clear_history()
+ try:
+ readline.add_history("entrée 1")
+ except UnicodeEncodeError as err:
+ skip("Locale cannot encode test data: " + format(err))
+ readline.add_history("entrée 2")
+ readline.replace_history_item(1, "entrée 22")
+ readline.write_history_file(TESTFN)
+ readline.clear_history()
+ readline.read_history_file(TESTFN)
+ if is_editline:
+ # An add_history() call seems to be required for get_history_
+ # item() to register items from the file
+ readline.add_history("dummy")
+ assert readline.get_history_item(1) == "entrée 1"
+ assert readline.get_history_item(2) == "entrée 22"
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit