Uploaded image for project: 'mod_python'
  1. mod_python
  2. MODPYTHON-198

Python 2.5 nested auth functions in publisher.

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 3.2.10
    • Fix Version/s: 3.3.1
    • Component/s: publisher
    • Labels:
      None

      Description

      Jim Gallacher wrote:

      With python 2.5 I get 2 failures:

      test_publisher_auth_nested
      test_publisher_auth_method_nested

      It looks like something has changed in python 2.5 introspection that is
      messing up publisher.

      Test script testme.py
      ---------------------

      def testfunc():
      print 'stuff'
      def _auth_():
      print '_auth_ called'
      def _access_():
      print '_access_ called'

      def main():
      func_obj = testfunc

      func_code = func_obj.func_code
      print func_code.co_names

      if _name_ == '_main_':
      main()

      Results
      -------

      $ python2.3 testme.py
      ('_auth', 'access_')
      $ python2.4 testme.py
      ('_auth', 'access_')
      $ python2.5 testme.py
      ()

      Dan Eloff points out that information is now in co_varnames.

      >>> 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')

      Still need to work out if actual code objects for the functions are available in co_consts or not. Ie., need to replace:

      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

        Activity

        Hide
        grahamd Graham Dumpleton added a comment -

        Dan provides confirmation that something like:

        >>> 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>

        would appear to work.

        In practice need to support old and new versions of Python, so will need to check both co_names and co_varnames.

        Show
        grahamd Graham Dumpleton added a comment - Dan provides confirmation that something like: >>> 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> would appear to work. In practice need to support old and new versions of Python, so will need to check both co_names and co_varnames.
        Hide
        grahamd Graham Dumpleton added a comment -

        Looks like JIRA is not showing subversion commits or has not recorded some from when they were doing their infrastructure update. Is fixed though. Ended up using:

        func_code = func_object.func_code
        func_globals = func_object.func_globals

        def lookup(name):
        i = None
        if name in func_code.co_names:
        i = list(func_code.co_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)

        (found_auth, _auth) = lookup('auth_')
        if found_auth and type(_auth_) == types.CodeType:
        _auth_ = new.function(_auth_, func_globals)

        (found_access, _access) = lookup('access_')
        if found_access and type(_access_) == types.CodeType:
        _access_ = new.function(_access_, func_globals)

        (found_realm, _auth_realm) = lookup('auth_realm_')
        if found_realm:
        realm = _auth_realm_

        Ie., look in co_names first as co_varnames wasn't ordered correctly for older versions of Python.

        Show
        grahamd Graham Dumpleton added a comment - Looks like JIRA is not showing subversion commits or has not recorded some from when they were doing their infrastructure update. Is fixed though. Ended up using: func_code = func_object.func_code func_globals = func_object.func_globals def lookup(name): i = None if name in func_code.co_names: i = list(func_code.co_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) (found_auth, _ auth ) = lookup(' auth _') if found_auth and type(_ auth _) == types.CodeType: _ auth _ = new.function(_ auth _, func_globals) (found_access, _ access ) = lookup(' access _') if found_access and type(_ access _) == types.CodeType: _ access _ = new.function(_ access _, func_globals) (found_realm, _ auth_realm ) = lookup(' auth_realm _') if found_realm: realm = _ auth_realm _ Ie., look in co_names first as co_varnames wasn't ordered correctly for older versions of Python.

          People

          • Assignee:
            grahamd Graham Dumpleton
            Reporter:
            grahamd Graham Dumpleton
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development