PEP 3155 / issue #13448: Qualified name for classes and functions.
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index 45f9f57..2839a24 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -6,7 +6,7 @@
 #include "structmember.h"
 
 PyObject *
-PyFunction_New(PyObject *code, PyObject *globals)
+PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname)
 {
     PyFunctionObject *op = PyObject_GC_New(PyFunctionObject,
                                         &PyFunction_Type);
@@ -54,6 +54,11 @@
             Py_INCREF(module);
             op->func_module = module;
         }
+        if (qualname)
+            op->func_qualname = qualname;
+        else
+            op->func_qualname = op->func_name;
+        Py_INCREF(op->func_qualname);
     }
     else
         return NULL;
@@ -62,6 +67,12 @@
 }
 
 PyObject *
+PyFunction_New(PyObject *code, PyObject *globals)
+{
+    return PyFunction_NewWithQualName(code, globals, NULL);
+}
+
+PyObject *
 PyFunction_GetCode(PyObject *op)
 {
     if (!PyFunction_Check(op)) {
@@ -334,6 +345,32 @@
 }
 
 static PyObject *
+func_get_qualname(PyFunctionObject *op)
+{
+    Py_INCREF(op->func_qualname);
+    return op->func_qualname;
+}
+
+static int
+func_set_qualname(PyFunctionObject *op, PyObject *value)
+{
+    PyObject *tmp;
+
+    /* Not legal to del f.__qualname__ or to set it to anything
+     * other than a string object. */
+    if (value == NULL || !PyUnicode_Check(value)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "__qualname__ must be set to a string object");
+        return -1;
+    }
+    tmp = op->func_qualname;
+    Py_INCREF(value);
+    op->func_qualname = value;
+    Py_DECREF(tmp);
+    return 0;
+}
+
+static PyObject *
 func_get_defaults(PyFunctionObject *op)
 {
     if (op->func_defaults == NULL) {
@@ -441,6 +478,7 @@
      (setter)func_set_annotations},
     {"__dict__", (getter)func_get_dict, (setter)func_set_dict},
     {"__name__", (getter)func_get_name, (setter)func_set_name},
+    {"__qualname__", (getter)func_get_qualname, (setter)func_set_qualname},
     {NULL} /* Sentinel */
 };
 
@@ -561,6 +599,7 @@
     Py_XDECREF(op->func_dict);
     Py_XDECREF(op->func_closure);
     Py_XDECREF(op->func_annotations);
+    Py_XDECREF(op->func_qualname);
     PyObject_GC_Del(op);
 }
 
@@ -568,7 +607,7 @@
 func_repr(PyFunctionObject *op)
 {
     return PyUnicode_FromFormat("<function %U at %p>",
-                               op->func_name, op);
+                               op->func_qualname, op);
 }
 
 static int
@@ -584,6 +623,7 @@
     Py_VISIT(f->func_dict);
     Py_VISIT(f->func_closure);
     Py_VISIT(f->func_annotations);
+    Py_VISIT(f->func_qualname);
     return 0;
 }
 
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index d53ae93..010120a 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -242,6 +242,19 @@
     }
 }
 
+static PyObject *
+type_qualname(PyTypeObject *type, void *context)
+{
+    if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) {
+        PyHeapTypeObject* et = (PyHeapTypeObject*)type;
+        Py_INCREF(et->ht_qualname);
+        return et->ht_qualname;
+    }
+    else {
+        return type_name(type, context);
+    }
+}
+
 static int
 type_set_name(PyTypeObject *type, PyObject *value, void *context)
 {
@@ -286,6 +299,25 @@
     return 0;
 }
 
+static int
+type_set_qualname(PyTypeObject *type, PyObject *value, void *context)
+{
+    PyHeapTypeObject* et;
+
+    if (!PyUnicode_Check(value)) {
+        PyErr_Format(PyExc_TypeError,
+                     "can only assign string to %s.__qualname__, not '%s'",
+                     type->tp_name, Py_TYPE(value)->tp_name);
+        return -1;
+    }
+
+    et = (PyHeapTypeObject*)type;
+    Py_INCREF(value);
+    Py_DECREF(et->ht_qualname);
+    et->ht_qualname = value;
+    return 0;
+}
+
 static PyObject *
 type_module(PyTypeObject *type, void *context)
 {
@@ -631,6 +663,7 @@
 
 static PyGetSetDef type_getsets[] = {
     {"__name__", (getter)type_name, (setter)type_set_name, NULL},
+    {"__qualname__", (getter)type_qualname, (setter)type_set_qualname, NULL},
     {"__bases__", (getter)type_get_bases, (setter)type_set_bases, NULL},
     {"__module__", (getter)type_module, (setter)type_set_module, NULL},
     {"__abstractmethods__", (getter)type_abstractmethods,
@@ -652,7 +685,7 @@
         Py_DECREF(mod);
         mod = NULL;
     }
-    name = type_name(type, NULL);
+    name = type_qualname(type, NULL);
     if (name == NULL)
         return NULL;
 
@@ -1955,7 +1988,7 @@
 {
     PyObject *name, *bases, *dict;
     static char *kwlist[] = {"name", "bases", "dict", 0};
-    PyObject *slots, *tmp, *newslots;
+    PyObject *qualname, *slots, *tmp, *newslots;
     PyTypeObject *type, *base, *tmptype, *winner;
     PyHeapTypeObject *et;
     PyMemberDef *mp;
@@ -2032,6 +2065,18 @@
         return NULL;
     }
 
+    /* Check for a __qualname__ variable in dict */
+    qualname = PyDict_GetItemString(dict, "__qualname__");
+    if (qualname == NULL) {
+        qualname = name;
+    }
+    else {
+        if (PyDict_DelItemString(dict, "__qualname__") < 0) {
+            Py_DECREF(bases);
+            return NULL;
+        }
+    }
+
     /* Check for a __slots__ sequence variable in dict, and count it */
     slots = PyDict_GetItemString(dict, "__slots__");
     nslots = 0;
@@ -2185,7 +2230,9 @@
     /* Keep name and slots alive in the extended type object */
     et = (PyHeapTypeObject *)type;
     Py_INCREF(name);
+    Py_INCREF(qualname);
     et->ht_name = name;
+    et->ht_qualname = qualname;
     et->ht_slots = slots;
 
     /* Initialize tp_flags */
@@ -2369,6 +2416,8 @@
     res->ht_name = PyUnicode_FromString(spec->name);
     if (!res->ht_name)
         goto fail;
+    res->ht_qualname = res->ht_name;
+    Py_INCREF(res->ht_qualname);
     res->ht_type.tp_name = _PyUnicode_AsString(res->ht_name);
     if (!res->ht_type.tp_name)
         goto fail;
@@ -2568,6 +2617,7 @@
      */
     PyObject_Free((char *)type->tp_doc);
     Py_XDECREF(et->ht_name);
+    Py_XDECREF(et->ht_qualname);
     Py_XDECREF(et->ht_slots);
     Py_TYPE(type)->tp_free((PyObject *)type);
 }
@@ -2983,7 +3033,7 @@
         Py_DECREF(mod);
         mod = NULL;
     }
-    name = type_name(type, NULL);
+    name = type_qualname(type, NULL);
     if (name == NULL)
         return NULL;
     if (mod != NULL && PyUnicode_CompareWithASCIIString(mod, "builtins"))