Re: Multiline plpython procedure - Mailing list pgsql-general

From Marco Colombo
Subject Re: Multiline plpython procedure
Date
Msg-id Pine.LNX.4.61.0501211306190.4205@Megathlon.ESI
Whole thread Raw
In response to Re: Multiline plpython procedure  (Stuart Bishop <stuart@stuartbishop.net>)
List 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@ESI.it

pgsql-general by date:

Previous
From: Abdul-Wahid Paterson
Date:
Subject: custom integrity check
Next
From: Martijn van Oosterhout
Date:
Subject: Re: Multiline plpython procedure