fix strange errors when setting attributes on tracebacks #4034
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index 8034839..0708f81 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -111,14 +111,6 @@
                 os.unlink(os.path.join(testdir, f))
             os.rmdir(testdir)
 
-    def test_members(self):
-        # Covers Python/structmember.c::listmembers()
-        try:
-            1/0
-        except:
-            import sys
-            sys.exc_traceback.__members__
-
     def test_base_exception(self):
         # Test that exceptions derived from BaseException are formatted right
         e = KeyboardInterrupt()
diff --git a/Misc/NEWS b/Misc/NEWS
index 9ac44f9..d3abb41 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@
 Core and Builtins
 -----------------
 
+- Issue #4034: Fix weird attribute error messages of the traceback object. (As a
+  result traceback.__members__ no longer exists.)
+
 - Issue #4474: PyUnicode_FromWideChar now converts characters outside
   the BMP to surrogate pairs, on systems with sizeof(wchar_t) == 4
   and sizeof(Py_UNICODE) == 2.
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 1ea586f..c8cf71b 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -604,7 +604,17 @@
 int _PyFrame_Init()
 {
 	builtin_object = PyString_InternFromString("__builtins__");
-	return (builtin_object != NULL);
+	if (builtin_object == NULL)
+		return 0;
+	/* 
+	   Traceback objects are not created the normal way (through calling the
+	   type), so PyType_Ready has to be called here.
+	*/
+	if (PyType_Ready(&PyTraceBack_Type)) {
+		Py_DECREF(builtin_object);
+		return 0;
+	}
+	return 1;
 }
 
 PyFrameObject *
diff --git a/Python/traceback.c b/Python/traceback.c
index 5df7694..c2d7e77 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -11,20 +11,14 @@
 
 #define OFF(x) offsetof(PyTracebackObject, x)
 
-static struct memberlist tb_memberlist[] = {
-	{"tb_next",	T_OBJECT,	OFF(tb_next)},
-	{"tb_frame",	T_OBJECT,	OFF(tb_frame)},
-	{"tb_lasti",	T_INT,		OFF(tb_lasti)},
-	{"tb_lineno",	T_INT,		OFF(tb_lineno)},
+static PyMemberDef tb_memberlist[] = {
+	{"tb_next",	T_OBJECT,	OFF(tb_next), READONLY},
+	{"tb_frame",	T_OBJECT,	OFF(tb_frame), READONLY},
+	{"tb_lasti",	T_INT,		OFF(tb_lasti), READONLY},
+	{"tb_lineno",	T_INT,		OFF(tb_lineno), READONLY},
 	{NULL}	/* Sentinel */
 };
 
-static PyObject *
-tb_getattr(PyTracebackObject *tb, char *name)
-{
-	return PyMember_Get((char *)tb, tb_memberlist, name);
-}
-
 static void
 tb_dealloc(PyTracebackObject *tb)
 {
@@ -58,7 +52,7 @@
 	0,
 	(destructor)tb_dealloc, /*tp_dealloc*/
 	0,		/*tp_print*/
-	(getattrfunc)tb_getattr, /*tp_getattr*/
+	0,              /*tp_getattr*/
 	0,		/*tp_setattr*/
 	0,		/*tp_compare*/
 	0,		/*tp_repr*/
@@ -80,8 +74,8 @@
 	0,					/* tp_iter */
 	0,					/* tp_iternext */
 	0,					/* tp_methods */
-	0,			/* tp_members */
-	0,			/* tp_getset */
+	tb_memberlist,			        /* tp_members */
+	0,			                /* tp_getset */
 	0,					/* tp_base */
 	0,					/* tp_dict */
 };