469,290 Members | 1,868 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,290 developers. It's quick & easy.

A critique of cgi.escape

The "escape" function in the "cgi" module escapes characters with special
meanings in HTML. The ones that need escaping are '<', '&' and '"'.
However, cgi.escape only escapes the quote character if you pass a second
argument of True (the default is False):
>>cgi.escape("the \"quick\" & <brownfox")
'the "quick" &amp; &lt;brown&gt; fox'
>>cgi.escape("the \"quick\" & <brownfox", True)
'the &quot;quick&quot; &amp; &lt;brown&gt; fox'

This seems to me to be dumb. The default option should be the safe one: that
is, escape _all_ the potentially troublesome characters. The only time you
can get away with NOT escaping the quote character is outside of markup,
e.g.

<TEXTAREA>
unescaped "quotes" allowed here
</TEXTAREA>

Nevertheless, even in that situation, escaped quotes are acceptable.

So I think the default for the second argument to cgi.escape should be
changed to True. Or alternatively, the second argument should be removed
altogether, and quotes should always be escaped.

Can changing the default break existing scripts? I don't see how. It might
even fix a few lurking bugs out there.
Sep 23 '06
131 8246
On 26 Sep 2006 15:53:46 GMT, Jon Ribbens <jo********@unequivocal.co.ukwrote:
To be honest I'm not sure what *sort* of code people test this way. It
just doesn't seem appropriate at all for web page generating code. Web
pages need to be manually viewed in web browsers, and validated, and
checked for accessibility. Checking they're equal to a particular
string just seems bizarre (and where does that string come from
anyway?)
The kind of acceptance testing that you are talking about is very
important, but you can't automate "Does it look OK in a browser?".
Unit tests suitable for automation don't have anything to work with
*but* the generated HTML.

--
Cheers,
Simon B,
si***@brunningonline.net
Sep 26 '06 #101
In article <ma**************************************@python.o rg>, Brian Quinlan wrote:
Well, there are dozens (hundreds?) of templating systems for Python.
I know, I wrote one of them ;-)
t = Template("test.html")
t['foo'] = 'Brian -"Hi!"'
assert str(t) == '<p>Brian -&gt; "Hi"</p>'

So how would you test our template system?
What I don't get is why you are testing the above code like that at
all. Surely if the template system somehow became so broken that it
couldn't even do trivial replacements, you would notice immediately
as all your web pages would go totally wrong.
Maybe, which is why I'm asking you how you do it. Some of our web
applications contain 100s of script generated pages. Testing each one by
hand after making a change would be completely impossible. So we use
HTTP scripting for testing purposes i.e. send this request, grab the
results, verify that the test in the element with id="username" equals
"Brian Quinlan", etc. The test also validates that each page is well
formed. We also view each page at some point but not every time a
developer makes a change that might (i.e. everything) affect the entire
system.
Ah, ok, that sounds more sensible. But something as specialised and
complicated as that can surely cope with un-encoding HTML entities?

Incidentally, the company I work for, www.sitemorse.com, does
automated web site testing - and it's all done in Python! :-)
Sep 26 '06 #102
Simon Brunning wrote:
On 26 Sep 2006 15:53:46 GMT, Jon Ribbens <jo********@unequivocal.co.ukwrote:
To be honest I'm not sure what *sort* of code people test this way. It
just doesn't seem appropriate at all for web page generating code. Web
pages need to be manually viewed in web browsers, and validated, and
checked for accessibility. Checking they're equal to a particular
string just seems bizarre (and where does that string come from
anyway?)

The kind of acceptance testing that you are talking about is very
important, but you can't automate "Does it look OK in a browser?".
Unit tests suitable for automation don't have anything to work with
*but* the generated HTML.
I can understand the disbelief that a straight string comparison
involving HTML might be a robust enough test for the output of a Web
application, given that potentially many equivalent representations of
some piece of text may exist, and especially given the typical
unpredictability of many XML-based solutions with respect to things
like whitespace, encodings, entity usage, and the like. On the other
hand, the initial complaint in this thread, whilst reasonable in the
context of some ideal function for "quoting stuff in HTML pages", is
somewhat inappropriate in the context of modifying an existing, mature
function which is now in ubiquitous usage. In order to minimise the
unpredictability of solutions, we should avoid making fundamental
changes especially at the lower levels of such solutions.

I can't remember whether I have any code using cgi.escape, although
since I usually use XML APIs rather than writing HTML manually, I
suspect that I haven't. Nevertheless, the breakage potentially caused
by even one call site involving a modified variant of cgi.escape would
be enough for most people to consider reimplementing the semantics of
the existing function, thus undermining the inclusion of such a
function in the standard library in the first place.

Paul

Sep 26 '06 #103
Brian Quinlan wrote:
I'd have to dig through the revision history to be sure, but I imagine
that cgi.escape was originally only used in the cgi module (and there
only in it's various print_* functions). Then it started being used by
other core Python modules e.g. cgitb, DocXMLRPCServer.
nah, it's an official API for simple HTML/XML escaping, and it's
perfectly usable for what it's supposed to be used for.

however, if you're doing serious web hacking, you *should* of course
work at the XHTML information set level whenever you can, where you
focus on the data you want to publish (using Unicode strings for any-
thing that's even remotely resembles human text), and the framework
makes sure that it gets to the other side in once piece, using HTML4 or
XHTML as necessary, and escaping and encoding things properly and
efficiently on the way. it's 2006. transferring data from Python
applications to web browsers is no rocket science.

</F>

Sep 26 '06 #104
Jon Ribbens wrote:
In article <ma**************************************@python.o rg>, Brian Quinlan wrote:
>Well, there are dozens (hundreds?) of templating systems for Python.

I know, I wrote one of them ;-)
>t = Template("test.html")
t['foo'] = 'Brian -"Hi!"'
assert str(t) == '<p>Brian -&gt; "Hi"</p>'

So how would you test our template system?

What I don't get is why you are testing the above code like that at
all. Surely if the template system somehow became so broken that it
couldn't even do trivial replacements, you would notice immediately
as all your web pages would go totally wrong.
If, in the example that I showed, the less-than character was not
correctly escaped, then it might not manifest itself frequently in a
typical application because the less-than character is seldom used in
English prose.

Also, assuming that single case was trivial to test without a test
harness, how many web pages do I have to look at to be reasonably
confident that *every* feature works correctly?

Cheers,
Brian
Sep 26 '06 #105
In article <ma**************************************@python.o rg>, Brian Quinlan wrote:
If, in the example that I showed, the less-than character was not
correctly escaped, then it might not manifest itself frequently in a
typical application because the less-than character is seldom used in
English prose.
OK, but effectively what you're talking about here is testing the
'cgi.escape' function itself - said test of course being part and
parcel of the cgi package and therefore easily updatable if the
cgi.escape function changes.
Also, assuming that single case was trivial to test without a test
harness, how many web pages do I have to look at to be reasonably
confident that *every* feature works correctly?
It depends on how many features you have! My templating system, for
example, has sections and replacements, and that's it. Replacements
can be unencoded, html-encoded or url-encoded. That's approximately
4 things to test ;-) Plus, the templating code basically never changes
so doesn't need regression testing.
Sep 26 '06 #106
At Tuesday 26/9/2006 04:16, Lawrence D'Oliveiro wrote:
What precisely do you think it would "break"?
FWIW, a *lot* of unit tests on *my* generated html code would break...
Why did you write your code that way?
Uhm, maybe because I relied on the published documentation of a
published standard module? Just modify the behavior in *your* own
cgi.escape and all of us will be happy...

Gabriel Genellina
Softlab SRL

__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas

Sep 26 '06 #107
At Tuesday 26/9/2006 12:53, Jon Ribbens wrote:
BTW, I am curious about how you do unit testing. The example that I used
in my summary is a very common pattern but would break in cgi.escape
changed it's semantics. What do you do instead?

To be honest I'm not sure what *sort* of code people test this way. It
just doesn't seem appropriate at all for web page generating code. Web
pages need to be manually viewed in web browsers, and validated, and
checked for accessibility. Checking they're equal to a particular
string just seems bizarre (and where does that string come from
anyway?)
By example, I do not validate a "page". I validate that all methods
that make up pieces of a page, build them the way they should - these
are our "unit tests". Then, it's up to the templating library to join
all the pieces into the final html page.
I validated the original html against the corresponding dtd some time
ago (using the w3c validator), and ocasionally when things "looks
wrong" on a browser, but most of the time the html generated pages
are not validated nor checked as a whole.
What you describe are another kind of tests, and really should not
depend on the details of cgi.escape - as the usability test of an MP3
player does not care about some transitor's hFE used inside...

Gabriel Genellina
Softlab SRL

__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas

Sep 26 '06 #108
Brian Quinlan <br***@sweetapp.comwrote:
A summary of this pointless argument:

Why cgi.escape should be changed to escape double quote (and maybe
single quote) characters by default:
o escaping should be very aggressive by default to avoid subtle bugs
o over-escaping is not likely to harm most program significantly
o people who do not read the documentation may be surprised by it's
behavior

Why cgi.escape should NOT be changed:
o it is current used in lots of code and changing it will almost
certainly break some of it, test suites at minimum e.g.
assert my_template_system("<p>{foo}</p>", foo='"') == '<p>"</p>'
You must be kidding.
o escaping attribute values is less common than escaping element
text
Again, you must be kidding: href="/search.cgi?query=3&results=10"

--
John MexIT: http://johnbokma.com/mexit/
personal page: http://johnbokma.com/
Experienced programmer available: http://castleamber.com/
Happy Customers: http://castleamber.com/testimonials.html
Sep 26 '06 #109
In message <ma**************************************@python.o rg>, Fredrik
Lundh wrote:
Jon Ribbens wrote:
>This has nothing to do with character encodings.

it has *everything* to do with encoding of existing data into HTML so it
can be safely transported to, and recreated by, an HTML-aware client.

does the word "information set" mean anything to you?
The special characters we're talking about escaping--ampersand, less-than,
single-quote, double-quote--are part of the basic syntax of XML and HTML.
They are information-set-independent.
Sep 27 '06 #110
In message <Xn*************************@130.133.1.4>, John Bokma wrote:
Brian Quinlan <br***@sweetapp.comwrote:
>o escaping attribute values is less common than escaping element
text

Again, you must be kidding...
I don't think Brian Quinlan was seriously trying to claim that was true,
only that was the argument some people were making. Anybody who's done much
work generating HTML for Web pages will know that dynamically-generated
attribute values occur far more often than dynamically-generated cdata. Or
is that pcdata?
... href="/search.cgi?query=3&results=10"
You _do_ realize that the "&" should be escaped as "&amp;", don't you?
Sep 27 '06 #111
In message <ma**************************************@python.o rg>, Steve
Holden wrote:
Lawrence D'Oliveiro wrote:
>In message <ef**********@news.albasani.net>, Georg Brandl wrote:

>>>Lawrence D'Oliveiro wrote:

In message <ef**********@news.albasani.net>, Georg Brandl wrote:
>Lawrence D'Oliveiro wrote:
>
>>In message <45***********************@dread15.news.tele.dk> , Max M
>>wrote:
>>
>>
>>>Lawrence is right that the escape method doesn't work the way he
>>>expects it to.
>>>
>>>Rewriting a library module simply because a developer is surprised is
>>>a *very* bad idea.
>>
>>I'm not surprised. Disappointed, yes. Verging on disgust at some
>>comments in this thread, yes. But "surprised" is what a lot of users
>>of the existing cgi.escape function are going to be when they discover
>>their code isn't doing what they thought it was.
>
>Why should they be surprised? The documentation states clearly what
>cgi.escape() does (as does the docstring).

Documentation frequently states stupid things. Doesn't mean it should be
treated as sacrosanct.

That's not the point. The point is that someone using cgi.escape() will
hardly be surprised of what it does and doesn't do.


And this surprise, or lack of it, is relevant to the argument how,
exactly?

Is there *any* branch of this thread that won't end with some snippy
remark from you?
And this is relevant to the argument how, exactly?
Sep 27 '06 #112
In message <ma**************************************@python.o rg>, Fredrik
Lundh wrote:
Lawrence D'Oliveiro wrote:
>>(cgi.escape(s, True) is slower than cgi.escape(s), for reasons that are
obvious for anyone who's looked at the code).

What you're doing is adding to the reasons why the existing cgi.escape
function is stupidly designed and implemented. The True case is by far
the most common

really? most HTML attributes cannot even contain things that would need
to be escaped...
Are you really serious about that?

Sep 27 '06 #113
In message <ma**************************************@python.o rg>, Gabriel G
wrote:
At Tuesday 26/9/2006 04:16, Lawrence D'Oliveiro wrote:
>What precisely do you think it would "break"?
FWIW, a *lot* of unit tests on *my* generated html code would break...
Why did you write your code that way?

Uhm, maybe because I relied on the published documentation of a
published standard module?
And if the published documentation said you had to jump off a cliff to use
it, you would do that?
Sep 27 '06 #114
In message <11**********************@h48g2000cwc.googlegroups .com>, George
Sakkis wrote:
Lawrence D'Oliveiro wrote:
>Fredrik Lundh wrote:
you're not the designer...

I don't have to be. Whoever the designer was, they had not properly
thought through the uses of this function. That's quite obvious already,
to anybody who works with HTML a lot. So the function is broken and needs
to be fixed.

If you're worried about changing the semantics of a function that keeps
the same "cgi.escape" name, then fine. We delete the existing function
and add a new, properly-designed one. _That_ will be a wake-up call to
all the users of the existing function to fix their code.

Wow. Are you always that arrogant for things you know very little
about, or just plain stupid ?
Wow. Express an opinion, and get called names by trolls.
Sep 27 '06 #115
Lawrence D'Oliveiro <ld*@geek-central.gen.new_zealandwrote:
In message <Xn*************************@130.133.1.4>, John Bokma
wrote:
[..]
>... href="/search.cgi?query=3&results=10"

You _do_ realize that the "&" should be escaped as "&amp;", don't you?
And what's "/search.cgi?query=3&results=10"? An attribute value. Exactly
my point.

--
John MexIT: http://johnbokma.com/mexit/
personal page: http://johnbokma.com/
Experienced programmer available: http://castleamber.com/
Happy Customers: http://castleamber.com/testimonials.html
Sep 27 '06 #116
In message <ma**************************************@python.o rg>, Fredrik
Lundh wrote:
most HTML attributes cannot even contain things that would need
to be escaped ...
sys.stdout.write \
(
"Email: <INPUT TYPE=\"TEXT\" NAME=\"email_address\" VALUE=\"%s\">\n"
%
QuoteHTML(WhateverTheUserPreviouslyTyped)
)
Sep 27 '06 #117
Lawrence D'Oliveiro wrote:
In message <11**********************@h48g2000cwc.googlegroups .com>, George
Sakkis wrote:
Lawrence D'Oliveiro wrote:
Fredrik Lundh wrote:
you're not the designer...

I don't have to be. Whoever the designer was, they had not properly
thought through the uses of this function. That's quite obvious already,
to anybody who works with HTML a lot. So the function is broken and needs
to be fixed.

If you're worried about changing the semantics of a function that keeps
the same "cgi.escape" name, then fine. We delete the existing function
and add a new, properly-designed one. _That_ will be a wake-up call to
all the users of the existing function to fix their code.
Wow. Are you always that arrogant for things you know very little
about, or just plain stupid ?

Wow. Express an opinion, and get called names by trolls.
Funny, "troll" was my initial thought after reading your first few
posts. As you went on and on though, exposing your smugness and failure
to grasp rocket-science concepts such as "backwards compatibility", I
expressed my opinion by dismissing "troll" for a more fit description
of you.

Sep 27 '06 #118
Lawrence D'Oliveiro wrote:
In message <ma**************************************@python.o rg>, Steve
Holden wrote:

>>Lawrence D'Oliveiro wrote:
>>>In message <ef**********@news.albasani.net>, Georg Brandl wrote:

Lawrence D'Oliveiro wrote:
>In message <ef**********@news.albasani.net>, Georg Brandl wrote:
>
>
>
>>Lawrence D'Oliveiro wrote:
>>
>>
>>>In message <45***********************@dread15.news.tele.dk> , Max M
>>>wrote:
>>>
>>>
>>>
>>>>Lawrence is right that the escape method doesn't work the way he
>>>>expects it to.
>>>>
>>>>Rewriting a library module simply because a developer is surprised is
>>>>a *very* bad idea.
>>>
>>>I'm not surprised. Disappointed, yes. Verging on disgust at some
>>>comments in this thread, yes. But "surprised" is what a lot of users
>>>of the existing cgi.escape function are going to be when they discover
>>>their code isn't doing what they thought it was.
>>
>>Why should they be surprised? The documentation states clearly what
>>cgi.escape() does (as does the docstring).
>
>Documentation frequently states stupid things. Doesn't mean it should be
>treated as sacrosanct.

That's not the point. The point is that someone using cgi.escape() will
hardly be surprised of what it does and doesn't do.
And this surprise, or lack of it, is relevant to the argument how,
exactly?

Is there *any* branch of this thread that won't end with some snippy
remark from you?


And this is relevant to the argument how, exactly?
I would really rather this were a discussion than an argument. You will
now no doubt reply telling me I wouldn't.

My posting was issued as a response to the irritation engendered by your
argumentative style of debate. Your latest response simply proves that
there is indeed no remark, however irrelevant, that you will allow to go
unanswered.

For heaven's sake, learn to shut up for at least some of the time!

regards
Steve

PS: Do you have the maturity to resist the temptation to reply to this?
I seriously doubt it.
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://holdenweb.blogspot.com
Recent Ramblings http://del.icio.us/steve.holden

Sep 27 '06 #119
I would really rather this were a discussion than an argument. You will
now no doubt reply telling me I wouldn't.

My posting was issued as a response to the irritation engendered by your
argumentative style of debate. Your latest response simply proves that
there is indeed no remark, however irrelevant, that you will allow to go
unanswered.
The Complaints department is down the hall...
Sep 27 '06 #120
Anthony Baxter wrote:
>I would really rather this were a discussion than an argument. You will
now no doubt reply telling me I wouldn't.

My posting was issued as a response to the irritation engendered by your
argumentative style of debate. Your latest response simply proves that
there is indeed no remark, however irrelevant, that you will allow to go
unanswered.

The Complaints department is down the hall...
Though some discussion participants seemingly want to stay for more
being-hit-on-the-head lessons ;)

Georg
Sep 27 '06 #121
Georg Brandl <g.*************@gmx.netwrites:
Anthony Baxter wrote:
I would really rather this were a discussion than an
argument. You will now no doubt reply telling me I wouldn't.
The Complaints department is down the hall...

Though some discussion participants seemingly want to stay for more
being-hit-on-the-head lessons ;)
No no, hold your head like this, and then go "waaagh". Try it again.

--
\ "It is seldom that liberty of any kind is lost all at once." |
`\ -- David Hume |
_o__) |
Ben Finney

Sep 27 '06 #122
John Bokma wrote:
>Why cgi.escape should NOT be changed:
o it is current used in lots of code and changing it will almost
certainly break some of it, test suites at minimum e.g.
assert my_template_system("<p>{foo}</p>", foo='"') == '<p>"</p>'

You must be kidding.
Nope. How do you write your templating system unit tests?
>o escaping attribute values is less common than escaping element
text

Again, you must be kidding: href="/search.cgi?query=3&results=10"
Actually, I wasn't kidding. I was basing this belief on greping through
the Python standard library where only the quote=None form is ever used.
It also matches my experience. But I don't have a large enough sample to
make any claim either way.

Cheers,
Brian
Sep 27 '06 #123
In article <ma**************************************@python.o rg>, Gabriel G wrote:
By example, I do not validate a "page". I validate that all methods
that make up pieces of a page, build them the way they should - these
are our "unit tests". Then, it's up to the templating library to join
all the pieces into the final html page.
That sounds sensible to me - and also likely to be the sort of tests
that are not going to get broken by changes to cgi.escape ;-)
I validated the original html against the corresponding dtd some time
ago (using the w3c validator), and ocasionally when things "looks
wrong" on a browser, but most of the time the html generated pages
are not validated nor checked as a whole.
That's possibly a mistake, but obviously that depends on details of
how your overall methodology works that I have no information about.
Sep 27 '06 #124
Brian Quinlan <br***@sweetapp.comwrote:
Actually, I wasn't kidding. I was basing this belief on greping through
the Python standard library where only the quote=None form is ever used.
It also matches my experience. But I don't have a large enough sample to
make any claim either way.
A better sample might be to grep the Zope sources. There are a lot of calls
to escape and the vast majority don't set the quote parameter, but most use
of escape is actually hidden by the templating system. The TAL engine uses
escape(s,1) for attribute values and escape(text) for content, so you get
the best of both worlds: you don't have to think about which form of escape
you need (or even that you need to escape strings at all), and you don't
get quotes escaped when they don't have to be.
Sep 27 '06 #125
Jon Ribbens wrote:
In article <ef**********@news.albasani.net>, Georg Brandl wrote:
>>I'm sorry, that's not good enough. How, precisely, would it break
"existing code"? Can you come up with an example, or even an
explanation of how it *could* break existing code?
Is that so hard to see? If cgi.escape replaced "'" with an entity reference,
code that expects it not to do so would break.
Sorry, that's still not good enough. Why would any code expect such a
thing?
Plenty of test suites for a start. A non-backwards compatible change suchas
being suggested can create a huge maintenance burden on lots of people.
People also use that function to escape non-HTML too - if they are using it
as documented, and it produces the correct results for them, great. Note
that the documentation doesn't say that input has to be HTML, nor that
output must be used as HTML. It just describes the transformation that it
does clearly and unambiguously and can quite happily be used for generating
quoted text for use in, say, XML documents. Also, because Python has a
conservative policy on backwards incompatible changes, you are protected
from some wanker going and changing the HTML safe mappings arbitrarily, say
using numerical entity references instead of &gt;, &lt; and &amp;. This
policy allows large software projects to be developed in Python and
maintained with less pain than if they were written in languages with a less
conservative policy.

If you want to improve the situation, join the WEB-SIG to help design new
and improved APIs so that the existing ones like the ancient cgi module can
be deprecated. Or maybe just some helpers can be added to the existing
htmllib module? There are better approaches than making non-backwards
compatible changes to functions people have been relying on since Python 1.5.
--
Stuart Bishop <st****@stuartbishop.net>
http://www.stuartbishop.net/
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

iD8DBQFFGz4NAfqZj7rGN0oRAodwAJ4qD+VF0VRNrguj/fqwtGgEBk1GTwCeJjcM
Qyd8IxuX+0D0VM083tqGbSs=
=IbTs
-----END PGP SIGNATURE-----

Sep 28 '06 #126
In message <ma**************************************@python.o rg>, Stuart
Bishop wrote:
People also use that function to escape non-HTML too - if they are using
it as documented, and it produces the correct results for them, great.
Note that the documentation doesn't say that input has to be HTML, nor
that output must be used as HTML.
It says that the input is converted to "HTML-safe sequences".
It just describes the transformation
that it does clearly and unambiguously and can quite happily be used for
generating quoted text for use in, say, XML documents.
And all those character entities references are also valid in XML.
Also, because Python has a
conservative policy on backwards incompatible changes, you are protected
from some wanker going and changing the HTML safe mappings arbitrarily,
say using numerical entity references instead of &gt;, &lt; and &amp;.
Why would that be wrong? It would still be consistent with the
documentation.

Sep 28 '06 #127
Lawrence D'Oliveiro <ld*@geek-central.gen.new_zealandwrote:
>Also, because Python has a
conservative policy on backwards incompatible changes, you are protected
from some wanker going and changing the HTML safe mappings arbitrarily,
say using numerical entity references instead of &gt;, &lt; and &amp;.

Why would that be wrong? It would still be consistent with the
documentation.
It would be wrong as he said because "Python has a conservative policy on
backwards incompatible changes". In general (although they may not always
succeed) Python's core developers try not to change functionality even when
that functionality isn't clearly documented. Rather if it becomes an issue
they would prefer to clarify the documentation.

Yes, there is a downside to this: a lot of the Python standard libraries
aren't as good as they could be if incompatible changes were allowed, but
it does reduce maintenance headaches.

The solution is usually that when the standard api is insufficient you wrap
it in something else. cgi.escape is a good example: most people writing web
applications never call it directly because they produce their html output
using a templating language which does all the necessary quoting for them
automatically (e.g. Zope's tal language). If you use tal then you have zero
chance of forgetting to use &quote; in a situation where it is required,
but an incompatible change to cgi.escape could still break your existing
code.
Sep 28 '06 #128
Jon Ribbens wrote:
In article <ma**************************************@python.o rg>, Fredrik Lundh wrote:
>maybe you haven't done software long enough to understand that
software works better if you use it the way it was intended to be
used, but that's no excuse for being stupid.

So what's your excuse?
If you don't like Fredrik's manner I suggest that you simply
don't use any code he's written. Good luck using Python! :^)
Don't bite the hand that feeds you...
Sep 29 '06 #129
Another useful function is this:

def JSString(Str) :
"""returns a JavaScript string literal that evaluates to Str. Note
I'm not worrying about non-ASCII characters for now."""
Result = []
for Ch in Str :
if Ch == "\\" :
Ch = "\\\\"
elif Ch == "\"" :
Ch = "\\\""
elif Ch == "\t" :
Ch = "\\t"
elif Ch == "\n" :
Ch = "\\n"
#end if
Result.append(Ch)
#end for
return "\"" + "".join(Result) + "\""
#end JSString

This can be used, for instance in

sys.stdout.write \
(
"window.setTimeout(%s, 1000)\n"
%
JSString("alert(%s)" % JSString("Hi There!"))
)

Oct 7 '06 #130
Lawrence D'Oliveiro <ld*@geek-central.gen.new_zealandwrote:
Another useful function is this:

def JSString(Str) :
"""returns a JavaScript string literal that evaluates to Str.
Note I'm not worrying about non-ASCII characters for now."""
<snip>

Here is a shorter alternative that handles non-ASCII sequences provided you
pass in unicode:

def JSString(s):
return repr(unicode(s))[1:]
>>print JSString(u"\u201chi there!\u201d")
'\u201chi there!\u201d'
>>print JSString("Hello world")
'Hello world'
>>print JSString("Hello 'world'")
"Hello 'world'"

For ascii strings you could also use the string-escape codec, but strangely
the unicode-escape codec doesn't escape quotes.
Oct 8 '06 #131
Lawrence D'Oliveiro wrote:
Another useful function is this:

def JSString(Str) :
"""returns a JavaScript string literal that evaluates to Str....
You can do this more simply:

_map = {"\\" : "\\\\", "\"" : "\\\"", "\t" : "\\t", "\n" : "\\n"}
def JSString(Str) :
mapped = [_map.get(Ch, Ch) for Ch in Str]
return "\"" + "".join(mapped) + "\""

--
--Scott David Daniels
sc***********@acm.org
Oct 8 '06 #132

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.