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

Issue with aiohttp + vcr: multidict 4.7.0 might be an issue #497

Closed
sudodoki opened this issue Dec 11, 2019 · 11 comments
Closed

Issue with aiohttp + vcr: multidict 4.7.0 might be an issue #497

sudodoki opened this issue Dec 11, 2019 · 11 comments

Comments

@sudodoki
Copy link

sudodoki commented Dec 11, 2019

Hello. Thanks for this awesome tool.
On dec 11, 2019, multidict released a new version and it seemed to break our CI setup. We are using aiohttp (3.6.2) + vcrpy (2.0.1) on Python 3
Freezing multidict==4.6.1 seemed to fix the issue. And even though it might be something related to changes in aiohttp, just leaving it here in case anyone else runs into this.

@sudodoki
Copy link
Author

If I get time (which I might not) gonna open a corresponding issue in aiohttp. Closing this, as it's probably not directly a vcr issue

@sudodoki
Copy link
Author

For SEO related purposes, I was getting
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host ... which was expected as host was a nonexistent one, but meant that requests were bypassing vcr and trying to go straight for upstream

@neozenith
Copy link
Collaborator

Thanks for reporting and documenting this issue.

@vEpiphyte
Copy link

@sudodoki @neozenith This was a regression in multidict which should be fixed soon.

aio-libs/multidict#418

@sudodoki
Copy link
Author

Seems that 4.7.1 was released and issue might be fixed, but not sure, how to handle that in library's dependencies to avoid accidentally getting the one that doesn't work

@neozenith
Copy link
Collaborator

neozenith commented Dec 12, 2019

We can put in our setup.py some multidict!=x.y.z specifiers.

https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-dependencies

Just need to know which versions or a range we should avoid.

@sudodoki
Copy link
Author

sudodoki commented Dec 12, 2019

4.6.1 worked ok, 4.7.0 (following version) - didn't work, 4.7.1 (newer one, supposedly, the one fixing the regression) didn't work for me as well (I didn't rewrite the cassettes though).
I use match_on=["method", "path", "query"] in my VCR constructor, not sure, whether there is any logiс in regards to comparing multidicts or something like this.

@vEpiphyte
Copy link

@sudodoki Can you document how your service is breaking with the updated multidict? I'm seeing successful tests using aiothttp + 4.7.1.

@sudodoki
Copy link
Author

@vEpiphyte Yeah, I can try, but it might be the issue with me updating multidict only and using it with older aiohttp

@vEpiphyte
Copy link

vEpiphyte commented Dec 17, 2019

@sudodoki I reproduced an issue issue when working with a project that had some older cassettes which had yaml pyobject hinting in them (vcrpy 1.13 and multidict 4.7.1). Ultimately the deserializer code was hiding the following exception:

code: https://github.com/kevin1024/vcrpy/blob/master/vcr/serialize.py#L40

    try:
        data = serializer.deserialize(cassette_string)
    # Old cassettes used to use yaml object thingy so I have to
    # check for some fairly stupid exceptions here
    except (ImportError, yaml.constructor.ConstructorError):
        _warn_about_old_cassette_format()   <---------------------- Hides the exception
    if _looks_like_an_old_cassette(data):
        _warn_about_old_cassette_format()

I encountered the following exception:

Traceback (most recent call last):
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/constructor.py", line 532, in find_python_name
    __import__(module_name)
ModuleNotFoundError: No module named 'multidict._istr'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/vcr/serialize.py", line 36, in deserialize
    data = serializer.deserialize(cassette_string)
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/vcr/serializers/yamlserializer.py", line 11, in deserialize
    return yaml.load(cassette_string, Loader=Loader)
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/__init__.py", line 114, in load
    return loader.get_single_	data()
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/constructor.py", line 43, in get_single_data
    return self.construct_document(node)
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/constructor.py", line 52, in construct_document
    for dummy in generator:
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/constructor.py", line 404, in construct_yaml_map
    value = self.construct_mapping(node)
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/constructor.py", line 210, in construct_mapping
    return super().construct_mapping(node, deep=deep)
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/constructor.py", line 131, in construct_mapping
    key = self.construct_object(key_node, deep=deep)
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/constructor.py", line 94, in construct_object
    data = constructor(self, tag_suffix, node)
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/constructor.py", line 635, in construct_python_object_new
    return self.construct_python_object_apply(suffix, node, newobj=True)
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/constructor.py", line 624, in construct_python_object_apply
    instance = self.make_python_instance(suffix, node, args, kwds, newobj)
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/constructor.py", line 715, in make_python_instance
    suffix, node, args, kwds, newobj, unsafe=True)
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/constructor.py", line 566, in make_python_instance
    cls = self.find_python_name(suffix, node.start_mark)
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/constructor.py", line 711, in find_python_name
    return super(UnsafeConstructor, self).find_python_name(name, mark, unsafe=True)
  File "/home/user/.pyenv/versions/3.7.3/envs/someproject373/lib/python3.7/site-packages/yaml/constructor.py", line 535, in find_python_name
    "cannot find module %r (%s)" % (module_name, exc), mark)
yaml.constructor.ConstructorError: while constructing a Python object
cannot find module 'multidict._istr' (No module named 'multidict._istr')
  in "<unicode string>", line 48, column 9

This causes deserialization failures and subsequently the cassette appears empty and vcrpy has no content to replay. This can result in a existing cassette being overwritten. Reverting to multidict 4.6.1 works.

Going to try re-recording the cassettes with a newer version of VCRPy to see if this issues persists or is just an artifact of the yaml serialization including the pyobject reference.

@vEpiphyte
Copy link

Using VCRPY 3.0.0 and multidict 4.7.1 works fine. The object serialization was fixed in the 2.1.x branch due to #454 .

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

3 participants