Re: Possible bug in PL/Python?

From: Adrian Klaver <adrian(dot)klaver(at)gmail(dot)com>
To: pgsql-general(at)postgresql(dot)org
Cc: Jeroen van Dongen <jeroen(at)jkwadraat(dot)net>
Subject: Re: Possible bug in PL/Python?
Date: 2012-01-17 16:40:38
Message-ID: 201201170840.39071.adrian.klaver@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On Tuesday, January 17, 2012 8:27:19 am Jeroen van Dongen wrote:
> Hi,
>
> In a current project I've a PL/Python function that uses default
> parameters, like this:
>
> CREATE FUNCTION auth.create_user(
> email text,
> initial_password text,
> display_name text DEFAULT NULL,
> mobile_phone text DEFAULT NULL,
> status auth.enum_user_status DEFAULT 'active'
> ) RETURNS text AS $$
> ... rest of function ...
>
> Now I try to test if 'display_name' is actually passed or not, and if not
> set it to something sensible, like so:
> ...
> if display_name is None:
> display_name = email[:email.find('@')]
> ...
>
> And ... that fails with an error stating that 'display_name' is referenced
> before assignment.
> However, if I do it like this, it works:
> ...
> if display_name is None:
> real_display_name = email[:email.find('@')]
> ...
>
> In straight Python the first example works, however in PL/Python only the
> second works.
>
> Is this how it is supposed to be and did I perhaps miss something in the
> docs, or is it a bug?

http://www.postgresql.org/docs/9.0/interactive/plpython-funcs.html

"
The arguments are set as global variables. Because of the scoping rules of
Python, this has the subtle consequence that an argument variable cannot be
reassigned inside the function to the value of an expression that involves the
variable name itself, unless the variable is redeclared as global in the block.
For example, the following won't work:

CREATE FUNCTION pystrip(x text)
RETURNS text
AS $$
x = x.strip() # error
return x
$$ LANGUAGE plpythonu;
because assigning to x makes x a local variable for the entire block, and so the
x on the right-hand side of the assignment refers to a not-yet-assigned local
variable x, not the PL/Python function parameter. Using the global statement,
this can be made to work:

CREATE FUNCTION pystrip(x text)
RETURNS text
AS $$
global x
x = x.strip() # ok now
return x
$$ LANGUAGE plpythonu;
But it is advisable not to rely on this implementation detail of PL/Python. It
is better to treat the function parameters as read-only.

"
>
> Kind regards,
> Jeroen

--
Adrian Klaver
adrian(dot)klaver(at)gmail(dot)com

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Joe Conway 2012-01-17 17:14:06 Southern California PostgreSQL Day
Previous Message Jeroen van Dongen 2012-01-17 16:27:19 Possible bug in PL/Python?