| 382 | } |
| 383 | |
| 384 | static PyObject* |
| 385 | pyrational_new(PyTypeObject* type, PyObject* args, PyObject* kwds) { |
| 386 | Py_ssize_t size; |
| 387 | PyObject* x[2]; |
| 388 | long n[2]={0,1}; |
| 389 | int i; |
| 390 | rational r; |
| 391 | if (kwds && PyDict_Size(kwds)) { |
| 392 | PyErr_SetString(PyExc_TypeError, |
| 393 | "constructor takes no keyword arguments"); |
| 394 | return 0; |
| 395 | } |
| 396 | size = PyTuple_GET_SIZE(args); |
| 397 | if (size > 2) { |
| 398 | PyErr_SetString(PyExc_TypeError, |
| 399 | "expected rational or numerator and optional denominator"); |
| 400 | return 0; |
| 401 | } |
| 402 | |
| 403 | if (size == 1) { |
| 404 | x[0] = PyTuple_GET_ITEM(args, 0); |
| 405 | if (PyRational_Check(x[0])) { |
| 406 | Py_INCREF(x[0]); |
| 407 | return x[0]; |
| 408 | } |
| 409 | // TODO: allow construction from unicode strings |
| 410 | else if (PyBytes_Check(x[0])) { |
| 411 | const char* s = PyBytes_AS_STRING(x[0]); |
| 412 | rational x; |
| 413 | if (scan_rational(&s,&x)) { |
| 414 | const char* p; |
| 415 | for (p = s; *p; p++) { |
| 416 | if (!isspace(*p)) { |
| 417 | goto bad; |
| 418 | } |
| 419 | } |
| 420 | return PyRational_FromRational(x); |
| 421 | } |
| 422 | bad: |
| 423 | PyErr_Format(PyExc_ValueError, |
| 424 | "invalid rational literal '%s'",s); |
| 425 | return 0; |
| 426 | } |
| 427 | } |
| 428 | |
| 429 | for (i=0; i<size; i++) { |
| 430 | PyObject* y; |
| 431 | int eq; |
| 432 | x[i] = PyTuple_GET_ITEM(args, i); |
| 433 | n[i] = PyLong_AsLong(x[i]); |
| 434 | if (error_converting(n[i])) { |
| 435 | if (PyErr_ExceptionMatches(PyExc_TypeError)) { |
| 436 | PyErr_Format(PyExc_TypeError, |
| 437 | "expected integer %s, got %s", |
| 438 | (i ? "denominator" : "numerator"), |
| 439 | x[i]->ob_type->tp_name); |
| 440 | } |
| 441 | return 0; |
nothing calls this directly
no test coverage detected