Skip to content

Instantly share code, notes, and snippets.

@syrusakbary
Created September 9, 2016 04:36
Show Gist options
  • Save syrusakbary/37db1f88db1675bc2aa78396879a2d67 to your computer and use it in GitHub Desktop.
Save syrusakbary/37db1f88db1675bc2aa78396879a2d67 to your computer and use it in GitHub Desktop.
Prepareable
import sys
import inspect
from functools import wraps
import six
class Prepareable(type):
if not six.PY3:
def __new__(cls, name, bases, attributes):
try:
constructor = attributes["__new__"]
except KeyError:
return type.__new__(cls, name, bases, attributes)
def preparing_constructor(cls, name, bases, attributes):
try:
cls.__prepare__
except AttributeError:
return constructor(cls, name, bases, attributes)
namespace = cls.__prepare__.im_func(name, bases)
defining_frame = sys._getframe(1)
get_index = lambda *_: 0
for constant in reversed(defining_frame.f_code.co_consts):
if inspect.iscode(constant) and constant.co_name == name:
def get_index(attribute_name, _names=constant.co_names):
try:
return _names.index(attribute_name)
except ValueError:
return 0
break
by_appearance = sorted(
attributes.items(), key=lambda item: get_index(item[0])
)
for key, value in by_appearance:
namespace[key] = value
return constructor(cls, name, bases, namespace)
attributes["__new__"] = wraps(constructor)(preparing_constructor)
return type.__new__(cls, name, bases, attributes)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment