Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

__prepare__ for Python 2.x

View example.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
from __future__ import print_function
from collections import OrderedDict
 
from prepareable import Prepareable
 
from six import with_metaclass, iteritems
 
 
class FooMeta(with_metaclass(Prepareable, type)):
def __new__(cls, name, bases, attributes):
assert isinstance(attributes, OrderedDict)
for name, attribute in iteritems(attributes):
if isinstance(attribute, Something):
print(name, attribute)
return super(FooMeta, cls).__new__(cls, name, bases, attributes)
def __prepare__(name, bases, **kwargs):
return OrderedDict()
 
class Something(object):
pass
class Foo(with_metaclass(FooMeta)):
a = Something()
b = Something()
View example.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
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)
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)

Very nice--I was just trying to think about whether there was a way to do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.