| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -201,6 +201,49 @@ def __dict__(self): | |||
| 201 | 201 | with self.assertRaises(ZeroDivisionError): | |
| 202 | 202 | WorseStruct().__setstate__({}, b'foo') | |
| 203 | 203 | ||
| 204 | + def test_parameter_repr(self): | ||
| 205 | + from ctypes import ( | ||
| 206 | + c_bool, | ||
| 207 | + c_char, | ||
| 208 | + c_wchar, | ||
| 209 | + c_byte, | ||
| 210 | + c_ubyte, | ||
| 211 | + c_short, | ||
| 212 | + c_ushort, | ||
| 213 | + c_int, | ||
| 214 | + c_uint, | ||
| 215 | + c_long, | ||
| 216 | + c_ulong, | ||
| 217 | + c_longlong, | ||
| 218 | + c_ulonglong, | ||
| 219 | + c_float, | ||
| 220 | + c_double, | ||
| 221 | + c_longdouble, | ||
| 222 | + c_char_p, | ||
| 223 | + c_wchar_p, | ||
| 224 | + c_void_p, | ||
| 225 | + ) | ||
| 226 | + self.assertRegex(repr(c_bool.from_param(True)), r"^<cparam '\?' at 0x[A-Fa-f0-9]+>$") | ||
| 227 | + self.assertEqual(repr(c_char.from_param(97)), "<cparam 'c' ('a')>") | ||
| 228 | + self.assertRegex(repr(c_wchar.from_param('a')), r"^<cparam 'u' at 0x[A-Fa-f0-9]+>$") | ||
| 229 | + self.assertEqual(repr(c_byte.from_param(98)), "<cparam 'b' (98)>") | ||
| 230 | + self.assertEqual(repr(c_ubyte.from_param(98)), "<cparam 'B' (98)>") | ||
| 231 | + self.assertEqual(repr(c_short.from_param(511)), "<cparam 'h' (511)>") | ||
| 232 | + self.assertEqual(repr(c_ushort.from_param(511)), "<cparam 'H' (511)>") | ||
| 233 | + self.assertRegex(repr(c_int.from_param(20000)), r"^<cparam '[li]' \(20000\)>$") | ||
| 234 | + self.assertRegex(repr(c_uint.from_param(20000)), r"^<cparam '[LI]' \(20000\)>$") | ||
| 235 | + self.assertRegex(repr(c_long.from_param(20000)), r"^<cparam '[li]' \(20000\)>$") | ||
| 236 | + self.assertRegex(repr(c_ulong.from_param(20000)), r"^<cparam '[LI]' \(20000\)>$") | ||
| 237 | + self.assertRegex(repr(c_longlong.from_param(20000)), r"^<cparam '[liq]' \(20000\)>$") | ||
| 238 | + self.assertRegex(repr(c_ulonglong.from_param(20000)), r"^<cparam '[LIQ]' \(20000\)>$") | ||
| 239 | + self.assertEqual(repr(c_float.from_param(1.5)), "<cparam 'f' (1.5)>") | ||
| 240 | + self.assertEqual(repr(c_double.from_param(1.5)), "<cparam 'd' (1.5)>") | ||
| 241 | + self.assertEqual(repr(c_double.from_param(1e300)), "<cparam 'd' (1e+300)>") | ||
| 242 | + self.assertRegex(repr(c_longdouble.from_param(1.5)), r"^<cparam ('d' \(1.5\)|'g' at 0x[A-Fa-f0-9]+)>$") | ||
| 243 | + self.assertRegex(repr(c_char_p.from_param(b'hihi')), "^<cparam 'z' \(0x[A-Fa-f0-9]+\)>$") | ||
| 244 | + self.assertRegex(repr(c_wchar_p.from_param('hihi')), "^<cparam 'Z' \(0x[A-Fa-f0-9]+\)>$") | ||
| 245 | + self.assertRegex(repr(c_void_p.from_param(0x12)), r"^<cparam 'P' \(0x0*12\)>$") | ||
| 246 | + | ||
| 204 | 247 | ################################################################ | |
| 205 | 248 | ||
| 206 | 249 | if __name__ == '__main__': | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Avoid static buffers when computing the repr of :class:`ctypes.c_double` and | ||
| 2 | + :class:`ctypes.c_longdouble` values. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -487,58 +487,47 @@ is_literal_char(unsigned char c) | |||
| 487 | 487 | static PyObject * | |
| 488 | 488 | PyCArg_repr(PyCArgObject *self) | |
| 489 | 489 | { | |
| 490 | - char buffer[256]; | ||
| 491 | 490 | switch(self->tag) { | |
| 492 | 491 | case 'b': | |
| 493 | 492 | case 'B': | |
| 494 | - sprintf(buffer, "<cparam '%c' (%d)>", | ||
| 493 | + return PyUnicode_FromFormat("<cparam '%c' (%d)>", | ||
| 495 | 494 | self->tag, self->value.b); | |
| 496 | - break; | ||
| 497 | 495 | case 'h': | |
| 498 | 496 | case 'H': | |
| 499 | - sprintf(buffer, "<cparam '%c' (%d)>", | ||
| 497 | + return PyUnicode_FromFormat("<cparam '%c' (%d)>", | ||
| 500 | 498 | self->tag, self->value.h); | |
| 501 | - break; | ||
| 502 | 499 | case 'i': | |
| 503 | 500 | case 'I': | |
| 504 | - sprintf(buffer, "<cparam '%c' (%d)>", | ||
| 501 | + return PyUnicode_FromFormat("<cparam '%c' (%d)>", | ||
| 505 | 502 | self->tag, self->value.i); | |
| 506 | - break; | ||
| 507 | 503 | case 'l': | |
| 508 | 504 | case 'L': | |
| 509 | - sprintf(buffer, "<cparam '%c' (%ld)>", | ||
| 505 | + return PyUnicode_FromFormat("<cparam '%c' (%ld)>", | ||
| 510 | 506 | self->tag, self->value.l); | |
| 511 | - break; | ||
| 512 | 507 | ||
| 513 | 508 | case 'q': | |
| 514 | 509 | case 'Q': | |
| 515 | - sprintf(buffer, | ||
| 516 | - #ifdef MS_WIN32 | ||
| 517 | - "<cparam '%c' (%I64d)>", | ||
| 518 | - #else | ||
| 519 | - "<cparam '%c' (%lld)>", | ||
| 520 | - #endif | ||
| 510 | + return PyUnicode_FromFormat("<cparam '%c' (%lld)>", | ||
| 521 | 511 | self->tag, self->value.q); | |
| 522 | - break; | ||
| 523 | 512 | case 'd': | |
| 524 | - sprintf(buffer, "<cparam '%c' (%f)>", | ||
| 525 | - self->tag, self->value.d); | ||
| 526 | - break; | ||
| 527 | - case 'f': | ||
| 528 | - sprintf(buffer, "<cparam '%c' (%f)>", | ||
| 529 | - self->tag, self->value.f); | ||
| 530 | - break; | ||
| 531 | - | ||
| 513 | + case 'f': { | ||
| 514 | + PyObject *f = PyFloat_FromDouble((self->tag == 'f') ? self->value.f : self->value.d); | ||
| 515 | + if (f == NULL) { | ||
| 516 | + return NULL; | ||
| 517 | + } | ||
| 518 | + PyObject *result = PyUnicode_FromFormat("<cparam '%c' (%R)>", self->tag, f); | ||
| 519 | + Py_DECREF(f); | ||
| 520 | + return result; | ||
| 521 | + } | ||
| 532 | 522 | case 'c': | |
| 533 | 523 | if (is_literal_char((unsigned char)self->value.c)) { | |
| 534 | - sprintf(buffer, "<cparam '%c' ('%c')>", | ||
| 524 | + return PyUnicode_FromFormat("<cparam '%c' ('%c')>", | ||
| 535 | 525 | self->tag, self->value.c); | |
| 536 | 526 | } | |
| 537 | 527 | else { | |
| 538 | - sprintf(buffer, "<cparam '%c' ('\\x%02x')>", | ||
| 528 | + return PyUnicode_FromFormat("<cparam '%c' ('\\x%02x')>", | ||
| 539 | 529 | self->tag, (unsigned char)self->value.c); | |
| 540 | 530 | } | |
| 541 | - break; | ||
| 542 | 531 | ||
| 543 | 532 | /* Hm, are these 'z' and 'Z' codes useful at all? | |
| 544 | 533 | Shouldn't they be replaced by the functionality of c_string | |
@@ -547,22 +536,20 @@ PyCArg_repr(PyCArgObject *self) | |||
| 547 | 536 | case 'z': | |
| 548 | 537 | case 'Z': | |
| 549 | 538 | case 'P': | |
| 550 | - sprintf(buffer, "<cparam '%c' (%p)>", | ||
| 539 | + return PyUnicode_FromFormat("<cparam '%c' (%p)>", | ||
| 551 | 540 | self->tag, self->value.p); | |
| 552 | 541 | break; | |
| 553 | 542 | ||
| 554 | 543 | default: | |
| 555 | 544 | if (is_literal_char((unsigned char)self->tag)) { | |
| 556 | - sprintf(buffer, "<cparam '%c' at %p>", | ||
| 545 | + return PyUnicode_FromFormat("<cparam '%c' at %p>", | ||
| 557 | 546 | (unsigned char)self->tag, (void *)self); | |
| 558 | 547 | } | |
| 559 | 548 | else { | |
| 560 | - sprintf(buffer, "<cparam 0x%02x at %p>", | ||
| 549 | + return PyUnicode_FromFormat("<cparam 0x%02x at %p>", | ||
| 561 | 550 | (unsigned char)self->tag, (void *)self); | |
| 562 | 551 | } | |
| 563 | - break; | ||
| 564 | 552 | } | |
| 565 | - return PyUnicode_FromString(buffer); | ||
| 566 | 553 | } | |
| 567 | 554 | ||
| 568 | 555 | static PyMemberDef PyCArgType_members[] = { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments