<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>On Aug 25, 2015, at 09:19, Erik Bray <<a href="mailto:erik.m.bray@gmail.com">erik.m.bray@gmail.com</a>> wrote:</div><div><br></div><blockquote type="cite"><div><span>On Tue, Aug 25, 2015 at 11:15 AM, Terry Reedy <<a href="mailto:tjreedy@udel.edu">tjreedy@udel.edu</a>> wrote:</span><br><blockquote type="cite"><span>2. Class statements would initially create an empty class bound to the class</span><br></blockquote><blockquote type="cite"><span>name.  This could break back compatibility, and would require cleanup in</span><br></blockquote><blockquote type="cite"><span>case of a syntax error in the body. This would be similar to import</span><br></blockquote><blockquote type="cite"><span>statements initially putting a empty module in sys.modules to support</span><br></blockquote><blockquote type="cite"><span>circular imports.  This is messy and still bug prone is use.</span><br></blockquote><span></span><br><span>I have been thinking about this lately in a different context, and I</span><br><span>would very much favor this approach.  I think in large part because it</span><br><span>works this way for modules it would make sense for it to work for</span><br><span>classes as well.  The fact that ClassName is bound to an object that</span><br><span>will *eventually* become the class as soon as the parser has read in:</span><br><span></span><br><span>    class ClassName:</span><br><span></span><br><span>represents, to me (and I would suspect to many students as well), the</span><br><span>least astonishment.</span><br></div></blockquote><div><br></div>The problem here is, what if someone writes this:<div><br></div><div><div><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);">    def __init__(self, left: Tree, right: Tree):<br></span></font></div><div><font color="#000000"><span style="background-color: rgba(255, 255, 255, 0);">        # something with left.left<br></span></font></div><div><br></div><div>Or:</div><div><br></div><div>    @classmethod</div><div>    def maketree(cls):</div><div>        return Tree(None, None)</div><div><br></div><div>Here, Tree is "defined", but the type checker can't actually infer the type of left.left or the arguments of Tree's constructor (even if __init__ was defined before maketree).</div><div><br></div><div>There are various ways you could special-case things to deal with this problem. The simplest would be that a forward-declared class just has no methods or other attributes, or maybe that it has only the ones inherited from superclasses or metaclasses, until the definition is completed, but my naive intuition says that it's obvious what both of the above mean, and the only reason I'd expect it to be an error is by understanding how it has to work under the covers.</div><div><br></div></div></body></html>