Issue #20998: Fixed re.fullmatch() of repeated single character pattern
with ignore case. Original patch by Matthew Barnett.
This commit is contained in:
parent
946cfc3e23
commit
429b59ec69
|
@ -1223,6 +1223,11 @@ class ReTests(unittest.TestCase):
|
||||||
pat.scanner(string='abracadabra', pos=3, endpos=10).search().span(),
|
pat.scanner(string='abracadabra', pos=3, endpos=10).search().span(),
|
||||||
(7, 9))
|
(7, 9))
|
||||||
|
|
||||||
|
def test_bug_20998(self):
|
||||||
|
# Issue #20998: Fullmatch of repeated single character pattern
|
||||||
|
# with ignore case.
|
||||||
|
self.assertEqual(re.fullmatch('[a-c]+', 'ABC', re.I).span(), (0, 3))
|
||||||
|
|
||||||
|
|
||||||
class PatternReprTests(unittest.TestCase):
|
class PatternReprTests(unittest.TestCase):
|
||||||
def check(self, pattern, expected):
|
def check(self, pattern, expected):
|
||||||
|
|
|
@ -23,6 +23,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #20998: Fixed re.fullmatch() of repeated single character pattern
|
||||||
|
with ignore case. Original patch by Matthew Barnett.
|
||||||
|
|
||||||
- Issue #21075: fileinput.FileInput now reads bytes from standard stream if
|
- Issue #21075: fileinput.FileInput now reads bytes from standard stream if
|
||||||
binary mode is specified. Patch by Sam Kimbrel.
|
binary mode is specified. Patch by Sam Kimbrel.
|
||||||
|
|
||||||
|
|
|
@ -505,14 +505,14 @@ pattern_dealloc(PatternObject* self)
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCAL(Py_ssize_t)
|
LOCAL(Py_ssize_t)
|
||||||
sre_match(SRE_STATE* state, SRE_CODE* pattern)
|
sre_match(SRE_STATE* state, SRE_CODE* pattern, int match_all)
|
||||||
{
|
{
|
||||||
if (state->charsize == 1)
|
if (state->charsize == 1)
|
||||||
return sre_ucs1_match(state, pattern);
|
return sre_ucs1_match(state, pattern, match_all);
|
||||||
if (state->charsize == 2)
|
if (state->charsize == 2)
|
||||||
return sre_ucs2_match(state, pattern);
|
return sre_ucs2_match(state, pattern, match_all);
|
||||||
assert(state->charsize == 4);
|
assert(state->charsize == 4);
|
||||||
return sre_ucs4_match(state, pattern);
|
return sre_ucs4_match(state, pattern, match_all);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCAL(Py_ssize_t)
|
LOCAL(Py_ssize_t)
|
||||||
|
@ -576,7 +576,7 @@ pattern_match(PatternObject *self, PyObject *args, PyObject *kwargs)
|
||||||
|
|
||||||
TRACE(("|%p|%p|MATCH\n", PatternObject_GetCode(self), state.ptr));
|
TRACE(("|%p|%p|MATCH\n", PatternObject_GetCode(self), state.ptr));
|
||||||
|
|
||||||
status = sre_match(&state, PatternObject_GetCode(self));
|
status = sre_match(&state, PatternObject_GetCode(self), 0);
|
||||||
|
|
||||||
TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
|
TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
|
@ -609,12 +609,11 @@ pattern_fullmatch(PatternObject* self, PyObject* args, PyObject* kw)
|
||||||
if (!string)
|
if (!string)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
state.match_all = 1;
|
|
||||||
state.ptr = state.start;
|
state.ptr = state.start;
|
||||||
|
|
||||||
TRACE(("|%p|%p|FULLMATCH\n", PatternObject_GetCode(self), state.ptr));
|
TRACE(("|%p|%p|FULLMATCH\n", PatternObject_GetCode(self), state.ptr));
|
||||||
|
|
||||||
status = sre_match(&state, PatternObject_GetCode(self));
|
status = sre_match(&state, PatternObject_GetCode(self), 1);
|
||||||
|
|
||||||
TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
|
TRACE(("|%p|%p|END\n", PatternObject_GetCode(self), state.ptr));
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
|
@ -2572,7 +2571,7 @@ scanner_match(ScannerObject* self, PyObject *unused)
|
||||||
|
|
||||||
state->ptr = state->start;
|
state->ptr = state->start;
|
||||||
|
|
||||||
status = sre_match(state, PatternObject_GetCode(self->pattern));
|
status = sre_match(state, PatternObject_GetCode(self->pattern), 0);
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,6 @@ typedef struct {
|
||||||
SRE_REPEAT *repeat;
|
SRE_REPEAT *repeat;
|
||||||
/* hooks */
|
/* hooks */
|
||||||
SRE_TOLOWER_HOOK lower;
|
SRE_TOLOWER_HOOK lower;
|
||||||
int match_all;
|
|
||||||
} SRE_STATE;
|
} SRE_STATE;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -173,7 +173,7 @@ SRE(charset)(SRE_CODE* set, SRE_CODE ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, SRE_CODE* pattern);
|
LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, SRE_CODE* pattern, int match_all);
|
||||||
|
|
||||||
LOCAL(Py_ssize_t)
|
LOCAL(Py_ssize_t)
|
||||||
SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount)
|
SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount)
|
||||||
|
@ -259,7 +259,7 @@ SRE(count)(SRE_STATE* state, SRE_CODE* pattern, Py_ssize_t maxcount)
|
||||||
/* repeated single character pattern */
|
/* repeated single character pattern */
|
||||||
TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
|
TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
|
||||||
while ((SRE_CHAR*) state->ptr < end) {
|
while ((SRE_CHAR*) state->ptr < end) {
|
||||||
i = SRE(match)(state, pattern);
|
i = SRE(match)(state, pattern, 0);
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
return i;
|
return i;
|
||||||
if (!i)
|
if (!i)
|
||||||
|
@ -490,7 +490,7 @@ typedef struct {
|
||||||
/* check if string matches the given pattern. returns <0 for
|
/* check if string matches the given pattern. returns <0 for
|
||||||
error, 0 for failure, and 1 for success */
|
error, 0 for failure, and 1 for success */
|
||||||
LOCAL(Py_ssize_t)
|
LOCAL(Py_ssize_t)
|
||||||
SRE(match)(SRE_STATE* state, SRE_CODE* pattern)
|
SRE(match)(SRE_STATE* state, SRE_CODE* pattern, int match_all)
|
||||||
{
|
{
|
||||||
SRE_CHAR* end = (SRE_CHAR *)state->end;
|
SRE_CHAR* end = (SRE_CHAR *)state->end;
|
||||||
Py_ssize_t alloc_pos, ctx_pos = -1;
|
Py_ssize_t alloc_pos, ctx_pos = -1;
|
||||||
|
@ -507,7 +507,7 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern)
|
||||||
ctx->last_ctx_pos = -1;
|
ctx->last_ctx_pos = -1;
|
||||||
ctx->jump = JUMP_NONE;
|
ctx->jump = JUMP_NONE;
|
||||||
ctx->pattern = pattern;
|
ctx->pattern = pattern;
|
||||||
ctx->match_all = state->match_all;
|
ctx->match_all = match_all;
|
||||||
ctx_pos = alloc_pos;
|
ctx_pos = alloc_pos;
|
||||||
|
|
||||||
entrance:
|
entrance:
|
||||||
|
@ -739,7 +739,7 @@ entrance:
|
||||||
RETURN_FAILURE;
|
RETURN_FAILURE;
|
||||||
|
|
||||||
if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS &&
|
if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS &&
|
||||||
(!ctx->match_all || ctx->ptr == state->end)) {
|
ctx->ptr == state->end) {
|
||||||
/* tail is empty. we're finished */
|
/* tail is empty. we're finished */
|
||||||
state->ptr = ctx->ptr;
|
state->ptr = ctx->ptr;
|
||||||
RETURN_SUCCESS;
|
RETURN_SUCCESS;
|
||||||
|
@ -824,7 +824,7 @@ entrance:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS &&
|
if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS &&
|
||||||
(!ctx->match_all || ctx->ptr == state->end)) {
|
(!match_all || ctx->ptr == state->end)) {
|
||||||
/* tail is empty. we're finished */
|
/* tail is empty. we're finished */
|
||||||
state->ptr = ctx->ptr;
|
state->ptr = ctx->ptr;
|
||||||
RETURN_SUCCESS;
|
RETURN_SUCCESS;
|
||||||
|
@ -1269,7 +1269,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
|
||||||
state->ptr = ptr - (prefix_len - prefix_skip - 1);
|
state->ptr = ptr - (prefix_len - prefix_skip - 1);
|
||||||
if (flags & SRE_INFO_LITERAL)
|
if (flags & SRE_INFO_LITERAL)
|
||||||
return 1; /* we got all of it */
|
return 1; /* we got all of it */
|
||||||
status = SRE(match)(state, pattern + 2*prefix_skip);
|
status = SRE(match)(state, pattern + 2*prefix_skip, 0);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
return status;
|
return status;
|
||||||
/* close but no cigar -- try again */
|
/* close but no cigar -- try again */
|
||||||
|
@ -1302,7 +1302,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
|
||||||
state->ptr = ++ptr;
|
state->ptr = ++ptr;
|
||||||
if (flags & SRE_INFO_LITERAL)
|
if (flags & SRE_INFO_LITERAL)
|
||||||
return 1; /* we got all of it */
|
return 1; /* we got all of it */
|
||||||
status = SRE(match)(state, pattern + 2);
|
status = SRE(match)(state, pattern + 2, 0);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1317,7 +1317,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
|
||||||
TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
|
TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
|
||||||
state->start = ptr;
|
state->start = ptr;
|
||||||
state->ptr = ptr;
|
state->ptr = ptr;
|
||||||
status = SRE(match)(state, pattern);
|
status = SRE(match)(state, pattern, 0);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
break;
|
break;
|
||||||
ptr++;
|
ptr++;
|
||||||
|
@ -1327,7 +1327,7 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
|
||||||
while (ptr <= end) {
|
while (ptr <= end) {
|
||||||
TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
|
TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
|
||||||
state->start = state->ptr = ptr++;
|
state->start = state->ptr = ptr++;
|
||||||
status = SRE(match)(state, pattern);
|
status = SRE(match)(state, pattern, 0);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue