Implements issue #9951: Adds a hex() method to bytes, bytearray, & me… · pythoncapi/cpython@8cb6569 · GitHub
Skip to content

Commit 8cb6569

Browse files
committed
Implements issue python#9951: Adds a hex() method to bytes, bytearray, & memoryview.
Also updates a few internal implementations of the same thing to use the new built-in code. Contributed by Arnon Yaari.
1 parent 644adc6 commit 8cb6569

15 files changed

Lines changed: 112 additions & 64 deletions

Doc/library/stdtypes.rst

Lines changed: 37 additions & 0 deletions

Doc/whatsnew/3.5.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ New built-in features:
8080

8181
* ``bytes % args``, ``bytearray % args``: :pep:`461` - Adding ``%`` formatting
8282
to bytes and bytearray
83+
* ``b'\xf0\x9f\x90\x8d'.hex()``, ``bytearray(b'\xf0\x9f\x90\x8d').hex()``,
84+
``memoryview(b'\xf0\x9f\x90\x8d').hex()``: :issue:`9951` - A ``hex`` method
85+
has been added to bytes, bytearray, and memoryview.
8386

8487
Implementation improvements:
8588

Lib/test/test_bytes.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,14 @@ def test_fromhex(self):
301301
self.assertRaises(ValueError, self.type2test.fromhex, '\x00')
302302
self.assertRaises(ValueError, self.type2test.fromhex, '12 \x00 34')
303303

304+
def test_hex(self):
305+
self.assertRaises(TypeError, self.type2test.hex)
306+
self.assertRaises(TypeError, self.type2test.hex, 1)
307+
self.assertEquals(self.type2test(b"").hex(), "")
308+
self.assertEquals(bytearray([0x1a, 0x2b, 0x30]).hex(), '1a2b30')
309+
self.assertEquals(self.type2test(b"\x1a\x2b\x30").hex(), '1a2b30')
310+
self.assertEquals(memoryview(b"\x1a\x2b\x30").hex(), '1a2b30')
311+
304312
def test_join(self):
305313
self.assertEqual(self.type2test(b"").join([]), b"")
306314
self.assertEqual(self.type2test(b"").join([b""]), b"")

Lib/test/test_doctest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ def non_Python_modules(): r"""
659659
660660
>>> import builtins
661661
>>> tests = doctest.DocTestFinder().find(builtins)
662-
>>> 790 < len(tests) < 800 # approximate number of objects with docstrings
662+
>>> 790 < len(tests) < 810 # approximate number of objects with docstrings
663663
True
664664
>>> real_tests = [t for t in tests if len(t.examples) > 0]
665665
>>> len(real_tests) # objects that actually have doctests

Makefile.pre.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ PYTHON_OBJS= \
402402
Python/getopt.o \
403403
Python/pystrcmp.o \
404404
Python/pystrtod.o \
405+
Python/pystrhex.o \
405406
Python/dtoa.o \
406407
Python/formatter_unicode.o \
407408
Python/fileutils.o \
@@ -919,6 +920,7 @@ PYTHON_HEADERS= \
919920
$(srcdir)/Include/pystate.h \
920921
$(srcdir)/Include/pystrcmp.h \
921922
$(srcdir)/Include/pystrtod.h \
923+
$(srcdir)/Include/pystrhex.h \
922924
$(srcdir)/Include/pythonrun.h \
923925
$(srcdir)/Include/pythread.h \
924926
$(srcdir)/Include/pytime.h \

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,6 +1547,7 @@ Doug Wyatt
15471547
Robert Xiao
15481548
Florent Xicluna
15491549
Hirokazu Yamamoto
1550+
Arnon Yaari
15501551
Ka-Ping Yee
15511552
Jason Yeo
15521553
EungJun Yi

Misc/NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Core and Builtins
1111
-----------------
1212

1313
- Issue #24022: Fix tokenizer crash when processing undecodable source code.
14+
- Issue #9951: Added a hex() method to bytes, bytearray, and memoryview.
1415

1516
Library
1617
-------

Modules/sha1module.c

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "Python.h"
2020
#include "hashlib.h"
21+
#include "pystrhex.h"
2122

2223
/*[clinic input]
2324
module _sha1
@@ -364,32 +365,12 @@ SHA1Type_hexdigest_impl(SHA1object *self)
364365
{
365366
unsigned char digest[SHA1_DIGESTSIZE];
366367
struct sha1_state temp;
367-
PyObject *retval;
368-
Py_UCS1 *hex_digest;
369-
int i, j;
370368

371369
/* Get the raw (binary) digest value */
372370
temp = self->hash_state;
373371
sha1_done(&temp, digest);
374372

375-
/* Create a new string */
376-
retval = PyUnicode_New(SHA1_DIGESTSIZE * 2, 127);
377-
if (!retval)
378-
return NULL;
379-
hex_digest = PyUnicode_1BYTE_DATA(retval);
380-
381-
/* Make hex version of the digest */
382-
for(i=j=0; i<SHA1_DIGESTSIZE; i++) {
383-
unsigned char c;
384-
c = (digest[i] >> 4) & 0xf;
385-
hex_digest[j++] = Py_hexdigits[c];
386-
c = (digest[i] & 0xf);
387-
hex_digest[j++] = Py_hexdigits[c];
388-
}
389-
#ifdef Py_DEBUG
390-
assert(_PyUnicode_CheckConsistency(retval, 1));
391-
#endif
392-
return retval;
373+
return _Py_strhex((const char *)digest, SHA1_DIGESTSIZE);
393374
}
394375

395376
/*[clinic input]

Modules/sha256module.c

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "Python.h"
2020
#include "structmember.h"
2121
#include "hashlib.h"
22+
#include "pystrhex.h"
2223

2324
/*[clinic input]
2425
module _sha256
@@ -454,32 +455,12 @@ SHA256Type_hexdigest_impl(SHAobject *self)
454455
{
455456
unsigned char digest[SHA_DIGESTSIZE];
456457
SHAobject temp;
457-
PyObject *retval;
458-
Py_UCS1 *hex_digest;
459-
int i, j;
460458

461459
/* Get the raw (binary) digest value */
462460
SHAcopy(self, &temp);
463461
sha_final(digest, &temp);
464462

465-
/* Create a new string */
466-
retval = PyUnicode_New(self->digestsize * 2, 127);
467-
if (!retval)
468-
return NULL;
469-
hex_digest = PyUnicode_1BYTE_DATA(retval);
470-
471-
/* Make hex version of the digest */
472-
for(i=j=0; i<self->digestsize; i++) {
473-
unsigned char c;
474-
c = (digest[i] >> 4) & 0xf;
475-
hex_digest[j++] = Py_hexdigits[c];
476-
c = (digest[i] & 0xf);
477-
hex_digest[j++] = Py_hexdigits[c];
478-
}
479-
#ifdef Py_DEBUG
480-
assert(_PyUnicode_CheckConsistency(retval, 1));
481-
#endif
482-
return retval;
463+
return _Py_strhex((const char *)digest, self->digestsize);
483464
}
484465

485466
/*[clinic input]

Modules/sha512module.c

Lines changed: 2 additions & 21 deletions

0 commit comments

Comments
 (0)