Core Dev PSF Fellow {Fellowship WG, Marketing WG} Board Member of EuroPython Society (EuroPython 2020 - 20th/26th July 2020) Former co-organiser of PythonFOSDEM (1st Feb 2020) 3 / 68
572: Assignment Expressions PEP 578: Python Runtime Audit Hooks Others points f-string{=}, ... PEP 574: Pickle protocol 5 with out-of-band data PEP 587: Python Initialization Configuration PEP 590: Vectorcall: a fast calling protocol for CPython https://python.org/dev/peps/pep-0569 5 / 68
arguments by position or by name. BUT sometimes, we would like to restrict the call to a function by passing the parameters by position and not by name For that, we have introduced a new syntax for the definition of the functions/methods with the '/'. API Designer Point of View: We can rename the name of a parameter and keep the backward compatibility. def name(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2): pass pos1 and pos2 are positional-only arguments pos_or_kwd is a positional or keyword argument kwd1, kwd2 are only keyword arguments https://www.python.org/dev/peps/pep-0570/ 11 / 68
mod=None): r = x ** y if mod is not None: r %= mod return r >>> pow(2, 10) 1024 >>> pow(2, 10, 17) 4 >>> pow(2, 10, mod=17) 4 >>> pow(x=2, y=10, mod=17) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: pow() got some positional-only arguments passed as keyword arguments: 'x, y' >>> https://www.python.org/dev/peps/pep-0570/ 12 / 68
= {'foo': 'bar'} >>> x = params.get('foo') >>> if x is not None: ... print(x) 'foo' After Say Hello to := The Walrus Operator >>> params = {'foo': 'bar'} >>> if x := params.get('foo'): ... print(x) https://www.python.org/dev/peps/pep-0572/ 14 / 68
pattern.search(data) if match is not None: do_something(match) After if (match := pattern.search(data)): do_something(match) https://www.python.org/dev/peps/pep-0572/ 16 / 68
len(a) if n > 10: print(f"List is too long ({n} elements, expected <= 10)") After if (n := len(a)) > 10: print(f"List is too long ({n} elements, expected <= 10)") https://www.python.org/dev/peps/pep-0572/ 18 / 68
3: >>> for angle in range(360): ... print(f'{angle=}\N{degree sign} {(theta:=radians(angle))=:.3f} {sin(theta)=:.3f}') >>> filtered_data = [y for x in data if (y := f(x)) is not None] Credit: Raymond Hettinger https://www.python.org/dev/peps/pep-0572/ 20 / 68
generete event for some (C-API and Python) functions Allow the monitoring of low-level access The events can be watched with hooks A Hook can't be removed or replaced https://www.python.org/dev/peps/pep-0578/ 23 / 68
Description sys.addaudithook Detect when new audit hooks are being added compile Detect dynamic code compilation exec Detect dynamic execution of code objects import Detect when modules are imported io.open Detect when a file is about to be opened object.setattr Detect monkey patching object.delattr Detect deletion of object attributes object.getattr Detect access to restricted attributes urllib.Request Detect URLS request etc... 26 / 68
the cases but the Python Performance Benchmark Suite shows no significant impact. Between 1.05% faster and 1.05% slower. https://github.com/python/pyperformance 28 / 68
log_exception(*args): print(f'got exception {args}') sys.excepthook = log_exception def foo(): a = 1 / 0 threading.Thread(target=foo).start() Exception in thread Thread-1: Traceback (most recent call last): File "cpython/Lib/threading.py", line 944, in _bootstrap_inner self.run() File "cpython/Lib/threading.py", line 882, in run self._target(*self._args, **self._kwargs) File "demo-fail-excepthook.py", line 10, in foo a = 1 / 0 ZeroDivisionError: division by zero 45 / 68
has occurred but there is no way for Python to handle it. Example: a destructor raises an exception or during garbage collection (gc.collect()). import sys def unraisablehook(args): sys.stderr.write(f'{args=}') sys.unraisablehook = unraisablehook class Demo: def __del__(self): raise Exception(':/') demo = Demo() del demo 47 / 68
to parse a string with a unicode. >>> import re >>> notice = 'I love 3.8' >>> PATTERN = re.compile(r'I love \N{SNAKE} ([0-9\.]*)') >>> if (match := PATTERN.search(notice)): ... print(match.group(1)) ... 3.8 SNAKE is a name of the Unicode Character 'SNAKE' (U+1F40D): Updated to Unicode 12.1.0 https://www.fileformat.info/info/unicode/char/1f40d/index.htm 48 / 68
2, 3)(4, 5)] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object is not callable Python >= 3.8 >>> [(1, 2, 3)(4, 5)] <stdin>:1: SyntaxWarning: 'tuple' object is not callable; perhaps you missed a comma? Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object is not callable 51 / 68
requires, files >>> version('requests') '2.22.0' >>> list(requires('requests')) ['chardet (<3.1.0,>=3.0.2)'] >>> list(files('requests'))[:2] [PackagePath('requests-2.22.0.dist-info/INSTALLER'), PackagePath('requests-2.22.0.dist-info/LICENSE')] You can also play with importlib.resources 52 / 68
access to their own process memory space shared memory permits the sharing of data between processes avoiding the need to instead send messages between processes. Sharing data directly via memory can provide significant performance benefits compared to sharing data via disk or socket or other communications requiring the serialization/deserialization and copying of data. 53 / 68
points. math.prod for the product of an iterable of numbers >>> math.prod([1, 2, 3, 4]) 24 math.isqrt for integer square roots >>> math.isqrt(4) 2 Changes math.hypot supports multiple dimensions math.factorial only for int. >>> math.factorial(4) 24 57 / 68
conditions are met: close_fds is False preexec_fn, pass_fds, cwd and start_new_sessions parameters are not set. the executable path contains a directory shutil.copyfile, shutil.copy, shutil.copy2, shutil.copytree and shutil.move use the "fast-copy" syscalls on Linux and macOS (implemented by the Kernel) outfd.write(infd.read()) By default, the pickle module uses Protocol 4, better performance and smaller size compared to Protocol 3 uuid.UUID uses __slots__ -> reduce memory footprint operator.itemgetter by 33%. etc... 65 / 68