2015-03-11 23:43:07 +08:00
|
|
|
import asyncio
|
2021-02-09 23:13:36 +08:00
|
|
|
import importlib.util
|
2021-02-12 06:01:54 +08:00
|
|
|
import inspect
|
2019-01-12 09:47:47 +08:00
|
|
|
import logging
|
2018-01-19 16:28:04 +08:00
|
|
|
import os
|
2021-02-09 23:13:36 +08:00
|
|
|
import pathlib
|
2019-01-12 09:47:47 +08:00
|
|
|
import string
|
|
|
|
import sys
|
2014-12-08 16:11:31 +08:00
|
|
|
|
2015-10-12 19:46:14 +08:00
|
|
|
import numpy as np
|
|
|
|
|
2019-11-10 15:55:17 +08:00
|
|
|
from sipyco import pyon
|
|
|
|
|
2019-01-12 09:47:47 +08:00
|
|
|
from artiq import __version__ as artiq_version
|
|
|
|
from artiq.appdirs import user_config_dir
|
2021-02-12 06:01:54 +08:00
|
|
|
from artiq.language.environment import is_public_experiment
|
2019-11-10 15:55:17 +08:00
|
|
|
|
2015-04-07 13:04:47 +08:00
|
|
|
|
2016-01-26 09:04:06 +08:00
|
|
|
__all__ = ["parse_arguments", "elide", "short_format", "file_import",
|
2019-11-10 15:55:17 +08:00
|
|
|
"get_experiment",
|
2019-11-14 15:21:51 +08:00
|
|
|
"exc_to_warning", "asyncio_wait_or_cancel",
|
2016-07-19 00:16:56 +08:00
|
|
|
"get_windows_drives", "get_user_config_dir"]
|
2015-11-11 16:22:12 +08:00
|
|
|
|
|
|
|
|
2015-08-08 23:36:12 +08:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
2015-04-07 13:04:47 +08:00
|
|
|
def parse_arguments(arguments):
|
|
|
|
d = {}
|
|
|
|
for argument in arguments:
|
|
|
|
name, eq, value = argument.partition("=")
|
|
|
|
d[name] = pyon.decode(value)
|
|
|
|
return d
|
2014-12-08 16:11:31 +08:00
|
|
|
|
2015-06-05 00:37:26 +08:00
|
|
|
|
2015-10-12 18:10:58 +08:00
|
|
|
def elide(s, maxlen):
|
|
|
|
elided = False
|
|
|
|
if len(s) > maxlen:
|
|
|
|
s = s[:maxlen]
|
|
|
|
elided = True
|
|
|
|
try:
|
|
|
|
idx = s.index("\n")
|
|
|
|
except ValueError:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
s = s[:idx]
|
|
|
|
elided = True
|
|
|
|
if elided:
|
|
|
|
maxlen -= 3
|
|
|
|
if len(s) > maxlen:
|
|
|
|
s = s[:maxlen]
|
|
|
|
s += "..."
|
|
|
|
return s
|
|
|
|
|
|
|
|
|
|
|
|
def short_format(v):
|
|
|
|
if v is None:
|
|
|
|
return "None"
|
|
|
|
t = type(v)
|
2016-05-22 02:11:08 +08:00
|
|
|
if np.issubdtype(t, np.number) or np.issubdtype(t, np.bool_):
|
2015-10-12 18:10:58 +08:00
|
|
|
return str(v)
|
2016-05-22 02:11:08 +08:00
|
|
|
elif np.issubdtype(t, np.unicode_):
|
2015-10-18 13:32:29 +08:00
|
|
|
return "\"" + elide(v, 50) + "\""
|
2015-10-12 18:10:58 +08:00
|
|
|
else:
|
|
|
|
r = t.__name__
|
|
|
|
if t is list or t is dict or t is set:
|
|
|
|
r += " ({})".format(len(v))
|
2015-10-21 11:13:46 +08:00
|
|
|
if t is np.ndarray:
|
|
|
|
r += " " + str(np.shape(v))
|
2015-10-12 18:10:58 +08:00
|
|
|
return r
|
|
|
|
|
|
|
|
|
2015-08-28 15:22:59 +08:00
|
|
|
def file_import(filename, prefix="file_import_"):
|
2021-02-09 23:13:36 +08:00
|
|
|
filename = pathlib.Path(filename)
|
|
|
|
modname = prefix + filename.stem
|
|
|
|
|
|
|
|
path = str(filename.resolve().parent)
|
2015-02-18 07:13:00 +08:00
|
|
|
sys.path.insert(0, path)
|
2021-02-09 23:13:36 +08:00
|
|
|
|
2016-02-01 03:33:17 +08:00
|
|
|
try:
|
2021-02-09 23:13:36 +08:00
|
|
|
spec = importlib.util.spec_from_file_location(modname, filename)
|
|
|
|
module = importlib.util.module_from_spec(spec)
|
|
|
|
spec.loader.exec_module(module)
|
2016-02-01 03:33:17 +08:00
|
|
|
finally:
|
|
|
|
sys.path.remove(path)
|
2015-02-18 07:13:00 +08:00
|
|
|
|
2015-02-18 04:07:09 +08:00
|
|
|
return module
|
2015-01-28 21:44:15 +08:00
|
|
|
|
|
|
|
|
2019-09-09 15:16:33 +08:00
|
|
|
def get_experiment(module, class_name=None):
|
|
|
|
if class_name:
|
|
|
|
return getattr(module, class_name)
|
2015-04-07 13:04:47 +08:00
|
|
|
|
2021-02-12 06:01:54 +08:00
|
|
|
exps = inspect.getmembers(module, is_public_experiment)
|
|
|
|
|
2015-04-07 13:04:47 +08:00
|
|
|
if not exps:
|
|
|
|
raise ValueError("No experiments in module")
|
|
|
|
if len(exps) > 1:
|
|
|
|
raise ValueError("More than one experiment found in module")
|
2021-02-12 06:01:54 +08:00
|
|
|
|
2015-04-07 13:04:47 +08:00
|
|
|
return exps[0][1]
|
|
|
|
|
|
|
|
|
2015-10-03 19:28:57 +08:00
|
|
|
async def exc_to_warning(coro):
|
2015-08-08 23:36:12 +08:00
|
|
|
try:
|
2015-10-03 19:28:57 +08:00
|
|
|
await coro
|
2015-08-08 23:36:12 +08:00
|
|
|
except:
|
|
|
|
logger.warning("asyncio coroutine terminated with exception",
|
|
|
|
exc_info=True)
|
|
|
|
|
|
|
|
|
2015-10-03 19:28:57 +08:00
|
|
|
async def asyncio_wait_or_cancel(fs, **kwargs):
|
2015-10-03 14:37:02 +08:00
|
|
|
fs = [asyncio.ensure_future(f) for f in fs]
|
2015-05-17 16:11:00 +08:00
|
|
|
try:
|
2015-10-03 19:28:57 +08:00
|
|
|
d, p = await asyncio.wait(fs, **kwargs)
|
2015-05-17 16:11:00 +08:00
|
|
|
except:
|
|
|
|
for f in fs:
|
|
|
|
f.cancel()
|
|
|
|
raise
|
|
|
|
for f in p:
|
|
|
|
f.cancel()
|
2015-10-03 19:28:57 +08:00
|
|
|
await asyncio.wait([f])
|
2015-05-17 16:11:00 +08:00
|
|
|
return fs
|
|
|
|
|
|
|
|
|
2015-12-09 19:13:57 +08:00
|
|
|
def get_windows_drives():
|
|
|
|
from ctypes import windll
|
|
|
|
|
|
|
|
drives = []
|
|
|
|
bitmask = windll.kernel32.GetLogicalDrives()
|
|
|
|
for letter in string.ascii_uppercase:
|
|
|
|
if bitmask & 1:
|
|
|
|
drives.append(letter)
|
|
|
|
bitmask >>= 1
|
|
|
|
return drives
|
2016-07-18 22:50:27 +08:00
|
|
|
|
|
|
|
|
|
|
|
def get_user_config_dir():
|
|
|
|
major = artiq_version.split(".")[0]
|
|
|
|
dir = user_config_dir("artiq", "m-labs", major)
|
|
|
|
os.makedirs(dir, exist_ok=True)
|
|
|
|
return dir
|