pypy / pypy

PyPy is a very fast and compliant implementation of the Python language.
https://pypy.org
Other
958 stars 55 forks source link

write pypy module meet "TypeError: need type object" #3389

Open gitlab-importer opened 3 years ago

gitlab-importer commented 3 years ago

In Heptapod by @LoHiaufung on Jan 30, 2021, 03:27

Hi, I am writing a msgpack in rpython, as an pypy extension.

Here is the code:

    def _pack(self, space, w_obj, nest_limit = DEFAULT_RECURSE_LIMIT):
        if nest_limit < 0:
            raise oefmt(space.w_ValueError, "recursion limit exceeded")
        # ……
        elif space.isinstance_w(w_obj, space.w_dict):
            nLen = space.len_w(w_obj)
            self._pack_map_header(space, nLen)

            w_keys = space.call_method(w_obj, 'keys')
            w_iter = space.iter(w_keys)
            while True:
                try:
                    w_key = space.next(w_iter)
                except OperationError, e:
                    if not e.match(space, space.w_StopIteration):
                        raise
                    break
                w_val = space.getitem(w_obj, w_key)

                self._pack(space, w_key, nest_limit-1)
                self._pack(space, w_val, nest_limit-1) 
        # ……

And here is the test code:

import rpy_msg_pack
def f(obj):
    return 'default'

rpy_msg_pack._set_default_pack_hook(f)
rpy_msg_pack._init_msg_packer()

pf = rpy_msg_pack._pack

print '111', str2Hex('\x80')
print '222', pf({})
assert '\x80' == pf({})

Then the code raise an exception:

Traceback (most recent call last):
  File "test_rpy_msg_pack.py", line 64, in <module>
    print '222', pf({})
TypeError: need type object

It seems that the rpython code:

space.isinstance_w(w_obj, space.w_dict)

doesn't work. I am confused, can someone help me?

gitlab-importer commented 3 years ago

In Heptapod by @mattip on Jan 31, 2021, 06:30

You need to wrap your input with space.newdict() in order to make {} into a w_obj

gitlab-importer commented 3 years ago

In Heptapod by @LoHiaufung on Feb 1, 2021, 10:54

The test code is python code. And the function _pack is rpython code. I compile all the pypy project, including the function _pack in a pypy extension library, which name 'rpy_msg_pack'.

The test code, is run by the compiled pypy interpreter. I input a python object '{}', when it runs into the rpython func _pack, it should be w_obj

So I am very confused, why the error "TypeError: need type object" is raised.