Running Python linters with pre-commit hooks

Pre-commit hooks1 can be a neat way to run automated ad-hoc tasks before submitting a new git commit. These tasks may include linting, trimming trailing whitespaces, running code formatter before code reviews etc. Let’s see how multiple Python linters and formatters can be applied automatically before each commit to impose strict conformity on your codebase. To keep my sanity, I only use three linters in all of my python projects: ...

April 6, 2020

Generic functions with Python's singledispatch

Updated on 2022-02-13: Change import style of functools.singledispatch. Recently, I was refactoring a portion of a Python function that somewhat looked like this: def process(data): if cond0 and cond1: # apply func01 on data that satisfies the cond0 & cond1 return func01(data) elif cond2 or cond3: # apply func23 on data that satisfies the cond2 & cond3 return func23(data) elif cond4 and cond5: # apply func45 on data that satisfies cond4 & cond5 return func45(data) def func01(data): ... def func23(data): ... def func45(data): ... This pattern gets tedious when the number of conditions and actionable functions start to grow. I was looking for a functional approach to avoid defining and calling three different functions that do very similar things. Situations like this is where parametric polymorphism1 comes into play. The idea is, you have to define a single function that’ll be dynamically overloaded with alternative implementations based on the type of the function arguments. ...

April 5, 2020

The curious case of Python's context manager

Python’s context managers are great for resource management and stopping the propagation of leaked abstractions. You’ve probably used it while opening a file or a database connection. Usually it starts with a with statement like this: with open("file.txt", "wt") as f: f.write("contents go here") In the above case, file.txt gets automatically closed when the execution flow goes out of the scope. This is equivalent to writing: try: f = open("file.txt", "wt") text = f.write("contents go here") finally: f.close() Writing custom context managers To write a custom context manager, you need to create a class that includes the __enter__ and __exit__ methods. Let’s recreate a custom context manager that will execute the same workflow as above. ...

March 26, 2020

Reduce boilerplate code with Python's dataclasses

Recently, my work needed me to create lots of custom data types and draw comparison among them. So, my code was littered with many classes that somewhat looked like this: class CartesianPoint: def __init__(self, x, y, z): self.x = x self.y = y self.z = z def __repr__(self): return f"CartesianPoint(x = {self.x}, y = {self.y}, z = {self.z})" print(CartesianPoint(1, 2, 3)) >>> CartesianPoint(x = 1, y = 2, z = 3) This class only creates a CartesianPoint type and shows a pretty output of the instances created from it. However, it already has two methods inside, __init__ and __repr__ that do not do much. ...

March 12, 2020

Docker sidecar communication with Unix Domain Socket (UDS)