Esempio n. 1
0
class StrRange(Range):
    _attrs = dict(lb=Attr(int, 0x20, doc='The lower bound'),
                  ub=Attr(int, 0x7e, doc='The upper bound'))
    _opts = dict(coerce_args=False)

    @init_hook
    def _ensure_ints(self):
        if isinstance(self.lb, STR):
            self.lb = ord(self.lb)

        if isinstance(self.ub, STR):
            self.ub = ord(self.ub)

    def display(self, **kwargs):
        return '[{}, {}]'.format(unichr(self.lb), unichr(self.ub))

    def hasmember(self, other):
        return super(StrRange, self).hasmember(ord(other))

    def sample(self, **kwargs):
        ret = super(StrRange, self).sample()
        return unichr(ret)

    def enumerate(self, **kwargs):
        for item in super(StrRange, self).enumerate(**kwargs):
            yield unichr(item)

    def to_set(self, **kwargs):
        return super(Range, self).to_set(**kwargs)
Esempio n. 2
0
class Problem(Base):
    _attrs = dict(constraints=Attr(List(Constraint)), domain=Attr(Domain))
    _opts = dict(init_validate=True, args=('domain', 'constraints'))

    @init_hook
    def _init(self):
        self.domain = self.domain.copy()
        self.var_constraint = defaultdict(set)

        for con in self.constraints:
            con.preprocess(self.domain)
            for var in con.args:
                self.var_constraint[var].add(con)

    def check(self, theory):
        for con in self.constraints:
            if set(con.args) <= set(theory):
                if not con.check(**theory):
                    return False
        return True

    def display(self, **kwargs):
        strs = [self.domain.display(**kwargs)]
        for con in self.constraints:
            s = con.display(**kwargs)
            if s:
                strs.append(s)
        return '\n'.join(strs)

    def validate(self):
        super(Problem, self).validate()

        if not set(self.var_constraint).issubset(set(self.domain)):
            raise ValueError('Some constraints defined in over '
                             'undefined variables')
Esempio n. 3
0
class Context(Base):
    context_name = None
    required_opts = ()

    _attrs = dict(inside = Attr(STR, ''),
                  envvars = Attr(Dict(STR), init=lambda self: dict()),
                  opts = Attr(dict, init=lambda self: dict()),
                  _skip_validation = Attr(bool, False, internal=True))
    _opts = dict(init_validate = True)

    @classmethod
    @create_hook
    def _register(cls):
        if cls.context_name:
            CONTEXT_REGISTRY[cls.context_name] = cls

    @classmethod
    def from_yaml(cls, name, dct):
        kwargs = {}
        kwargs['envvars'] = dct.get('env', {})
        kwargs['opts'] = dct.get('opts', {})
        kwargs['inside'] = dct.get('inside', '')

        # TODO: if invalid context specified, raise ValidationError
        cls_ = CONTEXT_REGISTRY.get(dct.get('instanceof', 'null'), cls)
        return cls_(**kwargs)

    def resolve_macros(self, env, **kwargs):
        envvars = dict(self.envvars)
        for key , value in self.envvars.items():
            envvars[key] = env.resolve(value)

        opts = dict(self.opts)
        for key, value in self.opts.items():
            if isinstance(value, STR):
                opts[key] = env.resolve(value)

        return envvars, opts

    def run_command(self, command, env, **kwargs):
        if self.inside:
            ctx = env.contexts[self.inside]
            command = ctx.run_command(command, env, **kwargs)
        return command

    run = None

    def validate(self):
        super(Context, self).validate()

        if self._skip_validation:
            return

        for opt in self.required_opts:
            if opt not in self.opts:
                raise ValidationError('Required option "{}" not defined'
                                      .format(opt))
Esempio n. 4
0
class SpecBase(Base):
    _attrs = dict(
        type=Attr(type, doc='The type of this argument'),
        name=Attr(STR, doc='The name of this argument'),
        required=Attr(
            bool,
            False,
            doc='If true, will throw an error if argument is not present'))
    _opts = dict(init_validate=True)

    def find_value(self, args, kwargs):
        raise NotImplementedError
Esempio n. 5
0
class Operation(ListWrapper):
    '''Representation of a system operation.'''
    _attrs = dict(order=Attr(int,
                             doc='An integer specifying the '
                             'order in which to perform the operation '
                             '(smaller values are performed earlier)'),
                  repetitions=Attr(int,
                                   0,
                                   doc='Number of times to repeat '
                                   'the operation'))
    _opts = dict(init_validate=True)

    order_offset = 0

    @init_hook
    def _adjust_order(self):
        self.order += self.order_offset

    @classmethod
    def optimize(cls, ops):
        ops.sort(key=attrgetter('order'))

        k = 0
        while k < len(ops) - 1:
            ops[k].reduce(ListView(ops, k + 1, -1))
            k += 1

    def combine(self, other):
        '''Combine with another operation to increase execution efficiency.'''
        raise NotImplementedError

    def execute(self):
        '''Execute the operation on the system'''
        raise NotImplementedError

    def _reduce_single(self, op, ops):
        self.combine(op)

    def reduce(self, ops):
        '''Reduce a list of operations for optimizing total execution'''
        N = len(ops)
        while ops:
            op = ops[0]
            if not same_lineage(self, op):
                break
            if not self.order == op.order:
                break

            self._reduce_single(op, ops)
            if N == len(ops):
                break
            N = len(ops)
Esempio n. 6
0
class MatchFailure(Base):
    _attrs = dict(message=Attr(STR, doc='Reason for failure'),
                  seq=Attr(IterableList,
                           doc='The sequence that failed to match'),
                  fails=OAttr(list, doc='List of sub-failures'))
    _opts = dict(init_validate=True)

    # So that "if pattern.match(...):" can be used
    def __nonzero__(self):
        return False

    def __bool__(self):
        return False
Esempio n. 7
0
class Logger(Base):
    _attrs = dict(logging_enabled = Attr(bool, True),
                  decoration_enabled = Attr(bool, True),
                  events = Attr(dict, internal=True)
                  )

    @init_hook
    def _init(self):
        if not hasattr(self, 'events'):
            self.events = defaultdict(list)

    def disable(self):
        self.logging_enabled = False

    def enable(self):
        self.logging_enabled = True

    def log_decorator(self, spec, before=True, after=False, name=None, log_return=True):
        def decorator(f):
            if not self.decoration_enabled:
                return f

            event_type_name = name
            if name is None:
                event_type_name = f.__name__
            event_type = FunctionCall(spec)

            @wraps(f)
            def func(*args, **kwargs):
                if self.logging_enabled:
                    event = event_type(args, kwargs)
                ret = f(*args, **kwargs)
                if self.logging_enabled:
                    if log_return:
                        event.return_value = ret
                    self.record_event(event_type_name, event)
                return ret
            return func
        return decorator

    def log_event(self):
        pass

    def log(self, *args, **kwargs):
        # Determine what the context is from args and kwargs, then call log_decorator or log_event
        # But this also needs to be fast, so strike a balance between magic and speed
        return self.log_decorator(*args, **kwargs)

    def record_event(self, name, event):
        self.events[name].append(event)
Esempio n. 8
0
class Command(Base):
    _attrs = dict(command = Attr(STR),
                  context = Attr(STR, '')) # string used to look up context object in env
    _opts = dict(init_validate = True,
                 args = ('command',))

    def resolve_macros(self, env, **kwargs):
        command = env.resolve(self.command)
        context = env.resolve(kwargs.get('context', self.context))
        return command, context

    def run(self, env, **kwargs):
        verbose = kwargs.get('verbose', False)
        preview = kwargs.get('preview', False)
        # Called from Task.run_preview()
        run_preview = kwargs.get('run_preview', False)
        silent = kwargs.get('silent', env.settings.get('silent', False))

        pre = ''
        if preview and not run_preview:
            pre = kwargs.get('preview_pre', '')

        command, context_name = self.resolve_macros(env, **kwargs)
        if not context_name:
            context = env.default_context
        else:
            context = env.contexts[context_name]
            
        if callable(context.run):
            return context.run(command, env, **kwargs)
        
        cmd = context.run_command(command, env, **kwargs)

        if verbose:
            sys.stdout.write(pre + cmd + '\n')
            sys.stdout.flush()
        
        if not preview:
            args = shlex.split(cmd)
            if args[0] == 'yatr':
                try:
                    from .main import _main
                    _main(*args[1:])
                    return 0
                except Exception as e:
                    eprint(message(e))
                    return 1
            return command_(cmd, silent)
Esempio n. 9
0
class Pip(Dependency):
    '''Representation of a pip dependency'''
    key = 'pip'
    order = 30

    _attrs = dict(order=Attr(int, order))

    @classmethod
    @create_hook
    def _populate_pkgs(cls):
        if not cls._pkgs:
            try:
                pkgs = output('pip freeze')
                cls._pkgs = dict([
                    tuple(line.split('==')) for line in pkgs.split('\n')
                    if line
                ])
            except OSError:
                pass

    def satisfy(self):
        inst = [Install(self.name, order=self.order)]
        instver = [
            Install('{}=={}'.format(self.name, self.version.rhs),
                    order=self.order)
        ]

        if self.always_upgrade:
            return inst

        if not self.check():
            if isinstance(self.version, (Eq, Le)):
                return instver
            return inst
        return []
Esempio n. 10
0
class TypeWrapper(SetLeaf):
    '''The idea is that a type implicitly represents the set of all of its
    valid instances.
    '''
    _attrs = dict(type=Attr(Type, doc=''))
    _opts = dict(args=('type', ), coerce_args=False)

    @init_hook
    def _convert_type(self):
        if not isinstance(self.type, Type):
            self.type = Type.dispatch(self.type)

    def display(self, **kwargs):
        return 'TypeWrapper({})'.format(self.type.display())

    def size(self):
        return float('inf')

    def hasmember(self, item):
        return self.type.query(item)

    def sample(self, **kwargs):
        return self.type.generate(**kwargs)

    def enumerate(self, **kwargs):
        args = Args(**kwargs)
        maxenum = min(args.max_enumerate, args.type_enumerate)

        for k in range(maxenum):
            item = self.sample(**kwargs)
            yield item

    def to_set(self, **kwargs):
        return super(SetLeaf, self).to_set(**kwargs)
Esempio n. 11
0
class Relation(Base):
    _attrs = dict(
        rhs=Attr(str, default='', doc='The value on the right hand side'))
    _opts = dict(init_validate=True, make_hashable=True, args=('rhs', ))

    func = None
    repr = None

    def __call__(self, value):
        if self.func is not None:
            return self.func(str(value), self.rhs)
        return True

    @classmethod
    @create_hook
    def _register(cls):
        if cls.repr is not None:
            RELATION_CACHE[cls.repr] = cls

    @classmethod
    def dispatch(cls, s):
        # Make sure the longer reprs get tested first
        for key, rel in sorted(RELATION_CACHE.items(),
                               key=lambda x: -len(x[0])):
            if key in s:
                name, rhs = s.split(key)
                return rel(rhs.strip(), name=name.strip())
        return cls('', name=s)

    def emit(self):
        repr = self.repr if self.repr else ''
        return repr + self.rhs
Esempio n. 12
0
class Positional(Argument):
    _attrs = dict(repeatable=Attr(bool, False, ('If true, multiple values can'
                                                ' be supplied')))

    def __init__(self, *args, **kwargs):
        super(Positional, self).__init__(*args, **kwargs)

        if not self.repeatable:
            self.quote = 'multiple'
Esempio n. 13
0
class BinaryOption(Option):
    _attrs = dict(value=Attr(bool, False, 'Value of the option'))

    def render(self, value):
        out = ''
        if value:
            out = self.name

        return out
Esempio n. 14
0
class SetWrapper(SetLeaf):
    _attrs = dict(set=Attr(set, doc=''))
    _opts = dict(args=('set', ))

    def display(self, **kwargs):
        return rstr(self.set)

    def size(self):
        return len(self.set)

    @_set_wrapper
    def union(self, *args):
        ret = reduce(set.union, (self.set, ) + args)
        return type(self)(ret)

    @_set_wrapper
    def intersection(self, *args):
        ret = reduce(set.intersection, (self.set, ) + args)
        return type(self)(ret)

    @_set_wrapper
    def difference(self, other):
        ret = self.set.difference(other)
        return type(self)(ret)

    @_set_wrapper
    def complement(self, universe):
        ret = universe.difference(self.set)
        return type(self)(ret)

    @_set_wrapper
    def issubset(self, other):
        return self.set.issubset(other)

    @_set_wrapper
    def issuperset(self, other):
        return self.set.issuperset(other)

    def hasmember(self, item):
        return item in self.set

    def sample(self, **kwargs):
        ret = choice(list(self.set))
        return ret

    def enumerate(self, **kwargs):
        args = Args(**kwargs)
        maxenum = args.max_enumerate

        for k, item in enumerate(self.set):
            if k >= maxenum:
                break
            yield item

    def to_set(self, **kwargs):
        return set(self.set)
Esempio n. 15
0
class Yatr(Dependency):
    key = 'yatr'
    order = 99999

    _attrs = dict(order=Attr(int, order), yatrfile=Attr(STR, ''))

    def check(self):
        '''Tasks will always run.'''
        return False

    def installed(self):
        return False

    def satisfy(self):
        args = [self.name]  # self.name is the task name + args (optional)
        if self.yatrfile:
            args.insert(0, '-f {}'.format(self.yatrfile))

        task = Task(*args, order=self.order)
        return [task]
Esempio n. 16
0
class Constraint(Base):
    _attrs = dict(args=Attr(Sequence, init=lambda self: tuple()))
    _opts = dict(init_validate=True, args=('args', ), make_hashable=True)

    def check(self, **kwargs):
        raise NotImplementedError

    def display(self, **kwargs):
        pass

    def preprocess(self, domain, **kwargs):
        pass
Esempio n. 17
0
class Arg(SpecBase):
    '''Descriptor of a positional argument.'''
    _attrs = dict(index=Attr(int, doc='The index of this argument in *args'))
    _opts = dict(args=('name', 'index', 'type'))

    def find_value(self, args, kwargs):
        if len(args) <= self.index:
            if self.required:
                raise ValidationError('Positional argument (index={}) '
                                      'not present'.format(self.index))
            return
        return args[self.index]
Esempio n. 18
0
class ClassWrapper(SetLeaf):
    '''The idea is that a type implicitly represents the set of all of its
    subclasses, including itself.
    '''
    _attrs = dict(type=Attr(type, doc=''),
                  subclasses=Attr(List(type),
                                  doc='',
                                  init=lambda self:
                                  ([self.type] + subclasses(self.type))))
    _opts = dict(args=('type', ))

    def __init__(self, *args, **kwargs):
        super(ClassWrapper, self).__init__(*args, **kwargs)
        self.subclasses = [self.type] + subclasses(self.type)

    def display(self, **kwargs):
        return 'ClassWrapper({})'.format(get_typename(self.type))

    def size(self):
        return len(self.subclasses)

    def hasmember(self, item):
        return item in self.subclasses

    def sample(self, **kwargs):
        ret = choice(self.subclasses)
        return ret

    def enumerate(self, **kwargs):
        args = Args(**kwargs)
        maxenum = min(args.max_enumerate, len(self.subclasses))

        for k, item in enumerate(self.subclasses):
            if k >= maxenum:
                break
            yield item

    def to_set(self, **kwargs):
        return super(SetLeaf, self).to_set(**kwargs)
Esempio n. 19
0
class Option(Argument):
    _opts = dict(args=('name', 'aliases'))
    _attrs = dict(
        aliases=Attr(list,
                     doc='Other strings denoting the option',
                     optional=True),
        use_eq=Attr(bool, False, 'Use name=value syntax'),
        interleave=Attr(bool, True, ('Repeat the option for '
                                     'multiple values')),
    )

    def __init__(self, *args, **kwargs):
        super(Option, self).__init__(*args, **kwargs)

        if self.aliases is None:
            self.aliases = []
        else:
            self.aliases = list(self.aliases)

    def render(self, value):
        multiple = False
        if (isinstance(value, Iterable) and not self.single_value
                and not isinstance(value, STR)):
            multiple = True

        prefix = self.name
        if self.use_eq:
            prefix += '='
        else:
            prefix += ' '

        if multiple and self.interleave:
            strs = [super(Option, self).render(val) for val in value]
        else:
            strs = [super(Option, self).render(value)]

        out = ' '.join(prefix + s for s in strs)
        return out
Esempio n. 20
0
class Domain(Base):
    _attrs = dict(vars=Attr(Mapping(SetNode), init=lambda self: dict()))
    _opts = dict(args=('vars', ))

    def __init__(self, *args, **kwargs):
        if not args and kwargs and not 'vars' in kwargs:
            kwargs = dict(vars=kwargs)
        if 'vars' in kwargs:
            for key in kwargs['vars']:
                value = kwargs['vars'][key]
                if not isinstance(value, SetNode):
                    if isinstance(value, type):
                        kwargs['vars'][key] = TypeWrapper(value)
                    else:
                        kwargs['vars'][key] = SetWrapper(value)
        super(Domain, self).__init__(*args, **kwargs)

    def __delitem__(self, key):
        del self.vars[key]

    def __getitem__(self, key):
        return self.vars[key]

    def __iter__(self):
        return iter(self.vars)

    def __len__(self):
        return len(self.vars)

    def __setitem__(self, key, value):
        if not isinstance(value, SetNode):
            if isinstance(value, type):
                self.vars[key] = TypeWrapper(value)
            else:
                self.vars[key] = SetWrapper(value)

    def copy(self, *args, **kwargs):
        return type(self)(self.vars.copy(*args, **kwargs))

    def display(self, **kwargs):
        ret = 'Domain('
        strs = [
            '{} = {}'.format(var, vals.display(**kwargs))
            for var, vals in sorted(self.vars.items(), key=itemgetter(0))
        ]
        ret += ',\n       '.join(strs) + ')'
        return ret
Esempio n. 21
0
class Kwarg(SpecBase):
    '''Descriptor of a keyword-only argument.'''
    _attrs = dict(key=Attr(STR, doc='The key of this argument in **kwargs'))
    _opts = dict(args=('key', 'type'))

    @init_hook
    def _init(self):
        if not hasattr(self, 'name'):
            self.name = self.key

    def find_value(self, args, kwargs):
        if self.key not in kwargs:
            if self.required:
                raise ValidationError('Keyword argument (key={}) '
                                      'not present'.format(self.key))
            return
        return kwargs[self.key]
Esempio n. 22
0
class SchemaNode(Node):
    _aliases = dict(_list=['elems'])
    _attrs = dict(set=Attr(SetNode,
                           optional=True,
                           internal=True,
                           doc='Internal set representation'))
    _opts = dict(optional_none=True)

    def __init__(self, *args, **kwargs):
        lst = []
        for arg in args:
            if isinstance(arg, SchemaNode):
                lst.append(arg)
            elif isinstance(arg, (type, Type_)):
                lst.append(Type(arg))
            elif isinstance(arg, SetNode):
                lst.append(Set(arg))
            elif isinstance(arg, SET) or is_proper_sequence(arg):
                lst.append(Set(SetWrapper(arg)))
            else:
                lst.append(Set(SetWrapper([arg])))  # Create a singleton
        super(SchemaNode, self).__init__(*lst, **kwargs)
Esempio n. 23
0
class Apt(Dependency):
    '''Representation of an apt dependency'''
    key = 'apt'
    order = 10

    _attrs = dict(order=Attr(int, order))

    @classmethod
    @create_hook
    def _populate_pkgs(cls):
        if not cls._pkgs:
            try:
                lines = output('dpkg -l').split('\n')
                partss = [l.split() for l in lines[5:] if l]
                pkgs = [(p[1], p[2]) for p in partss if fnmatch(p[0], '?i')]
                cls._pkgs = dict(pkgs)
            except OSError:
                pass

    def satisfy(self):
        up = [Update(order=self.order)]
        inst = up + [Install(self.name, order=self.order)]
        instver = up + [
            Install('{}={}'.format(self.name, self.version.rhs),
                    order=self.order)
        ]
        down = [Remove(self.name, order=self.order)] + instver

        if self.always_upgrade:
            return inst

        if not self.check():
            if isinstance(self.version, (Eq, Le)):
                if self.installed():
                    return down
                return instver
            return inst
        return []
Esempio n. 24
0
class Argument(Base):
    _arglist = None
    _opts = dict(args=('name', ),
                 coerce_args=True,
                 optional_none=True,
                 init_validate=True)
    _attrs = dict(sep=Attr(STR, ' ',
                           'Character used to separate multiple values'),
                  quote=Attr(['always', 'multiple', 'never'], 'multiple',
                             ('Values quoting policy - either always quote, '
                              'only quote if there are multiple values, or '
                              'never quote')),
                  quote_elements=Attr(bool, False, ('Quote only the individual'
                                                    'parts of a multi-value')),
                  quote_char=Attr(["'", '"', '\"'], '"',
                                  'Character to use for quoting values'),
                  single_value=Attr(bool, False, ('Interpret value as '
                                                  'a single value')),
                  name=Attr(STR, doc='The name of the argument'))

    def __init__(self, *args, **kwargs):
        super(Argument, self).__init__(*args, **kwargs)

        arglist = type(self)._arglist
        if arglist is not None:
            arglist.append(self)

    def render(self, value):
        if (isinstance(value, Iterable) and not self.single_value
                and not isinstance(value, STR)):
            if self.quote_elements:
                out = self.sep.join(
                    quote(strf(val), self.quote_char) for val in value)
            else:
                out = self.sep.join(strf(val) for val in value)
            multiple = True
        else:
            out = strf(value)
            multiple = False

        if self.quote == 'always' or (self.quote == 'multiple' and multiple
                                      and not self.quote_elements):
            out = quote(out, self.quote_char)

        return out
Esempio n. 25
0
class Task(Base):
    _attrs = dict(commands = Attr(List(Command)),
                  condition = Attr(This, optional=True),
                  loop = Attr(For, optional=True),
                  args = Attr(List((STR, int)), init=lambda self: list()),
                  kwargs = Attr(Dict((STR, int)), init=lambda self: dict()),
                  condition_type = Attr(bool, True))
    _opts = dict(init_validate = True,
                 optional_none = True)

    @classmethod
    def from_yaml(cls, name, dct):
        if isinstance(dct, STR):
            return cls(commands=[Command(dct)])

        elif List(STR).query(dct):
            cmds = [Command(s) for s in dct]
            return cls(commands=cmds)

        elif isinstance(dct, dict):
            if set(dct.keys()).issuperset({'command'}):
                ret = Task.from_yaml(name, dct['command'])

                if 'context' in dct:
                    for cmd in ret.commands:
                        cmd.context = dct['context']

                if 'args' in dct:
                    ret.args = dct['args']

                if 'kwargs' in dct:
                    ret.kwargs = dct['kwargs']

                if 'for' in dct:
                    ret.loop = For.from_yaml(dct['for'])

                if 'if' in dct:
                    ret.condition = Task.from_yaml(name + '-if', dct['if'])
                    ret.condition_type = True
                elif 'ifnot' in dct:
                    ret.condition = Task.from_yaml(name + '-ifnot', dct['ifnot'])
                    ret.condition_type = False

                ret.validate()
                return ret

        raise ValidationError('Invalid data for task: {}'.format(name))

    def run(self, env, **kwargs):
        codes = []
        looping = kwargs.get('looping', False)
        exit_on_error = kwargs.get('exit_on_error',
            env.settings.get('exit_on_error', True))
        preview_conditionals = kwargs.get('preview_conditionals',
            env.settings.get('preview_conditionals', True))

        if self.condition and not looping:
            if preview_conditionals:
                kwargs['preview_pre'] = 'if: ' if self.condition_type else 'ifnot: '
            codes_ = self.condition.run(env, **kwargs)
            code = max(codes_)
            if (((self.condition_type is True and code != 0) or
                 (self.condition_type is False and code == 0)) and 
                code is not None):
                return []
            if preview_conditionals:
                kwargs['preview_pre'] = '\t'

        if (self.args or self.kwargs) and not looping:
            env = env.copy(**kwargs)

            if self.args:
                for k, arg in enumerate(self.args):
                    env.env['_{}'.format(k + 1)] = arg

            if self.kwargs:
                for name, value in self.kwargs.items():
                    env.env[name] = value

        if self.loop and not looping:
            n = 0
            kwargs['looping'] = True
            for env_ in self.loop.loop(env, **kwargs):
                env_.env[env_.settings['loop_count_macro']] = n
                codes_ = self.run(env_, **kwargs)
                codes.extend(codes_)
                n += 1
            return codes

        for cmd in self.commands:
            if cmd.command in env.tasks:
                codes_ = env.tasks[cmd.command].run(env, **kwargs)
                codes.extend(codes_)

            else:
                code = cmd.run(env, **kwargs)
                codes.append(code)

            if exit_on_error and any(c != 0 for c in codes if c is not None):
                break

        return codes

    def run_preview(self, env, **kwargs):
        kwargs['preview'] = True
        kwargs['verbose'] = True
        kwargs['run_preview'] = True
        
        with assign(sys, 'stdout', cStringIO()):
            self.run(env, **kwargs)
            ret = sys.stdout.getvalue()
        return ret
Esempio n. 26
0
class For(Base):
    _attrs = dict(var = Attr((STR, List(STR)), doc='The loop variable(s)'),
                  in_ = Attr((STR, List((STR, int, list))), 
                             doc='Name(s) of list macro(s) to loop over'))
    _opts = dict(init_validate = True, 
                 args = ('var', 'in_'))

    @classmethod
    def from_yaml(cls, dct):
        if isinstance(dct, STR):
            m = re.match(FOREX, dct)
            if m:
                return cls(var=m.groups()[0], in_=m.groups()[1])
            else:
                raise ValidationError('Invalid for loop specifier: {}'
                                      .format(dct))

        kwargs = {}
        get_delete(dct, kwargs, 'var', None)
        get_delete(dct, kwargs, 'in', None, 'in_')
        
        if dct:
            raise ValidationError('Invalid for keys: {}'
                                  .format(','.join(dct.keys())))
        return cls(**kwargs)

    def resolve_macros(self, env, **kwargs):
        var = self.var
        in_ = self.in_
        if not isinstance(var, list):
            var = [self.var]
            in_ = [self.in_]

        outs = []
        for k, v in enumerate(var):
            name = in_[k]
            if isinstance(name, list):
                val = name
            else:
                val = env.env[name]
                if not isinstance(val, list):
                    raise ValidationError('For loop "in" specifier must be name of '
                                          'list macro: {}'.format(in_[k]))
            outs.append(val)
        return var, outs

    def loop(self, env, **kwargs):
        var, in_ = self.resolve_macros(env, **kwargs)
        
        for tup in product(*in_):
            yld = env.copy(**kwargs)
            for name, val in zip(var, tup):
                yld.env[name] = val
            yield yld

    def validate(self):
        super(For, self).validate()
        
        if isinstance(self.var, list):
            if len(self.var) != len(self.in_):
                raise ValidationError('"var" and "in" lists must be same '
                                      'length')
Esempio n. 27
0
class IstrTest(Base):
    _attrs = dict(a=Attr(int))
Esempio n. 28
0
class Range(SetLeaf):
    _attrs = dict(lb=Attr(int, doc='The lower bound'),
                  ub=Attr(int, doc='The upper bound'))
    _opts = dict(args=('lb', 'ub'))

    def display(self, **kwargs):
        return '[{}, {}]'.format(self.lb, self.ub)

    def size(self):
        return self.ub - self.lb + 1

    def validate(self):
        super(Range, self).validate()

        if self.lb > self.ub:
            raise ValueError("Invalid interval bounds")

    def overlaps(self, other):
        if isinstance(other, type(self)):
            if self.lb <= other.lb <= self.ub:
                return True

            if other.lb <= self.lb <= other.ub:
                return True

        return False

    @classmethod
    def _union(cls, a, b):
        if a is NULL and b is NULL:
            return NULL
        if a is NULL:
            return b
        if b is NULL:
            return a

        if a.lb <= b.lb and b.ub >= a.ub:
            return cls(a.lb, b.ub)
        elif a.lb <= b.lb:
            return a
        elif b.lb <= a.lb and a.ub <= b.ub:
            return b
        else:
            return cls(b.lb, a.ub)

    def union(self, *args):
        if not args:
            return self, []

        test = lambda item, accum: item.overlaps(accum) or accum is NULL
        return defer_reduce(type(self)._union, (self, ) + args, test, NULL)

    @classmethod
    def _intersection(cls, a, b):
        if a is NULL or b is NULL:
            return NULL

        if not a.overlaps(b):
            return NULL

        if a.lb <= b.lb and b.ub >= a.ub:
            return cls(b.lb, a.ub)
        elif a.lb <= b.lb:
            return b
        elif b.lb <= a.lb and a.ub <= b.ub:
            return a
        else:
            return cls(a.lb, b.ub)

    def intersection(self, *args):
        if not args:
            return self

        ret = reduce(type(self)._intersection, (self, ) + args)
        return ret

    def difference(self, other):
        if other is NULL:
            return self, None

        if not self.overlaps(other):
            return self, None

        a = self
        b = other
        cls = type(self)

        if a.lb < b.lb and b.ub >= a.ub:
            return cls(a.lb, b.lb - 1), None
        elif a.lb < b.lb:
            return cls(a.lb, b.lb - 1), cls(b.ub + 1, a.ub)
        elif b.lb < a.lb and a.ub < b.ub:
            return NULL, None
        else:
            return cls(b.ub + 1, a.ub), None

    def complement(self, universe):
        ret = universe.difference(self)
        return ret

    def issubset(self, other):
        return self.lb >= other.lb and self.ub <= other.ub

    def issuperset(self, other):
        return self.lb <= other.lb and self.ub >= other.ub

    def hasmember(self, other):
        return self.lb <= other <= self.ub

    def sample(self, **kwargs):
        ret = randint(self.lb, self.ub)
        return ret

    def enumerate(self, **kwargs):
        args = Args(**kwargs)
        maxenum = args.max_enumerate

        for k, item in enumerate(xrange(self.lb, self.ub + 1)):
            if k >= maxenum:
                break
            yield item

    def to_set(self, **kwargs):
        args = Args(**kwargs)
        N = self.ub - self.lb
        ub = self.lb + min(N, args.max_enumerate - 1)

        ret = set(range(self.lb, ub + 1))
        return ret
Esempio n. 29
0
 class B(Vars):
     _opts = dict(init_validate=True)
     _attrs = dict(foo=Attr(STR))
Esempio n. 30
0
 class A(Vars):
     _opts = dict(init_validate=True)
     _attrs = dict(a=Attr(int),
                   b=Attr(float),
                   c=Attr(STR),
                   d=Attr(STR, optional=True))