Commit 0aee41c7 authored by Georg Brandl's avatar Georg Brandl

merge with 3.3.5 release repo

parents 0e6ec79f fbafa2f7
This diff is collapsed.
...@@ -1072,8 +1072,10 @@ handling consistency are valid for these functions. ...@@ -1072,8 +1072,10 @@ handling consistency are valid for these functions.
>>> subprocess.getstatusoutput('/bin/junk') >>> subprocess.getstatusoutput('/bin/junk')
(256, 'sh: /bin/junk: not found') (256, 'sh: /bin/junk: not found')
.. versionchanged:: 3.3 Availability: Unix & Windows
Availability: Unix & Windows
.. versionchanged:: 3.3.4
Windows support added
.. function:: getoutput(cmd) .. function:: getoutput(cmd)
...@@ -1086,8 +1088,10 @@ handling consistency are valid for these functions. ...@@ -1086,8 +1088,10 @@ handling consistency are valid for these functions.
>>> subprocess.getoutput('ls /bin/ls') >>> subprocess.getoutput('ls /bin/ls')
'/bin/ls' '/bin/ls'
.. versionchanged:: 3.3 Availability: Unix & Windows
Availability: Unix & Windows
.. versionchanged:: 3.3.4
Windows support added
Notes Notes
......
...@@ -269,9 +269,12 @@ class FileInputTests(unittest.TestCase): ...@@ -269,9 +269,12 @@ class FileInputTests(unittest.TestCase):
with FileInput(files=TESTFN, with FileInput(files=TESTFN,
openhook=hook_encoded('ascii'), bufsize=8) as fi: openhook=hook_encoded('ascii'), bufsize=8) as fi:
self.assertEqual(fi.readline(), 'A\n') try:
self.assertEqual(fi.readline(), 'B\n') self.assertEqual(fi.readline(), 'A\n')
self.assertEqual(fi.readline(), 'C\n') self.assertEqual(fi.readline(), 'B\n')
self.assertEqual(fi.readline(), 'C\n')
except UnicodeDecodeError:
self.fail('Read to end of file')
with self.assertRaises(UnicodeDecodeError): with self.assertRaises(UnicodeDecodeError):
# Read to the end of file. # Read to the end of file.
list(fi) list(fi)
...@@ -854,8 +857,8 @@ class Test_hook_encoded(unittest.TestCase): ...@@ -854,8 +857,8 @@ class Test_hook_encoded(unittest.TestCase):
self.assertFalse(kwargs) self.assertFalse(kwargs)
def test_modes(self): def test_modes(self):
# Unlikely UTF-7 is locale encoding
with open(TESTFN, 'wb') as f: with open(TESTFN, 'wb') as f:
# UTF-7 is a convenient, seldom used encoding
f.write(b'A\nB\r\nC\rD+IKw-') f.write(b'A\nB\r\nC\rD+IKw-')
self.addCleanup(safe_unlink, TESTFN) self.addCleanup(safe_unlink, TESTFN)
......
...@@ -379,6 +379,30 @@ class RangeTest(unittest.TestCase): ...@@ -379,6 +379,30 @@ class RangeTest(unittest.TestCase):
it = pickle.loads(d) it = pickle.loads(d)
self.assertEqual(list(it), data[1:]) self.assertEqual(list(it), data[1:])
def test_exhausted_iterator_pickling(self):
r = range(2**65, 2**65+2)
i = iter(r)
while True:
r = next(i)
if r == 2**65+1:
break
d = pickle.dumps(i)
i2 = pickle.loads(d)
self.assertEqual(list(i), [])
self.assertEqual(list(i2), [])
def test_large_exhausted_iterator_pickling(self):
r = range(20)
i = iter(r)
while True:
r = next(i)
if r == 19:
break
d = pickle.dumps(i)
i2 = pickle.loads(d)
self.assertEqual(list(i), [])
self.assertEqual(list(i2), [])
def test_odd_bug(self): def test_odd_bug(self):
# This used to raise a "SystemError: NULL result without error" # This used to raise a "SystemError: NULL result without error"
# because the range validation step was eating the exception # because the range validation step was eating the exception
......
...@@ -1076,6 +1076,22 @@ class ReTests(unittest.TestCase): ...@@ -1076,6 +1076,22 @@ class ReTests(unittest.TestCase):
self.assertEqual(out.getvalue().splitlines(), self.assertEqual(out.getvalue().splitlines(),
['literal 102 ', 'literal 111 ', 'literal 111 ']) ['literal 102 ', 'literal 111 ', 'literal 111 '])
def test_keyword_parameters(self):
# Issue #20283: Accepting the string keyword parameter.
pat = re.compile(r'(ab)')
self.assertEqual(
pat.match(string='abracadabra', pos=7, endpos=10).span(), (7, 9))
self.assertEqual(
pat.search(string='abracadabra', pos=3, endpos=10).span(), (7, 9))
self.assertEqual(
pat.findall(string='abracadabra', pos=3, endpos=10), ['ab'])
self.assertEqual(
pat.split(string='abracadabra', maxsplit=1),
['', 'ab', 'racadabra'])
self.assertEqual(
pat.scanner(string='abracadabra', pos=3, endpos=10).search().span(),
(7, 9))
def run_re_tests(): def run_re_tests():
from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR
......
...@@ -13,6 +13,10 @@ Core and Builtins ...@@ -13,6 +13,10 @@ Core and Builtins
Library Library
------- -------
- Issue #20283: RE pattern methods now accept the string keyword parameters
as documented. The pattern and source keyword parameters are left as
deprecated aliases.
What's New in Python 3.3.5? What's New in Python 3.3.5?
=========================== ===========================
......
...@@ -1876,18 +1876,46 @@ pattern_dealloc(PatternObject* self) ...@@ -1876,18 +1876,46 @@ pattern_dealloc(PatternObject* self)
PyObject_DEL(self); PyObject_DEL(self);
} }
static PyObject*
fix_string_param(PyObject *string, PyObject *string2, const char *oldname)
{
if (string2 != NULL) {
if (string != NULL) {
PyErr_Format(PyExc_TypeError,
"Argument given by name ('%s') and position (1)",
oldname);
return NULL;
}
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
"The '%s' keyword parameter name is deprecated. "
"Use 'string' instead.", oldname) < 0)
return NULL;
return string2;
}
if (string == NULL) {
PyErr_SetString(PyExc_TypeError,
"Required argument 'string' (pos 1) not found");
return NULL;
}
return string;
}
static PyObject* static PyObject*
pattern_match(PatternObject* self, PyObject* args, PyObject* kw) pattern_match(PatternObject* self, PyObject* args, PyObject* kw)
{ {
SRE_STATE state; SRE_STATE state;
int status; int status;
PyObject* string; PyObject *string = NULL, *string2 = NULL;
Py_ssize_t start = 0; Py_ssize_t start = 0;
Py_ssize_t end = PY_SSIZE_T_MAX; Py_ssize_t end = PY_SSIZE_T_MAX;
static char* kwlist[] = { "pattern", "pos", "endpos", NULL }; static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:match", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:match", kwlist,
&string, &start, &end)) &string, &start, &end, &string2))
return NULL;
string = fix_string_param(string, string2, "pattern");
if (!string)
return NULL; return NULL;
string = state_init(&state, self, string, start, end); string = state_init(&state, self, string, start, end);
...@@ -1919,12 +1947,16 @@ pattern_search(PatternObject* self, PyObject* args, PyObject* kw) ...@@ -1919,12 +1947,16 @@ pattern_search(PatternObject* self, PyObject* args, PyObject* kw)
SRE_STATE state; SRE_STATE state;
int status; int status;
PyObject* string; PyObject *string = NULL, *string2 = NULL;
Py_ssize_t start = 0; Py_ssize_t start = 0;
Py_ssize_t end = PY_SSIZE_T_MAX; Py_ssize_t end = PY_SSIZE_T_MAX;
static char* kwlist[] = { "pattern", "pos", "endpos", NULL }; static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:search", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:search", kwlist,
&string, &start, &end)) &string, &start, &end, &string2))
return NULL;
string = fix_string_param(string, string2, "pattern");
if (!string)
return NULL; return NULL;
string = state_init(&state, self, string, start, end); string = state_init(&state, self, string, start, end);
...@@ -2052,12 +2084,16 @@ pattern_findall(PatternObject* self, PyObject* args, PyObject* kw) ...@@ -2052,12 +2084,16 @@ pattern_findall(PatternObject* self, PyObject* args, PyObject* kw)
int status; int status;
Py_ssize_t i, b, e; Py_ssize_t i, b, e;
PyObject* string; PyObject *string = NULL, *string2 = NULL;
Py_ssize_t start = 0; Py_ssize_t start = 0;
Py_ssize_t end = PY_SSIZE_T_MAX; Py_ssize_t end = PY_SSIZE_T_MAX;
static char* kwlist[] = { "source", "pos", "endpos", NULL }; static char* kwlist[] = { "string", "pos", "endpos", "source", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:findall", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:findall", kwlist,
&string, &start, &end)) &string, &start, &end, &string2))
return NULL;
string = fix_string_param(string, string2, "source");
if (!string)
return NULL; return NULL;
string = state_init(&state, self, string, start, end); string = state_init(&state, self, string, start, end);
...@@ -2180,11 +2216,15 @@ pattern_split(PatternObject* self, PyObject* args, PyObject* kw) ...@@ -2180,11 +2216,15 @@ pattern_split(PatternObject* self, PyObject* args, PyObject* kw)
Py_ssize_t i; Py_ssize_t i;
void* last; void* last;
PyObject* string; PyObject *string = NULL, *string2 = NULL;
Py_ssize_t maxsplit = 0; Py_ssize_t maxsplit = 0;
static char* kwlist[] = { "source", "maxsplit", NULL }; static char* kwlist[] = { "string", "maxsplit", "source", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|n:split", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kw, "|On$O:split", kwlist,
&string, &maxsplit)) &string, &maxsplit, &string2))
return NULL;
string = fix_string_param(string, string2, "source");
if (!string)
return NULL; return NULL;
string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX); string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);
...@@ -3882,12 +3922,16 @@ pattern_scanner(PatternObject* pattern, PyObject* args, PyObject* kw) ...@@ -3882,12 +3922,16 @@ pattern_scanner(PatternObject* pattern, PyObject* args, PyObject* kw)
ScannerObject* self; ScannerObject* self;
PyObject* string; PyObject *string = NULL, *string2 = NULL;
Py_ssize_t start = 0; Py_ssize_t start = 0;
Py_ssize_t end = PY_SSIZE_T_MAX; Py_ssize_t end = PY_SSIZE_T_MAX;
static char* kwlist[] = { "source", "pos", "endpos", NULL }; static char* kwlist[] = { "string", "pos", "endpos", "source", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:scanner", kwlist, if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:scanner", kwlist,
&string, &start, &end)) &string, &start, &end, &string2))
return NULL;
string = fix_string_param(string, string2, "source");
if (!string)
return NULL; return NULL;
/* create scanner object */ /* create scanner object */
......
...@@ -2798,6 +2798,8 @@ arrayiter_setstate(arrayiterobject *it, PyObject *state) ...@@ -2798,6 +2798,8 @@ arrayiter_setstate(arrayiterobject *it, PyObject *state)
return NULL; return NULL;
if (index < 0) if (index < 0)
index = 0; index = 0;
else if (index > Py_SIZE(it->ao))
index = Py_SIZE(it->ao); /* iterator exhausted */
it->index = index; it->index = index;
Py_RETURN_NONE; Py_RETURN_NONE;
} }
......
...@@ -3043,9 +3043,13 @@ bytearrayiter_setstate(bytesiterobject *it, PyObject *state) ...@@ -3043,9 +3043,13 @@ bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
Py_ssize_t index = PyLong_AsSsize_t(state); Py_ssize_t index = PyLong_AsSsize_t(state);
if (index == -1 && PyErr_Occurred()) if (index == -1 && PyErr_Occurred())
return NULL; return NULL;
if (index < 0) if (it->it_seq != NULL) {
index = 0; if (index < 0)
it->it_index = index; index = 0;
else if (index > PyByteArray_GET_SIZE(it->it_seq))
index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
it->it_index = index;
}
Py_RETURN_NONE; Py_RETURN_NONE;
} }
......
...@@ -2996,9 +2996,13 @@ striter_setstate(striterobject *it, PyObject *state) ...@@ -2996,9 +2996,13 @@ striter_setstate(striterobject *it, PyObject *state)
Py_ssize_t index = PyLong_AsSsize_t(state); Py_ssize_t index = PyLong_AsSsize_t(state);
if (index == -1 && PyErr_Occurred()) if (index == -1 && PyErr_Occurred())
return NULL; return NULL;
if (index < 0) if (it->it_seq != NULL) {
index = 0; if (index < 0)
it->it_index = index; index = 0;
else if (index > PyBytes_GET_SIZE(it->it_seq))
index = PyBytes_GET_SIZE(it->it_seq); /* iterator exhausted */
it->it_index = index;
}
Py_RETURN_NONE; Py_RETURN_NONE;
} }
......
...@@ -2803,6 +2803,8 @@ listiter_setstate(listiterobject *it, PyObject *state) ...@@ -2803,6 +2803,8 @@ listiter_setstate(listiterobject *it, PyObject *state)
if (it->it_seq != NULL) { if (it->it_seq != NULL) {
if (index < 0) if (index < 0)
index = 0; index = 0;
else if (index > PyList_GET_SIZE(it->it_seq))
index = PyList_GET_SIZE(it->it_seq); /* iterator exhausted */
it->it_index = index; it->it_index = index;
} }
Py_RETURN_NONE; Py_RETURN_NONE;
......
...@@ -1000,10 +1000,11 @@ rangeiter_setstate(rangeiterobject *r, PyObject *state) ...@@ -1000,10 +1000,11 @@ rangeiter_setstate(rangeiterobject *r, PyObject *state)
long index = PyLong_AsLong(state); long index = PyLong_AsLong(state);
if (index == -1 && PyErr_Occurred()) if (index == -1 && PyErr_Occurred())
return NULL; return NULL;
if (index < 0 || index >= r->len) { /* silently clip the index value */
PyErr_SetString(PyExc_ValueError, "index out of range"); if (index < 0)
return NULL; index = 0;
} else if (index > r->len)
index = r->len; /* exhausted iterator */
r->index = index; r->index = index;
Py_RETURN_NONE; Py_RETURN_NONE;
} }
...@@ -1178,6 +1179,28 @@ longrangeiter_reduce(longrangeiterobject *r) ...@@ -1178,6 +1179,28 @@ longrangeiter_reduce(longrangeiterobject *r)
static PyObject * static PyObject *
longrangeiter_setstate(longrangeiterobject *r, PyObject *state) longrangeiter_setstate(longrangeiterobject *r, PyObject *state)
{ {
int cmp;
/* clip the value */
PyObject *zero = PyLong_FromLong(0);
if (zero == NULL)
return NULL;
cmp = PyObject_RichCompareBool(state, zero, Py_LT);
if (cmp > 0) {
Py_CLEAR(r->index);
r->index = zero;
Py_RETURN_NONE;
}
Py_DECREF(zero);
if (cmp < 0)
return NULL;
cmp = PyObject_RichCompareBool(r->len, state, Py_LT);
if (cmp < 0)
return NULL;
if (cmp > 0)
state = r->len;
Py_CLEAR(r->index); Py_CLEAR(r->index);
r->index = state; r->index = state;
Py_INCREF(r->index); Py_INCREF(r->index);
......
...@@ -998,8 +998,8 @@ tupleiter_setstate(tupleiterobject *it, PyObject *state) ...@@ -998,8 +998,8 @@ tupleiter_setstate(tupleiterobject *it, PyObject *state)
if (it->it_seq != NULL) { if (it->it_seq != NULL) {
if (index < 0) if (index < 0)
index = 0; index = 0;
else if (it->it_seq != NULL && index > PyTuple_GET_SIZE(it->it_seq)) else if (index > PyTuple_GET_SIZE(it->it_seq))
index = PyTuple_GET_SIZE(it->it_seq); index = PyTuple_GET_SIZE(it->it_seq); /* exhausted iterator */
it->it_index = index; it->it_index = index;
} }
Py_RETURN_NONE; Py_RETURN_NONE;
......
...@@ -14420,9 +14420,13 @@ unicodeiter_setstate(unicodeiterobject *it, PyObject *state) ...@@ -14420,9 +14420,13 @@ unicodeiter_setstate(unicodeiterobject *it, PyObject *state)
Py_ssize_t index = PyLong_AsSsize_t(state); Py_ssize_t index = PyLong_AsSsize_t(state);
if (index == -1 && PyErr_Occurred()) if (index == -1 && PyErr_Occurred())
return NULL; return NULL;
if (index < 0) if (it->it_seq != NULL) {
index = 0; if (index < 0)
it->it_index = index; index = 0;
else if (index > PyUnicode_GET_LENGTH(it->it_seq))
index = PyUnicode_GET_LENGTH(it->it_seq); /* iterator truncated */
it->it_index = index;
}
Py_RETURN_NONE; Py_RETURN_NONE;
} }
......
...@@ -240,6 +240,11 @@ ...@@ -240,6 +240,11 @@
<ItemGroup> <ItemGroup>
<ResourceCompile Include="..\PC\pylauncher.rc" /> <ResourceCompile Include="..\PC\pylauncher.rc" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="make_versioninfo.vcxproj">
<Project>{f0e0541e-f17d-430b-97c4-93adf0dd284e}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
......
...@@ -125,6 +125,6 @@ def touch(ui, repo, basedir): ...@@ -125,6 +125,6 @@ def touch(ui, repo, basedir):
cmdtable = { cmdtable = {
"touch": (touch, "touch": (touch,
[('b', 'basedir', '', 'base dir of the tree to apply touching', 'BASEDIR')], [('b', 'basedir', '', 'base dir of the tree to apply touching')],
"hg touch [-b BASEDIR]") "hg touch [-b BASEDIR]")
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment