diff -r 2bb806539ca6 Doc/library/re.rst --- a/Doc/library/re.rst Sat Jun 04 20:53:38 2016 -0700 +++ b/Doc/library/re.rst Sun Jun 05 00:32:26 2016 -0700 @@ -926,6 +926,17 @@ The pattern string from which the RE object was compiled. +.. attribute:: regex.__pattern_code__ + + The compiled code of the regex pattern as a tuple of integers. + + .. impl-detail:: + + This attribute is not guaranteed to exist in all implementations of + Python. The code returned is an implementation detail that may change + without warning between CPython versions. + + .. _match-objects: Match Objects diff -r 2bb806539ca6 Lib/test/test_re.py --- a/Lib/test/test_re.py Sat Jun 04 20:53:38 2016 -0700 +++ b/Lib/test/test_re.py Sun Jun 05 00:32:26 2016 -0700 @@ -587,6 +587,16 @@ p.groupindex['other'] = 0 self.assertEqual(p.groupindex['other'], 2) + @cpython_only + def test_code(self): + pattern = re.compile('foo') + # contents are implementation-defined + pattern_code = pattern.__pattern_code__ + self.assertIsInstance(pattern_code, tuple) + for code in pattern_code: + self.assertIsInstance( + code, int, msg='bad entry in pattern code {}'.format(pattern_code)) + def test_special_escapes(self): self.assertEqual(re.search(r"\b(b.)\b", "abcd abc bcd bx").group(1), "bx") diff -r 2bb806539ca6 Modules/_sre.c --- a/Modules/_sre.c Sat Jun 04 20:53:38 2016 -0700 +++ b/Modules/_sre.c Sun Jun 05 00:32:26 2016 -0700 @@ -1429,13 +1429,36 @@ PyDoc_STRVAR(pattern_doc, "Compiled regular expression objects"); -/* PatternObject's 'groupindex' method. */ +/* PatternObject's 'groupindex' attribute. */ static PyObject * pattern_groupindex(PatternObject *self) { return PyDictProxy_New(self->groupindex); } +/* PatternObject's '__pattern_code__' attribute. */ +static PyObject * +pattern_code(PatternObject *self) +{ + PyObject *lst, *entry; + const Py_ssize_t codesize = self->codesize; + Py_ssize_t i; + + lst = PyTuple_New(self->codesize); + if (lst == NULL) { + return NULL; + } + for (i = 0; i < codesize; i++) { + entry = PyLong_FromUnsignedLong(self->code[i]); + if (entry == NULL) { + Py_DECREF(lst); + return NULL; + } + PyTuple_SET_ITEM(lst, i, entry); + } + return lst; +} + static int _validate(PatternObject *self); /* Forward */ /*[clinic input] @@ -2671,6 +2694,8 @@ static PyGetSetDef pattern_getset[] = { {"groupindex", (getter)pattern_groupindex, (setter)NULL, "A dictionary mapping group names to group numbers."}, + {"__pattern_code__", (getter)pattern_code, (setter)NULL, + "The pattern's code."}, {NULL} /* Sentinel */ };