quetz-mod_python-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Graham Dumpleton <grah...@dscpl.com.au>
Subject Re: Python 2.5 nested auth functions in publisher.
Date Sun, 29 Oct 2006 07:09:17 GMT
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, <code object __auth__ at 0xb7dbdbf0, file "hack.py",  
line 7>)
__access__ (1, <code object __access__ at 0xb7dbd7b8, file "hack.py",  
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 <grahamd@dscpl.com.au> 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__
>>> <function __auth__ at 0x01159830>
>>>
>>> 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, <code object __auth__ at 0x6a8a0, file "hack.py", line  
> 2>)
> __access__ (1, <code object __access__ at 0x70660, file "hack.py",  
> line 4>)
> __auth_realm__ (1, 'REALM')
>
>
> Thanks.
>
> Graham

Mime
View raw message