Skip to content

Commit e15c087

Browse files
author
Erlend E. Aasland
committed
Sync with main bco. pythongh-79097
2 parents 8708b34 + f33e2c8 commit e15c087

26 files changed

Lines changed: 799 additions & 28 deletions
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Example taken from https://www.sqlite.org/windowfunctions.html#udfwinfunc
2+
import sqlite3
3+
4+
5+
class WindowSumInt:
6+
def __init__(self):
7+
self.count = 0
8+
9+
def step(self, value):
10+
"""Adds a row to the current window."""
11+
self.count += value
12+
13+
def value(self):
14+
"""Returns the current value of the aggregate."""
15+
return self.count
16+
17+
def inverse(self, value):
18+
"""Removes a row from the current window."""
19+
self.count -= value
20+
21+
def finalize(self):
22+
"""Returns the final value of the aggregate.
23+
24+
Any clean-up actions should be placed here.
25+
"""
26+
return self.count
27+
28+
29+
con = sqlite3.connect(":memory:")
30+
cur = con.execute("create table test(x, y)")
31+
values = [
32+
("a", 4),
33+
("b", 5),
34+
("c", 3),
35+
("d", 8),
36+
("e", 1),
37+
]
38+
cur.executemany("insert into test values(?, ?)", values)
39+
con.create_window_function("sumint", 1, WindowSumInt)
40+
cur.execute("""
41+
select x, sumint(y) over (
42+
order by x rows between 1 preceding and 1 following
43+
) as sum_y
44+
from test order by x
45+
""")
46+
print(cur.fetchall())

‎Doc/library/shutil.rst‎

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,9 +230,8 @@ Directory and files operations
230230
dirs_exist_ok=False)
231231

232232
Recursively copy an entire directory tree rooted at *src* to a directory
233-
named *dst* and return the destination directory. *dirs_exist_ok* dictates
234-
whether to raise an exception in case *dst* or any missing parent directory
235-
already exists.
233+
named *dst* and return the destination directory. All intermediate
234+
directories needed to contain *dst* will also be created by default.
236235

237236
Permissions and times of directories are copied with :func:`copystat`,
238237
individual files are copied using :func:`~shutil.copy2`.
@@ -263,8 +262,14 @@ Directory and files operations
263262

264263
If *copy_function* is given, it must be a callable that will be used to copy
265264
each file. It will be called with the source path and the destination path
266-
  as arguments. By default, :func:`~shutil.copy2` is used, but any function
267-
  that supports the same signature (like :func:`~shutil.copy`) can be used.
265+
as arguments. By default, :func:`~shutil.copy2` is used, but any function
266+
that supports the same signature (like :func:`~shutil.copy`) can be used.
267+
268+
If *dirs_exist_ok* is false (the default) and *dst* already exists, a
269+
:exc:`FileExistsError` is raised. If *dirs_exist_ok* is true, the copying
270+
operation will continue if it encounters existing directories, and files
271+
within the *dst* tree will be overwritten by corresponding files from the
272+
*src* tree.
268273

269274
.. audit-event:: shutil.copytree src,dst shutil.copytree
270275

@@ -275,7 +280,7 @@ Directory and files operations
275280
.. versionchanged:: 3.2
276281
Added the *copy_function* argument to be able to provide a custom copy
277282
function.
278-
Added the *ignore_dangling_symlinks* argument to silent dangling symlinks
283+
Added the *ignore_dangling_symlinks* argument to silence dangling symlinks
279284
errors when *symlinks* is false.
280285

281286
.. versionchanged:: 3.8

‎Doc/library/sqlite3.rst‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,35 @@ Connection Objects
487487
.. literalinclude:: ../includes/sqlite3/mysumaggr.py
488488

489489

490+
.. method:: create_window_function(name, num_params, aggregate_class, /)
491+
492+
Creates user-defined aggregate window function *name*.
493+
494+
*aggregate_class* must implement the following methods:
495+
496+
* ``step``: adds a row to the current window
497+
* ``value``: returns the current value of the aggregate
498+
* ``inverse``: removes a row from the current window
499+
* ``finalize``: returns the final value of the aggregate
500+
501+
``step`` and ``value`` accept *num_params* number of parameters,
502+
unless *num_params* is ``-1``, in which case they may take any number of
503+
arguments. ``finalize`` and ``value`` can return any of the types
504+
supported by SQLite:
505+
:class:`bytes`, :class:`str`, :class:`int`, :class:`float`, and
506+
:const:`None`. Call :meth:`create_window_function` with
507+
*aggregate_class* set to :const:`None` to clear window function *name*.
508+
509+
Aggregate window functions are supported by SQLite 3.25.0 and higher.
510+
:exc:`NotSupportedError` will be raised if used with older versions.
511+
512+
.. versionadded:: 3.11
513+
514+
Example:
515+
516+
.. literalinclude:: ../includes/sqlite3/sumintwindow.py
517+
518+
490519
.. method:: create_collation(name, callable)
491520

492521
Creates a collation with the specified *name* and *callable*. The callable will

‎Doc/whatsnew/3.11.rst‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,10 @@ sqlite3
389389
serializing and deserializing databases.
390390
(Contributed by Erlend E. Aasland in :issue:`41930`.)
391391

392+
* Add :meth:`~sqlite3.Connection.create_window_function` to
393+
:class:`sqlite3.Connection` for creating aggregate window functions.
394+
(Contributed by Erlend E. Aasland in :issue:`34916`.)
395+
392396
* Add :meth:`~sqlite3.Connection.blobopen` to :class:`sqlite3.Connection`.
393397
:class:`sqlite3.Blob` allows incremental I/O operations on blobs.
394398
(Contributed by Aviv Palivoda and Erlend E. Aasland in :issue:`24905`)
@@ -854,6 +858,8 @@ Deprecated
854858
* :mod:`audioop`
855859
* :mod:`cgi`
856860
* :mod:`cgitb`
861+
* :mod:`chunk`
862+
* :mod:`crypt`
857863

858864
(Contributed by Brett Cannon in :issue:`47061`.)
859865

‎Include/opcode.h‎

Lines changed: 115 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Lib/aifc.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,9 @@ def _write_float(f, x):
255255
_write_ulong(f, himant)
256256
_write_ulong(f, lomant)
257257

258-
from chunk import Chunk
258+
with warnings.catch_warnings():
259+
warnings.simplefilter("ignore", DeprecationWarning)
260+
from chunk import Chunk
259261
from collections import namedtuple
260262

261263
_aifc_params = namedtuple('_aifc_params',

‎Lib/chunk.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@
4848
default is 1, i.e. aligned.
4949
"""
5050

51+
import warnings
52+
53+
warnings._deprecated(__name__, remove=(3, 13))
54+
5155
class Chunk:
5256
def __init__(self, file, align=True, bigendian=True, inclheader=False):
5357
import struct

‎Lib/crypt.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,14 @@
1212

1313
import errno
1414
import string as _string
15+
import warnings
1516
from random import SystemRandom as _SystemRandom
1617
from collections import namedtuple as _namedtuple
1718

1819

20+
warnings._deprecated(__name__, remove=(3, 13))
21+
22+
1923
_saltchars = _string.ascii_letters + _string.digits + './'
2024
_sr = _SystemRandom()
2125

‎Lib/shutil.py‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -518,9 +518,6 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,
518518
ignore_dangling_symlinks=False, dirs_exist_ok=False):
519519
"""Recursively copy a directory tree and return the destination directory.
520520
521-
dirs_exist_ok dictates whether to raise an exception in case dst or any
522-
missing parent directory already exists.
523-
524521
If exception(s) occur, an Error is raised with a list of reasons.
525522
526523
If the optional symlinks flag is true, symbolic links in the
@@ -551,6 +548,11 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,
551548
destination path as arguments. By default, copy2() is used, but any
552549
function that supports the same signature (like copy()) can be used.
553550
551+
If dirs_exist_ok is false (the default) and `dst` already exists, a
552+
`FileExistsError` is raised. If `dirs_exist_ok` is true, the copying
553+
operation will continue if it encounters existing directories, and files
554+
within the `dst` tree will be overwritten by corresponding files from the
555+
`src` tree.
554556
"""
555557
sys.audit("shutil.copytree", src, dst)
556558
with os.scandir(src) as itr:

‎Lib/test/test_crypt.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import sys
22
import unittest
3-
from test.support import check_sanitizer
3+
from test.support import check_sanitizer, warnings_helper
44

55

66
try:
77
if check_sanitizer(address=True, memory=True):
88
raise unittest.SkipTest("The crypt module SEGFAULTs on ASAN/MSAN builds")
9-
import crypt
9+
crypt = warnings_helper.import_deprecated("crypt")
1010
IMPORT_ERROR = None
1111
except ImportError as ex:
1212
if sys.platform != 'win32':

0 commit comments

Comments
 (0)