@@ -358,46 +358,86 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
358
358
359
359
Copy the Python integer value to a native *buffer* of size *n_bytes*::
360
360
361
- int value;
362
- Py_ssize_t bytes = PyLong_AsNativeBytes(v , &value, sizeof (value), -1 );
361
+ int32_t value;
362
+ Py_ssize_t bytes = PyLong_AsNativeBits(pylong , &value, sizeof (value), -1 );
363
363
if (bytes < 0 ) {
364
- // Error occurred
364
+ // A Python exception was set with the reason.
365
365
return NULL;
366
366
}
367
367
else if (bytes <= (Py_ssize_t)sizeof (value)) {
368
368
// Success!
369
369
}
370
370
else {
371
- // Overflow occurred, but 'value' contains truncated value
371
+ // Overflow occurred, but 'value' contains the truncated
372
+ // lowest bits of pylong.
372
373
}
373
374
375
+ The above example may look *similar * to
376
+ :c:func: `PyLong_As* <PyLong_AsSize_t> `
377
+ but instead fills in a specific caller defined type and never raises an
378
+ error about of the :class: `int ` *pylong *'s value regardless of *n_bytes *
379
+ or the returned byte count.
380
+
381
+ To get at the entire potentially big Python value, this can be used to
382
+ reserve enough space and copy it::
383
+
384
+ // Ask how much space we need.
385
+ Py_ssize_t expected = PyLong_AsNativeBits(pylong, NULL, 0, -1);
386
+ if (expected < 0) {
387
+ // A Python exception was set with the reason.
388
+ return NULL;
389
+ }
390
+ assert(expected != 0); // Impossible per the API definition.
391
+ uint8_t *bignum = malloc(expected);
392
+ if (!bignum) {
393
+ PyErr_SetString(PyExc_MemoryError, "bignum malloc failed.");
394
+ return NULL;
395
+ }
396
+ // Safely get the entire value.
397
+ Py_ssize_t bytes = PyLong_AsNativeBits(pylong, bignum, expected, -1);
398
+ if (bytes < 0) { // Exception set.
399
+ free(bignum);
400
+ return NULL;
401
+ }
402
+ else if (bytes > expected) { // Be safe, should not be possible.
403
+ PyErr_SetString(PyExc_RuntimeError,
404
+ "Unexpected bignum truncation after a size check.");
405
+ free(bignum);
406
+ return NULL;
407
+ }
408
+ // The expected success given the above pre-check.
409
+ // ... use bignum ...
410
+ free(bignum);
411
+
374
412
*endianness * may be passed ``-1 `` for the native endian that CPython was
375
413
compiled with, or ``0 `` for big endian and ``1 `` for little.
376
414
377
- Return ``-1 `` with an exception raised if *pylong * cannot be interpreted as
415
+ Returns ``-1 `` with an exception raised if *pylong * cannot be interpreted as
378
416
an integer. Otherwise, return the size of the buffer required to store the
379
417
value. If this is equal to or less than *n_bytes *, the entire value was
380
- copied.
418
+ copied. `` 0 `` will never be returned.
381
419
382
- Unless an exception is raised, all *n_bytes * of the buffer will be written
383
- with as much of the value as can fit. This allows the caller to ignore all
384
- non-negative results if the intent is to match the typical behavior of a
385
- C-style downcast. No exception is set for this case.
420
+ Unless an exception is raised, all *n_bytes * of the buffer will always be
421
+ written. In the case of truncation, as many of the lowest bits of the value
422
+ as could fit are written. This allows the caller to ignore all non-negative
423
+ results if the intent is to match the typical behavior of a C-style
424
+ downcast. No exception is set on truncation.
386
425
387
- Values are always copied as two's-complement, and sufficient buffer will be
426
+ Values are always copied as two's-complement and sufficient buffer will be
388
427
requested to include a sign bit. For example, this may cause an value that
389
428
fits into 8 bytes when treated as unsigned to request 9 bytes, even though
390
429
all eight bytes were copied into the buffer. What has been omitted is the
391
- zero sign bit, which is redundant when the intention is to treat the value as
392
- unsigned.
430
+ zero sign bit -- redundant if the caller's intention is to treat the value
431
+ as unsigned.
393
432
394
- Passing zero to *n_bytes * will return the requested buffer size.
433
+ Passing zero to *n_bytes * will return the size of a buffer that would
434
+ be large enough to hold the value. This may be larger than technically
435
+ necessary, but not unreasonably so.
395
436
396
437
.. note ::
397
438
398
- When the value does not fit in the provided buffer, the requested size
399
- returned from the function may be larger than necessary. Passing 0 to this
400
- function is not an accurate way to determine the bit length of a value.
439
+ Passing *n_bytes=0 * to this function is not an accurate way to determine
440
+ the bit length of a value.
401
441
402
442
.. versionadded :: 3.13
403
443
0 commit comments