def test_sh_runerror_unicode(): # https://github.com/activestate/applib/issues/12 with pytest.raises(sh.RunError): try: sh.run('echo ' + "\u1234" + " & nonexistant") except sh.RunError as e: print(safe_unicode(e)) raise
def test_sh_runerror_limit(): with pytest.raises(sh.RunError): from random import choice import string LINE = ''.join([choice(string.ascii_letters) for x in range(80)]) try: sh.run(r'''python -c "print('\n'.join(['%s']*100)); raise SystemExit('an error');"''' % LINE) except sh.RunError as e: c = str(e).count(LINE) # def _limit_str(s, maxchars=80*15): --- so ~ 15 lines (not 100 lines) assert c < 20, "original message: %s" % e assert '[...]' in str(e) raise
def postinstall_generic(pypmenv, ipkg): """Run the generic postinstall script (if exists) The postinstall script is expected to be found in the additional files area: share/<name>/postinstall.py. """ # Use forward slash, as that is ipkg.files_lists uses as well postinstall_script = 'share/{0}/postinstall.py'.format(ipkg.name) if postinstall_script not in ipkg.files_list: return postinstall_script = P.join(pypmenv.pyenv.base_dir, postinstall_script) assert P.exists(postinstall_script) LOG.debug('Running postinstall: %s', postinstall_script) try: stdout, _ = sh.run( [pypmenv.pyenv.python_exe, postinstall_script], merge_streams=True) except sh.RunError as e: LOG.error('** postinstall script failed **; ' 'run `pypm log` for details') LOG.debug('postinstall: %s', str(e).strip()) else: if stdout: LOG.info('postinstall: %s', stdout.strip())
def do_ls(self, subcmd, opts): """${cmd_name}: Show directory listing (runs 'ls') ${cmd_usage} ${cmd_option_list} """ with self.bootstrapped(): print(sh.run('ls')[0].decode('utf-8'))
def eval(self, expr, with_modules=None, preimport_stmts=[], python_args=None): """Evaluate `expr` and return the *printed* value (utf8 string) `expr` can be a string, or list of strings. For the later, each expr is printed in separate line. Note that `expr` supports only single-quote; and double-quotes will be appropriate escaped. Before evaluating `expr` execute `preimport_stmts` and import the mentioned modules. If `python_args` is None, use the default args (-B), otherwise use the argument value as Python args. Note that the returned value will include a newline at the end - which is the default behavior of `print`. XXX: we should change this? """ statements = [] if preimport_stmts: assert isinstance(preimport_stmts, (list, tuple)) statements.extend(preimport_stmts) if with_modules: assert isinstance(with_modules, (list, tuple)) statements.extend( ['import %s' % mod for mod in with_modules] ) if python_args is None: python_args = ['-B'] # no bytecode generation assert isinstance(python_args, (tuple, list)) if not isinstance(expr, (list, tuple)): expr = [expr] for e in expr: statements.append('print({0})'.format(e)) cmd = [self.python_exe] + python_args + [ '-s', '-c', ';'.join(statements) ] return sh.run(cmd)[0].decode('utf8')
def eval(self, expr, with_modules=None, preimport_stmts=[], python_args=None): """Evaluate `expr` and return the *printed* value (utf8 string) `expr` can be a string, or list of strings. For the later, each expr is printed in separate line. Note that `expr` supports only single-quote; and double-quotes will be appropriate escaped. Before evaluating `expr` execute `preimport_stmts` and import the mentioned modules. If `python_args` is None, use the default args (-B), otherwise use the argument value as Python args. Note that the returned value will include a newline at the end - which is the default behavior of `print`. XXX: we should change this? """ statements = [] if preimport_stmts: assert isinstance(preimport_stmts, (list, tuple)) statements.extend(preimport_stmts) if with_modules: assert isinstance(with_modules, (list, tuple)) statements.extend(['import %s' % mod for mod in with_modules]) if python_args is None: python_args = ['-B'] # no bytecode generation assert isinstance(python_args, (tuple, list)) if not isinstance(expr, (list, tuple)): expr = [expr] for e in expr: statements.append('print({0})'.format(e)) cmd = [self.python_exe ] + python_args + ['-s', '-c', ';'.join(statements)] return sh.run(cmd)[0].decode('utf8')
def postinstall_generic(pypmenv, ipkg): """Run the generic postinstall script (if exists) The postinstall script is expected to be found in the additional files area: share/<name>/postinstall.py. """ # Use forward slash, as that is ipkg.files_lists uses as well postinstall_script = 'share/{0}/postinstall.py'.format(ipkg.name) if postinstall_script not in ipkg.files_list: return postinstall_script = P.join(pypmenv.pyenv.base_dir, postinstall_script) assert P.exists(postinstall_script) LOG.debug('Running postinstall: %s', postinstall_script) try: stdout, _ = sh.run([pypmenv.pyenv.python_exe, postinstall_script], merge_streams=True) except sh.RunError as e: LOG.error('** postinstall script failed **; ' 'run `pypm log` for details') LOG.debug('postinstall: %s', str(e).strip()) else: if stdout: LOG.info('postinstall: %s', stdout.strip())