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.
>>> subprocess.getstatusoutput('/bin/junk')
(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)
......@@ -1086,8 +1088,10 @@ handling consistency are valid for these functions.
>>> subprocess.getoutput('ls /bin/ls')
'/bin/ls'
.. versionchanged:: 3.3
Availability: Unix & Windows
Availability: Unix & Windows
.. versionchanged:: 3.3.4
Windows support added
Notes
......
......@@ -269,9 +269,12 @@ class FileInputTests(unittest.TestCase):
with FileInput(files=TESTFN,
openhook=hook_encoded('ascii'), bufsize=8) as fi:
self.assertEqual(fi.readline(), 'A\n')
self.assertEqual(fi.readline(), 'B\n')
self.assertEqual(fi.readline(), 'C\n')
try:
self.assertEqual(fi.readline(), 'A\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):
# Read to the end of file.
list(fi)
......@@ -854,8 +857,8 @@ class Test_hook_encoded(unittest.TestCase):
self.assertFalse(kwargs)
def test_modes(self):
# Unlikely UTF-7 is locale encoding
with open(TESTFN, 'wb') as f:
# UTF-7 is a convenient, seldom used encoding
f.write(b'A\nB\r\nC\rD+IKw-')
self.addCleanup(safe_unlink, TESTFN)
......
......@@ -379,6 +379,30 @@ class RangeTest(unittest.TestCase):
it = pickle.loads(d)
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):
# This used to raise a "SystemError: NULL result without error"
# because the range validation step was eating the exception
......
......@@ -1076,6 +1076,22 @@ class ReTests(unittest.TestCase):
self.assertEqual(out.getvalue().splitlines(),
['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():
from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR
......
......@@ -13,6 +13,10 @@ Core and Builtins
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?
===========================
......
......@@ -1876,18 +1876,46 @@ pattern_dealloc(PatternObject* 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*
pattern_match(PatternObject* self, PyObject* args, PyObject* kw)
{
SRE_STATE state;
int status;
PyObject* string;
PyObject *string = NULL, *string2 = NULL;
Py_ssize_t start = 0;
Py_ssize_t end = PY_SSIZE_T_MAX;
static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:match", kwlist,
&string, &start, &end))
static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:match", kwlist,
&string, &start, &end, &string2))
return NULL;
string = fix_string_param(string, string2, "pattern");
if (!string)
return NULL;
string = state_init(&state, self, string, start, end);
......@@ -1919,12 +1947,16 @@ pattern_search(PatternObject* self, PyObject* args, PyObject* kw)
SRE_STATE state;
int status;
PyObject* string;
PyObject *string = NULL, *string2 = NULL;
Py_ssize_t start = 0;
Py_ssize_t end = PY_SSIZE_T_MAX;
static char* kwlist[] = { "pattern", "pos", "endpos", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:search", kwlist,
&string, &start, &end))
static char* kwlist[] = { "string", "pos", "endpos", "pattern", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:search", kwlist,
&string, &start, &end, &string2))
return NULL;
string = fix_string_param(string, string2, "pattern");
if (!string)
return NULL;
string = state_init(&state, self, string, start, end);
......@@ -2052,12 +2084,16 @@ pattern_findall(PatternObject* self, PyObject* args, PyObject* kw)
int status;
Py_ssize_t i, b, e;
PyObject* string;
PyObject *string = NULL, *string2 = NULL;
Py_ssize_t start = 0;
Py_ssize_t end = PY_SSIZE_T_MAX;
static char* kwlist[] = { "source", "pos", "endpos", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:findall", kwlist,
&string, &start, &end))
static char* kwlist[] = { "string", "pos", "endpos", "source", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:findall", kwlist,
&string, &start, &end, &string2))
return NULL;
string = fix_string_param(string, string2, "source");
if (!string)
return NULL;
string = state_init(&state, self, string, start, end);
......@@ -2180,11 +2216,15 @@ pattern_split(PatternObject* self, PyObject* args, PyObject* kw)
Py_ssize_t i;
void* last;
PyObject* string;
PyObject *string = NULL, *string2 = NULL;
Py_ssize_t maxsplit = 0;
static char* kwlist[] = { "source", "maxsplit", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|n:split", kwlist,
&string, &maxsplit))
static char* kwlist[] = { "string", "maxsplit", "source", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "|On$O:split", kwlist,
&string, &maxsplit, &string2))
return NULL;
string = fix_string_param(string, string2, "source");
if (!string)
return NULL;
string = state_init(&state, self, string, 0, PY_SSIZE_T_MAX);
......@@ -3882,12 +3922,16 @@ pattern_scanner(PatternObject* pattern, PyObject* args, PyObject* kw)
ScannerObject* self;
PyObject* string;
PyObject *string = NULL, *string2 = NULL;
Py_ssize_t start = 0;
Py_ssize_t end = PY_SSIZE_T_MAX;
static char* kwlist[] = { "source", "pos", "endpos", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "O|nn:scanner", kwlist,
&string, &start, &end))
static char* kwlist[] = { "string", "pos", "endpos", "source", NULL };
if (!PyArg_ParseTupleAndKeywords(args, kw, "|Onn$O:scanner", kwlist,
&string, &start, &end, &string2))
return NULL;
string = fix_string_param(string, string2, "source");
if (!string)
return NULL;
/* create scanner object */
......
......@@ -2798,6 +2798,8 @@ arrayiter_setstate(arrayiterobject *it, PyObject *state)
return NULL;
if (index < 0)
index = 0;
else if (index > Py_SIZE(it->ao))
index = Py_SIZE(it->ao); /* iterator exhausted */
it->index = index;
Py_RETURN_NONE;
}
......
......@@ -3043,9 +3043,13 @@ bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
Py_ssize_t index = PyLong_AsSsize_t(state);
if (index == -1 && PyErr_Occurred())
return NULL;
if (index < 0)
index = 0;
it->it_index = index;
if (it->it_seq != NULL) {
if (index < 0)
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;
}
......
......@@ -2996,9 +2996,13 @@ striter_setstate(striterobject *it, PyObject *state)
Py_ssize_t index = PyLong_AsSsize_t(state);
if (index == -1 && PyErr_Occurred())
return NULL;
if (index < 0)
index = 0;
it->it_index = index;
if (it->it_seq != NULL) {
if (index < 0)
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;
}
......
......@@ -2803,6 +2803,8 @@ listiter_setstate(listiterobject *it, PyObject *state)
if (it->it_seq != NULL) {
if (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;
}
Py_RETURN_NONE;
......
......@@ -1000,10 +1000,11 @@ rangeiter_setstate(rangeiterobject *r, PyObject *state)
long index = PyLong_AsLong(state);
if (index == -1 && PyErr_Occurred())
return NULL;
if (index < 0 || index >= r->len) {
PyErr_SetString(PyExc_ValueError, "index out of range");
return NULL;
}
/* silently clip the index value */
if (index < 0)
index = 0;
else if (index > r->len)
index = r->len; /* exhausted iterator */
r->index = index;
Py_RETURN_NONE;
}
......@@ -1178,6 +1179,28 @@ longrangeiter_reduce(longrangeiterobject *r)
static PyObject *
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);
r->index = state;
Py_INCREF(r->index);
......
......@@ -998,8 +998,8 @@ tupleiter_setstate(tupleiterobject *it, PyObject *state)
if (it->it_seq != NULL) {
if (index < 0)
index = 0;
else if (it->it_seq != NULL && index > PyTuple_GET_SIZE(it->it_seq))
index = PyTuple_GET_SIZE(it->it_seq);
else if (index > PyTuple_GET_SIZE(it->it_seq))
index = PyTuple_GET_SIZE(it->it_seq); /* exhausted iterator */
it->it_index = index;
}
Py_RETURN_NONE;
......
......@@ -14420,9 +14420,13 @@ unicodeiter_setstate(unicodeiterobject *it, PyObject *state)
Py_ssize_t index = PyLong_AsSsize_t(state);
if (index == -1 && PyErr_Occurred())
return NULL;
if (index < 0)
index = 0;
it->it_index = index;
if (it->it_seq != NULL) {
if (index < 0)
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;
}
......
......@@ -240,6 +240,11 @@
<ItemGroup>
<ResourceCompile Include="..\PC\pylauncher.rc" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="make_versioninfo.vcxproj">
<Project>{f0e0541e-f17d-430b-97c4-93adf0dd284e}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
......
......@@ -125,6 +125,6 @@ def touch(ui, repo, basedir):
cmdtable = {
"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]")
}
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