mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	bpo-32571: Avoid raising unneeded AttributeError and silencing it in C code (GH-5222)
Add two new private APIs: _PyObject_LookupAttr() and _PyObject_LookupAttrId()
This commit is contained in:
		
							parent
							
								
									2b822a0bb1
								
							
						
					
					
						commit
						f320be77ff
					
				
					 22 changed files with 1455 additions and 1442 deletions
				
			
		| 
						 | 
					@ -536,11 +536,20 @@ PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *);
 | 
				
			||||||
PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *);
 | 
					PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *);
 | 
				
			||||||
#ifndef Py_LIMITED_API
 | 
					#ifndef Py_LIMITED_API
 | 
				
			||||||
PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *);
 | 
					PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *);
 | 
				
			||||||
/* Same as PyObject_GetAttr(), but don't raise AttributeError. */
 | 
					 | 
				
			||||||
PyAPI_FUNC(PyObject *) _PyObject_GetAttrWithoutError(PyObject *, PyObject *);
 | 
					 | 
				
			||||||
PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, struct _Py_Identifier *);
 | 
					PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, struct _Py_Identifier *);
 | 
				
			||||||
PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, struct _Py_Identifier *, PyObject *);
 | 
					PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, struct _Py_Identifier *, PyObject *);
 | 
				
			||||||
PyAPI_FUNC(int) _PyObject_HasAttrId(PyObject *, struct _Py_Identifier *);
 | 
					PyAPI_FUNC(int) _PyObject_HasAttrId(PyObject *, struct _Py_Identifier *);
 | 
				
			||||||
 | 
					/* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which
 | 
				
			||||||
 | 
					   don't raise AttributeError.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Return 1 and set *result != NULL if an attribute is found.
 | 
				
			||||||
 | 
					   Return 0 and set *result == NULL if an attribute is not found;
 | 
				
			||||||
 | 
					   an AttributeError is silenced.
 | 
				
			||||||
 | 
					   Return -1 and set *result == NULL if an error other than AttributeError
 | 
				
			||||||
 | 
					   is raised.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					PyAPI_FUNC(int) _PyObject_LookupAttr(PyObject *, PyObject *, PyObject **);
 | 
				
			||||||
 | 
					PyAPI_FUNC(int) _PyObject_LookupAttrId(PyObject *, struct _Py_Identifier *, PyObject **);
 | 
				
			||||||
PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
 | 
					PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *);
 | 
					PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1339,12 +1339,10 @@ deque_reduce(dequeobject *deque)
 | 
				
			||||||
    PyObject *dict, *it;
 | 
					    PyObject *dict, *it;
 | 
				
			||||||
    _Py_IDENTIFIER(__dict__);
 | 
					    _Py_IDENTIFIER(__dict__);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dict = _PyObject_GetAttrId((PyObject *)deque, &PyId___dict__);
 | 
					    if (_PyObject_LookupAttrId((PyObject *)deque, &PyId___dict__, &dict) < 0) {
 | 
				
			||||||
    if (dict == NULL) {
 | 
					 | 
				
			||||||
        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        PyErr_Clear();
 | 
					    if (dict == NULL) {
 | 
				
			||||||
        dict = Py_None;
 | 
					        dict = Py_None;
 | 
				
			||||||
        Py_INCREF(dict);
 | 
					        Py_INCREF(dict);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1541,7 +1541,9 @@ _bufferedreader_read_all(buffered *self)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    _bufferedreader_reset_buf(self);
 | 
					    _bufferedreader_reset_buf(self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    readall = _PyObject_GetAttrWithoutError(self->raw, _PyIO_str_readall);
 | 
					    if (_PyObject_LookupAttr(self->raw, _PyIO_str_readall, &readall) < 0) {
 | 
				
			||||||
 | 
					        goto cleanup;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (readall) {
 | 
					    if (readall) {
 | 
				
			||||||
        tmp = _PyObject_CallNoArg(readall);
 | 
					        tmp = _PyObject_CallNoArg(readall);
 | 
				
			||||||
        Py_DECREF(readall);
 | 
					        Py_DECREF(readall);
 | 
				
			||||||
| 
						 | 
					@ -1561,9 +1563,6 @@ _bufferedreader_read_all(buffered *self)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        goto cleanup;
 | 
					        goto cleanup;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (PyErr_Occurred()) {
 | 
					 | 
				
			||||||
        goto cleanup;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    chunks = PyList_New(0);
 | 
					    chunks = PyList_New(0);
 | 
				
			||||||
    if (chunks == NULL)
 | 
					    if (chunks == NULL)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1073,12 +1073,10 @@ fileio_repr(fileio *self)
 | 
				
			||||||
    if (self->fd < 0)
 | 
					    if (self->fd < 0)
 | 
				
			||||||
        return PyUnicode_FromFormat("<_io.FileIO [closed]>");
 | 
					        return PyUnicode_FromFormat("<_io.FileIO [closed]>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name);
 | 
					    if (_PyObject_LookupAttrId((PyObject *) self, &PyId_name, &nameobj) < 0) {
 | 
				
			||||||
    if (nameobj == NULL) {
 | 
					 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (nameobj == NULL) {
 | 
				
			||||||
        res = PyUnicode_FromFormat(
 | 
					        res = PyUnicode_FromFormat(
 | 
				
			||||||
            "<_io.FileIO fd=%d mode='%s' closefd=%s>",
 | 
					            "<_io.FileIO fd=%d mode='%s' closefd=%s>",
 | 
				
			||||||
            self->fd, mode_string(self), self->closefd ? "True" : "False");
 | 
					            self->fd, mode_string(self), self->closefd ? "True" : "False");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,18 +133,12 @@ static int
 | 
				
			||||||
iobase_is_closed(PyObject *self)
 | 
					iobase_is_closed(PyObject *self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    PyObject *res;
 | 
					    PyObject *res;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
    /* This gets the derived attribute, which is *not* __IOBase_closed
 | 
					    /* This gets the derived attribute, which is *not* __IOBase_closed
 | 
				
			||||||
       in most cases! */
 | 
					       in most cases! */
 | 
				
			||||||
    res = _PyObject_GetAttrId(self, &PyId___IOBase_closed);
 | 
					    ret = _PyObject_LookupAttrId(self, &PyId___IOBase_closed, &res);
 | 
				
			||||||
    if (res == NULL) {
 | 
					    Py_XDECREF(res);
 | 
				
			||||||
        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					    return ret;
 | 
				
			||||||
            return -1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        PyErr_Clear();
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    Py_DECREF(res);
 | 
					 | 
				
			||||||
    return 1;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Flush and close methods */
 | 
					/* Flush and close methods */
 | 
				
			||||||
| 
						 | 
					@ -190,21 +184,17 @@ iobase_check_closed(PyObject *self)
 | 
				
			||||||
    int closed;
 | 
					    int closed;
 | 
				
			||||||
    /* This gets the derived attribute, which is *not* __IOBase_closed
 | 
					    /* This gets the derived attribute, which is *not* __IOBase_closed
 | 
				
			||||||
       in most cases! */
 | 
					       in most cases! */
 | 
				
			||||||
    res = _PyObject_GetAttrWithoutError(self, _PyIO_str_closed);
 | 
					    closed = _PyObject_LookupAttr(self, _PyIO_str_closed, &res);
 | 
				
			||||||
    if (res == NULL) {
 | 
					    if (closed > 0) {
 | 
				
			||||||
        if (PyErr_Occurred()) {
 | 
					 | 
				
			||||||
            return -1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
        closed = PyObject_IsTrue(res);
 | 
					        closed = PyObject_IsTrue(res);
 | 
				
			||||||
        Py_DECREF(res);
 | 
					        Py_DECREF(res);
 | 
				
			||||||
    if (closed <= 0) {
 | 
					        if (closed > 0) {
 | 
				
			||||||
        return closed;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
            PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
 | 
					            PyErr_SetString(PyExc_ValueError, "I/O operation on closed file.");
 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return closed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyObject *
 | 
					PyObject *
 | 
				
			||||||
_PyIOBase_check_closed(PyObject *self, PyObject *args)
 | 
					_PyIOBase_check_closed(PyObject *self, PyObject *args)
 | 
				
			||||||
| 
						 | 
					@ -273,8 +263,7 @@ iobase_finalize(PyObject *self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* If `closed` doesn't exist or can't be evaluated as bool, then the
 | 
					    /* If `closed` doesn't exist or can't be evaluated as bool, then the
 | 
				
			||||||
       object is probably in an unusable state, so ignore. */
 | 
					       object is probably in an unusable state, so ignore. */
 | 
				
			||||||
    res = _PyObject_GetAttrWithoutError(self, _PyIO_str_closed);
 | 
					    if (_PyObject_LookupAttr(self, _PyIO_str_closed, &res) <= 0) {
 | 
				
			||||||
    if (res == NULL) {
 | 
					 | 
				
			||||||
        PyErr_Clear();
 | 
					        PyErr_Clear();
 | 
				
			||||||
        closed = -1;
 | 
					        closed = -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -538,8 +527,7 @@ _io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit)
 | 
				
			||||||
    PyObject *peek, *buffer, *result;
 | 
					    PyObject *peek, *buffer, *result;
 | 
				
			||||||
    Py_ssize_t old_size = -1;
 | 
					    Py_ssize_t old_size = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    peek = _PyObject_GetAttrWithoutError(self, _PyIO_str_peek);
 | 
					    if (_PyObject_LookupAttr(self, _PyIO_str_peek, &peek) < 0) {
 | 
				
			||||||
    if (peek == NULL && PyErr_Occurred()) {
 | 
					 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -924,14 +924,10 @@ _textiowrapper_set_encoder(textio *self, PyObject *codec_info,
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Get the normalized named of the codec */
 | 
					    /* Get the normalized named of the codec */
 | 
				
			||||||
    res = _PyObject_GetAttrId(codec_info, &PyId_name);
 | 
					    if (_PyObject_LookupAttrId(codec_info, &PyId_name, &res) < 0) {
 | 
				
			||||||
    if (res == NULL) {
 | 
					 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (PyUnicode_Check(res)) {
 | 
					    if (res != NULL && PyUnicode_Check(res)) {
 | 
				
			||||||
        const encodefuncentry *e = encodefuncs;
 | 
					        const encodefuncentry *e = encodefuncs;
 | 
				
			||||||
        while (e->name != NULL) {
 | 
					        while (e->name != NULL) {
 | 
				
			||||||
            if (_PyUnicode_EqualToASCIIString(res, e->name)) {
 | 
					            if (_PyUnicode_EqualToASCIIString(res, e->name)) {
 | 
				
			||||||
| 
						 | 
					@ -1177,20 +1173,18 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (Py_TYPE(buffer) == &PyBufferedReader_Type ||
 | 
					    if (Py_TYPE(buffer) == &PyBufferedReader_Type ||
 | 
				
			||||||
        Py_TYPE(buffer) == &PyBufferedWriter_Type ||
 | 
					        Py_TYPE(buffer) == &PyBufferedWriter_Type ||
 | 
				
			||||||
        Py_TYPE(buffer) == &PyBufferedRandom_Type) {
 | 
					        Py_TYPE(buffer) == &PyBufferedRandom_Type)
 | 
				
			||||||
        raw = _PyObject_GetAttrId(buffer, &PyId_raw);
 | 
					    {
 | 
				
			||||||
        /* Cache the raw FileIO object to speed up 'closed' checks */
 | 
					        if (_PyObject_LookupAttrId(buffer, &PyId_raw, &raw) < 0)
 | 
				
			||||||
        if (raw == NULL) {
 | 
					 | 
				
			||||||
            if (PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
                PyErr_Clear();
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            goto error;
 | 
					            goto error;
 | 
				
			||||||
        }
 | 
					        /* Cache the raw FileIO object to speed up 'closed' checks */
 | 
				
			||||||
        else if (Py_TYPE(raw) == &PyFileIO_Type)
 | 
					        if (raw != NULL) {
 | 
				
			||||||
 | 
					            if (Py_TYPE(raw) == &PyFileIO_Type)
 | 
				
			||||||
                self->raw = raw;
 | 
					                self->raw = raw;
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                Py_DECREF(raw);
 | 
					                Py_DECREF(raw);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res = _PyObject_CallMethodId(buffer, &PyId_seekable, NULL);
 | 
					    res = _PyObject_CallMethodId(buffer, &PyId_seekable, NULL);
 | 
				
			||||||
    if (res == NULL)
 | 
					    if (res == NULL)
 | 
				
			||||||
| 
						 | 
					@ -1201,17 +1195,12 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer,
 | 
				
			||||||
        goto error;
 | 
					        goto error;
 | 
				
			||||||
    self->seekable = self->telling = r;
 | 
					    self->seekable = self->telling = r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res = _PyObject_GetAttrWithoutError(buffer, _PyIO_str_read1);
 | 
					    r = _PyObject_LookupAttr(buffer, _PyIO_str_read1, &res);
 | 
				
			||||||
    if (res != NULL) {
 | 
					    if (r < 0) {
 | 
				
			||||||
        Py_DECREF(res);
 | 
					 | 
				
			||||||
        self->has_read1 = 1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else if (!PyErr_Occurred()) {
 | 
					 | 
				
			||||||
        self->has_read1 = 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
        goto error;
 | 
					        goto error;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    Py_XDECREF(res);
 | 
				
			||||||
 | 
					    self->has_read1 = r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    self->encoding_start_of_stream = 0;
 | 
					    self->encoding_start_of_stream = 0;
 | 
				
			||||||
    if (_textiowrapper_fix_encoder_state(self) < 0) {
 | 
					    if (_textiowrapper_fix_encoder_state(self) < 0) {
 | 
				
			||||||
| 
						 | 
					@ -3020,10 +3009,9 @@ textiowrapper_newlines_get(textio *self, void *context)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    PyObject *res;
 | 
					    PyObject *res;
 | 
				
			||||||
    CHECK_ATTACHED(self);
 | 
					    CHECK_ATTACHED(self);
 | 
				
			||||||
    if (self->decoder == NULL)
 | 
					    if (self->decoder == NULL ||
 | 
				
			||||||
        Py_RETURN_NONE;
 | 
					        _PyObject_LookupAttr(self->decoder, _PyIO_str_newlines, &res) == 0)
 | 
				
			||||||
    res = _PyObject_GetAttrWithoutError(self->decoder, _PyIO_str_newlines);
 | 
					    {
 | 
				
			||||||
    if (res == NULL && !PyErr_Occurred()) {
 | 
					 | 
				
			||||||
        Py_RETURN_NONE;
 | 
					        Py_RETURN_NONE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -367,18 +367,15 @@ init_method_ref(PyObject *self, _Py_Identifier *name,
 | 
				
			||||||
                PyObject **method_func, PyObject **method_self)
 | 
					                PyObject **method_func, PyObject **method_self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    PyObject *func, *func2;
 | 
					    PyObject *func, *func2;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* *method_func and *method_self should be consistent.  All refcount decrements
 | 
					    /* *method_func and *method_self should be consistent.  All refcount decrements
 | 
				
			||||||
       should be occurred after setting *method_self and *method_func. */
 | 
					       should be occurred after setting *method_self and *method_func. */
 | 
				
			||||||
    func = _PyObject_GetAttrId(self, name);
 | 
					    ret = _PyObject_LookupAttrId(self, name, &func);
 | 
				
			||||||
    if (func == NULL) {
 | 
					    if (func == NULL) {
 | 
				
			||||||
        *method_self = NULL;
 | 
					        *method_self = NULL;
 | 
				
			||||||
        Py_CLEAR(*method_func);
 | 
					        Py_CLEAR(*method_func);
 | 
				
			||||||
        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					        return ret;
 | 
				
			||||||
            return -1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        PyErr_Clear();
 | 
					 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (PyMethod_Check(func) && PyMethod_GET_SELF(func) == self) {
 | 
					    if (PyMethod_Check(func) && PyMethod_GET_SELF(func) == self) {
 | 
				
			||||||
| 
						 | 
					@ -1155,9 +1152,10 @@ _Pickler_SetOutputStream(PicklerObject *self, PyObject *file)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _Py_IDENTIFIER(write);
 | 
					    _Py_IDENTIFIER(write);
 | 
				
			||||||
    assert(file != NULL);
 | 
					    assert(file != NULL);
 | 
				
			||||||
    self->write = _PyObject_GetAttrId(file, &PyId_write);
 | 
					    if (_PyObject_LookupAttrId(file, &PyId_write, &self->write) < 0) {
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (self->write == NULL) {
 | 
					    if (self->write == NULL) {
 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
        PyErr_SetString(PyExc_TypeError,
 | 
					        PyErr_SetString(PyExc_TypeError,
 | 
				
			||||||
                        "file must have a 'write' attribute");
 | 
					                        "file must have a 'write' attribute");
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
| 
						 | 
					@ -1504,19 +1502,16 @@ _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file)
 | 
				
			||||||
    _Py_IDENTIFIER(read);
 | 
					    _Py_IDENTIFIER(read);
 | 
				
			||||||
    _Py_IDENTIFIER(readline);
 | 
					    _Py_IDENTIFIER(readline);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    self->peek = _PyObject_GetAttrId(file, &PyId_peek);
 | 
					    if (_PyObject_LookupAttrId(file, &PyId_peek, &self->peek) < 0) {
 | 
				
			||||||
    if (self->peek == NULL) {
 | 
					 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    self->read = _PyObject_GetAttrId(file, &PyId_read);
 | 
					    (void)_PyObject_LookupAttrId(file, &PyId_read, &self->read);
 | 
				
			||||||
    self->readline = _PyObject_GetAttrId(file, &PyId_readline);
 | 
					    (void)_PyObject_LookupAttrId(file, &PyId_readline, &self->readline);
 | 
				
			||||||
    if (self->readline == NULL || self->read == NULL) {
 | 
					    if (self->readline == NULL || self->read == NULL) {
 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					        if (!PyErr_Occurred()) {
 | 
				
			||||||
            PyErr_SetString(PyExc_TypeError,
 | 
					            PyErr_SetString(PyExc_TypeError,
 | 
				
			||||||
                            "file must have 'read' and 'readline' attributes");
 | 
					                            "file must have 'read' and 'readline' attributes");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        Py_CLEAR(self->read);
 | 
					        Py_CLEAR(self->read);
 | 
				
			||||||
        Py_CLEAR(self->readline);
 | 
					        Py_CLEAR(self->readline);
 | 
				
			||||||
        Py_CLEAR(self->peek);
 | 
					        Py_CLEAR(self->peek);
 | 
				
			||||||
| 
						 | 
					@ -1691,7 +1686,7 @@ get_deep_attribute(PyObject *obj, PyObject *names, PyObject **pparent)
 | 
				
			||||||
        PyObject *name = PyList_GET_ITEM(names, i);
 | 
					        PyObject *name = PyList_GET_ITEM(names, i);
 | 
				
			||||||
        Py_XDECREF(parent);
 | 
					        Py_XDECREF(parent);
 | 
				
			||||||
        parent = obj;
 | 
					        parent = obj;
 | 
				
			||||||
        obj = PyObject_GetAttr(parent, name);
 | 
					        (void)_PyObject_LookupAttr(parent, name, &obj);
 | 
				
			||||||
        if (obj == NULL) {
 | 
					        if (obj == NULL) {
 | 
				
			||||||
            Py_DECREF(parent);
 | 
					            Py_DECREF(parent);
 | 
				
			||||||
            return NULL;
 | 
					            return NULL;
 | 
				
			||||||
| 
						 | 
					@ -1704,16 +1699,6 @@ get_deep_attribute(PyObject *obj, PyObject *names, PyObject **pparent)
 | 
				
			||||||
    return obj;
 | 
					    return obj;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
reformat_attribute_error(PyObject *obj, PyObject *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
        PyErr_Clear();
 | 
					 | 
				
			||||||
        PyErr_Format(PyExc_AttributeError,
 | 
					 | 
				
			||||||
                     "Can't get attribute %R on %R", name, obj);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
getattribute(PyObject *obj, PyObject *name, int allow_qualname)
 | 
					getattribute(PyObject *obj, PyObject *name, int allow_qualname)
 | 
				
			||||||
| 
						 | 
					@ -1727,10 +1712,13 @@ getattribute(PyObject *obj, PyObject *name, int allow_qualname)
 | 
				
			||||||
        attr = get_deep_attribute(obj, dotted_path, NULL);
 | 
					        attr = get_deep_attribute(obj, dotted_path, NULL);
 | 
				
			||||||
        Py_DECREF(dotted_path);
 | 
					        Py_DECREF(dotted_path);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else {
 | 
				
			||||||
        attr = PyObject_GetAttr(obj, name);
 | 
					        (void)_PyObject_LookupAttr(obj, name, &attr);
 | 
				
			||||||
    if (attr == NULL)
 | 
					    }
 | 
				
			||||||
        reformat_attribute_error(obj, name);
 | 
					    if (attr == NULL && !PyErr_Occurred()) {
 | 
				
			||||||
 | 
					        PyErr_Format(PyExc_AttributeError,
 | 
				
			||||||
 | 
					                     "Can't get attribute %R on %R", name, obj);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return attr;
 | 
					    return attr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1748,9 +1736,6 @@ _checkmodule(PyObject *module_name, PyObject *module,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    PyObject *candidate = get_deep_attribute(module, dotted_path, NULL);
 | 
					    PyObject *candidate = get_deep_attribute(module, dotted_path, NULL);
 | 
				
			||||||
    if (candidate == NULL) {
 | 
					    if (candidate == NULL) {
 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (candidate != global) {
 | 
					    if (candidate != global) {
 | 
				
			||||||
| 
						 | 
					@ -1772,14 +1757,10 @@ whichmodule(PyObject *global, PyObject *dotted_path)
 | 
				
			||||||
    _Py_IDENTIFIER(modules);
 | 
					    _Py_IDENTIFIER(modules);
 | 
				
			||||||
    _Py_IDENTIFIER(__main__);
 | 
					    _Py_IDENTIFIER(__main__);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    module_name = _PyObject_GetAttrId(global, &PyId___module__);
 | 
					    if (_PyObject_LookupAttrId(global, &PyId___module__, &module_name) < 0) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (module_name == NULL) {
 | 
					 | 
				
			||||||
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
        PyErr_Clear();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    if (module_name) {
 | 
				
			||||||
        /* In some rare cases (e.g., bound methods of extension types),
 | 
					        /* In some rare cases (e.g., bound methods of extension types),
 | 
				
			||||||
           __module__ can be None. If it is so, then search sys.modules for
 | 
					           __module__ can be None. If it is so, then search sys.modules for
 | 
				
			||||||
           the module of global. */
 | 
					           the module of global. */
 | 
				
			||||||
| 
						 | 
					@ -3328,12 +3309,8 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name)
 | 
				
			||||||
        global_name = name;
 | 
					        global_name = name;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        global_name = _PyObject_GetAttrId(obj, &PyId___qualname__);
 | 
					        if (_PyObject_LookupAttrId(obj, &PyId___qualname__, &global_name) < 0)
 | 
				
			||||||
        if (global_name == NULL) {
 | 
					 | 
				
			||||||
            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
            goto error;
 | 
					            goto error;
 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (global_name == NULL) {
 | 
					        if (global_name == NULL) {
 | 
				
			||||||
            global_name = _PyObject_GetAttrId(obj, &PyId___name__);
 | 
					            global_name = _PyObject_GetAttrId(obj, &PyId___name__);
 | 
				
			||||||
            if (global_name == NULL)
 | 
					            if (global_name == NULL)
 | 
				
			||||||
| 
						 | 
					@ -3656,14 +3633,10 @@ get_class(PyObject *obj)
 | 
				
			||||||
    PyObject *cls;
 | 
					    PyObject *cls;
 | 
				
			||||||
    _Py_IDENTIFIER(__class__);
 | 
					    _Py_IDENTIFIER(__class__);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cls = _PyObject_GetAttrId(obj, &PyId___class__);
 | 
					    if (_PyObject_LookupAttrId(obj, &PyId___class__, &cls) == 0) {
 | 
				
			||||||
    if (cls == NULL) {
 | 
					 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        cls = (PyObject *) Py_TYPE(obj);
 | 
					        cls = (PyObject *) Py_TYPE(obj);
 | 
				
			||||||
        Py_INCREF(cls);
 | 
					        Py_INCREF(cls);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return cls;
 | 
					    return cls;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3734,14 +3707,10 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj)
 | 
				
			||||||
        PyObject *name;
 | 
					        PyObject *name;
 | 
				
			||||||
        _Py_IDENTIFIER(__name__);
 | 
					        _Py_IDENTIFIER(__name__);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        name = _PyObject_GetAttrId(callable, &PyId___name__);
 | 
					        if (_PyObject_LookupAttrId(callable, &PyId___name__, &name) < 0) {
 | 
				
			||||||
        if (name == NULL) {
 | 
					 | 
				
			||||||
            if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
            PyErr_Clear();
 | 
					        if (name != NULL && PyUnicode_Check(name)) {
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if (PyUnicode_Check(name)) {
 | 
					 | 
				
			||||||
            _Py_IDENTIFIER(__newobj_ex__);
 | 
					            _Py_IDENTIFIER(__newobj_ex__);
 | 
				
			||||||
            use_newobj_ex = _PyUnicode_EqualToASCIIId(
 | 
					            use_newobj_ex = _PyUnicode_EqualToASCIIId(
 | 
				
			||||||
                    name, &PyId___newobj_ex__);
 | 
					                    name, &PyId___newobj_ex__);
 | 
				
			||||||
| 
						 | 
					@ -4108,7 +4077,9 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
 | 
				
			||||||
           don't actually have to check for a __reduce__ method. */
 | 
					           don't actually have to check for a __reduce__ method. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Check for a __reduce_ex__ method. */
 | 
					        /* Check for a __reduce_ex__ method. */
 | 
				
			||||||
        reduce_func = _PyObject_GetAttrId(obj, &PyId___reduce_ex__);
 | 
					        if (_PyObject_LookupAttrId(obj, &PyId___reduce_ex__, &reduce_func) < 0) {
 | 
				
			||||||
 | 
					            goto error;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if (reduce_func != NULL) {
 | 
					        if (reduce_func != NULL) {
 | 
				
			||||||
            PyObject *proto;
 | 
					            PyObject *proto;
 | 
				
			||||||
            proto = PyLong_FromLong(self->proto);
 | 
					            proto = PyLong_FromLong(self->proto);
 | 
				
			||||||
| 
						 | 
					@ -4119,12 +4090,6 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            PickleState *st = _Pickle_GetGlobalState();
 | 
					            PickleState *st = _Pickle_GetGlobalState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
                PyErr_Clear();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else {
 | 
					 | 
				
			||||||
                goto error;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            /* Check for a __reduce__ method. */
 | 
					            /* Check for a __reduce__ method. */
 | 
				
			||||||
            reduce_func = _PyObject_GetAttrId(obj, &PyId___reduce__);
 | 
					            reduce_func = _PyObject_GetAttrId(obj, &PyId___reduce__);
 | 
				
			||||||
            if (reduce_func != NULL) {
 | 
					            if (reduce_func != NULL) {
 | 
				
			||||||
| 
						 | 
					@ -4401,14 +4366,10 @@ _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file,
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    self->dispatch_table = _PyObject_GetAttrId((PyObject *)self,
 | 
					    if (_PyObject_LookupAttrId((PyObject *)self,
 | 
				
			||||||
                                               &PyId_dispatch_table);
 | 
					                                    &PyId_dispatch_table, &self->dispatch_table) < 0) {
 | 
				
			||||||
    if (self->dispatch_table == NULL) {
 | 
					 | 
				
			||||||
        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        PyErr_Clear();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -5370,12 +5331,11 @@ instantiate(PyObject *cls, PyObject *args)
 | 
				
			||||||
    if (!PyTuple_GET_SIZE(args) && PyType_Check(cls)) {
 | 
					    if (!PyTuple_GET_SIZE(args) && PyType_Check(cls)) {
 | 
				
			||||||
        _Py_IDENTIFIER(__getinitargs__);
 | 
					        _Py_IDENTIFIER(__getinitargs__);
 | 
				
			||||||
        _Py_IDENTIFIER(__new__);
 | 
					        _Py_IDENTIFIER(__new__);
 | 
				
			||||||
        PyObject *func = _PyObject_GetAttrId(cls, &PyId___getinitargs__);
 | 
					        PyObject *func;
 | 
				
			||||||
        if (func == NULL) {
 | 
					        if (_PyObject_LookupAttrId(cls, &PyId___getinitargs__, &func) < 0) {
 | 
				
			||||||
            if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
            return NULL;
 | 
					            return NULL;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
            PyErr_Clear();
 | 
					        if (func == NULL) {
 | 
				
			||||||
            return _PyObject_CallMethodIdObjArgs(cls, &PyId___new__, cls, NULL);
 | 
					            return _PyObject_CallMethodIdObjArgs(cls, &PyId___new__, cls, NULL);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Py_DECREF(func);
 | 
					        Py_DECREF(func);
 | 
				
			||||||
| 
						 | 
					@ -6225,16 +6185,11 @@ load_build(UnpicklerObject *self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inst = self->stack->data[Py_SIZE(self->stack) - 1];
 | 
					    inst = self->stack->data[Py_SIZE(self->stack) - 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    setstate = _PyObject_GetAttrId(inst, &PyId___setstate__);
 | 
					    if (_PyObject_LookupAttrId(inst, &PyId___setstate__, &setstate) < 0) {
 | 
				
			||||||
    if (setstate == NULL) {
 | 
					 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        else {
 | 
					 | 
				
			||||||
        Py_DECREF(state);
 | 
					        Py_DECREF(state);
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					    if (setstate != NULL) {
 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
        PyObject *result;
 | 
					        PyObject *result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* The explicit __setstate__ is responsible for everything. */
 | 
					        /* The explicit __setstate__ is responsible for everything. */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2203,11 +2203,10 @@ array_array___reduce_ex__(arrayobject *self, PyObject *value)
 | 
				
			||||||
    if (protocol == -1 && PyErr_Occurred())
 | 
					    if (protocol == -1 && PyErr_Occurred())
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
 | 
					    if (_PyObject_LookupAttrId((PyObject *)self, &PyId___dict__, &dict) < 0) {
 | 
				
			||||||
    if (dict == NULL) {
 | 
					 | 
				
			||||||
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
        PyErr_Clear();
 | 
					    }
 | 
				
			||||||
 | 
					    if (dict == NULL) {
 | 
				
			||||||
        dict = Py_None;
 | 
					        dict = Py_None;
 | 
				
			||||||
        Py_INCREF(dict);
 | 
					        Py_INCREF(dict);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -830,17 +830,15 @@ tee(PyObject *self, PyObject *args)
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    copyfunc = _PyObject_GetAttrId(it, &PyId___copy__);
 | 
					    if (_PyObject_LookupAttrId(it, &PyId___copy__, ©func) < 0) {
 | 
				
			||||||
    if (copyfunc != NULL) {
 | 
					 | 
				
			||||||
        copyable = it;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
        Py_DECREF(it);
 | 
					        Py_DECREF(it);
 | 
				
			||||||
        Py_DECREF(result);
 | 
					        Py_DECREF(result);
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (copyfunc != NULL) {
 | 
				
			||||||
 | 
					        copyable = it;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        PyErr_Clear();
 | 
					 | 
				
			||||||
        copyable = tee_fromiterable(it);
 | 
					        copyable = tee_fromiterable(it);
 | 
				
			||||||
        Py_DECREF(it);
 | 
					        Py_DECREF(it);
 | 
				
			||||||
        if (copyable == NULL) {
 | 
					        if (copyable == NULL) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -171,16 +171,14 @@ PyObject_GetItem(PyObject *o, PyObject *key)
 | 
				
			||||||
    if (PyType_Check(o)) {
 | 
					    if (PyType_Check(o)) {
 | 
				
			||||||
        PyObject *meth, *result, *stack[1] = {key};
 | 
					        PyObject *meth, *result, *stack[1] = {key};
 | 
				
			||||||
        _Py_IDENTIFIER(__class_getitem__);
 | 
					        _Py_IDENTIFIER(__class_getitem__);
 | 
				
			||||||
        meth = _PyObject_GetAttrId(o, &PyId___class_getitem__);
 | 
					        if (_PyObject_LookupAttrId(o, &PyId___class_getitem__, &meth) < 0) {
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if (meth) {
 | 
					        if (meth) {
 | 
				
			||||||
            result = _PyObject_FastCall(meth, stack, 1);
 | 
					            result = _PyObject_FastCall(meth, stack, 1);
 | 
				
			||||||
            Py_DECREF(meth);
 | 
					            Py_DECREF(meth);
 | 
				
			||||||
            return result;
 | 
					            return result;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
            return NULL;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        PyErr_Clear();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return type_error("'%.200s' object is not subscriptable", o);
 | 
					    return type_error("'%.200s' object is not subscriptable", o);
 | 
				
			||||||
| 
						 | 
					@ -2268,14 +2266,9 @@ abstract_get_bases(PyObject *cls)
 | 
				
			||||||
    PyObject *bases;
 | 
					    PyObject *bases;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Py_ALLOW_RECURSION
 | 
					    Py_ALLOW_RECURSION
 | 
				
			||||||
    bases = _PyObject_GetAttrId(cls, &PyId___bases__);
 | 
					    (void)_PyObject_LookupAttrId(cls, &PyId___bases__, &bases);
 | 
				
			||||||
    Py_END_ALLOW_RECURSION
 | 
					    Py_END_ALLOW_RECURSION
 | 
				
			||||||
    if (bases == NULL) {
 | 
					    if (bases != NULL && !PyTuple_Check(bases)) {
 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        return NULL;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (!PyTuple_Check(bases)) {
 | 
					 | 
				
			||||||
        Py_DECREF(bases);
 | 
					        Py_DECREF(bases);
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -2338,26 +2331,23 @@ static int
 | 
				
			||||||
recursive_isinstance(PyObject *inst, PyObject *cls)
 | 
					recursive_isinstance(PyObject *inst, PyObject *cls)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    PyObject *icls;
 | 
					    PyObject *icls;
 | 
				
			||||||
    int retval = 0;
 | 
					    int retval;
 | 
				
			||||||
    _Py_IDENTIFIER(__class__);
 | 
					    _Py_IDENTIFIER(__class__);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (PyType_Check(cls)) {
 | 
					    if (PyType_Check(cls)) {
 | 
				
			||||||
        retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
 | 
					        retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
 | 
				
			||||||
        if (retval == 0) {
 | 
					        if (retval == 0) {
 | 
				
			||||||
            PyObject *c = _PyObject_GetAttrId(inst, &PyId___class__);
 | 
					            retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls);
 | 
				
			||||||
            if (c == NULL) {
 | 
					            if (icls != NULL) {
 | 
				
			||||||
                if (PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					                if (icls != (PyObject *)(inst->ob_type) && PyType_Check(icls)) {
 | 
				
			||||||
                    PyErr_Clear();
 | 
					                    retval = PyType_IsSubtype(
 | 
				
			||||||
                else
 | 
					                        (PyTypeObject *)icls,
 | 
				
			||||||
                    retval = -1;
 | 
					                        (PyTypeObject *)cls);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else {
 | 
					                else {
 | 
				
			||||||
                if (c != (PyObject *)(inst->ob_type) &&
 | 
					                    retval = 0;
 | 
				
			||||||
                    PyType_Check(c))
 | 
					                }
 | 
				
			||||||
                    retval = PyType_IsSubtype(
 | 
					                Py_DECREF(icls);
 | 
				
			||||||
                        (PyTypeObject *)c,
 | 
					 | 
				
			||||||
                        (PyTypeObject *)cls);
 | 
					 | 
				
			||||||
                Py_DECREF(c);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -2365,14 +2355,8 @@ recursive_isinstance(PyObject *inst, PyObject *cls)
 | 
				
			||||||
        if (!check_class(cls,
 | 
					        if (!check_class(cls,
 | 
				
			||||||
            "isinstance() arg 2 must be a type or tuple of types"))
 | 
					            "isinstance() arg 2 must be a type or tuple of types"))
 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
        icls = _PyObject_GetAttrId(inst, &PyId___class__);
 | 
					        retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls);
 | 
				
			||||||
        if (icls == NULL) {
 | 
					        if (icls != NULL) {
 | 
				
			||||||
            if (PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
                PyErr_Clear();
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                retval = -1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else {
 | 
					 | 
				
			||||||
            retval = abstract_issubclass(icls, cls);
 | 
					            retval = abstract_issubclass(icls, cls);
 | 
				
			||||||
            Py_DECREF(icls);
 | 
					            Py_DECREF(icls);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -246,21 +246,14 @@ method_repr(PyMethodObject *a)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    PyObject *self = a->im_self;
 | 
					    PyObject *self = a->im_self;
 | 
				
			||||||
    PyObject *func = a->im_func;
 | 
					    PyObject *func = a->im_func;
 | 
				
			||||||
    PyObject *funcname = NULL, *result = NULL;
 | 
					    PyObject *funcname, *result;
 | 
				
			||||||
    const char *defname = "?";
 | 
					    const char *defname = "?";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    funcname = _PyObject_GetAttrId(func, &PyId___qualname__);
 | 
					    if (_PyObject_LookupAttrId(func, &PyId___qualname__, &funcname) < 0 ||
 | 
				
			||||||
    if (funcname == NULL) {
 | 
					        (funcname == NULL &&
 | 
				
			||||||
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					         _PyObject_LookupAttrId(func, &PyId___name__, &funcname) < 0))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
        PyErr_Clear();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        funcname = _PyObject_GetAttrId(func, &PyId___name__);
 | 
					 | 
				
			||||||
        if (funcname == NULL) {
 | 
					 | 
				
			||||||
            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
                return NULL;
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (funcname != NULL && !PyUnicode_Check(funcname)) {
 | 
					    if (funcname != NULL && !PyUnicode_Check(funcname)) {
 | 
				
			||||||
| 
						 | 
					@ -542,7 +535,7 @@ static PyObject *
 | 
				
			||||||
instancemethod_repr(PyObject *self)
 | 
					instancemethod_repr(PyObject *self)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    PyObject *func = PyInstanceMethod_Function(self);
 | 
					    PyObject *func = PyInstanceMethod_Function(self);
 | 
				
			||||||
    PyObject *funcname = NULL , *result = NULL;
 | 
					    PyObject *funcname, *result;
 | 
				
			||||||
    const char *defname = "?";
 | 
					    const char *defname = "?";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (func == NULL) {
 | 
					    if (func == NULL) {
 | 
				
			||||||
| 
						 | 
					@ -550,13 +543,10 @@ instancemethod_repr(PyObject *self)
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    funcname = _PyObject_GetAttrId(func, &PyId___name__);
 | 
					    if (_PyObject_LookupAttrId(func, &PyId___name__, &funcname) < 0) {
 | 
				
			||||||
    if (funcname == NULL) {
 | 
					 | 
				
			||||||
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
        PyErr_Clear();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (!PyUnicode_Check(funcname)) {
 | 
					    if (funcname != NULL && !PyUnicode_Check(funcname)) {
 | 
				
			||||||
        Py_DECREF(funcname);
 | 
					        Py_DECREF(funcname);
 | 
				
			||||||
        funcname = NULL;
 | 
					        funcname = NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2234,17 +2234,16 @@ dict_update_common(PyObject *self, PyObject *args, PyObject *kwds,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (arg != NULL) {
 | 
					    else if (arg != NULL) {
 | 
				
			||||||
        _Py_IDENTIFIER(keys);
 | 
					        _Py_IDENTIFIER(keys);
 | 
				
			||||||
        PyObject *func = _PyObject_GetAttrId(arg, &PyId_keys);
 | 
					        PyObject *func;
 | 
				
			||||||
        if (func != NULL) {
 | 
					        if (_PyObject_LookupAttrId(arg, &PyId_keys, &func) < 0) {
 | 
				
			||||||
 | 
					            result = -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (func != NULL) {
 | 
				
			||||||
            Py_DECREF(func);
 | 
					            Py_DECREF(func);
 | 
				
			||||||
            result = PyDict_Merge(self, arg, 1);
 | 
					            result = PyDict_Merge(self, arg, 1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
            result = PyDict_MergeFromSeq2(self, arg, 1);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            result = -1;
 | 
					            result = PyDict_MergeFromSeq2(self, arg, 1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -352,13 +352,11 @@ gen_close_iter(PyObject *yf)
 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        PyObject *meth = _PyObject_GetAttrId(yf, &PyId_close);
 | 
					        PyObject *meth;
 | 
				
			||||||
        if (meth == NULL) {
 | 
					        if (_PyObject_LookupAttrId(yf, &PyId_close, &meth) < 0) {
 | 
				
			||||||
            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
            PyErr_WriteUnraisable(yf);
 | 
					            PyErr_WriteUnraisable(yf);
 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        if (meth) {
 | 
				
			||||||
            retval = _PyObject_CallNoArg(meth);
 | 
					            retval = _PyObject_CallNoArg(meth);
 | 
				
			||||||
            Py_DECREF(meth);
 | 
					            Py_DECREF(meth);
 | 
				
			||||||
            if (retval == NULL)
 | 
					            if (retval == NULL)
 | 
				
			||||||
| 
						 | 
					@ -471,13 +469,12 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
 | 
				
			||||||
            gen->gi_running = 0;
 | 
					            gen->gi_running = 0;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            /* `yf` is an iterator or a coroutine-like object. */
 | 
					            /* `yf` is an iterator or a coroutine-like object. */
 | 
				
			||||||
            PyObject *meth = _PyObject_GetAttrId(yf, &PyId_throw);
 | 
					            PyObject *meth;
 | 
				
			||||||
            if (meth == NULL) {
 | 
					            if (_PyObject_LookupAttrId(yf, &PyId_throw, &meth) < 0) {
 | 
				
			||||||
                if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
                Py_DECREF(yf);
 | 
					                Py_DECREF(yf);
 | 
				
			||||||
                return NULL;
 | 
					                return NULL;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
                PyErr_Clear();
 | 
					            if (meth == NULL) {
 | 
				
			||||||
                Py_DECREF(yf);
 | 
					                Py_DECREF(yf);
 | 
				
			||||||
                goto throw_here;
 | 
					                goto throw_here;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -817,16 +817,11 @@ _PyObject_IsAbstract(PyObject *obj)
 | 
				
			||||||
    if (obj == NULL)
 | 
					    if (obj == NULL)
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    isabstract = _PyObject_GetAttrId(obj, &PyId___isabstractmethod__);
 | 
					    res = _PyObject_LookupAttrId(obj, &PyId___isabstractmethod__, &isabstract);
 | 
				
			||||||
    if (isabstract == NULL) {
 | 
					    if (res > 0) {
 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
            return 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return -1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
        res = PyObject_IsTrue(isabstract);
 | 
					        res = PyObject_IsTrue(isabstract);
 | 
				
			||||||
        Py_DECREF(isabstract);
 | 
					        Py_DECREF(isabstract);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -888,48 +883,75 @@ PyObject_GetAttr(PyObject *v, PyObject *name)
 | 
				
			||||||
    return NULL;
 | 
					    return NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PyObject *
 | 
					int
 | 
				
			||||||
_PyObject_GetAttrWithoutError(PyObject *v, PyObject *name)
 | 
					_PyObject_LookupAttr(PyObject *v, PyObject *name, PyObject **result)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    PyTypeObject *tp = Py_TYPE(v);
 | 
					    PyTypeObject *tp = Py_TYPE(v);
 | 
				
			||||||
    PyObject *ret = NULL;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!PyUnicode_Check(name)) {
 | 
					    if (!PyUnicode_Check(name)) {
 | 
				
			||||||
        PyErr_Format(PyExc_TypeError,
 | 
					        PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
                     "attribute name must be string, not '%.200s'",
 | 
					                     "attribute name must be string, not '%.200s'",
 | 
				
			||||||
                     name->ob_type->tp_name);
 | 
					                     name->ob_type->tp_name);
 | 
				
			||||||
        return NULL;
 | 
					        *result = NULL;
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (tp->tp_getattro == PyObject_GenericGetAttr) {
 | 
					    if (tp->tp_getattro == PyObject_GenericGetAttr) {
 | 
				
			||||||
        return _PyObject_GenericGetAttrWithDict(v, name, NULL, 1);
 | 
					        *result = _PyObject_GenericGetAttrWithDict(v, name, NULL, 1);
 | 
				
			||||||
 | 
					        if (*result != NULL) {
 | 
				
			||||||
 | 
					            return 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (PyErr_Occurred()) {
 | 
				
			||||||
 | 
					            return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (tp->tp_getattro != NULL) {
 | 
					    if (tp->tp_getattro != NULL) {
 | 
				
			||||||
        ret = (*tp->tp_getattro)(v, name);
 | 
					        *result = (*tp->tp_getattro)(v, name);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (tp->tp_getattr != NULL) {
 | 
					    else if (tp->tp_getattr != NULL) {
 | 
				
			||||||
        const char *name_str = PyUnicode_AsUTF8(name);
 | 
					        const char *name_str = PyUnicode_AsUTF8(name);
 | 
				
			||||||
        if (name_str == NULL)
 | 
					        if (name_str == NULL) {
 | 
				
			||||||
            return NULL;
 | 
					            *result = NULL;
 | 
				
			||||||
        ret = (*tp->tp_getattr)(v, (char *)name_str);
 | 
					            return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        *result = (*tp->tp_getattr)(v, (char *)name_str);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (*result != NULL) {
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (ret == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
    PyErr_Clear();
 | 
					    PyErr_Clear();
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
    return ret;
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					_PyObject_LookupAttrId(PyObject *v, _Py_Identifier *name, PyObject **result)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
 | 
				
			||||||
 | 
					    if (!oname) {
 | 
				
			||||||
 | 
					        *result = NULL;
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return  _PyObject_LookupAttr(v, oname, result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
PyObject_HasAttr(PyObject *v, PyObject *name)
 | 
					PyObject_HasAttr(PyObject *v, PyObject *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    PyObject *res = _PyObject_GetAttrWithoutError(v, name);
 | 
					    PyObject *res;
 | 
				
			||||||
    if (res != NULL) {
 | 
					    if (_PyObject_LookupAttr(v, name, &res) < 0) {
 | 
				
			||||||
        Py_DECREF(res);
 | 
					 | 
				
			||||||
        return 1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
        PyErr_Clear();
 | 
					        PyErr_Clear();
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (res == NULL) {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    Py_DECREF(res);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int
 | 
					int
 | 
				
			||||||
PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
 | 
					PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2359,7 +2359,10 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
 | 
				
			||||||
            goto handle_kwargs;
 | 
					            goto handle_kwargs;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        func = _PyObject_GetAttrId(other, &PyId_keys);
 | 
					        if (_PyObject_LookupAttrId(other, &PyId_keys, &func) < 0) {
 | 
				
			||||||
 | 
					            Py_DECREF(other);
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if (func != NULL) {
 | 
					        if (func != NULL) {
 | 
				
			||||||
            PyObject *keys, *iterator, *key;
 | 
					            PyObject *keys, *iterator, *key;
 | 
				
			||||||
            keys = _PyObject_CallNoArg(func);
 | 
					            keys = _PyObject_CallNoArg(func);
 | 
				
			||||||
| 
						 | 
					@ -2391,15 +2394,11 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
 | 
				
			||||||
                return NULL;
 | 
					                return NULL;
 | 
				
			||||||
            goto handle_kwargs;
 | 
					            goto handle_kwargs;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					
 | 
				
			||||||
 | 
					        if (_PyObject_LookupAttrId(other, &PyId_items, &func) < 0) {
 | 
				
			||||||
            Py_DECREF(other);
 | 
					            Py_DECREF(other);
 | 
				
			||||||
            return NULL;
 | 
					            return NULL;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        func = _PyObject_GetAttrId(other, &PyId_items);
 | 
					 | 
				
			||||||
        if (func != NULL) {
 | 
					        if (func != NULL) {
 | 
				
			||||||
            PyObject *items;
 | 
					            PyObject *items;
 | 
				
			||||||
            Py_DECREF(other);
 | 
					            Py_DECREF(other);
 | 
				
			||||||
| 
						 | 
					@ -2413,13 +2412,6 @@ mutablemapping_update(PyObject *self, PyObject *args, PyObject *kwargs)
 | 
				
			||||||
                return NULL;
 | 
					                return NULL;
 | 
				
			||||||
            goto handle_kwargs;
 | 
					            goto handle_kwargs;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
            Py_DECREF(other);
 | 
					 | 
				
			||||||
            return NULL;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else {
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        res = mutablemapping_add_pairs(self, other);
 | 
					        res = mutablemapping_add_pairs(self, other);
 | 
				
			||||||
        Py_DECREF(other);
 | 
					        Py_DECREF(other);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2403,7 +2403,9 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
 | 
				
			||||||
            if (PyType_Check(tmp)) {
 | 
					            if (PyType_Check(tmp)) {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            tmp = _PyObject_GetAttrId(tmp, &PyId___mro_entries__);
 | 
					            if (_PyObject_LookupAttrId(tmp, &PyId___mro_entries__, &tmp) < 0) {
 | 
				
			||||||
 | 
					                return NULL;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            if (tmp != NULL) {
 | 
					            if (tmp != NULL) {
 | 
				
			||||||
                PyErr_SetString(PyExc_TypeError,
 | 
					                PyErr_SetString(PyExc_TypeError,
 | 
				
			||||||
                                "type() doesn't support MRO entry resolution; "
 | 
					                                "type() doesn't support MRO entry resolution; "
 | 
				
			||||||
| 
						 | 
					@ -2411,12 +2413,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
 | 
				
			||||||
                Py_DECREF(tmp);
 | 
					                Py_DECREF(tmp);
 | 
				
			||||||
                return NULL;
 | 
					                return NULL;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
                PyErr_Clear();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else {
 | 
					 | 
				
			||||||
                return NULL;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        /* Search the bases for the proper metatype to deal with this: */
 | 
					        /* Search the bases for the proper metatype to deal with this: */
 | 
				
			||||||
        winner = _PyType_CalculateMetaclass(metatype, bases);
 | 
					        winner = _PyType_CalculateMetaclass(metatype, bases);
 | 
				
			||||||
| 
						 | 
					@ -4099,14 +4095,11 @@ _PyObject_GetState(PyObject *obj, int required)
 | 
				
			||||||
    PyObject *getstate;
 | 
					    PyObject *getstate;
 | 
				
			||||||
    _Py_IDENTIFIER(__getstate__);
 | 
					    _Py_IDENTIFIER(__getstate__);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    getstate = _PyObject_GetAttrId(obj, &PyId___getstate__);
 | 
					    if (_PyObject_LookupAttrId(obj, &PyId___getstate__, &getstate) < 0) {
 | 
				
			||||||
    if (getstate == NULL) {
 | 
					 | 
				
			||||||
        PyObject *slotnames;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        PyErr_Clear();
 | 
					    if (getstate == NULL) {
 | 
				
			||||||
 | 
					        PyObject *slotnames;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (required && obj->ob_type->tp_itemsize) {
 | 
					        if (required && obj->ob_type->tp_itemsize) {
 | 
				
			||||||
            PyErr_Format(PyExc_TypeError,
 | 
					            PyErr_Format(PyExc_TypeError,
 | 
				
			||||||
| 
						 | 
					@ -4174,14 +4167,12 @@ _PyObject_GetState(PyObject *obj, int required)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                name = PyList_GET_ITEM(slotnames, i);
 | 
					                name = PyList_GET_ITEM(slotnames, i);
 | 
				
			||||||
                Py_INCREF(name);
 | 
					                Py_INCREF(name);
 | 
				
			||||||
                value = PyObject_GetAttr(obj, name);
 | 
					                if (_PyObject_LookupAttr(obj, name, &value) < 0) {
 | 
				
			||||||
                if (value == NULL) {
 | 
					 | 
				
			||||||
                    Py_DECREF(name);
 | 
					 | 
				
			||||||
                    if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
                    goto error;
 | 
					                    goto error;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                if (value == NULL) {
 | 
				
			||||||
 | 
					                    Py_DECREF(name);
 | 
				
			||||||
                    /* It is not an error if the attribute is not present. */
 | 
					                    /* It is not an error if the attribute is not present. */
 | 
				
			||||||
                    PyErr_Clear();
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else {
 | 
					                else {
 | 
				
			||||||
                    int err = PyDict_SetItem(slots, name, value);
 | 
					                    int err = PyDict_SetItem(slots, name, value);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -497,11 +497,27 @@ def isSimpleType(self, field):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def visitField(self, field, name, sum=None, prod=None, depth=0):
 | 
					    def visitField(self, field, name, sum=None, prod=None, depth=0):
 | 
				
			||||||
        ctype = get_c_type(field.type)
 | 
					        ctype = get_c_type(field.type)
 | 
				
			||||||
 | 
					        self.emit("if (_PyObject_LookupAttrId(obj, &PyId_%s, &tmp) < 0) {" % field.name, depth)
 | 
				
			||||||
 | 
					        self.emit("return 1;", depth+1)
 | 
				
			||||||
 | 
					        self.emit("}", depth)
 | 
				
			||||||
        if not field.opt:
 | 
					        if not field.opt:
 | 
				
			||||||
            self.emit("tmp = _PyObject_GetAttrId(obj, &PyId_%s);" % field.name, depth)
 | 
					            self.emit("if (tmp == NULL) {", depth)
 | 
				
			||||||
 | 
					            message = "required field \\\"%s\\\" missing from %s" % (field.name, name)
 | 
				
			||||||
 | 
					            format = "PyErr_SetString(PyExc_TypeError, \"%s\");"
 | 
				
			||||||
 | 
					            self.emit(format % message, depth+1, reflow=False)
 | 
				
			||||||
 | 
					            self.emit("return 1;", depth+1)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.emit("tmp = get_not_none(obj, &PyId_%s);" % field.name, depth)
 | 
					            self.emit("if (tmp == NULL || tmp == Py_None) {", depth)
 | 
				
			||||||
        self.emit("if (tmp != NULL) {", depth)
 | 
					            self.emit("Py_CLEAR(tmp);", depth+1)
 | 
				
			||||||
 | 
					            if self.isNumeric(field):
 | 
				
			||||||
 | 
					                self.emit("%s = 0;" % field.name, depth+1)
 | 
				
			||||||
 | 
					            elif not self.isSimpleType(field):
 | 
				
			||||||
 | 
					                self.emit("%s = NULL;" % field.name, depth+1)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                raise TypeError("could not determine the default value for %s" % field.name)
 | 
				
			||||||
 | 
					        self.emit("}", depth)
 | 
				
			||||||
 | 
					        self.emit("else {", depth)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.emit("int res;", depth+1)
 | 
					        self.emit("int res;", depth+1)
 | 
				
			||||||
        if field.seq:
 | 
					        if field.seq:
 | 
				
			||||||
            self.emit("Py_ssize_t len;", depth+1)
 | 
					            self.emit("Py_ssize_t len;", depth+1)
 | 
				
			||||||
| 
						 | 
					@ -539,25 +555,6 @@ def visitField(self, field, name, sum=None, prod=None, depth=0):
 | 
				
			||||||
            self.emit("if (res != 0) goto failed;", depth+1)
 | 
					            self.emit("if (res != 0) goto failed;", depth+1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.emit("Py_CLEAR(tmp);", depth+1)
 | 
					        self.emit("Py_CLEAR(tmp);", depth+1)
 | 
				
			||||||
        if not field.opt:
 | 
					 | 
				
			||||||
            self.emit("} else {", depth)
 | 
					 | 
				
			||||||
            self.emit("if (PyErr_ExceptionMatches(PyExc_AttributeError)) {", depth+1)
 | 
					 | 
				
			||||||
            message = "required field \\\"%s\\\" missing from %s" % (field.name, name)
 | 
					 | 
				
			||||||
            format = "PyErr_SetString(PyExc_TypeError, \"%s\");"
 | 
					 | 
				
			||||||
            self.emit(format % message, depth+2, reflow=False)
 | 
					 | 
				
			||||||
            self.emit("}", depth+1)
 | 
					 | 
				
			||||||
            self.emit("return 1;", depth+1)
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            self.emit("} else if (PyErr_Occurred()) {", depth)
 | 
					 | 
				
			||||||
            self.emit("return 1;", depth+1)
 | 
					 | 
				
			||||||
            self.emit("} else {", depth)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if self.isNumeric(field):
 | 
					 | 
				
			||||||
                self.emit("%s = 0;" % field.name, depth+1)
 | 
					 | 
				
			||||||
            elif not self.isSimpleType(field):
 | 
					 | 
				
			||||||
                self.emit("%s = NULL;" % field.name, depth+1)
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                raise TypeError("could not determine the default value for %s" % field.name)
 | 
					 | 
				
			||||||
        self.emit("}", depth)
 | 
					        self.emit("}", depth)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -662,18 +659,14 @@ def visitModule(self, mod):
 | 
				
			||||||
    Py_ssize_t i, numfields = 0;
 | 
					    Py_ssize_t i, numfields = 0;
 | 
				
			||||||
    int res = -1;
 | 
					    int res = -1;
 | 
				
			||||||
    PyObject *key, *value, *fields;
 | 
					    PyObject *key, *value, *fields;
 | 
				
			||||||
    fields = _PyObject_GetAttrId((PyObject*)Py_TYPE(self), &PyId__fields);
 | 
					    if (_PyObject_LookupAttrId((PyObject*)Py_TYPE(self), &PyId__fields, &fields) < 0) {
 | 
				
			||||||
 | 
					        goto cleanup;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (fields) {
 | 
					    if (fields) {
 | 
				
			||||||
        numfields = PySequence_Size(fields);
 | 
					        numfields = PySequence_Size(fields);
 | 
				
			||||||
        if (numfields == -1)
 | 
					        if (numfields == -1)
 | 
				
			||||||
            goto cleanup;
 | 
					            goto cleanup;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
        PyErr_Clear();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					 | 
				
			||||||
        goto cleanup;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res = 0; /* if no error occurs, this stays 0 to the end */
 | 
					    res = 0; /* if no error occurs, this stays 0 to the end */
 | 
				
			||||||
    if (numfields < PyTuple_GET_SIZE(args)) {
 | 
					    if (numfields < PyTuple_GET_SIZE(args)) {
 | 
				
			||||||
| 
						 | 
					@ -713,19 +706,13 @@ def visitModule(self, mod):
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
ast_type_reduce(PyObject *self, PyObject *unused)
 | 
					ast_type_reduce(PyObject *self, PyObject *unused)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    PyObject *res;
 | 
					 | 
				
			||||||
    _Py_IDENTIFIER(__dict__);
 | 
					    _Py_IDENTIFIER(__dict__);
 | 
				
			||||||
    PyObject *dict = _PyObject_GetAttrId(self, &PyId___dict__);
 | 
					    PyObject *dict;
 | 
				
			||||||
    if (dict == NULL) {
 | 
					    if (_PyObject_LookupAttrId(self, &PyId___dict__, &dict) < 0) {
 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (dict) {
 | 
					    if (dict) {
 | 
				
			||||||
        res = Py_BuildValue("O()O", Py_TYPE(self), dict);
 | 
					        return Py_BuildValue("O()N", Py_TYPE(self), dict);
 | 
				
			||||||
        Py_DECREF(dict);
 | 
					 | 
				
			||||||
        return res;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return Py_BuildValue("O()", Py_TYPE(self));
 | 
					    return Py_BuildValue("O()", Py_TYPE(self));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -965,22 +952,6 @@ def visitModule(self, mod):
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *get_not_none(PyObject *obj, _Py_Identifier *id)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    PyObject *attr = _PyObject_GetAttrId(obj, id);
 | 
					 | 
				
			||||||
    if (!attr) {
 | 
					 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return NULL;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else if (attr == Py_None) {
 | 
					 | 
				
			||||||
        Py_DECREF(attr);
 | 
					 | 
				
			||||||
        return NULL;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return attr;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
""", 0, reflow=False)
 | 
					""", 0, reflow=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.emit("static int init_types(void)",0)
 | 
					        self.emit("static int init_types(void)",0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2066
									
								
								Python/Python-ast.c
									
										
									
									
									
								
							
							
						
						
									
										2066
									
								
								Python/Python-ast.c
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
					@ -80,11 +80,8 @@ get_warnings_attr(_Py_Identifier *attr_id, int try_import)
 | 
				
			||||||
            return NULL;
 | 
					            return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    obj = _PyObject_GetAttrId(warnings_module, attr_id);
 | 
					    (void)_PyObject_LookupAttrId(warnings_module, attr_id, &obj);
 | 
				
			||||||
    Py_DECREF(warnings_module);
 | 
					    Py_DECREF(warnings_module);
 | 
				
			||||||
    if (obj == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
        PyErr_Clear();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return obj;
 | 
					    return obj;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -893,13 +890,10 @@ get_source_line(PyObject *module_globals, int lineno)
 | 
				
			||||||
    Py_INCREF(module_name);
 | 
					    Py_INCREF(module_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Make sure the loader implements the optional get_source() method. */
 | 
					    /* Make sure the loader implements the optional get_source() method. */
 | 
				
			||||||
    get_source = _PyObject_GetAttrId(loader, &PyId_get_source);
 | 
					    (void)_PyObject_LookupAttrId(loader, &PyId_get_source, &get_source);
 | 
				
			||||||
    Py_DECREF(loader);
 | 
					    Py_DECREF(loader);
 | 
				
			||||||
    if (!get_source) {
 | 
					    if (!get_source) {
 | 
				
			||||||
        Py_DECREF(module_name);
 | 
					        Py_DECREF(module_name);
 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
            PyErr_Clear();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /* Call get_source() to get the source code. */
 | 
					    /* Call get_source() to get the source code. */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,12 +71,10 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        meth = _PyObject_GetAttrId(base, &PyId___mro_entries__);
 | 
					        if (_PyObject_LookupAttrId(base, &PyId___mro_entries__, &meth) < 0) {
 | 
				
			||||||
        if (!meth) {
 | 
					 | 
				
			||||||
            if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
            goto error;
 | 
					            goto error;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
            PyErr_Clear();
 | 
					        if (!meth) {
 | 
				
			||||||
            if (new_bases) {
 | 
					            if (new_bases) {
 | 
				
			||||||
                if (PyList_Append(new_bases, base) < 0) {
 | 
					                if (PyList_Append(new_bases, base) < 0) {
 | 
				
			||||||
                    goto error;
 | 
					                    goto error;
 | 
				
			||||||
| 
						 | 
					@ -218,19 +216,12 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /* else: meta is not a class, so we cannot do the metaclass
 | 
					    /* else: meta is not a class, so we cannot do the metaclass
 | 
				
			||||||
       calculation, so we will use the explicitly given object as it is */
 | 
					       calculation, so we will use the explicitly given object as it is */
 | 
				
			||||||
    prep = _PyObject_GetAttrId(meta, &PyId___prepare__);
 | 
					    if (_PyObject_LookupAttrId(meta, &PyId___prepare__, &prep) < 0) {
 | 
				
			||||||
    if (prep == NULL) {
 | 
					        ns = NULL;
 | 
				
			||||||
        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					    }
 | 
				
			||||||
            PyErr_Clear();
 | 
					    else if (prep == NULL) {
 | 
				
			||||||
        ns = PyDict_New();
 | 
					        ns = PyDict_New();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        else {
 | 
					 | 
				
			||||||
            Py_DECREF(meta);
 | 
					 | 
				
			||||||
            Py_XDECREF(mkw);
 | 
					 | 
				
			||||||
            Py_DECREF(bases);
 | 
					 | 
				
			||||||
            return NULL;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        PyObject *pargs[2] = {name, bases};
 | 
					        PyObject *pargs[2] = {name, bases};
 | 
				
			||||||
        ns = _PyObject_FastCallDict(prep, pargs, 2, mkw);
 | 
					        ns = _PyObject_FastCallDict(prep, pargs, 2, mkw);
 | 
				
			||||||
| 
						 | 
					@ -1127,8 +1118,7 @@ builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (dflt != NULL) {
 | 
					    if (dflt != NULL) {
 | 
				
			||||||
        result = _PyObject_GetAttrWithoutError(v, name);
 | 
					        if (_PyObject_LookupAttr(v, name, &result) == 0) {
 | 
				
			||||||
        if (result == NULL && !PyErr_Occurred()) {
 | 
					 | 
				
			||||||
            Py_INCREF(dflt);
 | 
					            Py_INCREF(dflt);
 | 
				
			||||||
            return dflt;
 | 
					            return dflt;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -1191,13 +1181,12 @@ builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name)
 | 
				
			||||||
                        "hasattr(): attribute name must be string");
 | 
					                        "hasattr(): attribute name must be string");
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    v = _PyObject_GetAttrWithoutError(obj, name);
 | 
					    if (_PyObject_LookupAttr(obj, name, &v) < 0) {
 | 
				
			||||||
    if (v == NULL) {
 | 
					 | 
				
			||||||
        if (!PyErr_Occurred()) {
 | 
					 | 
				
			||||||
            Py_RETURN_FALSE;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (v == NULL) {
 | 
				
			||||||
 | 
					        Py_RETURN_FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    Py_DECREF(v);
 | 
					    Py_DECREF(v);
 | 
				
			||||||
    Py_RETURN_TRUE;
 | 
					    Py_RETURN_TRUE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4813,13 +4813,12 @@ import_from(PyObject *v, PyObject *name)
 | 
				
			||||||
    _Py_IDENTIFIER(__name__);
 | 
					    _Py_IDENTIFIER(__name__);
 | 
				
			||||||
    PyObject *fullmodname, *pkgname, *pkgpath, *pkgname_or_unknown, *errmsg;
 | 
					    PyObject *fullmodname, *pkgname, *pkgpath, *pkgname_or_unknown, *errmsg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    x = PyObject_GetAttr(v, name);
 | 
					    if (_PyObject_LookupAttr(v, name, &x) != 0) {
 | 
				
			||||||
    if (x != NULL || !PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
        return x;
 | 
					        return x;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    /* Issue #17636: in case this failed because of a circular relative
 | 
					    /* Issue #17636: in case this failed because of a circular relative
 | 
				
			||||||
       import, try to fallback on reading the module directly from
 | 
					       import, try to fallback on reading the module directly from
 | 
				
			||||||
       sys.modules. */
 | 
					       sys.modules. */
 | 
				
			||||||
    PyErr_Clear();
 | 
					 | 
				
			||||||
    pkgname = _PyObject_GetAttrId(v, &PyId___name__);
 | 
					    pkgname = _PyObject_GetAttrId(v, &PyId___name__);
 | 
				
			||||||
    if (pkgname == NULL) {
 | 
					    if (pkgname == NULL) {
 | 
				
			||||||
        goto error;
 | 
					        goto error;
 | 
				
			||||||
| 
						 | 
					@ -4881,19 +4880,18 @@ import_all_from(PyObject *locals, PyObject *v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _Py_IDENTIFIER(__all__);
 | 
					    _Py_IDENTIFIER(__all__);
 | 
				
			||||||
    _Py_IDENTIFIER(__dict__);
 | 
					    _Py_IDENTIFIER(__dict__);
 | 
				
			||||||
    PyObject *all = _PyObject_GetAttrId(v, &PyId___all__);
 | 
					    PyObject *all, *dict, *name, *value;
 | 
				
			||||||
    PyObject *dict, *name, *value;
 | 
					 | 
				
			||||||
    int skip_leading_underscores = 0;
 | 
					    int skip_leading_underscores = 0;
 | 
				
			||||||
    int pos, err;
 | 
					    int pos, err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (all == NULL) {
 | 
					    if (_PyObject_LookupAttrId(v, &PyId___all__, &all) < 0) {
 | 
				
			||||||
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
        return -1; /* Unexpected error */
 | 
					        return -1; /* Unexpected error */
 | 
				
			||||||
        PyErr_Clear();
 | 
					    }
 | 
				
			||||||
        dict = _PyObject_GetAttrId(v, &PyId___dict__);
 | 
					    if (all == NULL) {
 | 
				
			||||||
        if (dict == NULL) {
 | 
					        if (_PyObject_LookupAttrId(v, &PyId___dict__, &dict) < 0) {
 | 
				
			||||||
            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
 | 
					 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (dict == NULL) {
 | 
				
			||||||
            PyErr_SetString(PyExc_ImportError,
 | 
					            PyErr_SetString(PyExc_ImportError,
 | 
				
			||||||
                    "from-import-* object has no __dict__ and no __all__");
 | 
					                    "from-import-* object has no __dict__ and no __all__");
 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -540,15 +540,11 @@ PyObject * _PyCodec_LookupTextEncoding(const char *encoding,
 | 
				
			||||||
     * attribute.
 | 
					     * attribute.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    if (!PyTuple_CheckExact(codec)) {
 | 
					    if (!PyTuple_CheckExact(codec)) {
 | 
				
			||||||
        attr = _PyObject_GetAttrId(codec, &PyId__is_text_encoding);
 | 
					        if (_PyObject_LookupAttrId(codec, &PyId__is_text_encoding, &attr) < 0) {
 | 
				
			||||||
        if (attr == NULL) {
 | 
					 | 
				
			||||||
            if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
 | 
					 | 
				
			||||||
                PyErr_Clear();
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
            Py_DECREF(codec);
 | 
					            Py_DECREF(codec);
 | 
				
			||||||
            return NULL;
 | 
					            return NULL;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        } else {
 | 
					        if (attr != NULL) {
 | 
				
			||||||
            is_text_codec = PyObject_IsTrue(attr);
 | 
					            is_text_codec = PyObject_IsTrue(attr);
 | 
				
			||||||
            Py_DECREF(attr);
 | 
					            Py_DECREF(attr);
 | 
				
			||||||
            if (is_text_codec <= 0) {
 | 
					            if (is_text_codec <= 0) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue