[Python-bugs-list] [ python-Bugs-446645 ] rexec and function attributes

noreply@sourceforge.net noreply@sourceforge.net
Wed, 01 Aug 2001 13:00:07 -0700


Bugs item #446645, was opened at 2001-07-31 19:21
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=446645&group_id=5470

>Category: Python Interpreter Core
Group: None
Status: Open
Resolution: None
>Priority: 6
Submitted By: Matthew Brecknell (brecknell)
>Assigned to: Barry Warsaw (bwarsaw)
Summary: rexec and function attributes

Initial Comment:
The behaviour of the rexec module seems to be 
inconsistent with respect to function attributes. The 
function attribute dictionary is read-only in the 
restricted environment until you go and write to it 
outside the restricted environment. After that, the 
dictionary becomes writable in the restricted 
environment too. See the following examples:

Python 2.1 (#1, Jun 29 2001, 15:51:00) 
[GCC 2.95.3 19991030 (prerelease)] on openbsd2
Type "copyright", "credits" or "license" for more 
information.
>>> import rexec
>>> r = rexec.RExec()
>>> def f(): pass
... 
>>> r.modules['__main__'].f = f
>>> r.r_exec('f.__dict__["attr"] = "value"')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/opt/python/lib/python2.1/rexec.py", line 264, 
in r_exec
    exec code in m.__dict__
  File "<string>", line 1, in ?
TypeError: object does not support item assignment
>>> f.attr = "value"
>>> r.r_exec('f.__dict__["attr"] = "new value"')
>>> f.attr
'new value'
>>> 

Or, looking at it another way:

Python 2.1 (#1, Jun 29 2001, 15:51:00) 
[GCC 2.95.3 19991030 (prerelease)] on openbsd2
Type "copyright", "credits" or "license" for more 
information.
>>> import rexec
>>> r = rexec.RExec()
>>> r.r_exec("def f(): pass")
>>> r.r_exec('f.__dict__["attr"] = "value"')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/opt/python/lib/python2.1/rexec.py", line 264, 
in r_exec
    exec code in m.__dict__
  File "<string>", line 1, in ?
TypeError: object does not support item assignment
>>> f = r.modules['__main__'].f
>>> f.attr = "value"
>>> r.r_exec('f.__dict__["attr"] = "new value"')
>>> f.attr
'new value'
>>> 

Please don't abuse me too much for still being on 
Python 2.1, since I haven't had time to try 2.1.1 or 
2.2a1! If I don't put this in now, I'll forget. I'm 
guessing that neither rexec nor function attributes 
are widely used, so not too many people would have 
come across this. If I get more time down the track, 
I'll look into it further.

Regards,
Matt.


----------------------------------------------------------------------

>Comment By: Jeremy Hylton (jhylton)
Date: 2001-08-01 13:00

Message:
Logged In: YES 
user_id=31392

You can see this behavior without using rexec.  The problem
you're seeing is that a function's __dict__ is None until
you set an attribute on the function.  Then the __dict__
slot is created and a new dictionary bound there.  The error
you see, which you attributed to rexec, is attempting to
execute f.__dict__["attr"] => None["attr"].

There are two policy questions here, which Barry can better
answer:

1. Should a function's __dict__ be accessible in restricted
mode?  A class's __dict__ is not, but it's a horse of a
different color.

2. Is it okay for __dict__ to occasionally return None?  I
don't think it is.  It's fine to be lazy about the creation
of __dict__, but it should be created as soon as it is
referenced.  Otherwise, any code that wants to use __dict__
should be prepared to deal with None.


----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=446645&group_id=5470