IntColumn raises TypeError on assignment of an mpz

Bug #702933 reported by Robert Collins
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Storm
New
Undecided
Unassigned

Bug Description

this occurs if using gmpy - e.g.
tableinstance.intcolumn = pow(mpz(9),mpz(10))

We ran into this when conch installed a __builtin__.pow() that casts into mpz.

I think it would be reasonable for intcolumn to catch TypeError and for mpz objects cast to int.

description: updated
Revision history for this message
James Henstridge (jamesh) wrote :

So, the problem code is in IntVariable:

   def parse_set(self, value, from_db):
        if not isinstance(value, (int, long, float, Decimal)):
            raise TypeError("Expected int, found %r: %r"
                            % (type(value), value))
        return int(value)

The intent of this code is to only accept "number" type values, rather than anything that has an __int__ that succeeds. For instance, we want the following to raise an error:

    foo.int_column = '42'

I'm not sure of what the best course of action is. I don't think we want to be checking for every possible number-like type that has ever been created individually.

Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote : Re: [Bug 702933] Re: IntColumn raises TypeError on assignment of an mpz

On Wed, 26 Jan 2011 21:45:49 -0000, James Henstridge <email address hidden> wrote:
> So, the problem code is in IntVariable:
>
> def parse_set(self, value, from_db):
> if not isinstance(value, (int, long, float, Decimal)):
> raise TypeError("Expected int, found %r: %r"
> % (type(value), value))
> return int(value)
>
> The intent of this code is to only accept "number" type values, rather
> than anything that has an __int__ that succeeds.

Strings don't have __int__s:

>>> 'a'.__int__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute '__int__'

Rather the conversion is done by code in int.__new__ (effectively, at
least).

> For instance, we want the following to raise an error:
>
> foo.int_column = '42'
>
> I'm not sure of what the best course of action is. I don't think we
> want to be checking for every possible number-like type that has ever
> been created individually.

I think checking for __int__ is OK, something like:

try:
    int_conv = value.__int__
except AttributeError:
    raise TypeError(...)
else:
    return int_conv()

Checking for a number type is one of those things that's frustratingly
much easier in C than in Python!

Cheers,
mwh

Revision history for this message
James Henstridge (jamesh) wrote :

I had forgotten the detail over where the string->integer conversion occurred, but I was pretty sure that was the reason for the check.

Checking for __int__ looks like a good replacement. Does it handle the case you are interested in?

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.