Skip to content

Instantly share code, notes, and snippets.

View ambv's full-sized avatar
🐍
CPython Dev in Residence

Łukasz Langa ambv

🐍
CPython Dev in Residence
View GitHub Profile
@ambv
ambv / exceptions.py
Created March 14, 2016 04:11
Behavior of exception name binding in Python
from __future__ import print_function
import sys
def example1():
try:
pass # nothing is raised
except Exception as e1:
pass
def func():
try:
raise ValueError('ve')
except Exception as e:
handle_exception(e)
def handle_exception(e):
if 'some terrible thing' in e.args[0]:
raise
@ambv
ambv / post_iteration_deletion.py
Created May 21, 2016 23:52
Requires Python 3.3+
from contextlib import ExitStack
d = {index: str(index) for index in range(100)}
with ExitStack() as stack:
for key in d:
if key % 13 == 0:
stack.callback(d.pop, key)
print(d)
@ambv
ambv / per_instance_memoization.py
Last active May 26, 2016 08:22
Per-instance memoization in Python. The per-instance lazy binder is thread-safe.
from functools import lru_cache
import threading
import time
def per_instance(factory, *factory_args, **factory_kwargs):
"""Applies the given decorator on a per-instance basis."""
def lazy_binder(method):
"""Replaces the method just in time when it is first invoked."""
@ambv
ambv / clog_the_event_loop.py
Created June 2, 2016 19:43
In which rogue call_soons starve cooperating callbacks.
import asyncio
import time
loop = asyncio.get_event_loop()
async def go(sleep):
await asyncio.sleep(sleep)
print('I slept', sleep, 'seconds')
def clog(sleep):
@ambv
ambv / ensure_dead_with_parent.py
Last active May 3, 2025 08:22
Defensive programming for unhandled errors. Add this to preexec_fn= in your subprocess calls.
import ctypes
import sys
import signal
def ensure_dead_with_parent():
"""A last resort measure to make sure this process dies with its parent.
Defensive programming for unhandled errors.
"""
if not sys.platform.startswith('linux'):
return # not supported on OS X, Windows, etc. Use process groups.
@ambv
ambv / repro.sh
Created December 20, 2016 19:54
Demonstrates how `ignore = ` overrides the default ignore list, implicitly re-enabling optional warnings in bugbear. Note the line "Overriding default value of". Change bugbear version to 16.12.2 to see the workaround in action (note the line "Optional warning B950").
#!/bin/bash -e
# Create the environment
rm -rf .v # remove old stuff if present
python3 -m venv .v
source .v/bin/activate
cd .v
pip install flake8==3.2.1
pip install flake8-bugbear==16.12.1 # the newer version works around the issue
@ambv
ambv / config.cson
Created January 7, 2017 00:08
File-type specific Atom configuration
'.gfm.source':
'editor':
'softWrap': true
'tabLength': 4
'preferredLineLength': 72
@ambv
ambv / tokenize.diff
Last active April 23, 2018 00:34
Unified diff between Lib/tokenize.py and Lib/lib2to3/pgen2/tokenize.py
--- Lib/tokenize.py 2018-04-22 17:33:48.000000000 -0700
+++ Lib/lib2to3/pgen2/tokenize.py 2018-04-22 17:32:55.000000000 -0700
@@ -31,14 +31,15 @@
import itertools as _itertools
import re
import sys
-from token import *
+from .token import *
cookie_re = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)', re.ASCII)
@ambv
ambv / PythonFormatLinter.php
Created September 26, 2018 19:36
How to integrate Black with Arcanist
<?php
final class PythonFormatLinter extends ArcanistFutureLinter {
public function getLinterName() {
return 'BLACK';
}
protected function getFuturesLimit() {
return 8;
}