How to determine if a line of python code is a continuation of the line above it

S

Sandra-24

I'm not sure how complex this is, I've been brainstorming a little, and
I've come up with:

If the previous line ended with a comma or a \ (before an optional
comment)

That's easy to cover with a regex

But that doesn't cover everything, because this is legal:

l = [
1,
2,
3
]

and with dictionaries and tuples as well.

Not sure how I would check for that programmatically yet.

Is there any others I'm missing?

Thanks,
-Sandra
 
D

Dan Sommers

I'm not sure how complex this is, I've been brainstorming a little, and
I've come up with:

["This" meaning how to determine if a line of python code is a
continuation of the line above it.]
If the previous line ended with a comma or a \ (before an optional
comment)

A line ending with a comma does *not* indicate a single statement spread
out over two lines:

a = 1,
print a,
a = [ ]

None of those lines is a continuation of the line above it.
That's easy to cover with a regex
But that doesn't cover everything ...

I think you'll end up having to parse the code in its entirety to do
this correctly. Consider triple quoted strings and multiple uses of
parenthesis, both of which can be nested arbitrarily, including inside
each other, and arbitrarily nested delimeters are beyond the ability of
regexen.

Is this merely an academic exercise, or is there a larger purpose for
wanting this information?

Regards,
Dan
 
S

Sandra-24

No it's not an academic excercise, but your right, the situation is
more complex than I originally thought. I've got a minor bug in my
template code, but it'd cause more trouble to fix than to leave in for
the moment.

Thanks for your input!
-Sandra
 
M

Michael Spencer

Sandra-24 said:
No it's not an academic excercise, but your right, the situation is
more complex than I originally thought. I've got a minor bug in my
template code, but it'd cause more trouble to fix than to leave in for
the moment.

Thanks for your input!
-Sandra
Take a look at the codeop module in the standard library

Michael
 
H

Hans Georg Krauthaeuser

Sandra-24 said:
I'm not sure how complex this is, I've been brainstorming a little, and
I've come up with:

If the previous line ended with a comma or a \ (before an optional
comment)

That's easy to cover with a regex

But that doesn't cover everything, because this is legal:

l = [
1,
2,
3
]

and with dictionaries and tuples as well.

Not sure how I would check for that programmatically yet.

Is there any others I'm missing?

Thanks,
-Sandra
Sandra,

in a similar situation I used 'inspect' and 'compile' like so:


import inspect

def func(*arg, **kwarg):
return get_cmd()

def get_cmd():
frame = inspect.currentframe()
outerframes = inspect.getouterframes(frame)
caller = outerframes[1][0]
ccframe = outerframes[2][0]
ccfname = outerframes[2][1]
ccmodule = inspect.getmodule(ccframe)
slines, start = inspect.getsourcelines(ccmodule)
clen = len(slines)
finfo = inspect.getframeinfo(ccframe, clen)
theindex = finfo[4]
lines = finfo[3]
theline = lines[theindex]
cmd = theline
for i in range(theindex-1, 0, -1):
line = lines
try:
compile (cmd.lstrip(), '<string>', 'exec')
except SyntaxError:
cmd = line + cmd
else:
break
return cmd

if __name__ == '__main__':
a=0
b="test"
c=42

cmd=func(a)
print cmd
cmd=func(a,
b,
c)
print cmd



output:
cmd=func(a)

cmd=func(a,
b,
c)

Regards
Hans Georg
 
L

Leif K-Brooks

Sandra-24 said:
I'm not sure how complex this is, I've been brainstorming a little, and
I've come up with:

from tokenize import generate_tokens, NL, NEWLINE
from cStringIO import StringIO

def code_lines(source):
"""Takes Python source code (as either a string or file-like
object) and yields a tuple of (is_new_logical, code) for each
physical line of code.
"""

if isinstance(source, basestring):
source = StringIO(source)

buffer = []
new_logical = True

for token_type, source, sloc, eloc, line in \
generate_tokens(source.readline):
buffer.append(source)
if token_type == NL:
yield new_logical, ''.join(buffer)
buffer = []
new_logical = False
elif token_type == NEWLINE:
yield new_logical, ''.join(buffer)
buffer = []
new_logical = True
if buffer:
yield new_logical, ''.join(buffer)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,814
Latest member
SpicetreeDigital

Latest Threads

Top