Last active
February 5, 2019 07:31
-
-
Save vberlier/0fbecf88f9cec897552c2fbe66b46a80 to your computer and use it in GitHub Desktop.
A little example that demonstrates how far you can push metaclasses insanity in Python.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from functools import partial | |
from query import run_query | |
class QueryResolver(dict): | |
def __getitem__(self, key): | |
if key.lower().startswith('select_') and key not in self: | |
self[key] = partial(run_query, key) | |
return super().__getitem__(key) | |
class QueryProvider(type): | |
@classmethod | |
def __prepare__(cls, name, bases): | |
return QueryResolver() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
def run_query(query, iterable, **kwargs): | |
fields = list(get_fields(query)) | |
for element in iterable: | |
if any(element[key] != value for key, value in kwargs.items()): | |
continue | |
if len(fields) > 1: | |
yield {name if alias is None else alias: element[name] | |
for name, alias in fields} | |
else: | |
yield element[fields[0][0]] | |
def get_fields(query): | |
for field in re.split(r'select_|_and_|_from', query, flags=re.I): | |
if '_as_' in field.lower(): | |
yield re.split(r'_as_', field, maxsplit=1, flags=re.I) | |
elif field: | |
yield field, None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from magic import QueryProvider | |
people = [ | |
{ | |
'name': 'Foo', | |
'age': 36, | |
'birthday': 'feb 3', | |
'gender': 'girl' | |
}, | |
{ | |
'name': 'Bar', | |
'age': 19, | |
'birthday': 'nov 14', | |
'gender': 'boy' | |
}, | |
{ | |
'name': 'Spam', | |
'age': 48, | |
'birthday': 'apr 26', | |
'gender': 'girl' | |
}, | |
{ | |
'name': 'Egg', | |
'age': 36, | |
'birthday': 'feb 3', | |
'gender': 'boy' | |
} | |
] | |
class WeirdContext(metaclass=QueryProvider): | |
for person in select_name_and_birthday_as_date_of_birth_from(people, age=36): | |
print(person) | |
for boy, girl in zip(select_name_from(people, gender='boy'), | |
select_name_from(people, gender='girl')): | |
print(boy, girl) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment