public
Created

__prepare__ for Python 2.x

  • Download Gist
example.py
Python
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()
prepareable.py
Python
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)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.