# Path: nolang/function.py
# class W_BuiltinFunction(W_Root):
#     def __init__(self, name, callable, min_args, max_args):
#         self.name = name
#         self.min_args = min_args
#         self.max_args = max_args
#         self.callable = callable
# 
#     def setup(self, space):
#         pass
# 
#     def call(self, space, interpreter, args_w, kwargs):
#         if kwargs is not None:
#             raise Exception('unimplemented')
#         if self.min_args != -1 and not self.min_args <= len(args_w) <= self.max_args:
#             if self.min_args == self.max_args:
#                 msg = "Function %s got %d arguments, expected %d" % (self.name,
#                     len(args_w), self.min_args)
#             else:
#                 msg = "Function %s got %d arguments, expected %d-%d" % (
#                     self.name, len(args_w), self.min_args, self.max_args)
#             raise space.apperr(space.w_argerror, msg)
#         return self.callable(space, args_w)
# 
#     def bind(self, space, w_obj):
#         return W_BoundMethod(w_obj, self)
# 
#     def __repr__(self):
#         return "<BuiltinFunction %s/%d-%d>" % (self.name, self.min_args,
#             self.max_args)
# 
# class W_Property(W_Root):
#     def __init__(self, name, getter, setter):
#         self.name = name
#         self.getter = getter
#         self.setter = setter
# 
#     def bind(self, space, w_obj):
#         return self.getter(w_obj, space)
# 
#     def setup(self, space):
#         pass
# 
# Path: nolang/objects/usertype.py
# class W_UserType(W_Root):
#     def __init__(self, allocate, name, class_elements_w, w_parent,
#                  default_alloc=True, force_names=None):
#         self.name = name
#         self.allocate = allocate
#         self.class_elements_w = class_elements_w
#         self.default_alloc = default_alloc
#         if w_parent is not None:
#             self._dict_w = w_parent._dict_w.copy()
#         else:
#             self._dict_w = {}
#         for item in class_elements_w:
#             self._dict_w[item.name] = item
#         self.w_parent = w_parent
#         if force_names is None:
#             self.force_names = None
#         else:
#             self.force_names = {}
#             for elem in force_names:
#                 self.force_names[elem] = None
# 
#     def setup(self, space):
#         for item in self.class_elements_w:
#             item.setup(space)
# 
#     def call(self, space, interpreter, args_w, kwargs):
#         if self.allocate is None:
#             raise Exception("cannot be called like that")
#         w_obj = space.call(self.allocate, [self] + args_w, kwargs)
#         if '__init__' in self._dict_w:
#             space.call(self._dict_w['__init__'], [w_obj] + args_w, kwargs)
#         elif self.default_alloc:
#             if len(args_w) != 0:
#                 raise space.apperr(space.w_argerror, "Default constructor"
#                     " expecting no arguments")
#         return w_obj
# 
#     def getattr(self, space, attrname):
#         try:
#             return self._dict_w[attrname]
#         except KeyError:
#             return space.w_NotImplemented
# 
#     def issubclass(self, w_type):
#         cur = self
#         while cur is not None:
#             if cur is w_type:
#                 return True
#             cur = cur.w_parent
#         return False
# 
#     def __repr__(self):
#         return "<UserType %s>" % (self.name,)


import types
import py
from nolang.function import W_BuiltinFunction, W_Property
from nolang.objects.usertype import W_UserType
        lines += extralines
    args = ", ".join(['arg%d' % i for i in range(len(argnames))])
    lines.append('    return orig_%s(%s)' % (name, args))
    src = py.code.Source("\n".join(lines))
    exec src.compile() in d
    exported_name = name
    if getattr(f, 'unwrap_parameters', None):
        exported_name = f.unwrap_parameters.get('name', exported_name)
    return W_BuiltinFunction(exported_name, d[name],
        min_args=numargs - len(defs),
        max_args=numargs)


def wrap_type(space, tp):
    spec = tp.spec
    if spec.constructor is None:
        allocate = None
    else:
        allocate = wrap_function(space, spec.constructor)
    properties = []
    for name, (get_prop, set_prop) in spec.properties.iteritems():
        if set_prop is not None:
            set_prop = set_prop.im_func
        properties.append(W_Property(name, get_prop.im_func, set_prop))
    for name, meth in spec.methods.iteritems():
        properties.append(wrap_function(space, meth, name=name, exp_name=spec.name))
    if spec.parent_name is None:
        parent = None
    else:
        parent = space.builtin_dict[spec.parent_name]

# Path: nolang/function.py
# class W_BuiltinFunction(W_Root):
#     def __init__(self, name, callable, min_args, max_args):
#         self.name = name
#         self.min_args = min_args
#         self.max_args = max_args
#         self.callable = callable
# 
#     def setup(self, space):
#         pass
# 
#     def call(self, space, interpreter, args_w, kwargs):
#         if kwargs is not None:
#             raise Exception('unimplemented')
#         if self.min_args != -1 and not self.min_args <= len(args_w) <= self.max_args:
#             if self.min_args == self.max_args:
#                 msg = "Function %s got %d arguments, expected %d" % (self.name,
#                     len(args_w), self.min_args)
#             else:
#                 msg = "Function %s got %d arguments, expected %d-%d" % (
#                     self.name, len(args_w), self.min_args, self.max_args)
#             raise space.apperr(space.w_argerror, msg)
#         return self.callable(space, args_w)
# 
#     def bind(self, space, w_obj):
#         return W_BoundMethod(w_obj, self)
# 
#     def __repr__(self):
#         return "<BuiltinFunction %s/%d-%d>" % (self.name, self.min_args,
#             self.max_args)
# 
# class W_Property(W_Root):
#     def __init__(self, name, getter, setter):
#         self.name = name
#         self.getter = getter
#         self.setter = setter
# 
#     def bind(self, space, w_obj):
#         return self.getter(w_obj, space)
# 
#     def setup(self, space):
#         pass
# 
# Path: nolang/objects/usertype.py
# class W_UserType(W_Root):
#     def __init__(self, allocate, name, class_elements_w, w_parent,
#                  default_alloc=True, force_names=None):
#         self.name = name
#         self.allocate = allocate
#         self.class_elements_w = class_elements_w
#         self.default_alloc = default_alloc
#         if w_parent is not None:
#             self._dict_w = w_parent._dict_w.copy()
#         else:
#             self._dict_w = {}
#         for item in class_elements_w:
#             self._dict_w[item.name] = item
#         self.w_parent = w_parent
#         if force_names is None:
#             self.force_names = None
#         else:
#             self.force_names = {}
#             for elem in force_names:
#                 self.force_names[elem] = None
# 
#     def setup(self, space):
#         for item in self.class_elements_w:
#             item.setup(space)
# 
#     def call(self, space, interpreter, args_w, kwargs):
#         if self.allocate is None:
#             raise Exception("cannot be called like that")
#         w_obj = space.call(self.allocate, [self] + args_w, kwargs)
#         if '__init__' in self._dict_w:
#             space.call(self._dict_w['__init__'], [w_obj] + args_w, kwargs)
#         elif self.default_alloc:
#             if len(args_w) != 0:
#                 raise space.apperr(space.w_argerror, "Default constructor"
#                     " expecting no arguments")
#         return w_obj
# 
#     def getattr(self, space, attrname):
#         try:
#             return self._dict_w[attrname]
#         except KeyError:
#             return space.w_NotImplemented
# 
#     def issubclass(self, w_type):
#         cur = self
#         while cur is not None:
#             if cur is w_type:
#                 return True
#             cur = cur.w_parent
#         return False
# 
#     def __repr__(self):
#         return "<UserType %s>" % (self.name,)


# Path: nolang/builtins/spec.py
import types
import py
from nolang.function import W_BuiltinFunction, W_Property
from nolang.objects.usertype import W_UserType

        lines += extralines
    args = ", ".join(['arg%d' % i for i in range(len(argnames))])
    lines.append('    return orig_%s(%s)' % (name, args))
    src = py.code.Source("\n".join(lines))
    exec src.compile() in d
    exported_name = name
    if getattr(f, 'unwrap_parameters', None):
        exported_name = f.unwrap_parameters.get('name', exported_name)
    return W_BuiltinFunction(exported_name, d[name],
        min_args=numargs - len(defs),
        max_args=numargs)


def wrap_type(space, tp):
    spec = tp.spec
    if spec.constructor is None:
        allocate = None
    else:
        allocate = wrap_function(space, spec.constructor)
    properties = []
    for name, (get_prop, set_prop) in spec.properties.iteritems():
        if set_prop is not None:
            set_prop = set_prop.im_func
        properties.append(W_Property(name, get_prop.im_func, set_prop))
    for name, meth in spec.methods.iteritems():
        properties.append(wrap_function(space, meth, name=name, exp_name=spec.name))
    if spec.parent_name is None:
        parent = None
    else:
        parent = space.builtin_dict[spec.parent_name]

    w_tp = W_UserType(allocate, spec.name, properties, parent, default_alloc=False)