8

Have a function fix(), as a helper function to an output function which writes strings to a text file.

def fix(line):
    """
    returns the corrected line, with all apostrophes prefixed by an escape character

    >>> fix('DOUG\'S')
    'DOUG\\\'S'

    """
    if '\'' in line:
        return line.replace('\'', '\\\'')
    return line

Turning on doctests, I get the following error:

Failed example:
    fix('DOUG'S')
Exception raised:
    Traceback (most recent call last):
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/doctest.py", line 1254, in __run
        compileflags, 1) in test.globs
      File "<doctest convert.fix[0]>", line 1
        fix('DOUG'S')
                  ^

No matter what combination of \ and 's I use, the doctest doesn't seem to to want to work, even though the function itself works perfectly. Have a suspicion that it is a result of the doctest being in a block comment, but any tips to resolve this.

zhuyxn
  • 6,671
  • 9
  • 38
  • 44
  • Note that a triple quoted string isn't really a block-comment (although I've seen it used as such). A triple quoted string is just a string that is allowed to have a newline in it. When used as a comment, what you're really doing is creating a string and not assigning it to anything (e.g. creating the string and then throwing it away). Python doesn't actually have a block-comment ... the strings that immediately follow a function definition are special and are implicitly assigned to the `__doc__` attribute of the function. – mgilson Aug 01 '12 at 19:03

2 Answers2

9

Is this what you want?:

def fix(line):
    r"""
    returns the corrected line, with all apostrophes prefixed by an escape character

    >>> fix("DOUG\'S")
    "DOUG\\'S"
    >>> fix("DOUG'S") == r"DOUG\'S"
    True
    >>> fix("DOUG'S")
    "DOUG\\'S"

    """
    return line.replace("'", r"\'")

import doctest
doctest.testmod()

raw strings are your friend...

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • I don't think this is right, since this would pass in a different string to the function then the OP intended. – Sven Marnach Aug 01 '12 at 18:48
  • @SvenMarnach -- I don't know what string the OP intended to pass in via the doctest (too many escape sequences for my taste). But the function does what the doc string asks for, and it passes... I'll update though with the some more tests ... – mgilson Aug 01 '12 at 18:57
  • Sorry, I had meant single-quotes in the original question rather than double-quotes, but will try this out! – zhuyxn Aug 01 '12 at 19:00
  • @mgilson: You are right, too many escapes. And this is indeed the same as what the OP does – I got confused by the fact that the *outer* string is a raw string literal, while the *inner* string is still a plain string literal, so the backslash gets stripped out anyway. – Sven Marnach Aug 02 '12 at 10:06
1

First, this is what happens if you actually call your function in the interactive interpreter:

>>> fix("Doug's")
"Doug\\'s"

Note that you don't need to escape single quotes in double-quoted strings, and that Python does not do this in the representation of the resulting string – only the back slash gets escaped.

This means the correct docstring should be (untested!)

"""
returns the corrected line, with all apostrophes prefixed by an escape character

>>> fix("DOUG'S")
"DOUG\\\\'S"

"""

I'd use a raw string literal for this docstring to make this more readable:

r"""
returns the corrected line, with all apostrophes prefixed by an escape character

>>> fix("DOUG'S")
"DOUG\\'S"

"""
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • Sorry I had made a typo in the original question, and had meant a single-quote instead, I understand your solution and i did get my test to work when using double-quotes, but is there a reason why the single-quote case does not work? – zhuyxn Aug 01 '12 at 19:07