Example #1
0
def parseScript(script, name=None, format=None, compilecode=True):
    if compilecode:
        def compiler(src):
            if not isinstance(src, text_type):
                src = src.decode('utf-8')
            return compile(src + '\n', '<script>', 'single', CO_DIVISION)
    else:
        compiler = lambda src: src
    if '\n' not in script:
        # if the script is a single line, compile it like a line
        # in the interactive interpreter, so that expression
        # results are shown
        code = [session.commandHandler(script, compiler)]
        blocks = None
    else:
        pycode = script
        # check for SPM scripts
        if format != 'py':
            pycode = session.scriptHandler(script, name or '', lambda c: c)
        # replace bare except clauses in the code with "except Exception"
        # so that ControlStop is not caught
        pycode = fixupScript(pycode)
        if not compilecode:
            # no splitting desired
            code = [compiler(pycode)]
            blocks = None
        else:
            # long script: split into blocks
            code, blocks = splitBlocks(pycode)

    return code, blocks
Example #2
0
def _RunScript(filename, statdevices, debug=False):
    fn = _scriptfilename(filename)
    if not path.isfile(fn) and os.access(fn, os.R_OK):
        raise UsageError('The file %r does not exist or is not readable' % fn)
    if session.mode == SIMULATION:
        starttime = session.clock.time
        for dev in statdevices:
            if not isinstance(dev, Readable):
                session.log.warning('unable to collect statistics on %r', dev)
                continue
            dev._sim_min = None
            dev._sim_max = None
    session.log.info('running user script: %s', fn)
    try:
        fp = io.open(fn, 'r', encoding='utf-8')
    except Exception as e:
        if session.mode == SIMULATION:
            session.log.exception('Dry run: error opening script')
            return
        raise NicosError('cannot open script %r: %s' % (filename, e))
    with fp:
        code = fp.read()
        # guard against bare excepts
        code = fixupScript(code)
        # quick guard against self-recursion
        if session.experiment and session.experiment.scripts and \
                code.strip() == session.experiment.scripts[-1].strip():
            raise NicosError('script %r would call itself, aborting' %
                             filename)

        def compiler(src):
            return compile(src + '\n', fn, 'exec', CO_DIVISION)
        compiled = session.scriptHandler(code, fn, compiler)
        with _ScriptScope(path.basename(fn), code):
            try:
                exec_(compiled, session.namespace)
            except Exception:
                if debug:
                    traceback.print_exc()
                raise
    session.log.info('finished user script: %s', fn)
    if session.mode == SIMULATION:
        session.log.info('simulated minimum runtime: %s',
                         formatDuration(session.clock.time - starttime,
                                        precise=False))
        for dev in statdevices:
            if not isinstance(dev, Readable):
                continue
            session.log.info('%s: min %s, max %s, last %s %s',
                             dev.name,
                             dev.format(dev._sim_min),
                             dev.format(dev._sim_max),
                             dev.format(dev._sim_value), dev.unit)
Example #3
0
def _RunCode(code, debug=False):
    if session.mode == SIMULATION:
        starttime = session.clock.time
    code = fixupScript(code)
    try:
        exec_(code, session.namespace)
    except Exception:
        if debug:
            traceback.print_exc()
        raise
    if session.mode == SIMULATION:
        session.log.info('simulated minimum runtime: %s',
                         formatDuration(session.clock.time - starttime,
                                        precise=False))
Example #4
0
    def update(self, text, reason, controller, user):
        """Update the code with a new script.

        This method is called from a different thread than execute(),
        so we must unset the _run flag before doing anything to
        self.curblock, self.code or self.blocks.
        """
        if not self.blocks:
            raise ScriptError('cannot update single-line script')
        text = fixupScript(text)
        newcode, newblocks = splitBlocks(text)
        # stop execution after the current block
        self._run.clear()
        curblock = self.curblock  # this may be off by one
        try:
            # make sure that everything that has already been executed matches
            if curblock >= len(newblocks):
                # insufficient number of new blocks
                raise ScriptError('new script too short')
            # compare all executed blocks
            for i in range(curblock + 1):
                if not self._compare(self.blocks[i], newblocks[i]):
                    raise ScriptError('new script differs in already executed '
                                      'part of the code')
            # everything is ok, replace the script and the remaining blocks
            self.text = text
            session.scriptEvent('update', (self.name, self.text))
            # also set the updating user as the new user of the script
            self.user = user
            if session._experiment and session.mode == MASTER:
                scr = list(session.experiment.scripts)  # convert readonly list
                scr[self._exp_script_index] = self.text
                session.experiment.scripts = scr
            updateLinecache('<script>', text)
            self.code, self.blocks = newcode, newblocks
            self.resetSimstate()
            # let the client know of the update
            controller.eventfunc('processing', self.serialize())
            updatemsg = 'UPDATE (%s)' % reason if reason else 'UPDATE'
            session.log.log(INPUT, formatScript(self, updatemsg))
        finally:
            # let the script continue execution in any case
            self._run.set()