launchpad plugin doesn't work with Python 2.7

Bug #647588 reported by OneBugGuest
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Bazaar
New
Undecided
Unassigned

Bug Description

I've failed to access a public online branch with 'bzr branch lp:~<<path_to_branch>> > some_log_file 2>&1' command. I've tested it with bazaar version 2.2.1 and 2.2.0, same results (see below for full logged traceback - v 2.2.1 only)

Perhaps I've guessed the source of troubles, but I'm not a python programmer (nor I am a bzr user at the moment, I've just installed it to download and compile that one project), I've enough coding knowledge to understand the bare basics of its object structures (code seems quite easy to understand, with respect to its bare essentials), so please, take my analysis with caution.

Looking at the last few lines in below traceback, it seems the problem is related to the way you build a Request object in bzrlib.plugins.launchpad.lp_registration.XMLRPCTransport and pass it to parse_response method of Python xmlrpclib.Transport object. Giving a look at its code, I've found that version 2.7 of that Python library adds support for a gzipped content (with respect to previous implementations -- I've looked into 2.6.5 code for same library, but I couldn't use it in my environment), so it looks for a "Content-Encoding" header through a call to 'response.getheader' in parse_response method, and it seems that your code generates an object missing such a method.

A closer look showed me your 'response' object (in lp_registration.XMLRPCTransport request method) is build by calling the 'open' method of a _urllib2_wrappers.Opener object, which wraps a urllib2.build_opener object (and so uses urllib2.OpenDirector open method, as I've understood it), upon a _urllib2_wrappers.Request object, which in turn wraps a urllib2.Request object. This one provides a 'get_header' method, but no 'getheader', so I can think of three cases:

- urllib2.build_opener/OpenDirector open method is not suitable for your needs, or is buggy in Python 2.7 (I haven't investigated much of its implementation, but I'd expect it to be just handling the actual connection and populating the Request object with received data, without modifying its interface, though);

- xmlrpclib.Transport class has a buggy implementation of its parse_response method (e.g. it should call 'response.get_header' - as defined in urllib2.Request class - instead of 'response.getheader' -- though I'd think this is not the case, because parse_response is called by 'Transport.request', passing through an object being build 'ad hoc' before the call, so it should have been tested by Python developers);

- urllib2.Request class is (no more?) suited to work properly with xmlrpclib.Transport through your implementation of lp_registration.XMLRPCTransport, thus you should modify it. Perhaps, if not prevented by more specific needs (such as requiring a more specific response object), or by backward compatibility issues, or the like, you could just call xmlrpclib.Transport request method from within lp_registration.XMLRPCTransport.request, or modify _urllib2_wrappers.Request constructor so to add a line like 'self.getheader = self.get_header' -- though I cannot tell if that would work, a further investigation should be made on the actual request/response object being built within request method of xmlrpclib.Transport class, to find out whether it is compatible with urllib2.Request class interface (it could be a derived class, for instance, with a 'getheader' method substantially differing from Request.get_header - but the returned object should be the main focus, since, as I understand it, xmlrpclib.Transport.parse_response method expects that to be a simple string representing the value part of key+value header).

Best regards.

--- Traceback Log start ---

bzr: ERROR: exceptions.AttributeError: addinfourl instance has no attribute 'getheader'

Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/bzrlib/commands.py", line 912, in exception_to_return_code
    return the_callable(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/bzrlib/commands.py", line 1112, in run_bzr
    ret = run(*run_argv)
  File "/usr/lib/python2.7/site-packages/bzrlib/commands.py", line 690, in run_argv_aliases
    return self.run(**all_cmd_args)
  File "/usr/lib/python2.7/site-packages/bzrlib/commands.py", line 705, in run
    return self._operation.run_simple(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/bzrlib/cleanup.py", line 135, in run_simple
    self.cleanups, self.func, *args, **kwargs)
  File "/usr/lib/python2.7/site-packages/bzrlib/cleanup.py", line 165, in _do_with_cleanups
    result = func(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/bzrlib/builtins.py", line 1209, in run
    from_location)
  File "/usr/lib/python2.7/site-packages/bzrlib/bzrdir.py", line 1032, in open_tree_or_branch
    bzrdir = klass.open(location)
  File "/usr/lib/python2.7/site-packages/bzrlib/bzrdir.py", line 910, in open
    t = get_transport(base, possible_transports=possible_transports)
  File "/usr/lib/python2.7/site-packages/bzrlib/lazy_import.py", line 125, in __call__
    return obj(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/bzrlib/transport/__init__.py", line 1569, in get_transport
    base = directories.dereference(base)
  File "/usr/lib/python2.7/site-packages/bzrlib/directory_service.py", line 58, in dereference
    return service().look_up(name, url)
  File "/usr/lib/python2.7/site-packages/bzrlib/plugins/launchpad/lp_directory.py", line 59, in look_up
    return self._resolve(url)
  File "/usr/lib/python2.7/site-packages/bzrlib/plugins/launchpad/lp_directory.py", line 69, in _resolve
    result = resolve.submit(service)
  File "/usr/lib/python2.7/site-packages/bzrlib/plugins/launchpad/lp_registration.py", line 272, in submit
    self._authenticated)
  File "/usr/lib/python2.7/site-packages/bzrlib/plugins/launchpad/lp_registration.py", line 195, in send_request
    result = method(*method_params)
  File "/usr/lib/python2.7/xmlrpclib.py", line 1224, in __call__
    return self.__send(self.__name, args)
  File "/usr/lib/python2.7/xmlrpclib.py", line 1570, in __request
    verbose=self.__verbose
  File "/usr/lib/python2.7/site-packages/bzrlib/plugins/launchpad/lp_registration.py", line 78, in request
    return self.parse_response(response)
  File "/usr/lib/python2.7/xmlrpclib.py", line 1449, in parse_response
    if response.getheader("Content-Encoding", "") == "gzip":
AttributeError: addinfourl instance has no attribute 'getheader'

bzr 2.2.1 on python 2.7.0 (Linux-2.6.33.2-i686-with-glibc2.4)
arguments: ['/usr/bin/bzr', 'branch', 'lp:~alphab/dmraid/rc16-amdsbhack']
encoding: 'ISO-8859-15', fsenc: 'ISO-8859-15', lang: 'it_IT@euro'
plugins:
  bash_completion /usr/lib/python2.7/site-packages/bzrlib/plugins/bash_completion [2.2.1]
  bzrtools /usr/lib/python2.7/site-packages/bzrlib/plugins/bzrtools [2.2.0]
  launchpad /usr/lib/python2.7/site-packages/bzrlib/plugins/launchpad [2.2.1]
  netrc_credential_store /usr/lib/python2.7/site-packages/bzrlib/plugins/netrc_credential_store [2.2.1]
  news_merge /usr/lib/python2.7/site-packages/bzrlib/plugins/news_merge [2.2.1]

*** Bazaar has encountered an internal error. This probably indicates a
    bug in Bazaar. You can help us fix it by filing a bug report at
        https://bugs.launchpad.net/bzr/+filebug
    including this traceback and a description of the problem.

--- Traceback Log end ---

Revision history for this message
Martin Packman (gz) wrote :

Thanks for looking into this in such detail, see the existing bug report for more. The fix has landed and will be available in the next Bazaar release.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.