Lenard,
Thanks a lot! :) I incorporated your fix into the baseline code, and there
just needed to be some slight modifications for the other conversion
functions, long, int, float, in addition to float and oct. I had initially
considered LONG_MAX, but I wasn't sure what it would do, and didn't know if
it would break 32 bit code. Now I know. Thanks. :) Here's an updated patch
that covers all the conversion functions.
-Tyler
On Fri, May 1, 2009 at 9:34 PM, Lenard Lindstrom <[email protected]> wrote:
> Hi,
>
> Yes, I was using the second patch which only modifies color.c. However the
> 'L's are necessary on 32 bit machines since 0xCC00CC00 can only be
> represented as a Python long. So try this patch. It keeps the "L"s but
> replaces INT_MAX with LONG_MAX, which is the proper test for a Python int
> (*).
>
> Lenard
>
> (*) ints are longs and longs are, well, something else.
>
> Tyler Laing wrote:
>
>> Are you using the second patch I provided? I had to make some
>> modifications initially to the color_test.py, which I had a feeling would
>> break on 32 bit machines. The second patch avoids modifying color_test.py,
>> and instead does not cast the results from hex and oct as longs, which was
>> adding a 'L' to the end of the result, but rather as ints every time.
>>
>> -Tyler
>>
>> On Fri, May 1, 2009 at 8:41 PM, Lenard Lindstrom <[email protected]<mailto:
>> [email protected]>> wrote:
>>
>> Hi Tyler,
>>
>> This patch breaks things for 32bit machines. Give me a few minutes
>> and I will see if I can cook something up.
>>
>> Lenard
>>
>>
>> Tyler Laing wrote:
>>
>> Rene,
>>
>> Oops, about the windows line ends. I'll make sure that doesn't
>> happen again. Sorry about that. I do have SVN write access
>> now, I just wanted to start with the patch first.
>>
>> I honestly don't know much about pygame.color, so I can't help
>> there.
>>
>> However, if we never want to return a long, then, we can change:
>>
>> /**
>> * oct(color)
>> */
>> static PyObject*
>> _color_oct (PyColor *color)
>> {
>> char buf[100];
>> unsigned long tmp = ((long)color->r << 24) +
>> ((long)color->g << 16) + ((long)color->b << 8) +
>> color->a;
>> if (tmp < INT_MAX)
>> PyOS_snprintf (buf, sizeof (buf), "0%lo", tmp);
>> else
>> PyOS_snprintf (buf, sizeof (buf), "0%loL", tmp);
>> return PyString_FromString (buf);
>> }
>>
>> to
>> static PyObject*
>> _color_oct (PyColor *color)
>> {
>> char buf[100];
>> unsigned long tmp = ((long)color->r << 24) +
>> ((long)color->g << 16) + ((long)color->b << 8) +
>> color->a;
>> if (tmp < INT_MAX)
>> PyOS_snprintf (buf, sizeof (buf), "0%lo", tmp);
>> else
>> PyOS_snprintf (buf, sizeof (buf), "0%lo", tmp);
>> return PyString_FromString (buf);
>> }
>>
>> as an example, where we remove the 'L' from the else branch.
>>
>> I've got a fixed patch.diff now, where we don't return longs,
>> and its a lot smaller, because color_test.py does not need the
>> fixes now.
>>
>> I only have one error in the tests, and that results from not
>> having the right permissions, which is solved by a simple sudo.
>>
>> -Tyler
>>
>> On Fri, May 1, 2009 at 6:59 PM, René Dudfield
>> <[email protected] <mailto:[email protected]>
>> <mailto:[email protected] <mailto:[email protected]>>> wrote:
>>
>> Cool, thanks.
>>
>> I think we can look applying this patch after Lenard has
>> merged his
>> py3k stuff back in... so we don't get any many conflicts. As I
>> noticed he's already touched the color.c.
>>
>> We shouldn't ever be returning a long I don't think. So
>> perhaps we
>> can do a conversion from python long to python int at the
>> end of the
>> functions.
>>
>> For endian checking, you can use this define...
>>
>> #if SDL_BYTEORDER == SDL_LIL_ENDIAN
>> // lil endian code here...
>> #else
>> // big endian code here...
>> #endif
>>
>> However, I'm not positive the color code *should* be endian
>> safe...
>> without using the map/unmap methods on Surface for example.
>> However I
>> think maybe it should be. We will have to study how it is
>> being used
>> at the moment... and how the old behaviour worked(as some
>> code might
>> rely on it being endian unsafe).
>>
>>
>> ps. with patches it's good to check them to make sure
>> they're only
>> for the change you made... not for other issues at the same
>> time. eg,
>> there were lots of windows end of line characters in the
>> color test
>> before, and your patch removes them.
>>
>> pps. just a note, that a request has been put in to the
>> lovely server
>> administrators at seul.org <http://seul.org>
>> <http://seul.org> for adding svn
>>
>> accounts for the all the
>> GSOC peoples. So you should get your svn account within a
>> week or so.
>>
>>
>>
>> cu,
>>
>>
>>
>>
>>
>> On Sat, May 2, 2009 at 11:42 AM, Tyler Laing
>> <[email protected] <mailto:[email protected]>
>> <mailto:[email protected] <mailto:[email protected]>>>
>>
>> wrote:
>> > Hmm, just noticed another issue. I had to make the change
>> from
>> INT_MAX to
>> > LONG_MAX because the outputs for the specific number had
>> an 'L'
>> on the end
>> > of them, where the number exceeds INT_MAX, and so a 'L' is
>> appended to the
>> > end of the outputs from oct and hex, which causes a lot of
>> fails, as when
>> > Python converts the numbers to hex/int, there is no 'L'
>> on the
>> end of that
>> > value.
>> >
>> > Basically this line:
>> >
>> > self.assertEquals (hex (c), str(hex (0xCC00CC11))
>> >
>> > fails with this message:
>> >
>> >
>>
>> ======================================================================
>> > FAIL: ColorTypeTest.test_webstyle
>> >
>>
>> ----------------------------------------------------------------------
>> > Traceback (most recent call last):
>> > File
>>
>> "/usr/lib/python2.5/site-packages/pygame/tests/color_test.py",
>> line
>> > 465, in test_webstyle
>> > self.assertEquals (hex (c), hex (0xCC00CC11))
>> > AssertionError: '0xcc00cc11L' != '0xcc00cc11'
>> >
>> > My fix, which I do not like, at all, is:
>> >
>> > self.assertEquals (str(hex (c))[:-1], str(hex (0xCC00CCFF)))
>> >
>> > I don't know if this would behave differently on a 32 bit
>> platform.
>> >
>> > Here is the patch.diff.
>> >
>> > -Tyler
>> >
>> > On Fri, May 1, 2009 at 6:23 PM, René Dudfield
>> <[email protected] <mailto:[email protected]>
>> <mailto:[email protected] <mailto:[email protected]>>> wrote:
>> >>
>> >> Hi,
>> >>
>> >> cool, nice one.
>> >>
>> >> make your change to the file/files, make sure it
>> compiles and
>> passes
>> >> the tests...
>> >>
>> >> Then run: svn diff > patch.diff
>> >>
>> >> Then send the patch to the mailing list... or upload it
>> somewhere, and
>> >> send a link to it if it's really big... or just paste
>> it into the
>> >> email if it's tiny.
>> >>
>> >> cu,
>> >>
>> >>
>> >>
>> >>
>> >> On Sat, May 2, 2009 at 11:21 AM, Tyler Laing
>> <[email protected] <mailto:[email protected]>
>> <mailto:[email protected] <mailto:[email protected]>>> wrote:
>> >> > Rene,
>> >> >
>> >> > Okay, so I've got a fix. You have to prefix color->r with
>> (long), and
>> >> > then
>> >> > for hex and oct functions, you need to change INT_MAX to
>> LONG_MAX for a
>> >> > 64
>> >> > bit platform.
>> >> >
>> >> > How do I make a patch for submission?
>> >> >
>> >> > -Tyler
>> >> >
>> >> > On Fri, May 1, 2009 at 5:33 PM, Tyler Laing
>> <[email protected] <mailto:[email protected]>
>> <mailto:[email protected] <mailto:[email protected]>>> wrote:
>> >> >>
>> >> >> Rene,
>> >> >>
>> >> >> You are right. I isolated the specific issue, and
>> here's a
>> sample .c
>> >> >> file
>> >> >> that shows the error on the 64 bit platform. When I get
>> something that
>> >> >> works
>> >> >> on the the test file, I'll try it on the actual
>> pygame code
>> and see how
>> >> >> the
>> >> >> test performs.
>> >> >>
>> >> >> -Tyler
>> >> >>
>> >> >> On Fri, May 1, 2009 at 4:30 PM, Tyler Laing
>> <[email protected] <mailto:[email protected]>
>> <mailto:[email protected] <mailto:[email protected]>>>
>>
>> >> >> wrote:
>> >> >>>
>> >> >>> I'll try that then. For reference, I am using an AMD
>> Athlon
>> 64 X2
>> >> >>> 5200+
>> >> >>> processor. What would be the proper way to make it
>> endian safe?
>> >> >>>
>> >> >>> Change the unsigned long tmp to unsigned int tmp?
>> >> >>>
>> >> >>> -Tyler
>> >> >>>
>> >> >>> On Fri, May 1, 2009 at 4:24 PM, René Dudfield
>> <[email protected] <mailto:[email protected]>
>> <mailto:[email protected] <mailto:[email protected]>>>
>>
>> >> >>> wrote:
>> >> >>>>
>> >> >>>> hi,
>> >> >>>>
>> >> >>>> there's some parts like this...
>> >> >>>>
>> >> >>>> static PyObject*
>> >> >>>> _color_float (PyColor *color)
>> >> >>>> {
>> >> >>>> unsigned long tmp = (color->r << 24) + (color->g
>> << 16) +
>> >> >>>> (color->b
>> >> >>>> << 8) +
>> >> >>>> color->a;
>> >> >>>> return PyFloat_FromDouble ((double) tmp);
>> >> >>>> }
>> >> >>>>
>> >> >>>> this code isn't endian or 64bit safe... since it is
>> using bit
>> >> >>>> shifting
>> >> >>>> for packing. On different platforms, this produces
>> different
>> >> >>>> outputs.
>> >> >>>>
>> >> >>>> I think it has to convert into the same 32bit unsigned
>> int, and then
>> >> >>>> return that.
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>>
>> >> >>>> On Sat, May 2, 2009 at 8:54 AM, Tyler Laing
>> <[email protected] <mailto:[email protected]>
>> <mailto:[email protected] <mailto:[email protected]>>>
>>
>>
>> >> >>>> wrote:
>> >> >>>> > Taking a look at color.c, I believe the bug may
>> actually
>> rest in
>> >> >>>> > the
>> >> >>>> >
>>
>> Py<type>_FromUnsignedLong/Py<type>_FromDouble/Py<type>_FromString
>> >> >>>> > functions
>> >> >>>> > provided by the Python libs. There is no logical or
>> numerical
>> >> >>>> > reason
>> >> >>>> > why,
>> >> >>>> > from the numbers we have, we would get those
>> values with
>> those
>> >> >>>> > operations.
>> >> >>>> > The tests beforehand affirm that the r, g, b, and a
>> variables all
>> >> >>>> > the
>> >> >>>> > proper
>> >> >>>> > values, it just happens to be the one step in the
>> code. I'll
>> >> >>>> > examine
>> >> >>>> > further.
>> >> >>>> >
>> >> >>>> > -Tyler
>> >> >>>> >
>> >> >>>> > On Fri, May 1, 2009 at 3:28 PM, René Dudfield
>> <[email protected] <mailto:[email protected]>
>> <mailto:[email protected] <mailto:[email protected]>>>
>>
>>
>> >> >>>> > wrote:
>> >> >>>> >>
>> >> >>>> >> hi,
>> >> >>>> >>
>> >> >>>> >> Below are the failing unittests for Color on
>> 64bit ubuntu.
>> >> >>>> >>
>> >> >>>> >>
>> >> >>>> >>
>> >> >>>> >>
>> >> >>>> >>
>> >> >>>> >>
>> >> >>>> >>
>>
>> ======================================================================
>> >> >>>> >> > FAIL: ColorTypeTest.test_float
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>>
>> ----------------------------------------------------------------------
>> >> >>>> >> > Traceback (most recent call last):
>> >> >>>> >> > File
>> >> >>>> >> >
>> "/usr/lib/python2.5/site-packages/pygame/tests/color_test.py",
>> >> >>>> >> > line
>> >> >>>> >> > 412, in test_float
>> >> >>>> >> > self.assertEquals (float (c), float
>> (0xCC00CC00))
>> >> >>>> >> > AssertionError: 1.844674407283719e+19 !=
>> 3422604288.0
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>>
>> ======================================================================
>> >> >>>> >> > FAIL: ColorTypeTest.test_hex
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>>
>> ----------------------------------------------------------------------
>> >> >>>> >> > Traceback (most recent call last):
>> >> >>>> >> > File
>> >> >>>> >> >
>> "/usr/lib/python2.5/site-packages/pygame/tests/color_test.py",
>> >> >>>> >> > line
>> >> >>>> >> > 442, in test_hex
>> >> >>>> >> > self.assertEquals (hex (c), hex (0xCC00CC00))
>> >> >>>> >> > AssertionError: '0xffffffffcc00cc00L' !=
>> '0xcc00cc00'
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>>
>> ======================================================================
>> >> >>>> >> > FAIL: ColorTypeTest.test_int
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>>
>> ----------------------------------------------------------------------
>> >> >>>> >> > Traceback (most recent call last):
>> >> >>>> >> > File
>> >> >>>> >> >
>> "/usr/lib/python2.5/site-packages/pygame/tests/color_test.py",
>> >> >>>> >> > line
>> >> >>>> >> > 494, in test_int
>> >> >>>> >> > self.assertEquals (int (c), int (0xCC00CC00))
>> >> >>>> >> > AssertionError: 18446744072837188608L !=
>> 3422604288
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>>
>> ======================================================================
>> >> >>>> >> > FAIL: ColorTypeTest.test_long
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>>
>> ----------------------------------------------------------------------
>> >> >>>> >> > Traceback (most recent call last):
>> >> >>>> >> > File
>> >> >>>> >> >
>> "/usr/lib/python2.5/site-packages/pygame/tests/color_test.py",
>> >> >>>> >> > line
>> >> >>>> >> > 511, in test_long
>> >> >>>> >> > self.assertEquals (long (c), long
>> (0xCC00CC00))
>> >> >>>> >> > AssertionError: 18446744072837188608L !=
>> 3422604288L
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>>
>> ======================================================================
>> >> >>>> >> > FAIL: ColorTypeTest.test_oct
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>>
>> ----------------------------------------------------------------------
>> >> >>>> >> > Traceback (most recent call last):
>> >> >>>> >> > File
>> >> >>>> >> >
>> "/usr/lib/python2.5/site-packages/pygame/tests/color_test.py",
>> >> >>>> >> > line
>> >> >>>> >> > 427, in test_oct
>> >> >>>> >> > self.assertEquals (oct (c), oct (0xCC00CC00))
>> >> >>>> >> > AssertionError: '01777777777771400146000L' !=
>> '031400146000'
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>>
>> ======================================================================
>> >> >>>> >> > FAIL: ColorTypeTest.test_webstyle
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> >
>>
>> ----------------------------------------------------------------------
>> >> >>>> >> > Traceback (most recent call last):
>> >> >>>> >> > File
>> >> >>>> >> >
>> "/usr/lib/python2.5/site-packages/pygame/tests/color_test.py",
>> >> >>>> >> > line
>> >> >>>> >> > 458, in test_webstyle
>> >> >>>> >> > self.assertEquals (hex (c), hex (0xCC00CC11))
>> >> >>>> >> > AssertionError: '0xffffffffcc00cc11L' !=
>> '0xcc00cc11'
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >
>>
>>
>>
>
--
Visit my blog at http://oddco.ca/zeroth/zblog
Index: src/color.c
===================================================================
--- src/color.c (revision 2051)
+++ src/color.c (working copy)
@@ -1407,7 +1407,7 @@
static PyObject*
_color_int (PyColor *color)
{
- unsigned long tmp = (color->r << 24) + (color->g << 16) + (color->b << 8) +
+ unsigned long tmp = ((unsigned long)color->r << 24) + (color->g << 16) + (color->b << 8) +
color->a;
#if !PY3
if (tmp < INT_MAX)
@@ -1422,7 +1422,7 @@
static PyObject*
_color_long (PyColor *color)
{
- unsigned long tmp = (color->r << 24) + (color->g << 16) + (color->b << 8) +
+ unsigned long tmp = ((unsigned long)color->r << 24) + (color->g << 16) + (color->b << 8) +
color->a;
return PyLong_FromUnsignedLong (tmp);
}
@@ -1433,7 +1433,7 @@
static PyObject*
_color_float (PyColor *color)
{
- unsigned long tmp = (color->r << 24) + (color->g << 16) + (color->b << 8) +
+ unsigned long tmp = ((unsigned long)color->r << 24) + (color->g << 16) + (color->b << 8) +
color->a;
return PyFloat_FromDouble ((double) tmp);
}
@@ -1446,9 +1446,9 @@
_color_oct (PyColor *color)
{
char buf[100];
- unsigned long tmp = (color->r << 24) + (color->g << 16) + (color->b << 8) +
+ unsigned long tmp = ((unsigned long)color->r << 24) + (color->g << 16) + (color->b << 8) +
color->a;
- if (tmp < INT_MAX)
+ if (tmp < LONG_MAX)
PyOS_snprintf (buf, sizeof (buf), "0%lo", tmp);
else
PyOS_snprintf (buf, sizeof (buf), "0%loL", tmp);
@@ -1462,9 +1462,9 @@
_color_hex (PyColor *color)
{
char buf[100];
- unsigned long tmp = (color->r << 24) + (color->g << 16) + (color->b << 8) +
+ unsigned long tmp = ((unsigned long)color->r << 24) + (color->g << 16) + (color->b << 8) +
color->a;
- if (tmp < INT_MAX)
+ if (tmp < LONG_MAX)
PyOS_snprintf (buf, sizeof (buf), "0x%lx", tmp);
else
{
@@ -1475,7 +1475,7 @@
PyOS_snprintf (buf, sizeof (buf), "0x%lXL", tmp);
#endif
}
- return Text_FromUTF8 (buf);
+ return PyString_FromString (buf);
}
#endif