Skip to content

Instantly share code, notes, and snippets.

@taozle
Last active November 6, 2022 10:14
Show Gist options
  • Save taozle/f3b3d90337bfde97be68858ea89c66b7 to your computer and use it in GitHub Desktop.
Save taozle/f3b3d90337bfde97be68858ea89c66b7 to your computer and use it in GitHub Desktop.
How `hasattr` implemented in python

How hasattr implemented in Python

Python 2.7:

static PyObject *
builtin_hasattr(PyObject *self, PyObject *args)
{
    PyObject *v;
    PyObject *name;

    if (!PyArg_UnpackTuple(args, "hasattr", 2, 2, &v, &name))
        return NULL;
#ifdef Py_USING_UNICODE
    if (PyUnicode_Check(name)) {
        name = _PyUnicode_AsDefaultEncodedString(name, NULL);
        if (name == NULL)
            return NULL;
    }
#endif

    if (!PyString_Check(name)) {
        PyErr_SetString(PyExc_TypeError,
                        "hasattr(): attribute name must be string");
        return NULL;
    }
    v = PyObject_GetAttr(v, name);
    if (v == NULL) {
        if (!PyErr_ExceptionMatches(PyExc_Exception))
            return NULL;
        else {
            PyErr_Clear();
            Py_INCREF(Py_False);
            return Py_False;
        }
    }
    Py_DECREF(v);
    Py_INCREF(Py_True);
    return Py_True;
}

Python 3.6

static PyObject *
builtin_hasattr_impl(PyObject *module, PyObject *obj, PyObject *name)
{
    PyObject *v;

    if (!PyUnicode_Check(name)) {
        PyErr_SetString(PyExc_TypeError,
                        "hasattr(): attribute name must be string");
        return NULL;
    }
    v = PyObject_GetAttr(obj, name);
    if (v == NULL) {
        if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
            PyErr_Clear();
            Py_RETURN_FALSE;
        }
        return NULL;
    }
    Py_DECREF(v);
    Py_RETURN_TRUE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment