Issue 3276: httplib.HTTPConnection._send_request should not blindly assume dicts for headers (original) (raw)

Presently it's impossible to use httplib.HTTPConnection.request and send the several headers with the same name. This is because _send_request assumes a dict is passed in, or a dict-like interface. Obviously one could make a list subclass or some such and give it an iteritems that returns itself, but IMHO the solution is to fix httplib.

Attached patch changes the current behavior to using iteritems only if it exists, otherwise iterate directly (which would fit with sequences of two- tuples).

Indeed, as Terry wrote the assumption is that header is a mapping (not necessarily a dict). It is not hard to implement a Multimap that has this API:

import collections.abc

class Multimap(collections.abc.Mapping): def init(self): self.data = collections.defaultdict(list)

def __getitem__(self, key):
    return self.data[key]

def __setitem__(self, key, value):
    self.data[key].append(value)

def __iter__(self):
    yield from self.data

def items(self):
    for k in list(self.data.keys()):
        for v in list(self.data[k]):
            yield (k,v)

def __len__(self):
    return sum([len(v) for v in self.data.values()])

mm = Multimap() mm['1'] = 'a' mm['1'] = 'aa' mm['1'] = 'aaa' mm['2'] = 'b' mm['3'] = 'c' mm['3'] = 'cc' print(f'len = {len(mm)}') print(f'mm.items() = {list(mm.items())}')

Output: len = 6 mm.items() = [('1', 'a'), ('1', 'aa'), ('1', 'aaa'), ('2', 'b'), ('3', 'c'), ('3', 'cc')]