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

OverflowError: Python int too large to convert to C long #339

Closed
hgc2002 opened this issue Jun 19, 2018 · 4 comments
Closed

OverflowError: Python int too large to convert to C long #339

hgc2002 opened this issue Jun 19, 2018 · 4 comments

Comments

@hgc2002
Copy link

hgc2002 commented Jun 19, 2018

This error happening just importing the av library (on Python 3.4.3), not even starting using it.

File "av/enums.pyx", line 145, in av.enums.EnumItem.cinit

The full trace:

File "/usr/local/lib/python3.4/dist-packages/av/__init__.py", line 15, in <module>
    from av.audio.fifo import AudioFifo
  File "/usr/local/lib/python3.4/dist-packages/av/audio/__init__.py", line 1, in <module>
    from .frame import AudioFrame
  File "av/audio/frame.pyx", line 1, in init av.audio.frame
  File "av/codec/codec.pxd", line 6, in init av.frame
  File "/usr/local/lib/python3.4/dist-packages/av/codec/__init__.py", line 1, in <module>
    from .codec import Codec, codecs_available, codec_descriptor
  File "av/descriptor.pxd", line 4, in init av.codec.codec
  File "av/option.pxd", line 4, in init av.descriptor
  File "av/option.pyx", line 18, in init av.option
  File "av/enums.pyx", line 225, in av.enums.define_enum
  File "av/enums.pyx", line 28, in av.enums.EnumType._init
  File "av/enums.pyx", line 32, in av.enums.EnumType._create
  File "av/enums.pyx", line 145, in av.enums.EnumItem.__cinit__
OverflowError: Python int too large to convert to C long

Here is where the trace points to:

cdef class EnumItem(object):

    cdef readonly str name
    cdef readonly long value #int
    cdef long _hash

    def __cinit__(self, sentinel_, name, value):

        if sentinel_ is not sentinel:
            raise RuntimeError("Cannot instantiate {}.".format(self.__class__.__name__))
        self.name = name
        self.value = value

        # Establish a hash that doesn't collide with anything that would return
        # true from __eq__.
        hash_ = id(self)
        name_hash = hash(name)
        value_hash = hash(value)
        while hash_ == name_hash or hash_ == value_hash:
            hash_ += 1
        self._hash = hash_ # <--- here is where the trace points to !!!

I've tried lot of things but nothing goes. Any idea?
Thanks!

@hgc2002
Copy link
Author

hgc2002 commented Jun 19, 2018

More info: i'm using FFmpeg 4.0 and PyAv compiled (both) directly on local.
PyAv comes directly from Github, version 0.4.1

@Kamekameha
Copy link

Kamekameha commented Jun 19, 2018

I don't know about the size of long in this case but maybe EnumItem._hash should be cdef-ed as Py_ssize_t? At least that's what CPython typedefs Py_hash_t as, Py_hash_t being the return type of the PyTypeObject.tp_hash slot, and considering this hash value is computed from the object's address.

@mikeboers
Copy link
Member

That sounds very reasonable.

@mikeboers
Copy link
Member

Thanks @hgc2002 @Kamekameha and @tshirtman for the dicussion and PRs.

I've typed _hash as Py_hash_t, and also simplified the calculation so that it starts at value + 1. Then it only needs to compare once against the hash of name, and we know it will be unique. Everything is cdef-ed, so it will all be the right size and wrap around if it needs to.

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