TypeError during assignment to attribute reference?
<p>Reading about <a href="https://docs.python.org/3/reference/simple_stmts.html#assignment-statements" rel="nofollow">Assignment statements</a> in the Python's docs I found this:</p>

<blockquote>
  <p>If the target is an attribute reference: The primary expression in the reference is evaluated. It should yield an object with assignable attributes; if this is not the case, <code>TypeError</code> is raised. That object is then asked to assign the assigned object to the given attribute; if it cannot perform the assignment, it raises an exception (usually but not necessarily <code>AttributeError</code>).</p>
</blockquote>

<p>I'm wondering how to get this <code>TypeError</code>?</p>

<p><strong>What Python's types doesn't have routine for setting attributes?</strong></p>

<p>This documentation line is just really out of date. It dates back to at least <a href="https://docs.python.org/release/1.4/ref/ref6.html#HDR2" rel="nofollow">Python 1.4</a>, long before type/class unification. I believe back then, trying to do something like</p>

<pre><code>x = 1
x.foo = 3
</code></pre>

<p>would have produced a TypeError, but I wasn't writing Python back then, and I don't have a sufficiently ancient interpreter version to test it.</p>

<p>If you look at the <a href="https://hg.python.org/cpython/file/3.5/Objects/object.c#l914" rel="nofollow">source code</a> for attribute assignment dispatch, you can see that the documented check still exists:</p>

<pre><code>if (tp-&gt;tp_setattro != NULL) {
    ...
    return ...;
}
if (tp-&gt;tp_setattr != NULL) {
    ...
    return ...;
}
Py_DECREF(name);
assert(name-&gt;ob_refcnt &gt;= 1);
if (tp-&gt;tp_getattr == NULL &amp;&amp; tp-&gt;tp_getattro == NULL)
    PyErr_Format(PyExc_TypeError,
                 "'%.100s' object has no attributes "
                 "(%s .%U)",
                 tp-&gt;tp_name,
                 value==NULL ? "del" : "assign to",
                 name);
else
    PyErr_Format(PyExc_TypeError,
                 "'%.100s' object has only read-only attributes "
                 "(%s .%U)",
                 tp-&gt;tp_name,
                 value==NULL ? "del" : "assign to",
                 name);
return -1;
</code></pre>

<p>If an object's type has no routine for setting attributes, Python raises an error, complaining about "no attributes" or "only read-only attributes" depending on whether the type has a routine for getting attributes. I believe in the early days, types like <code>int</code> would have gone down this code path. However, all types now inherit such routines from <code>object</code>, so I don't think this code path is ever taken.</p>

<p>There's a related code path in <a href="https://hg.python.org/cpython/file/3.5/Objects/typeobject.c#l3005" rel="nofollow"><code>type.__setattr__</code></a> that raises a <code>TypeError</code> for setting attributes on types written in C. This code path is still taken, but it's not as general as what the documentation describes:</p>

<pre><code>if (!(type-&gt;tp_flags &amp; Py_TPFLAGS_HEAPTYPE)) {
    PyErr_Format(
        PyExc_TypeError,
        "can't set attributes of built-in/extension type '%s'",
        type-&gt;tp_name);
    return -1;
}
</code></pre>

python python-3.x typeerror attr