Skip to content

No int conversion for int-derived types available #1782

Closed
@chrysn

Description

@chrysn

Currently, it is hard to get back the integer value of a class inheriting from int, especially when overriding more and more methods. Consider this example:

class A(int):
    __repr__ = lambda self: "<A %d>"%self
    __add__ = lambda self, other: A(int(self) + other)

Both fail with "TypeError: can't convert A to int". No __int__ or __index__ methods are available; the best workaround I've found is replacing int(self) with +self or self * 1 – provided those are not overridden too.

Use cases: mainly enum-style objects, and everything that wraps semantics around an integer (playground examples are is_prime() and is_odd(), more realistic ones are is_successful() when wrapping response codes).

I've started looking into the code, and my impression is that the mp_obj_get_int function should have one more case. My initial approach was to use the mechanisms around mp_obj_class_lookup to find any native base object if it exists before failing; it turned out that if I went that way, I'd probably have to go all the way and implement a slot for it – not too friendly on RAM usage for a rarely used operation.

Looking for solutions in the other issues (sorry if I'm writing this a second time – I could swear I had attached a note about this to a duplicate bug report yesterday, but failed to find either my comment or the report I though I had found), #238 seems to provide a nice way: Treat int-conversion like a unary operator. (That's suspiciously close to the +a workaround).

Do you consider adding __int__ functionality alongside __bool__ and __len__ as MP_UNARY_OP_INT a viable solution? If so, I'd be happy to implement it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions