Re: Multiline plpython procedure

From: Marco Colombo <pgsql(at)esiway(dot)net>
To: Stuart Bishop <stuart(at)stuartbishop(dot)net>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Greg Stark <gsstark(at)mit(dot)edu>, pgsql-general(at)postgresql(dot)org
Subject: Re: Multiline plpython procedure
Date: 2005-01-21 12:40:06
Message-ID: Pine.LNX.4.61.0501211306190.4205@Megathlon.ESI
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On Fri, 21 Jan 2005, Stuart Bishop wrote:

> This is currently being discussed on python-dev:
>
> http://mail.python.org/pipermail/python-dev/2005-January/051203.html
>
> It looks like my earlier concerns were unwarrented - current consensus seems
> to be to transform line endings in the string to the one-true-format expected
> by Python's guts:
>
> http://mail.python.org/pipermail/python-dev/2005-January/051214.html

I'm not sure that exec expects strings in Unix format:

http://docs.python.org/ref/physical.html
"A physical line ends in whatever the current platform's convention is for
terminating lines. On Unix, this is the ASCII LF (linefeed) character.
On Windows, it is the ASCII sequence CR LF (return followed by linefeed).
On Macintosh, it is the ASCII CR (return) character."

Reading the following message from Guido, and the above paragraph,
I think that the lexxer always uses platform conventions to split lines.

http://mail.python.org/pipermail/python-dev/2002-March/021741.html
"I still think that this PEP is a big hack -- but as big hacks go, it
seems to have a pretty good payback.

I'm hoping that eventually the parser (really the lexer) will be able
to open the file in binary mode and recognize all three newline styles
directly. That would solve the problems with exec, eval, and compile."

So I think you can't just pass exec a string with \n as line terminator.
That would work only under Unix. You should use os.linesep instead.
E.g.:

import os
import re

# a small program with mixed line ending conventions
a = "print 1\rprint 2\r\nprint 3\nprint 4\n"

try:
exec a
except SyntaxError:
print "SyntaxError"
pass

# transform it according to local line ending convention
b = os.linesep.join(re.split("\r\n|\r|\n", a))

try:
exec b
except SyntaxError:
print "SyntaxError"
pass

This produces, under Unix:
SyntaxError
1
2
3
4

Anyone can try it under Windows and under some old Mac?
I think we could do the same before passing the string to the interpreter
(I'm not familiar with how the interpreter is called in PostgreSQL, tho).

For those not fluent in python, this line:

os.linesep.join(re.split("\r\n|\r|\n", a))

first splits the string into a list for lines, using this pattern: \r\n|\r|\n
as separator. Then joins the lines again using os.linesep as separator instead.

.TM.
--
____/ ____/ /
/ / / Marco Colombo
___/ ___ / / Technical Manager
/ / / ESI s.r.l.
_____/ _____/ _/ Colombo(at)ESI(dot)it

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Martijn van Oosterhout 2005-01-21 12:42:42 Re: Multiline plpython procedure
Previous Message Abdul-Wahid Paterson 2005-01-21 11:58:25 custom integrity check