The pattern string from which the RE object was compiled.
+.. versionchanged:: 3.7
+ Added support of :func:`copy.copy` and :func:`copy.deepcopy`. Compiled
+ regular expression objects are considered atomic.
+
+
.. _match-objects:
Match Objects
The string passed to :meth:`~regex.match` or :meth:`~regex.search`.
+.. versionchanged:: 3.7
+ Added support of :func:`copy.copy` and :func:`copy.deepcopy`. Match objects
+ are considered atomic.
+
+
.. _re-examples:
Regular Expression Examples
# current pickle expects the _compile() reconstructor in re module
from re import _compile
+ def test_copying(self):
+ import copy
+ p = re.compile(r'(?P<int>\d+)(?:\.(?P<frac>\d*))?')
+ self.assertIs(copy.copy(p), p)
+ self.assertIs(copy.deepcopy(p), p)
+ m = p.match('12.34')
+ self.assertIs(copy.copy(m), m)
+ self.assertIs(copy.deepcopy(m), m)
+
def test_constants(self):
self.assertEqual(re.I, re.IGNORECASE)
self.assertEqual(re.L, re.LOCALE)
Library
-------
+- bpo-10076: Compiled regular expression and match objects in the re module
+ now support copy.copy() and copy.deepcopy() (they are considered atomic).
+
- bpo-30068: _io._IOBase.readlines will check if it's closed first when
hint is present.
/* defining this one enables tracing */
#undef VERBOSE
-/* -------------------------------------------------------------------- */
-/* optional features */
-
-/* enables copy/deepcopy handling (work in progress) */
-#undef USE_BUILTIN_COPY
-
/* -------------------------------------------------------------------- */
#if defined(_MSC_VER)
return result;
}
-#ifdef USE_BUILTIN_COPY
-static int
-deepcopy(PyObject** object, PyObject* memo)
-{
- PyObject* copy;
-
- if (!*object)
- return 1;
-
- copy = call(
- "copy", "deepcopy",
- PyTuple_Pack(2, *object, memo)
- );
- if (!copy)
- return 0;
-
- Py_SETREF(*object, copy);
-
- return 1; /* success */
-}
-#endif
-
/*[clinic input]
_sre.SRE_Pattern.findall
_sre_SRE_Pattern___copy___impl(PatternObject *self)
/*[clinic end generated code: output=85dedc2db1bd8694 input=a730a59d863bc9f5]*/
{
-#ifdef USE_BUILTIN_COPY
- PatternObject* copy;
- int offset;
-
- copy = PyObject_NEW_VAR(PatternObject, &Pattern_Type, self->codesize);
- if (!copy)
- return NULL;
-
- offset = offsetof(PatternObject, groups);
-
- Py_XINCREF(self->groupindex);
- Py_XINCREF(self->indexgroup);
- Py_XINCREF(self->pattern);
-
- memcpy((char*) copy + offset, (char*) self + offset,
- sizeof(PatternObject) + self->codesize * sizeof(SRE_CODE) - offset);
- copy->weakreflist = NULL;
-
- return (PyObject*) copy;
-#else
- PyErr_SetString(PyExc_TypeError, "cannot copy this pattern object");
- return NULL;
-#endif
+ Py_INCREF(self);
+ return (PyObject *)self;
}
/*[clinic input]
_sre.SRE_Pattern.__deepcopy__
memo: object
+ /
[clinic start generated code]*/
static PyObject *
-_sre_SRE_Pattern___deepcopy___impl(PatternObject *self, PyObject *memo)
-/*[clinic end generated code: output=75efe69bd12c5d7d input=3959719482c07f70]*/
+_sre_SRE_Pattern___deepcopy__(PatternObject *self, PyObject *memo)
+/*[clinic end generated code: output=2ad25679c1f1204a input=a465b1602f997bed]*/
{
-#ifdef USE_BUILTIN_COPY
- PatternObject* copy;
-
- copy = (PatternObject*) pattern_copy(self);
- if (!copy)
- return NULL;
-
- if (!deepcopy(©->groupindex, memo) ||
- !deepcopy(©->indexgroup, memo) ||
- !deepcopy(©->pattern, memo)) {
- Py_DECREF(copy);
- return NULL;
- }
-
-#else
- PyErr_SetString(PyExc_TypeError, "cannot deepcopy this pattern object");
- return NULL;
-#endif
+ Py_INCREF(self);
+ return (PyObject *)self;
}
static PyObject *
_sre_SRE_Match___copy___impl(MatchObject *self)
/*[clinic end generated code: output=a779c5fc8b5b4eb4 input=3bb4d30b6baddb5b]*/
{
-#ifdef USE_BUILTIN_COPY
- MatchObject* copy;
- Py_ssize_t slots, offset;
-
- slots = 2 * (self->pattern->groups+1);
-
- copy = PyObject_NEW_VAR(MatchObject, &Match_Type, slots);
- if (!copy)
- return NULL;
-
- /* this value a constant, but any compiler should be able to
- figure that out all by itself */
- offset = offsetof(MatchObject, string);
-
- Py_XINCREF(self->pattern);
- Py_XINCREF(self->string);
- Py_XINCREF(self->regs);
-
- memcpy((char*) copy + offset, (char*) self + offset,
- sizeof(MatchObject) + slots * sizeof(Py_ssize_t) - offset);
-
- return (PyObject*) copy;
-#else
- PyErr_SetString(PyExc_TypeError, "cannot copy this match object");
- return NULL;
-#endif
+ Py_INCREF(self);
+ return (PyObject *)self;
}
/*[clinic input]
_sre.SRE_Match.__deepcopy__
memo: object
+ /
[clinic start generated code]*/
static PyObject *
-_sre_SRE_Match___deepcopy___impl(MatchObject *self, PyObject *memo)
-/*[clinic end generated code: output=2b657578eb03f4a3 input=b65b72489eac64cc]*/
+_sre_SRE_Match___deepcopy__(MatchObject *self, PyObject *memo)
+/*[clinic end generated code: output=ba7cb46d655e4ee2 input=779d12a31c2c325e]*/
{
-#ifdef USE_BUILTIN_COPY
- MatchObject* copy;
-
- copy = (MatchObject*) match_copy(self);
- if (!copy)
- return NULL;
-
- if (!deepcopy((PyObject**) ©->pattern, memo) ||
- !deepcopy(©->string, memo) ||
- !deepcopy(©->regs, memo)) {
- Py_DECREF(copy);
- return NULL;
- }
-
-#else
- PyErr_SetString(PyExc_TypeError, "cannot deepcopy this match object");
- return NULL;
-#endif
+ Py_INCREF(self);
+ return (PyObject *)self;
}
PyDoc_STRVAR(match_doc,
}
PyDoc_STRVAR(_sre_SRE_Pattern___deepcopy____doc__,
-"__deepcopy__($self, /, memo)\n"
+"__deepcopy__($self, memo, /)\n"
"--\n"
"\n");
#define _SRE_SRE_PATTERN___DEEPCOPY___METHODDEF \
- {"__deepcopy__", (PyCFunction)_sre_SRE_Pattern___deepcopy__, METH_FASTCALL, _sre_SRE_Pattern___deepcopy____doc__},
-
-static PyObject *
-_sre_SRE_Pattern___deepcopy___impl(PatternObject *self, PyObject *memo);
-
-static PyObject *
-_sre_SRE_Pattern___deepcopy__(PatternObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
-{
- PyObject *return_value = NULL;
- static const char * const _keywords[] = {"memo", NULL};
- static _PyArg_Parser _parser = {"O:__deepcopy__", _keywords, 0};
- PyObject *memo;
-
- if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
- &memo)) {
- goto exit;
- }
- return_value = _sre_SRE_Pattern___deepcopy___impl(self, memo);
-
-exit:
- return return_value;
-}
+ {"__deepcopy__", (PyCFunction)_sre_SRE_Pattern___deepcopy__, METH_O, _sre_SRE_Pattern___deepcopy____doc__},
PyDoc_STRVAR(_sre_compile__doc__,
"compile($module, /, pattern, flags, code, groups, groupindex,\n"
}
PyDoc_STRVAR(_sre_SRE_Match___deepcopy____doc__,
-"__deepcopy__($self, /, memo)\n"
+"__deepcopy__($self, memo, /)\n"
"--\n"
"\n");
#define _SRE_SRE_MATCH___DEEPCOPY___METHODDEF \
- {"__deepcopy__", (PyCFunction)_sre_SRE_Match___deepcopy__, METH_FASTCALL, _sre_SRE_Match___deepcopy____doc__},
-
-static PyObject *
-_sre_SRE_Match___deepcopy___impl(MatchObject *self, PyObject *memo);
-
-static PyObject *
-_sre_SRE_Match___deepcopy__(MatchObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
-{
- PyObject *return_value = NULL;
- static const char * const _keywords[] = {"memo", NULL};
- static _PyArg_Parser _parser = {"O:__deepcopy__", _keywords, 0};
- PyObject *memo;
-
- if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
- &memo)) {
- goto exit;
- }
- return_value = _sre_SRE_Match___deepcopy___impl(self, memo);
-
-exit:
- return return_value;
-}
+ {"__deepcopy__", (PyCFunction)_sre_SRE_Match___deepcopy__, METH_O, _sre_SRE_Match___deepcopy____doc__},
PyDoc_STRVAR(_sre_SRE_Scanner_match__doc__,
"match($self, /)\n"
{
return _sre_SRE_Scanner_search_impl(self);
}
-/*[clinic end generated code: output=5df18da8e2dc762c input=a9049054013a1b77]*/
+/*[clinic end generated code: output=e6dab3ba8864da9e input=a9049054013a1b77]*/