ruff: except: -> except Exception:
This commit is contained in:
parent
779133d203
commit
b43fc87e3a
38 changed files with 67 additions and 67 deletions
|
|
@ -110,7 +110,7 @@ class AddrListID(HiliteStr, InitErrors, MMGenObject):
|
|||
sid = SeedID(sid=a)
|
||||
try:
|
||||
mmtype = MMGenAddrType(proto=proto, id_str=b)
|
||||
except:
|
||||
except Exception:
|
||||
mmtype = MMGenPasswordType(proto=proto, id_str=b)
|
||||
else:
|
||||
assert isinstance(sid, SeedID), f'{sid!r} not a SeedID instance'
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ class CoinInfo:
|
|||
def get_entry(cls, coin, network):
|
||||
try:
|
||||
idx = [e.symbol for e in cls.coin_constants[network]].index(coin.upper())
|
||||
except:
|
||||
except Exception:
|
||||
return None
|
||||
return cls.coin_constants[network][idx]
|
||||
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ class Autosign:
|
|||
|
||||
try:
|
||||
dirlist = self.wallet_dir.iterdir()
|
||||
except:
|
||||
except Exception:
|
||||
die(1,
|
||||
f'Cannot open wallet directory ‘{self.wallet_dir}’. '
|
||||
'Did you run ‘mmgen-autosign setup’?')
|
||||
|
|
@ -330,7 +330,7 @@ class Autosign:
|
|||
try:
|
||||
self.keyfile.write_text(os.urandom(32).hex())
|
||||
self.keyfile.chmod(0o400)
|
||||
except:
|
||||
except Exception:
|
||||
die(2, 'Unable to write ' + desc)
|
||||
msg('Wrote ' + desc)
|
||||
|
||||
|
|
@ -367,17 +367,17 @@ class Autosign:
|
|||
import shutil
|
||||
try:
|
||||
shutil.rmtree(self.wallet_dir)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def create_wallet_dir():
|
||||
try:
|
||||
self.wallet_dir.mkdir(parents=True)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
self.wallet_dir.stat()
|
||||
except:
|
||||
except Exception:
|
||||
die(2, f'Unable to create wallet directory ‘{self.wallet_dir}’')
|
||||
|
||||
self.gen_key(no_unmount=True)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ def is_mmgen_mnemonic(s):
|
|||
try:
|
||||
baseconv('mmgen').tobytes(s.split(), pad='seed')
|
||||
return True
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
class baseconv:
|
||||
|
|
|
|||
|
|
@ -840,7 +840,7 @@ def check_opts(cfg): # Raises exception if any check fails
|
|||
case 'hidden_incog_output_params':
|
||||
try:
|
||||
os.stat(fn)
|
||||
except:
|
||||
except Exception:
|
||||
b = os.path.dirname(fn)
|
||||
if b:
|
||||
check_outdir(b)
|
||||
|
|
@ -969,5 +969,5 @@ def conv_type(name, val, refval, *, src, invert_bool=False):
|
|||
else:
|
||||
try:
|
||||
return type(refval)(not val if invert_bool else val)
|
||||
except:
|
||||
except Exception:
|
||||
do_fail()
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class cfg_file:
|
|||
with open(fn, 'w') as fp:
|
||||
fp.write('\n'.join(data)+'\n')
|
||||
os.chmod(fn, 0o600)
|
||||
except:
|
||||
except Exception:
|
||||
die(2, f'ERROR: unable to write to {fn!r}')
|
||||
|
||||
def parse_value(self, value, refval):
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ class Daemon(Lockable):
|
|||
def state_msg(self, *, extra_text=None):
|
||||
try:
|
||||
pid = self.pid
|
||||
except:
|
||||
except Exception:
|
||||
pid = None
|
||||
extra_text = 'not ' if self.state == 'stopped' else f'{extra_text} ' if extra_text else ''
|
||||
return '{:{w}} {:10} {}'.format(
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ def check_binary(args):
|
|||
from subprocess import run, DEVNULL
|
||||
try:
|
||||
run(args, stdout=DEVNULL, stderr=DEVNULL, check=True)
|
||||
except:
|
||||
except Exception:
|
||||
die(2, f'{args[0]!r} binary missing, not in path, or not executable')
|
||||
|
||||
def shred_file(cfg, fn, *, iterations=30):
|
||||
|
|
@ -137,7 +137,7 @@ def get_seed_file(cfg, *, nargs, wallets=None, invoked_as=None):
|
|||
def _open_or_die(filename, mode, *, silent=False):
|
||||
try:
|
||||
return open(filename, mode)
|
||||
except:
|
||||
except Exception:
|
||||
if silent:
|
||||
die(2, '')
|
||||
else:
|
||||
|
|
@ -216,7 +216,7 @@ def write_data_to_file(
|
|||
# MSWin workaround. See msg_r()
|
||||
try:
|
||||
sys.stdout.write(data.decode() if isinstance(data, bytes) else data)
|
||||
except:
|
||||
except Exception:
|
||||
os.write(1, data if isinstance(data, bytes) else data.encode())
|
||||
|
||||
def do_file(outfile, ask_write_prompt):
|
||||
|
|
@ -260,7 +260,7 @@ def write_data_to_file(
|
|||
try:
|
||||
with _open_or_die(outfile, 'wb') as fp:
|
||||
fp.write(data if binary else data.encode())
|
||||
except:
|
||||
except Exception:
|
||||
die(2, f'Failed to write {desc} to file {outfile!r}')
|
||||
|
||||
if not (hush or quiet):
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ def launch(*, mod=None, func=None, fqmod=None, package='mmgen'):
|
|||
except Exception as e:
|
||||
try:
|
||||
errmsg = str(e.args[0])
|
||||
except:
|
||||
except Exception:
|
||||
errmsg = repr(e.args[0]) if e.args else repr(e)
|
||||
|
||||
from collections import namedtuple
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class MsgOps:
|
|||
async def __init__(self, msgfile, *, addr=None):
|
||||
try:
|
||||
m = SignedOnlineMsg(cfg, infile=msgfile)
|
||||
except:
|
||||
except Exception:
|
||||
m = ExportedMsgSigs(cfg, infile=msgfile)
|
||||
|
||||
nSigs = await m.verify(addr=addr)
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ def process_result(ret, *, pager=False, print_result=False):
|
|||
case bytes():
|
||||
try:
|
||||
return triage_result(ret.decode())
|
||||
except:
|
||||
except Exception:
|
||||
# don't add NL to binary data if it can't be converted to utf8
|
||||
return os.write(1, ret) if print_result else ret
|
||||
case _:
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ def init_autosign(arg):
|
|||
elif post_send_op:
|
||||
try:
|
||||
tx_range = SentTXRange(arg)
|
||||
except:
|
||||
except Exception:
|
||||
die(2, f'{arg}: invalid transaction index arg '
|
||||
'(must be a non-negative integer or hyphen-separated range)')
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ class BitcoinRPCClient(RPCClient, metaclass=AsyncInit):
|
|||
try:
|
||||
lines = get_lines_from_file(
|
||||
self.cfg, fn, desc='daemon config file', silent=not self.cfg.verbose)
|
||||
except:
|
||||
except Exception:
|
||||
self.cfg._util.vmsg(f'Warning: {fn!r} does not exist or is unreadable')
|
||||
return {k: None for k in req_keys}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class BitcoinTwJSON(TwJSON):
|
|||
try:
|
||||
await self.twctl.rpc.check_or_create_daemon_wallet()
|
||||
return True
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
async def get_entries(self):
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class New(Base, TxNew):
|
|||
self.cfg.fee_estimate_mode.upper())
|
||||
fee_per_kb = self.proto.coin_amt(ret['feerate']) if 'feerate' in ret else None
|
||||
fe_type = 'estimatesmartfee'
|
||||
except:
|
||||
except Exception:
|
||||
args = self.rpc.daemon.estimatefee_args(self.rpc)
|
||||
ret = await self.rpc.call('estimatefee', *args)
|
||||
fee_per_kb = self.proto.coin_amt(ret)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class Status(TxBase.Status):
|
|||
txid = tx.coin_txid,
|
||||
include_watchonly = True,
|
||||
verbose = False)
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
if ret.get('confirmations', 0) > 0:
|
||||
r.confs = ret['confirmations']
|
||||
|
|
@ -49,14 +49,14 @@ class Status(TxBase.Status):
|
|||
async def is_in_utxos():
|
||||
try:
|
||||
return 'txid' in await tx.rpc.call('getrawtransaction', tx.coin_txid, True)
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
async def is_in_mempool():
|
||||
try:
|
||||
await tx.rpc.call('getmempoolentry', tx.coin_txid)
|
||||
return True
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
async def is_replaced():
|
||||
|
|
@ -68,7 +68,7 @@ class Status(TxBase.Status):
|
|||
txid = tx.coin_txid,
|
||||
include_watchonly = True,
|
||||
verbose = False)
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
else:
|
||||
if 'bip125-replaceable' in ret and ret.get('confirmations', 1) <= 0:
|
||||
|
|
@ -108,7 +108,7 @@ class Status(TxBase.Status):
|
|||
for txid in r.replacing_txs:
|
||||
try:
|
||||
d.append(await tx.rpc.call('getmempoolentry', txid))
|
||||
except:
|
||||
except Exception:
|
||||
d.append({})
|
||||
for txid, mp_entry in zip(r.replacing_txs, d):
|
||||
msg(f' {txid}' + (' in mempool' if 'height' in mp_entry else ''))
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ class Token(Contract):
|
|||
try:
|
||||
assert ret.startswith('0x')
|
||||
return int(ret, 16)
|
||||
except:
|
||||
except Exception:
|
||||
msg(f'RPC call to decimals() failed (returned {ret!r})')
|
||||
|
||||
async def get_total_supply(self):
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ class RPCClient:
|
|||
return ret
|
||||
else:
|
||||
return json.loads(text, parse_float=float_parser)
|
||||
except:
|
||||
except Exception:
|
||||
if not m:
|
||||
t = json.loads(text)
|
||||
try:
|
||||
|
|
@ -184,10 +184,10 @@ class RPCClient:
|
|||
if text:
|
||||
try:
|
||||
m = json.loads(text)['error']['message']
|
||||
except:
|
||||
except Exception:
|
||||
try:
|
||||
m = text.decode()
|
||||
except:
|
||||
except Exception:
|
||||
m = text
|
||||
die('RPCFailure', f'{s.value} {s.name}: {m}')
|
||||
|
||||
|
|
|
|||
|
|
@ -105,12 +105,12 @@ class MMGenTermLinux(MMGenTerm):
|
|||
def get_terminal_size(cls):
|
||||
try:
|
||||
ret = os.get_terminal_size()
|
||||
except:
|
||||
except Exception:
|
||||
try:
|
||||
ret = (
|
||||
int(os.environ['COLUMNS']),
|
||||
int(os.environ['LINES']))
|
||||
except:
|
||||
except Exception:
|
||||
ret = (80, 25)
|
||||
return _term_dimensions(*ret)
|
||||
|
||||
|
|
@ -207,7 +207,7 @@ class MMGenTermMSWin(MMGenTerm):
|
|||
left, top, right, bottom = struct.unpack('hhhhHhhhhhh', csbi.raw)[5:9]
|
||||
x = right - left + 1
|
||||
y = bottom - top + 1
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if x and y:
|
||||
|
|
@ -276,7 +276,7 @@ class MMGenTermMSWinStub(MMGenTermMSWin):
|
|||
while True:
|
||||
try:
|
||||
return sys.stdin.read(1)
|
||||
except:
|
||||
except Exception:
|
||||
msg('[read error, trying again]')
|
||||
time.sleep(0.5)
|
||||
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ def process_args(cmd, cmd_args, cls):
|
|||
|
||||
try:
|
||||
return __builtins__[arg_type](arg)
|
||||
except:
|
||||
except Exception:
|
||||
die(1, f'{arg!r}: Invalid argument for argument {arg_name} ({arg_type!r} required)')
|
||||
|
||||
if flag == 'VAR_ARGS':
|
||||
|
|
|
|||
|
|
@ -100,10 +100,10 @@ class TwCtlWithStore(TwCtl):
|
|||
try:
|
||||
self.orig_data = get_data_from_file(self.cfg, self.tw_path, quiet=True)
|
||||
self.data = json.loads(self.orig_data)
|
||||
except:
|
||||
except Exception:
|
||||
try:
|
||||
self.tw_path.stat()
|
||||
except:
|
||||
except Exception:
|
||||
self.orig_data = ''
|
||||
self.init_empty()
|
||||
self.force_write()
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class DataOutput(bytes, InitErrors):
|
|||
elif data_spec.startswith('data:'):
|
||||
try:
|
||||
ret = data_spec[5:].encode('utf8')
|
||||
except:
|
||||
except Exception:
|
||||
raise ValueError(f'{cls.desc} value must be UTF-8 encoded')
|
||||
else:
|
||||
raise ValueError(f'{cls.desc} argument must start with ‘data:’ or ‘hexdata:’')
|
||||
|
|
@ -53,7 +53,7 @@ class DataOutput(bytes, InitErrors):
|
|||
self.display_hex = True
|
||||
try:
|
||||
ret = self.decode('utf8')
|
||||
except:
|
||||
except Exception:
|
||||
return self.hex()
|
||||
else:
|
||||
import unicodedata
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ class MMGenTxFile(MMGenObject):
|
|||
from ast import literal_eval
|
||||
try:
|
||||
return literal_eval(raw_data)
|
||||
except:
|
||||
except Exception:
|
||||
if desc == 'inputs':
|
||||
ymsg('Warning: transaction data appears to be in old format')
|
||||
import re
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class TxInfo:
|
|||
else:
|
||||
try:
|
||||
blockcount = tx.rpc.blockcount
|
||||
except:
|
||||
except Exception:
|
||||
blockcount = None
|
||||
|
||||
def get_max_mmwid(io):
|
||||
|
|
|
|||
|
|
@ -207,7 +207,7 @@ def do_pager(text):
|
|||
input = text.encode() if pager == 'less' else (text + end_msg).encode(),
|
||||
check = True)
|
||||
msg_r('\r')
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ if gc.platform == 'win32':
|
|||
try:
|
||||
gv.stderr.write(s)
|
||||
gv.stderr.flush()
|
||||
except:
|
||||
except Exception:
|
||||
os.write(2, s.encode())
|
||||
|
||||
def msg(s):
|
||||
|
|
@ -111,7 +111,7 @@ if gc.platform == 'win32':
|
|||
try:
|
||||
gv.stdout.write(s)
|
||||
gv.stdout.flush()
|
||||
except:
|
||||
except Exception:
|
||||
os.write(1, s.encode())
|
||||
|
||||
def Msg(s):
|
||||
|
|
@ -392,7 +392,7 @@ def is_hex_str_lc(s):
|
|||
def is_utf8(s):
|
||||
try:
|
||||
s.decode('utf8')
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
|
@ -490,7 +490,7 @@ def have_sudo(*, silent=False):
|
|||
try:
|
||||
run(['sudo', '--non-interactive', 'true'], stdout=redir, stderr=redir, check=True)
|
||||
return True
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def distro_codename():
|
||||
|
|
|
|||
|
|
@ -224,7 +224,7 @@ def decode_pretty_hexdump(data):
|
|||
lines = [pat.sub('', line) for line in data.splitlines()]
|
||||
try:
|
||||
return bytes.fromhex(''.join(''.join(lines).split()))
|
||||
except:
|
||||
except Exception:
|
||||
msg('Data not in hexdump format')
|
||||
return False
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class OpMixinSpec:
|
|||
idx = int(m[i])
|
||||
try:
|
||||
res = self.kal.entry(idx)
|
||||
except:
|
||||
except Exception:
|
||||
die(1,
|
||||
'Supplied key-address file does not contain address '
|
||||
f'{self.kal.al_id.sid}:{idx}')
|
||||
|
|
|
|||
|
|
@ -202,5 +202,5 @@ class MoneroWalletRPC:
|
|||
ret = self.c.call('relay_tx', hex=tx_hex)
|
||||
try:
|
||||
msg('\n Relayed {}'.format(CoinTxID(ret['tx_hash']).hl()))
|
||||
except:
|
||||
except Exception:
|
||||
msg(f'\n Server returned: {ret!s}')
|
||||
|
|
|
|||
|
|
@ -34,15 +34,15 @@ def create_shm_dir(data_dir, autosign_data_dir, trash_dir, trash_dir2):
|
|||
for tdir in (data_dir, autosign_data_dir, trash_dir, trash_dir2):
|
||||
try:
|
||||
os.listdir(tdir)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
shutil.rmtree(tdir)
|
||||
except: # we couldn't remove data dir - perhaps regtest daemon is running
|
||||
except Exception: # we couldn't remove data dir - perhaps regtest daemon is running
|
||||
try:
|
||||
run(['python3', os.path.join('cmds', 'mmgen-regtest'), 'stop'], check=True)
|
||||
except:
|
||||
except Exception:
|
||||
die(4, f'Unable to remove {tdir!r}!')
|
||||
else:
|
||||
time.sleep(2)
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ class CmdTestAutosignBase(CmdTestBase):
|
|||
def _macOS_eject_disk(self, label):
|
||||
try:
|
||||
run(['diskutil' , 'eject', label], stdout=DEVNULL, stderr=DEVNULL)
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def start_daemons(self):
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class CmdTestBase:
|
|||
fn = os.path.join(self.tmpdir, fn)
|
||||
try:
|
||||
return os.unlink(fn)
|
||||
except:
|
||||
except Exception:
|
||||
msg(f'{fn}: file does not exist or could not be deleted')
|
||||
|
||||
def skip_on_condition(self, condition, message, extra_msg):
|
||||
|
|
|
|||
|
|
@ -465,7 +465,7 @@ def dump_test(proto, kg, ag, filename):
|
|||
qmsg_r(f'\rKey {count}/{len(dump)} ')
|
||||
try:
|
||||
b_sec = PrivKey(proto, wif=b_wif)
|
||||
except:
|
||||
except Exception:
|
||||
die(2, f'\nInvalid {proto.network} WIF address in dump file: {b_wif}')
|
||||
a_addr = ag.to_addr(kg.gen_data(b_sec))
|
||||
vmsg(f'\nwif: {b_wif}\naddr: {b_addr}\n')
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ def cleandir(d, do_msg=False):
|
|||
|
||||
try:
|
||||
files = os.listdir(d_enc)
|
||||
except:
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
if files:
|
||||
|
|
@ -148,7 +148,7 @@ def cleandir(d, do_msg=False):
|
|||
for f in files:
|
||||
try:
|
||||
os.unlink(os.path.join(d_enc, f))
|
||||
except:
|
||||
except Exception:
|
||||
rmtree(os.path.join(d_enc, f), ignore_errors=True)
|
||||
|
||||
return files
|
||||
|
|
@ -406,7 +406,7 @@ class VirtBlockDeviceBase:
|
|||
def try_detach(self):
|
||||
try:
|
||||
dev = self.dev
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
self.do_detach(dev, check=False)
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ def run_test(test, subtest=None):
|
|||
|
||||
if do_desc and not cfg.quiet:
|
||||
msg('OK\n' if cfg.verbose else 'OK')
|
||||
except:
|
||||
except Exception:
|
||||
if getattr(t, 'silence_output', False):
|
||||
end_silence()
|
||||
raise
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ def run_test(mod, test, arg, input_data, arg1, exc_name):
|
|||
else:
|
||||
try:
|
||||
ret_disp = ret.decode()
|
||||
except:
|
||||
except Exception:
|
||||
ret_disp = ret
|
||||
msg(f'==> {ret_disp!r}')
|
||||
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ class MMGenToolTestUtils:
|
|||
from test.include.common import dmsg
|
||||
try:
|
||||
dmsg(err.decode())
|
||||
except:
|
||||
except Exception:
|
||||
dmsg(repr(err))
|
||||
if not binary:
|
||||
out = out.decode()
|
||||
|
|
@ -354,7 +354,7 @@ tu = MMGenToolTestUtils()
|
|||
def ok_or_die(val, chk_func, s, skip_ok=False):
|
||||
try:
|
||||
ret = chk_func(val)
|
||||
except:
|
||||
except Exception:
|
||||
ret = False
|
||||
if ret:
|
||||
if not skip_ok:
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ def fork_cmd(cmd_name, args, opts, stdin_input):
|
|||
cp = run(cmd, input=stdin_input or None, capture_output=True)
|
||||
try:
|
||||
cmd_out = cp.stdout.decode()
|
||||
except:
|
||||
except Exception:
|
||||
cmd_out = cp.stdout
|
||||
if cp.stderr:
|
||||
vmsg(cp.stderr.strip().decode())
|
||||
|
|
@ -162,7 +162,7 @@ def check_output(out, chk):
|
|||
|
||||
try:
|
||||
outd = out.decode()
|
||||
except:
|
||||
except Exception:
|
||||
outd = None
|
||||
|
||||
err_fs = "Output ({!r}) doesn't match expected output ({!r})"
|
||||
|
|
@ -242,7 +242,7 @@ def run_test(cls, gid, cmd_name):
|
|||
|
||||
try:
|
||||
vmsg(f'Output:\n{cmd_out}\n')
|
||||
except:
|
||||
except Exception:
|
||||
vmsg(f'Output:\n{cmd_out!r}\n')
|
||||
|
||||
if isinstance(out, tuple) and type(out[0]).__name__ == 'function':
|
||||
|
|
|
|||
Loading…
Reference in a new issue