Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

http/cookies.py breaks existing Python 2/3 code using Unicode literals if python-future is installed #564

Open
0x9fff00 opened this issue Jun 15, 2020 · 0 comments

Comments

@0x9fff00
Copy link

0x9fff00 commented Jun 15, 2020

(I have also reported this at getsentry/responses#330)

The Responses library is already compatible with both Python 2 and 3. It uses Unicode literals, and the Cookies library instead of http.cookies on Python 2. It does this by using http.cookies if it's available and falling back to the Cookies library if it's not. However, it breaks on Python 2 if python-future is installed because the http.cookies module provided by it (which just imports the Python 2 Cookie module) doesn't handle Unicode strings. The reason for this is in the Cookie.py file provided by the Python 2 standard library:

def load(self, rawdata):
    """Load cookies from a string (presumably HTTP_COOKIE) or
    from a dictionary.  Loading cookies from a dictionary 'd'
    is equivalent to calling:
        map(Cookie.__setitem__, d.keys(), d.values())
    """
    if type(rawdata) == type(""):
        self.__ParseString(rawdata)
    else:
        # self.update() wouldn't call our custom __setitem__
        for k, v in rawdata.items():
            self[k] = v
    return

The type of "" is str, which is not equal to unicode, so it tries to parse rawdata as a dict which causes the following error:

test_responses.py:1119: in test_cookies_from_headers
    cookiejar = responses._cookies_from_headers(headers)
responses.py:122: in _cookies_from_headers
    resp_cookie.load(headers["set-cookie"])
/usr/lib/python2.7/Cookie.py:643: in load
    for k, v in rawdata.items():
E   AttributeError: 'unicode' object has no attribute 'items'

The following code can be used to reproduce this:

from __future__ import print_function, unicode_literals

try:
    import http.cookies as cookies

    print('On Python 3, using http.cookies')
    resp_cookie = cookies.SimpleCookie()
    resp_cookie.load('test=test')
    print('Success!')
except ImportError:
    print('On Python 2, using Cookies library')

Output on Python 3:

On Python 3, using http.cookies
Success!

Output on Python 2 without python-future installed:

On Python 2, using Cookies library

Output on Python 2 with python-future installed:

On Python 3, using http.cookies
Traceback (most recent call last):
  File "main.py", line 8, in <module>
    resp_cookie.load('test=test')
  File "/usr/lib/python2.7/Cookie.py", line 643, in load
    for k, v in rawdata.items():
AttributeError: 'unicode' object has no attribute 'items'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant