Author: Ronan Lamy <ronan.l...@gmail.com> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit