Skip to content
Create a gist now

Instantly share code, notes, and snippets.

__prepare__ for Python 2.x
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):
class Foo(with_metaclass(FooMeta)):
a = Something()
b = Something()
import sys
import inspect
from functools import wraps
import six
class Prepareable(type):
if not six.PY3:
def __new__(cls, name, bases, attributes):
constructor = attributes["__new__"]
except KeyError:
return type.__new__(cls, name, bases, attributes)
def preparing_constructor(cls, name, bases, attributes):
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):
return _names.index(attribute_name)
except ValueError:
return 0
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)
embray commented Oct 29, 2014

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.