from collections import namedtuple
import pkg_resources

import six

from .bundle import Bundle, Code, Data
from .inner.schematics import interpreter_injector
from .sources import interpreter
from .sources.core import DiskLocal


class Arx(namedtuple('Arx', 'interpreter')):
    def Bundle(self, *args, **kwargs):
        """Generate a new bundle. Inputs, if passed, are used to initialize
           the bundle.
        """
        with interpreter_injector.using(self.interpreter):   # NB: Evil globals
            return Bundle(*args, **kwargs)

    def Source(self, *args, **kwargs):
        return self.interpreter(*args, **kwargs)

    def Code(self, *args, **kwargs):
        """Generate a new Code object, translating URLs and other sources
           according to this context's interpreter.
        """
        if len(args) > 0:
            if isinstance(args[0], six.string_types) and '://' not in args[0]:
                kwargs.update(cmd=args[0])
            else:
                kwargs.update(source=self.Source(args[0]))
            kwargs.update(args=args[1:])
            args = []
        return Code(*args, **kwargs)

    def Data(self, *args, **kwargs):
        """Generate a new Data object, translating URLs and other sources
           according to this context's interpreter.
        """
        if len(args) > 0:
            kwargs.update(source=self.Source(args[0]))
            args = args[1:]
        if len(args) > 0:
            kwargs.update(target=args[0])
            args = args[1:]
        return Data(*args, **kwargs)

    def local(self, source, under=None):
        cached = source.cache(under)
        assert isinstance(cached, DiskLocal)
        return self.Source(cached.externalize())

    def inline(self, source):
        raise NotImplementedError()


arx = Arx(interpreter.default)


def version():
    try:
        return pkg_resources.get_distribution(__package__).version
    except:
        pass
    try:
        return pkg_resources.resource_string(__package__, 'VERSION').strip()
    except:
        pass
    return '19991231'


__version__ = version()

@@ -510,22 +510,24 @@
         
-return
+bundle =
  Bundle(
@@ -534,32 +534,88 @@
 *args, **kwargs)
+%0A            bundle.validate()%0A            return bundle
 %0A%0A    def Source
@@ -1160,22 +1160,22 @@
         
-return
+code =
  Code(*a
@@ -1180,32 +1180,76 @@
 *args, **kwargs)
+%0A        code.validate()%0A        return code
 %0A%0A    def Data(s
@@ -1622,22 +1622,22 @@
         
-return
+data =
  Data(*a
@@ -1642,32 +1642,76 @@
 *args, **kwargs)
+%0A        data.validate()%0A        return data
 %0A%0A    def local(

Apply validations before returning data