> As you can see, the line "m1 = method1()" landed into the second
> child.
I think that leo really only sees the def and class blocks, and just punts on where to put the stuff that comes between them. A @decorator should obviously go with the thing that follows it. But for comments and statements there's no way for leo to know what makes sense.
class t(object):
def m1(self):
pass
m = m1
def m2(self, func=m):
print func
I know that's a weird piece of code, but I think you could argue the m = m1 belongs with the m2 definition in that case.
Cheers -Terry
> A) stick to the default assumptions that it uses now (I'm not happy
> with them, and I don't like the idea of modifying some code base just
> for the sake of fitting into the leo import algorithms)
> B) put the code blocks that have the same indentation as class methods
> (but are not class methods themselves) in their own subnodes of the
> class node
> C) use an option set by the user to decide if it needs to include the
> "code" part in the "method-code-method" scenario into the first node
> body or into the second one, this shall also include the special case
> "method-code" at the end of the class body
>
> Your comments are welcome.
Not sure how (C) would work, seems like code could belong to the preceding of following def randomly throughout a class def. The same issue comes up at the module level of course.
I like (B), it seems to me that putting code into def nodes (with the exception of @decorators) can lead to a lot of confusion, as the code may have some adverse impact and you might have trouble finding it. Comments are harmless of course, but you still might miss an important comment for function X if the comment gets shoved into function Y's node.
So,
class foo(object):
"""class to do some stuff"""
stream_base = sys.stdout
def m_int(self, x):
pass
mdef = m_int
# minty doesn't do anything
def minty(self):
pass
raise SystemExit
would be cut like this
class foo(object):
"""class to do some stuff"""
--------------------------------------
stream_base = sys.stdout
--------------------------------------
def m_int(self, x):
pass
--------------------------------------
mdef = m_int
# minty doesn't do anything
--------------------------------------
def minty(self):
pass
--------------------------------------
raise SystemExit
producing nodes like this
foo
foo code
m_int
foo code
minty
foo code
the two bad cuts in this case are the node containing only 'stream_base = sys.stdout', which might have been better left in the foo node (containing the class name line and docstring), and the separation of the comment about minty from the def of minty. For the stream_base case... perhaps the class node should contain everything up to the first def (or nested class)? For the minty case, dumb place to put the comment, no way to tell whether it applies to the preceding or following def.
Cheers -Terry
[snip]
> As you can see, the line "m1 = method1()" landed into the second
> child.
> I want it to land into the first one, because it's related to it.
I've wanted the same thing for a long time. For example, here is a
common pattern:
def foo():
pass
Foo = Foo
> I can make the needed changes manually to achieve my goal.
> The changes will stay persistent (to leo restarts) as long as there
> will be "shadows" in .leo_shadow directories.
> As soon as these directories disappear (for any reason: they get
> deleted, the source code tree is replicated in another place without
> them), the @shadow tree gets refreshed automatically, and I loose the
> correct layout again.
Right. This is an import problem, and will reappear any time an import happens.
Please create a wish-list bug for this. There almost certainly will
be some complications, but we must start somewhere.
Edward