Will's blog

purpose: Will Kahn-Greene's blog of Python, Linux, random content, PyBlosxom, Miro, and other projects mixed in there ad hoc, half-baked, and with a twist of lemon

Sat, 06 Sep 2008

Long strings in Python

In Miro, we've got long strings that are displayed in the user interface. I think the code that defines these strings is messy and hard to parse. For example:

def some_func():
    description = _("""\
This is a really long description that has multiple sentences and a few \
things that need to %(getfilledin)s and it goes on and on and on and on \
and I'm not really sure what's the best way to format it so that it's happy \
in editors and easier to parse.""") % {"getfilledin": blahblah}

PEP-8 doesn't address this, which is fine. I was curious to see what other projects do.

Posted by Steve Holden on Sat Sep 6 10:49:20 2008
I'd say the easiest way was to use the automatic concatenation that the parser does when it sees two adjacent strings. So your example would instead become:
def some_func():
    description = _(
"This is a really long description that has multiple sentences and a few "
"things that need to %(getfilledin)s and it goes on and on and on and on "
"and I'm not really sure what's the best way to format it so that it's happy "
"in editors and easier to parse.") % {"getfilledin": blahblah}
Feel free to edit this before publication: I don't know the pyblosxom markup conventions.


Posted by will on Sat Sep 6 10:58:11 2008
Simon Willson sent me an email with something similar:
def some_func():
    description = _(
        "This is a really long description that has multiple sentences and a few "
        "things that need to %(getfilledin)s and it goes on and on and on and on "
        "and I'm not really sure what's the best way to format it so that it's happy "
        "in editors and easier to parse."
    ) % {"getfilledin": blahblah}



Posted by PJ on Sat Sep 6 11:21:58 2008
If you want to do less programmer work at the cost of a little machine time you could do:

description = _("""
This is a really long description that has multiple etc
etc
etc
etc
etc
""".replace("\n","")) % { "getfilledin": blahblah }


Posted by James Thiele on Sat Sep 6 11:55:41 2008
FYI the "\" chars aren't needed in triple quoted strings.

python 2.5.1 (r251:54863, Jun 17 2007, 10:51:50)
[GCC 3.3 20030304 (Apple Computer, Inc. build 1495)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> """ hi
... there
... """
' hi\nthere\n'


Posted by will on Sat Sep 6 12:11:11 2008
James: The "\" quells the carriage returns.  In this case, we need them.


Posted by Michael Foord on Sat Sep 6 14:03:51 2008
I think the backslash escapes look really ugly.

We do something:
from textwrap import dedent
def function():
    x = dedent("""
    Start here.
    Indented.
    Coz it looks better.
    """[1:] % values)
Notice the [1:] to trim the leading LF and the dedent function so that you can indent your long strings inline with whatever is using them.

Michael


Posted by will on Sat Sep 6 14:11:35 2008
Michael: The backslash escapes are not only ugly, but they're problematic in cases where there's additional white-space after the escape.

However, your solution produces a really different string with the potential for additional problems.  The carriage returns get maintained in the resulting string (which is why we had the backslashes) and you can't tell whether there are spaces at the end of text lines that are inadvertently added.

So I'm not sure that works for our case.


Posted by Michael Foord on Sat Sep 6 14:38:47 2008
Yeah - I didn't see that you were escaping all the carriage returns. The suggestions that just concatenate string literals are probably the best for your situation.


Posted by Michael Mata on Mon Sep 8 13:07:39 2008
This sounds like a case for templates.  Check out Genshi, Kid, Mako or Cheetah.


Posted by will on Mon Sep 8 13:20:37 2008
That would certainly complicate the situation by adding another set of runtime requirements and more infrastructure for handling translations in templates as well as in code.  In our case, I don't think the benefits outweigh the costs.


Please keep comments appropriate. I reserve the right to remove anonymous comments, flames, spammy, inappropriate, and other comments that I deem to be worth removing.

Note: New comments get placed in a "draft" status and will NOT show up on the site until I explicitly approve it. Usually that happens within 24 hours, but sometimes I go away and it takes a day or two.

Note 2: There is now a preview button for those of you who want to see a preview! However, it doesn't quite work the way you'd think it should work. I'll look into adjusting it some day.

Note 3: If you can't for some reason post a comment, send me an email: willg at bluesock dot org.

Your name:


Your e-mail address (this doesn't get displayed to anyone--I use it to contact you if there are issues):


URL of your website (optional):


Comment:


Yes, I am a human!

pyblosxom::2.0 dev

All contents Copyright 1996 to 2008 Will Guaraldi.
Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.