Skip to content

- Interesting SqlAlchemy Python code

Most of us in private industry have a way easier time coding, than those authoring and maintaining OpenSource and products for use outside of our own engineering teams.

Perhaps you disagree with this sentiment. It is opinion, and a rather broad brush. Rather than the result of some detailed meta-analysis of projects. It has been my experience that a lot of supplementary engineering is put into OpenSource and public projects. Sometimes this draws my critique as it complicates comprehension of problem domains.

You would likely have an issue with a bridge builder, simply taking a specification and trying to make it fit into a different space.

Luckily for us, we have undo buttons to forgive us.

Background

I was trying to build the Kolibri documentation using Python 3.8.

I have never been one to use bleeding edge runtimes outside of virtual environments. I could have rolled back a few versions, and made this someone else problem. I May have done that if I had encountered more problems, or was less comfortable in Python.

The error I saw was as follows

					
AttributeError: module 'time' has no attribute 'clock'
					
				

This was not what interested me. My fix was a single-line edit

					
if win32 or jython:
    time_func = time.clock
else:
	time_func = time.time
					
				

Became

					
if win32 or jython:
    time_func = time.perf_counter
else:
	time_func = time.time
					
				

Code

What interested me was how readable that if / else statement was.

So, I located the code for that at the top of the file.

					
py36 = sys.version_info >= (3, 6)
py33 = sys.version_info >= (3, 3)
py35 = sys.version_info >= (3, 5)
py32 = sys.version_info >= (3, 2)
py3k = sys.version_info >= (3, 0)
py2k = sys.version_info < (3, 0)
py265 = sys.version_info >= (2, 6, 5)
jython = sys.platform.startswith('java')
pypy = hasattr(sys, 'pypy_version_info')
win32 = sys.platform.startswith('win')
cpython = not pypy and not jython  # TODO: something better for this ?
					
				

First, let me say. SQL is an Operating system independent language, as-is Python. I did not expect to see this, even in an ORM, but what a gorgeous, expressive and readable way to express intent.

Takeaways

You will notice that there are even patch version checks. A lesson that even the most dedicated groups, occasionally overlook something that modifies behavior or API.

There is not more to this, other than what a beautiful, simple piece of code this is, and a method applicable to most languages I can think of.

A particularly powerful approach I have seen elsewhere, is dependency injection and service discovery. For micro-changes such as these, it seems a large weapon to wield, but a function, perhaps memoized for recall might look like this.

					
def semantic_version(major, minor=None, patch=None):
	if all([
		minor,
		patch,
		str(minor).isnumeric(),
		str(patch).isnumeric(),
	]):
		return (major, minor, patch)
	elif all([
		minor,
		str(minor).isnumeric(),
		not patch,
		not str(patch).isnumeric(),
	]):
		return (major, minor)
	return (major, 0)

def version_check(identifier, op=None, minor=None, patch=None):
	if str(identifier).isnumeric():
		# semver
		version = semantic_version(identifier, minor, patch)
		sys_version = sys.version_info
		if op == 'gte':
			return sys_version >= version
		elif op == 'lte':
			return sys_version <= version
		elif op == 'gt':
			return sys_version > version
		elif op == 'lt':
			return sys_version < version
		else:
			return sys_version >= version and not sys_version < version and not sys_version > version
	else:
		return bool(
			identifier and any([
				identifier == 'jython' and sys.platform.startswith('java'),
				identifier == 'pypy' and hasattr(sys, 'pypy_version_info'),
				identifier == 'win32' and sys.platform.startswith('win'),
				identifier == 'cython' and not version_check('jython') and not version_check('pypy'),  # TODO: something better for this ?
			])
		)
					
				

I hope we can agree that is less elegant, although perhaps as readable, and easily memoized. The one improvement I would make would be to separate into distinct functions.

By