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

TypeError: unhashable type: 'dict' #125

Closed
Kyria opened this issue Jun 7, 2017 · 5 comments
Closed

TypeError: unhashable type: 'dict' #125

Kyria opened this issue Jun 7, 2017 · 5 comments
Labels
Milestone

Comments

@Kyria
Copy link

Kyria commented Jun 7, 2017

Hello,

I use pyswagger 0.8.29 and python 2.7.

You have this error unless you specify raw_body_only=True in the Response object before you do the request.
This is also the swagger UI doc link : https://esi.tech.ccp.is/latest/#!/Mail/get_characters_character_id_mail if you need / want it.

Feel free to ask for any additional information that may help you.

Thanks !

Used code:

from pyswagger import App
from pyswagger.contrib.client.requests import Client

app = App.create('https://esi.tech.ccp.is/latest/swagger.json')
# esisecurity is a security object that works the same of the pyswagger one
# but set Bearer header instead of just basic
client = Client(esisecurity)

# create error
op = app.op['get_characters_character_id_mail'](character_id=961633431)
mails = client.request(op)

# works
op = app.op['get_characters_character_id_mail'](character_id=961633431)
op[1].raw_body_only=True
mails = client.request(op)

Stacktrace

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/contrib/client/requests.py", line 74, in request
    raw=six.BytesIO(rs.content).getvalue()
  File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/io.py", line 410, in apply_with
    self.__data = r.schema._prim_(data, self.__op._prim_factory, ctx=dict(read=True))
  File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/spec/v2_0/objects.py", line 92, in _prim_
    return prim_factory.produce(self, v, ctx)
  File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/primitives/__init__.py", line 182, in produce
    val = _2nd(obj, ret, val, ctx)
  File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/primitives/comm.py", line 40, in _2nd_pass_obj
    return ret.apply_with(obj, val, ctx)
  File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/primitives/_array.py", line 37, in apply_with
    self.extend(map(functools.partial(ctx['factory'].produce, obj.items), val))
  File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/primitives/__init__.py", line 182, in produce
    val = _2nd(obj, ret, val, ctx)
  File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/primitives/comm.py", line 40, in _2nd_pass_obj
    return ret.apply_with(obj, val, ctx)
  File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/primitives/_model.py", line 29, in apply_with
    self[k] = ctx['factory'].produce(pobj, v)
  File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/primitives/__init__.py", line 182, in produce
    val = _2nd(obj, ret, val, ctx)
  File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/primitives/comm.py", line 40, in _2nd_pass_obj
    return ret.apply_with(obj, val, ctx)
  File "/home/Kyria/dev/LazyBlacksmith/env/local/lib/python2.7/site-packages/pyswagger/primitives/_array.py", line 34, in apply_with
    val = set(val) if obj.uniqueItems else val
TypeError: unhashable type: 'dict'

Actual result from the swagger API [truncated because it's too long. If you need the full response, just tell me]

[
  {
    "mail_id": 366067184,
    "subject": "contact",
    "from": 2112809481,
    "timestamp": "2017-05-18T18:09:00Z",
    "labels": [
      1
    ],
    "recipients": [
      {
        "recipient_type": "character",
        "recipient_id": 961633431
      }
    ],
    "is_read": true
  },
  {
    "mail_id": 366066710,
    "subject": "blabla",
    "from": 961633431,
    "timestamp": "2017-05-18T17:39:00Z",
    "labels": [
      2
    ],
    "recipients": [
      {
        "recipient_type": "character",
        "recipient_id": 1107830848
      }
    ],
    "is_read": true
  },
  {
    "mail_id": 365825451,
    "subject": "another blabla",
    "from": 961633431,
    "timestamp": "2017-05-03T12:12:00Z",
    "labels": [
      2
    ],
    "recipients": [
      {
        "recipient_type": "character",
        "recipient_id": 2112712954
      }
    ],
    "is_read": true
  }
]
@mission-liao
Copy link
Member

@Kyria I'll look into this issue after work (12 hours from now), thanks for reporting

@mission-liao
Copy link
Member

@Kyria The problem is this line:

val = set(val) if obj.uniqueItems else val

and in your swagger.json:

{
    "mail_id": 366066710,
    "subject": "blabla",
    "from": 961633431,
    "timestamp": "2017-05-18T17:39:00Z",
    "labels": [
      2
    ],
    "recipients": [    // <- you prefer uniqueItem on an Object
      {
        "recipient_type": "character",
        "recipient_id": 1107830848
      }
    ],
    "is_read": true
  },

pyswagger didn't handle this case well, as you can see, using set to assure uniqueness only work for simple primitives, not for array, object.

This can be fixed (in next release).

My suggestion is, if the uniqueness is just for descriptive purpose, you can turn it to false to make this part work temporarily.

@mission-liao mission-liao added this to the v0.8.30 milestone Jun 8, 2017
@Kyria
Copy link
Author

Kyria commented Jun 8, 2017

As I don't have any rights on the swagger.json description, i'll just wait for that change :) (I'm just a user of this swagger endpoint actually).

It's not a blocking problem, since I can use raw_body_only=True as stated in the first message.

thanks!

@mission-liao
Copy link
Member

@Kyria this issue is fixed with these consideration:

  • the comparison of dict is never easy in every language, I just pick the easiest way to fix it
  • it seems that pyswagger should provide an option to allow users to turn on/off these additional behavior (ex. remove duplicated item when uniqueItem == True)

thanks for reporting issue anyway, I'll provide a release later.

@mission-liao
Copy link
Member

This issue is fixed should already be fixed in latest build: 0.8.30

mission-liao added a commit to pyopenapi/pyopenapi that referenced this issue Aug 12, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants