From 1add719516f49aacd260c44f9dcbd6af269fdb21 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Tue, 4 May 2021 11:27:28 -0700 Subject: [PATCH 1/6] Fix inconsistent fsum vs sum and fmean vs mean (GH-25898) --- Lib/statistics.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/statistics.py b/Lib/statistics.py index 673a162b3a79fc0..edb11c868c1c879 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -882,8 +882,8 @@ def covariance(x, y, /): raise StatisticsError('covariance requires that both inputs have same number of data points') if n < 2: raise StatisticsError('covariance requires at least two data points') - xbar = mean(x) - ybar = mean(y) + xbar = fmean(x) + ybar = fmean(y) total = fsum((xi - xbar) * (yi - ybar) for xi, yi in zip(x, y)) return total / (n - 1) @@ -956,7 +956,7 @@ def linear_regression(regressor, dependent_variable, /): slope = covariance(regressor, dependent_variable) / variance(regressor) except ZeroDivisionError: raise StatisticsError('regressor is constant') - intercept = mean(dependent_variable) - slope * mean(regressor) + intercept = fmean(dependent_variable) - slope * fmean(regressor) return LinearRegression(intercept=intercept, slope=slope) From 09490298d4485e9322edc6e1e8e15eb66c586164 Mon Sep 17 00:00:00 2001 From: Jean-Abou-Samra <37271310+Jean-Abou-Samra@users.noreply.github.com> Date: Tue, 4 May 2021 21:37:39 +0200 Subject: [PATCH 2/6] Clarify rx parameter of compileall functions (#25857) --- Doc/library/compileall.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst index 5c6e68f93047537..de34664acb84ab7 100644 --- a/Doc/library/compileall.rst +++ b/Doc/library/compileall.rst @@ -166,9 +166,10 @@ Public functions If *force* is true, modules are re-compiled even if the timestamps are up to date. - If *rx* is given, its search method is called on the complete path to each + If *rx* is given, its ``search`` method is called on the complete path to each file considered for compilation, and if it returns a true value, the file - is skipped. + is skipped. This can be used to exclude files matching a regular expression, + given as a :ref:`re.Pattern ` object. If *quiet* is ``False`` or ``0`` (the default), the filenames and other information are printed to standard out. Set to ``1``, only errors are @@ -242,9 +243,10 @@ Public functions cases where the source file does not exist at the time the byte-code file is executed. - If *rx* is given, its search method is passed the full path name to the + If *rx* is given, its ``search`` method is passed the full path name to the file being compiled, and if it returns a true value, the file is not - compiled and ``True`` is returned. + compiled and ``True`` is returned. This can be used to exclude files matching + a regular expression, given as a :ref:`re.Pattern ` object. If *quiet* is ``False`` or ``0`` (the default), the filenames and other information are printed to standard out. Set to ``1``, only errors are From 355bae88822bee4de6092b63d69c5a5dad393a16 Mon Sep 17 00:00:00 2001 From: karl ding Date: Tue, 4 May 2021 13:37:13 -0700 Subject: [PATCH 3/6] bpo-40297: Fix test_socket.CANTest.testSendFrame (GH-19548) The address tuple for CAN_RAW no longer returns the address family after the introduction of CAN ISO-TP support in a30f6d45ac3. However, updating test_socket.CANTest.testSendFrame was missed as part of the change, so the test incorrectly attempts to index past the last tuple item to retrieve the address family. This removes the now-redundant check for equality against socket.AF_CAN, as the tuple will not contain the address family. --- Lib/test/test_socket.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 3c45278748a9410..828d1f3dcc67012 100755 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -224,7 +224,7 @@ class SocketCANTest(unittest.TestCase): the following commands: # modprobe vcan # ip link add dev vcan0 type vcan - # ifconfig vcan0 up + # ip link set up vcan0 """ interface = 'vcan0' bufsize = 128 @@ -2085,7 +2085,6 @@ def testSendFrame(self): cf, addr = self.s.recvfrom(self.bufsize) self.assertEqual(self.cf, cf) self.assertEqual(addr[0], self.interface) - self.assertEqual(addr[1], socket.AF_CAN) def _testSendFrame(self): self.cf = self.build_can_frame(0x00, b'\x01\x02\x03\x04\x05') From 6fdc4d37f3fdbc1bd51f841be6e5e4708a3b8798 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Tue, 4 May 2021 17:08:31 -0700 Subject: [PATCH 4/6] bpo-40521: Convert deque freelist from global vars to instance vars (GH-25906) --- Lib/test/test_deque.py | 3 +- Modules/_collectionsmodule.c | 59 +++++++++++++++++++----------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py index 93cc6ca4f44ecb5..f1a79373decda5d 100644 --- a/Lib/test/test_deque.py +++ b/Lib/test/test_deque.py @@ -740,8 +740,9 @@ class C(object): @support.cpython_only def test_sizeof(self): + MAXFREEBLOCKS = 16 BLOCKLEN = 64 - basesize = support.calcvobjsize('2P4nP') + basesize = support.calcvobjsize('2P5n%dPP' % MAXFREEBLOCKS) blocksize = struct.calcsize('P%dPP' % BLOCKLEN) self.assertEqual(object.__sizeof__(deque()), basesize) check = self.check_sizeof diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 9c8701af904ab98..79c6b5752afa2e6 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -30,6 +30,7 @@ static PyTypeObject tuplegetter_type; #define BLOCKLEN 64 #define CENTER ((BLOCKLEN - 1) / 2) +#define MAXFREEBLOCKS 16 /* Data for deque objects is stored in a doubly-linked list of fixed * length blocks. This assures that appends or pops never move any @@ -92,6 +93,8 @@ typedef struct { Py_ssize_t rightindex; /* 0 <= rightindex < BLOCKLEN */ size_t state; /* incremented whenever the indices move */ Py_ssize_t maxlen; /* maxlen is -1 for unbounded deques */ + Py_ssize_t numfreeblocks; + block *freeblocks[MAXFREEBLOCKS]; PyObject *weakreflist; } dequeobject; @@ -123,16 +126,12 @@ static PyTypeObject deque_type; added at about the same rate as old blocks are being freed. */ -#define MAXFREEBLOCKS 16 -static Py_ssize_t numfreeblocks = 0; -static block *freeblocks[MAXFREEBLOCKS]; - -static block * -newblock(void) { +static inline block * +newblock(dequeobject *deque) { block *b; - if (numfreeblocks) { - numfreeblocks--; - return freeblocks[numfreeblocks]; + if (deque->numfreeblocks) { + deque->numfreeblocks--; + return deque->freeblocks[deque->numfreeblocks]; } b = PyMem_Malloc(sizeof(block)); if (b != NULL) { @@ -142,12 +141,12 @@ newblock(void) { return NULL; } -static void -freeblock(block *b) +static inline void +freeblock(dequeobject *deque, block *b) { - if (numfreeblocks < MAXFREEBLOCKS) { - freeblocks[numfreeblocks] = b; - numfreeblocks++; + if (deque->numfreeblocks < MAXFREEBLOCKS) { + deque->freeblocks[deque->numfreeblocks] = b; + deque->numfreeblocks++; } else { PyMem_Free(b); } @@ -164,7 +163,7 @@ deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (deque == NULL) return NULL; - b = newblock(); + b = newblock(deque); if (b == NULL) { Py_DECREF(deque); return NULL; @@ -180,6 +179,7 @@ deque_new(PyTypeObject *type, PyObject *args, PyObject *kwds) deque->rightindex = CENTER; deque->state = 0; deque->maxlen = -1; + deque->numfreeblocks = 0; deque->weakreflist = NULL; return (PyObject *)deque; @@ -204,7 +204,7 @@ deque_pop(dequeobject *deque, PyObject *unused) if (Py_SIZE(deque)) { prevblock = deque->rightblock->leftlink; assert(deque->leftblock != deque->rightblock); - freeblock(deque->rightblock); + freeblock(deque, deque->rightblock); CHECK_NOT_END(prevblock); MARK_END(prevblock->rightlink); deque->rightblock = prevblock; @@ -242,7 +242,7 @@ deque_popleft(dequeobject *deque, PyObject *unused) if (Py_SIZE(deque)) { assert(deque->leftblock != deque->rightblock); prevblock = deque->leftblock->rightlink; - freeblock(deque->leftblock); + freeblock(deque, deque->leftblock); CHECK_NOT_END(prevblock); MARK_END(prevblock->leftlink); deque->leftblock = prevblock; @@ -278,7 +278,7 @@ static inline int deque_append_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) { if (deque->rightindex == BLOCKLEN - 1) { - block *b = newblock(); + block *b = newblock(deque); if (b == NULL) return -1; b->leftlink = deque->rightblock; @@ -315,7 +315,7 @@ static inline int deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) { if (deque->leftindex == 0) { - block *b = newblock(); + block *b = newblock(deque); if (b == NULL) return -1; b->rightlink = deque->leftblock; @@ -584,7 +584,7 @@ deque_clear(dequeobject *deque) adversary could cause it to never terminate). */ - b = newblock(); + b = newblock(deque); if (b == NULL) { PyErr_Clear(); goto alternate_method; @@ -623,13 +623,13 @@ deque_clear(dequeobject *deque) itemptr = leftblock->data; limit = itemptr + m; n -= m; - freeblock(prevblock); + freeblock(deque, prevblock); } item = *(itemptr++); Py_DECREF(item); } CHECK_END(leftblock->rightlink); - freeblock(leftblock); + freeblock(deque, leftblock); return 0; alternate_method: @@ -679,7 +679,7 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) deque->state++; for (i = 0 ; i < n-1 ; ) { if (deque->rightindex == BLOCKLEN - 1) { - block *b = newblock(); + block *b = newblock(deque); if (b == NULL) { Py_SET_SIZE(deque, Py_SIZE(deque) + i); return NULL; @@ -797,7 +797,7 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n) while (n > 0) { if (leftindex == 0) { if (b == NULL) { - b = newblock(); + b = newblock(deque); if (b == NULL) goto done; } @@ -841,7 +841,7 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n) while (n < 0) { if (rightindex == BLOCKLEN - 1) { if (b == NULL) { - b = newblock(); + b = newblock(deque); if (b == NULL) goto done; } @@ -885,7 +885,7 @@ _deque_rotate(dequeobject *deque, Py_ssize_t n) rv = 0; done: if (b != NULL) - freeblock(b); + freeblock(deque, b); deque->leftblock = leftblock; deque->rightblock = rightblock; deque->leftindex = leftindex; @@ -1306,16 +1306,21 @@ deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v) static void deque_dealloc(dequeobject *deque) { + Py_ssize_t i; + PyObject_GC_UnTrack(deque); if (deque->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) deque); if (deque->leftblock != NULL) { deque_clear(deque); assert(deque->leftblock != NULL); - freeblock(deque->leftblock); + freeblock(deque, deque->leftblock); } deque->leftblock = NULL; deque->rightblock = NULL; + for (i=0 ; i < deque->numfreeblocks ; i++) { + PyMem_Free(deque->freeblocks[i]); + } Py_TYPE(deque)->tp_free(deque); } From 23362f8c301f72bbf261b56e1af93e8c52f5b6cf Mon Sep 17 00:00:00 2001 From: Brad Larsen Date: Tue, 4 May 2021 23:41:11 -0400 Subject: [PATCH 5/6] Eliminate duplicated assignment in _randommodule.c (GH-25904) --- Modules/_randommodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index cae49a009cbcc8f..0137e34da650a18 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -597,7 +597,7 @@ _random_exec(PyObject *module) } /* Look up and save int.__abs__, which is needed in random_seed(). */ - PyObject *longval = longval = PyLong_FromLong(0); + PyObject *longval = PyLong_FromLong(0); if (longval == NULL) { return -1; } From 96d5c7038b06e93d20822d28ed42a2183f876857 Mon Sep 17 00:00:00 2001 From: Kevin Follstad Date: Wed, 5 May 2021 01:08:26 -0700 Subject: [PATCH 6/6] bpo-44040: Update broken link in pathlib source (GH-25905) --- Lib/pathlib.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index cf40370c049a313..94e079fffef600d 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1295,7 +1295,7 @@ def is_dir(self): if not _ignore_error(e): raise # Path doesn't exist or is a broken symlink - # (see https://bitbucket.org/pitrou/pathlib/issue/12/) + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) return False except ValueError: # Non-encodable path @@ -1312,7 +1312,7 @@ def is_file(self): if not _ignore_error(e): raise # Path doesn't exist or is a broken symlink - # (see https://bitbucket.org/pitrou/pathlib/issue/12/) + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) return False except ValueError: # Non-encodable path @@ -1363,7 +1363,7 @@ def is_block_device(self): if not _ignore_error(e): raise # Path doesn't exist or is a broken symlink - # (see https://bitbucket.org/pitrou/pathlib/issue/12/) + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) return False except ValueError: # Non-encodable path @@ -1379,7 +1379,7 @@ def is_char_device(self): if not _ignore_error(e): raise # Path doesn't exist or is a broken symlink - # (see https://bitbucket.org/pitrou/pathlib/issue/12/) + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) return False except ValueError: # Non-encodable path @@ -1395,7 +1395,7 @@ def is_fifo(self): if not _ignore_error(e): raise # Path doesn't exist or is a broken symlink - # (see https://bitbucket.org/pitrou/pathlib/issue/12/) + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) return False except ValueError: # Non-encodable path @@ -1411,7 +1411,7 @@ def is_socket(self): if not _ignore_error(e): raise # Path doesn't exist or is a broken symlink - # (see https://bitbucket.org/pitrou/pathlib/issue/12/) + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) return False except ValueError: # Non-encodable path