betamaxpy / betamax

A VCR imitation designed only for python-requests.
https://betamax.readthedocs.io/en/latest/
Other
566 stars 62 forks source link

Update TestPreserveExactBodyBytes to include request bodies. #71

Closed bboe closed 9 years ago

bboe commented 9 years ago

Locally I'm testing with only python 2.7 and 3.4. At present, the cassette can be generated and matched fine with python 2.7. Python 3.4 cannot currently generate the cassette, nor can it match on the cassette generated by python 2.7.

TODO: Update betamax such that python 3.4 can match on the 2.7 cassette and such that 3.4 can generate the cassettes and match on it (hopefully that means all other versions will work as well).

sigmavirus24 commented 9 years ago

Weird

bboe commented 9 years ago
    def b64encode(s, altchars=None):
        """Encode a byte string using Base64.

        s is the byte string to encode.  Optional altchars must be a byte
        string of length 2 which specifies an alternative alphabet for the
        '+' and '/' characters.  This allows an application to
        e.g. generate url or filesystem safe Base64 strings.

        The encoded byte string is returned.
        """
        # Strip off the trailing newline
>       encoded = binascii.b2a_base64(s)[:-1]
E       TypeError: 'str' does not support the buffer interface

That's the py34 creation error BTW.

sigmavirus24 commented 9 years ago

So somewhere along the line we're not converting it to bytes appropriately. Hm.

bboe commented 9 years ago

It's in add_body (or maybe requests should be doing it?)

sigmavirus24 commented 9 years ago

Yep https://github.com/sigmavirus24/betamax/blob/master/betamax/cassette/util.py#L55

We probably want to do something like


    if (preserve_exact_body_bytes or
            'gzip' in r.headers.get('Content-Encoding', '')):
        if hasattr(body, 'encode'):
            body = body.encode(body_dict['encoding'] or 'utf-8')
        body_dict['base64_string'] = base64.b64encode(body).decode()
    else:
        body_dict['string'] = coerce_content(body, body_dict['encoding'])
bboe commented 9 years ago

That's exactly what I have right now, but it fails in python 2.7:

>               body = body.encode(body_dict['encoding'] or 'utf-8')
E               UnicodeDecodeError: 'ascii' codec can't decode byte 0x8b in position 1: ordinal not in range(128)

That's on the gzip and unicode tests.

What are your thoughts about only doing that encoding when in python3 (I'm not sure if that'll solve it, but it's my current thought process).

bboe commented 9 years ago

@sigmavirus24 please let me know how you feel about the latest commit. That appears to get everything working, though it feels a little hackish.

sigmavirus24 commented 9 years ago

Looking now. Sorry for the delay.

bboe commented 9 years ago

Sorry for the delay.

No apology necessary. I know how it goes.