Re: Python 2.5 nested auth functions in publisher.
Got access to Python 2.5 finally. My test script works on it so they
have
fixed the ordering issue.
2.5 (r25:51908, Oct 29 2006, 01:52:52)
[GCC 3.3.3 20040412 (Red Hat Linux 3.3.3-7)]
()
('req', '__auth__', '__access__', '__auth_realm__')
1
__auth__ (1, line 7>)
__access__ (1, line 9>)
__auth_realm__ (1, 'REALM')
Have thus committed some changes back into mod_python for it now,
so should pass tests okay on Python 2.5.
Graham
On 29/10/2006, at 4:18 PM, Graham Dumpleton wrote:
On 29/10/2006, at 12:05 PM, Graham Dumpleton wrote:
On 28/10/2006, at 10:01 PM, Dan Eloff wrote:
On 10/28/06, Graham Dumpleton <[EMAIL PROTECTED]> wrote:
Dan, the code that needs to be updated is:
if "__auth__" in func_code.co_names:
i = list(func_code.co_names).index("__auth__")
__auth__ = func_code.co_consts[i+1]
if hasattr(__auth__, "co_name"):
__auth__ = new.function(__auth__, func_globals)
found_auth = 1
Note how it accesses code objects for functions from co_consts. Do
they still appear
to be there in Python 2.5? Are you able to work out some code that
does the same
thing as this?
Using the test function:
def foo(a,b):
d = 5
def __auth__(req):
return True
e = d + 5
fc = foo.func_code
import new
func_globals = globals()
for i, var_name in enumerate(fc.co_varnames):
if var_name == '__auth__':
__auth__ = fc.co_consts[i-fc.co_argcount+1]
if hasattr(__auth__, 'co_name'):
__auth__ = new.function(__auth__, func_globals)
found_auth = 1
break
__auth__
I am curious as to the hasattr(__auth__, 'co_name') section. Is
there
any case where this is not true? (and does it make sense to say
found_auth = 1 if it isn't?)
The co_name check is making sure it is a code object as opposed to a
dictionary or some other constant.
See:
http://www.modpython.org/live/current/doc-html/hand-pub-alg-
auth.html
for what __auth__ can be.
Actually, I am partly wrong about that, when nesting these inside of a
function they must be functions or a constant, they can't be a
dictionary.
The documentation even states this:
Note that this technique will also work if __auth__ or __access__
is a
constant, but will not work if they are a dictionary or a list.
What I have found though is that even in Python 2.3.5, the names
can be
found in co_varnames. The problem is that in Python 2.3.5, where the
names appear in co_varnames, they aren't in the same order as they
appear in co_names or as required for indexing into co_consts which
looks like a bug to me.
The question now is whether in Python 2.5 the names appear in
co_varnames
in the correct order or not. If they aren't in the correct order
and it is still
broken, makes it impossible for it to work.
Can you run the following test program and see if you get what
would be
expected.
def handler(req):
def __auth__(req, user, password):
return 1
def __access__(req, user):
return 1
__auth_realm__ = 'REALM'
func_code = handler.func_code
print func_code.co_names
print func_code.co_varnames
print func_code.co_argcount
print
def lookup(name):
i = None
if name in func_code.co_names:
names = func_code.co_names
i = list(names).index(name)
elif func_code.co_argcount < len(func_code.co_varnames):
names = func_code.co_varnames[func_code.co_argcount:]
if name in names:
i = list(names).index(name)
if i is not None:
return (1, func_code.co_consts[i+1])
return (0, None)
print '__auth__', lookup('__auth__')
print '__access__', lookup('__access__')
print '__auth_realm__', lookup('__auth_realm__')
On Python 2.3.5 I get:
('__auth__', '__access__', '__auth_realm__')
('req', '__access__', '__auth_realm__', '__auth__')
1
__auth__ (1, 2>)
__access__ (1, line 4>)
__auth_realm__ (1, 'REALM')
Thanks.
Graham
Re: Python 2.5 nested auth functions in publisher.
On 29/10/2006, at 12:05 PM, Graham Dumpleton wrote:
On 28/10/2006, at 10:01 PM, Dan Eloff wrote:
On 10/28/06, Graham Dumpleton <[EMAIL PROTECTED]> wrote:
Dan, the code that needs to be updated is:
if "__auth__" in func_code.co_names:
i = list(func_code.co_names).index("__auth__")
__auth__ = func_code.co_consts[i+1]
if hasattr(__auth__, "co_name"):
__auth__ = new.function(__auth__, func_globals)
found_auth = 1
Note how it accesses code objects for functions from co_consts. Do
they still appear
to be there in Python 2.5? Are you able to work out some code that
does the same
thing as this?
Using the test function:
def foo(a,b):
d = 5
def __auth__(req):
return True
e = d + 5
fc = foo.func_code
import new
func_globals = globals()
for i, var_name in enumerate(fc.co_varnames):
if var_name == '__auth__':
__auth__ = fc.co_consts[i-fc.co_argcount+1]
if hasattr(__auth__, 'co_name'):
__auth__ = new.function(__auth__, func_globals)
found_auth = 1
break
__auth__
I am curious as to the hasattr(__auth__, 'co_name') section. Is there
any case where this is not true? (and does it make sense to say
found_auth = 1 if it isn't?)
The co_name check is making sure it is a code object as opposed to a
dictionary or some other constant.
See:
http://www.modpython.org/live/current/doc-html/hand-pub-alg-
auth.html
for what __auth__ can be.
Actually, I am partly wrong about that, when nesting these inside of a
function they must be functions or a constant, they can't be a
dictionary.
The documentation even states this:
Note that this technique will also work if __auth__ or __access__
is a
constant, but will not work if they are a dictionary or a list.
What I have found though is that even in Python 2.3.5, the names can be
found in co_varnames. The problem is that in Python 2.3.5, where the
names appear in co_varnames, they aren't in the same order as they
appear in co_names or as required for indexing into co_consts which
looks like a bug to me.
The question now is whether in Python 2.5 the names appear in
co_varnames
in the correct order or not. If they aren't in the correct order and
it is still
broken, makes it impossible for it to work.
Can you run the following test program and see if you get what would be
expected.
def handler(req):
def __auth__(req, user, password):
return 1
def __access__(req, user):
return 1
__auth_realm__ = 'REALM'
func_code = handler.func_code
print func_code.co_names
print func_code.co_varnames
print func_code.co_argcount
print
def lookup(name):
i = None
if name in func_code.co_names:
names = func_code.co_names
i = list(names).index(name)
elif func_code.co_argcount < len(func_code.co_varnames):
names = func_code.co_varnames[func_code.co_argcount:]
if name in names:
i = list(names).index(name)
if i is not None:
return (1, func_code.co_consts[i+1])
return (0, None)
print '__auth__', lookup('__auth__')
print '__access__', lookup('__access__')
print '__auth_realm__', lookup('__auth_realm__')
On Python 2.3.5 I get:
('__auth__', '__access__', '__auth_realm__')
('req', '__access__', '__auth_realm__', '__auth__')
1
__auth__ (1, )
__access__ (1, line 4>)
__auth_realm__ (1, 'REALM')
Thanks.
Graham
Re: Python 2.5 nested auth functions in publisher.
On 28/10/2006, at 10:01 PM, Dan Eloff wrote:
On 10/28/06, Graham Dumpleton <[EMAIL PROTECTED]> wrote:
Dan, the code that needs to be updated is:
if "__auth__" in func_code.co_names:
i = list(func_code.co_names).index("__auth__")
__auth__ = func_code.co_consts[i+1]
if hasattr(__auth__, "co_name"):
__auth__ = new.function(__auth__, func_globals)
found_auth = 1
Note how it accesses code objects for functions from co_consts. Do
they still appear
to be there in Python 2.5? Are you able to work out some code that
does the same
thing as this?
Using the test function:
def foo(a,b):
d = 5
def __auth__(req):
return True
e = d + 5
fc = foo.func_code
import new
func_globals = globals()
for i, var_name in enumerate(fc.co_varnames):
if var_name == '__auth__':
__auth__ = fc.co_consts[i-fc.co_argcount+1]
if hasattr(__auth__, 'co_name'):
__auth__ = new.function(__auth__, func_globals)
found_auth = 1
break
__auth__
I am curious as to the hasattr(__auth__, 'co_name') section. Is there
any case where this is not true? (and does it make sense to say
found_auth = 1 if it isn't?)
The co_name check is making sure it is a code object as opposed to a
dictionary or some other constant.
See:
http://www.modpython.org/live/current/doc-html/hand-pub-alg-auth.html
for what __auth__ can be.
Graham
Re: Python 2.5 nested auth functions in publisher.
On 10/28/06, Graham Dumpleton <[EMAIL PROTECTED]> wrote:
Dan, the code that needs to be updated is:
if "__auth__" in func_code.co_names:
i = list(func_code.co_names).index("__auth__")
__auth__ = func_code.co_consts[i+1]
if hasattr(__auth__, "co_name"):
__auth__ = new.function(__auth__, func_globals)
found_auth = 1
Note how it accesses code objects for functions from co_consts. Do
they still appear
to be there in Python 2.5? Are you able to work out some code that
does the same
thing as this?
Using the test function:
def foo(a,b):
d = 5
def __auth__(req):
return True
e = d + 5
fc = foo.func_code
import new
func_globals = globals()
for i, var_name in enumerate(fc.co_varnames):
if var_name == '__auth__':
__auth__ = fc.co_consts[i-fc.co_argcount+1]
if hasattr(__auth__, 'co_name'):
__auth__ = new.function(__auth__, func_globals)
found_auth = 1
break
__auth__
I am curious as to the hasattr(__auth__, 'co_name') section. Is there
any case where this is not true? (and does it make sense to say
found_auth = 1 if it isn't?)
-Dan
Re: Python 2.5 nested auth functions in publisher.
On 27/10/2006, at 11:03 PM, Dan Eloff wrote:
On 10/27/06, Graham Dumpleton <[EMAIL PROTECTED]> wrote:
Unless they have really screwed things around, co_varnames is
specifically
for function argument names and is unlikely to contained nested
constant
names. If it did, then I would expect a lot of the publisher code to
break in
other ways as it uses co_varnames for the very specific purpose of
matching
form parameters against function arguments.
I'd look into that code then.
fc.co_names
()
fc.co_varnames
('__auth__', '__access__')
def foo(a,b):
d = 5
def bar(c):
return c
fc.co_names
()
fc.co_varnames
('a', 'b', 'd', 'bar')
To get just args, try:
fc.co_varnames[:fc.co_argcount]
('a', 'b')
And for just local vars:
fc.co_varnames[fc.co_argcount:]
('d', 'bar')
Dan, the code that needs to be updated is:
if "__auth__" in func_code.co_names:
i = list(func_code.co_names).index("__auth__")
__auth__ = func_code.co_consts[i+1]
if hasattr(__auth__, "co_name"):
__auth__ = new.function(__auth__, func_globals)
found_auth = 1
Note how it accesses code objects for functions from co_consts. Do
they still appear
to be there in Python 2.5? Are you able to work out some code that
does the same
thing as this?
Graham
Re: Python 2.5 nested auth functions in publisher.
On 10/27/06, Graham Dumpleton <[EMAIL PROTECTED]> wrote:
Unless they have really screwed things around, co_varnames is
specifically
for function argument names and is unlikely to contained nested constant
names. If it did, then I would expect a lot of the publisher code to
break in
other ways as it uses co_varnames for the very specific purpose of
matching
form parameters against function arguments.
I'd look into that code then.
fc.co_names
()
fc.co_varnames
('__auth__', '__access__')
def foo(a,b):
d = 5
def bar(c):
return c
fc.co_names
()
fc.co_varnames
('a', 'b', 'd', 'bar')
To get just args, try:
fc.co_varnames[:fc.co_argcount]
('a', 'b')
And for just local vars:
fc.co_varnames[fc.co_argcount:]
('d', 'bar')
-Dan
Re: Python 2.5 nested auth functions in publisher.
On 27/10/2006, at 9:31 PM, Dan Eloff wrote: On 10/27/06, Graham Dumpleton <[EMAIL PROTECTED]> wrote: Jim sent this to me when the python-dev list was down for maintenance. Can anyone with Python 2.5 who knows something about function internals enlighten us about what may have changed here. Previously the names of nested functions appeared in func_code.co_names but that doesn't appear to be the case in Python 2.5. Confirmed. Try func_code.co_varnames instead. I don't know why the change, and a quick search wasn't very enlightening, other than they python guys mentioned something about co_names and co_varnames changed, and some people fixing this problem by using co_varnames in python 2.5. Unless they have really screwed things around, co_varnames is specifically for function argument names and is unlikely to contained nested constant names. If it did, then I would expect a lot of the publisher code to break in other ways as it uses co_varnames for the very specific purpose of matching form parameters against function arguments. I guess time will tell. Anyway, time for me to sleep. :-) Graham
Re: Python 2.5 nested auth functions in publisher.
On 10/27/06, Graham Dumpleton <[EMAIL PROTECTED]> wrote: Jim sent this to me when the python-dev list was down for maintenance. Can anyone with Python 2.5 who knows something about function internals enlighten us about what may have changed here. Previously the names of nested functions appeared in func_code.co_names but that doesn't appear to be the case in Python 2.5. Confirmed. Try func_code.co_varnames instead. I don't know why the change, and a quick search wasn't very enlightening, other than they python guys mentioned something about co_names and co_varnames changed, and some people fixing this problem by using co_varnames in python 2.5. -Dan
