...
 
Commits (19)
......@@ -18,10 +18,10 @@ style:
tests:
stage: tests
before_script:
- conda create --name testenv --channel http://bcu-ci.esrf.fr/stable python=3 --file requirements-conda.txt --file requirements-test-conda.txt
- conda create -q --yes --name testenv --channel http://bcu-ci.esrf.fr/stable python=3 --file requirements-conda.txt --file requirements-test-conda.txt
- source activate testenv
# Get louie from github for python 3 compatibility
- conda install --yes git
- conda install -q --yes git
- pip install git+https://github.com/11craft/louie.git
# Install bliss and its pip-only dependencies
- pip install .
......@@ -35,7 +35,7 @@ tests:
build_doc:
stage: build_doc
before_script:
- conda create --name docenv --channel http://bcu-ci.esrf.fr/stable python=3 --file requirements-conda.txt --file requirements-doc-conda.txt
- conda create -q --yes --name docenv --channel http://bcu-ci.esrf.fr/stable python=3 --file requirements-conda.txt --file requirements-doc-conda.txt
- source activate docenv
- pip install -r requirements-doc.txt
script:
......@@ -48,7 +48,7 @@ build_doc:
build_user_doc:
stage: build_user_doc
before_script:
- conda install --yes --channel http://bcu-ci.esrf.fr/stable --file requirements-doc-conda.txt
- conda install -q --yes --channel http://bcu-ci.esrf.fr/stable --file requirements-doc-conda.txt
- pip install -r requirements-doc.txt
script:
- cd doc && mkdocs build
......
......@@ -3,6 +3,4 @@ repos:
rev: 18.6b4
hooks:
- id: black
args:
- "--fast"
language_version: python3 # Should be >= 3.6
\ No newline at end of file
......@@ -89,7 +89,7 @@ class Enet(EnetSocket):
def __init__(self, cnt, **keys):
EnetSocket.__init__(self, None) # Don't use the socket connection
url = keys.pop("url")
url_parse = re.compile("^(enet://)?([^:/]+):?([0-9]*)$")
url_parse = re.compile(r"^(enet://)?([^:/]+):?([0-9]*)$")
match = url_parse.match(url)
if match is None:
raise EnetError("Enet: url is not valid (%s)" % url)
......@@ -129,7 +129,7 @@ class Prologix:
self._logger = logging.getLogger(str(self))
self._debug = self._logger.debug
url = keys.pop("url")
url_parse = re.compile("^(prologix://)?([^:/]+):?([0-9]*)$")
url_parse = re.compile(r"^(prologix://)?([^:/]+):?([0-9]*)$")
match = url_parse.match(url)
if match is None:
raise PrologixError("Inet: url is not valid (%s)" % url)
......@@ -272,7 +272,7 @@ class LocalGpibError(GpibError):
class LocalGpib(object):
URL_RE = re.compile("^(local://)?([0-9]{1,2})$")
URL_RE = re.compile(r"^(local://)?([0-9]{1,2})$")
def __init__(self, cnt, **keys):
url = keys.pop("url")
......
......@@ -27,7 +27,7 @@ except ImportError:
pass
else:
# import all rfc2217 protol keys in this module
key_match = re.compile("^[A-Z_]+$")
key_match = re.compile(r"^[A-Z_]+$")
pro_keys_dict = dict(
[(x, rfc2217.__dict__[x]) for x in dir(rfc2217) if key_match.match(x)]
)
......@@ -74,7 +74,7 @@ class _BaseSerial:
self._cnt = weakref.ref(cnt)
self._port = port
self._data = ""
self._data = b""
self._event = event.Event()
self._rx_filter = None
self._rpipe, self._wpipe = os.pipe()
......@@ -89,7 +89,7 @@ class _BaseSerial:
return gevent.Timeout(timeout, SerialTimeout(timeout_errmsg))
def _close(self):
os.write(self._wpipe, "|")
os.write(self._wpipe, b"|")
if self._raw_read_task:
self._raw_read_task.join()
self._raw_read_task = None
......@@ -172,7 +172,7 @@ class _BaseSerial:
self._data = self._data[maxsize:]
else:
msg = self._data
self._data = ""
self._data = b""
return msg
@staticmethod
......@@ -213,7 +213,7 @@ class LocalSerial(_BaseSerial):
def flushInput(self):
self.__serial.flushInput()
self._data = ""
self._data = b""
def close(self):
self._close()
......@@ -231,19 +231,19 @@ class RFC2217Timeout(SerialTimeout):
class RFC2217(_BaseSerial):
class TelnetCmd:
def __init__(self):
self.data = ""
self.data = b""
def telnetSendOption(self, action, option):
self.data += "".join([IAC, action, option])
self.data += b"".join([IAC, action, option])
class TelnetSubNego:
def __init__(self):
self.data = ""
self.data = b""
self.logger = None
def rfc2217SendSubnegotiation(self, option, value):
value = value.replace(IAC, IAC_DOUBLED)
self.data += "".join(
self.data += b"".join(
[IAC, SB, COM_PORT_OPTION, option] + list(value) + [IAC, SE]
)
......@@ -277,7 +277,7 @@ class RFC2217(_BaseSerial):
# RFC 2217 flow control between server and client
self._remote_suspend_flow = False
port_parse = re.compile("^(rfc2217://)?([^:/]+?):([0-9]+)$")
port_parse = re.compile(r"^(rfc2217://)?([^:/]+?):([0-9]+)$")
match = port_parse.match(port)
if match is None:
raise RFC2217Error("port is not a valid url (%s)" % port)
......@@ -390,7 +390,7 @@ class RFC2217(_BaseSerial):
self.rfc2217_options["control"].set(SET_CONTROL_USE_NO_FLOW_CONTROL)
self._socket.send(telnet_sub_cmd.data)
telnet_sub_cmd.data = ""
telnet_sub_cmd.data = b""
items = list(self.rfc2217_port_settings.values())
while 1:
self._parse_nego(telnet_cmd)
......@@ -417,20 +417,20 @@ class RFC2217(_BaseSerial):
purge = self.rfc2217_options["purge"]
telnet_sub_cmd = purge.connection
purge.set(PURGE_RECEIVE_BUFFER)
self._data = ""
self._data = b""
self._rx_filter = None
self._socket.send(telnet_sub_cmd.data)
telnet_sub_cmd.data = ""
telnet_sub_cmd.data = b""
while not purge.isReady():
self._parse_nego(telnet_cmd)
self._rx_filter = self._rfc2217_filter
self._data = ""
self._data = b""
def _rfc2217_filter(self, data):
if data[-1] == IAC and data[-2] != IAC:
self._pending_data = data
return ""
return b""
if self._pending_data:
data = self._pending_data + data
......@@ -494,7 +494,7 @@ class RFC2217(_BaseSerial):
if iac_pos == -1: # no more negotiation rx
if telnet_cmd.data:
self._socket.send(telnet_cmd.data)
telnet_cmd.data = ""
telnet_cmd.data = b""
break
def close(self):
......@@ -509,7 +509,7 @@ class SER2NETError(SerialError):
class SER2NET(RFC2217):
def __init__(self, cnt, **keys):
port = keys.pop("port")
port_parse = re.compile("^(ser2net://)?([^:/]+?):([0-9]+)(.+)$")
port_parse = re.compile(r"^(ser2net://)?([^:/]+?):([0-9]+)(.+)$")
match = port_parse.match(port)
if match is None:
raise SER2NETError("port is not a valid url (%s)" % port)
......@@ -518,7 +518,7 @@ class SER2NET(RFC2217):
rx = comm.write_readline(msg)
msg_pos = rx.find(msg)
rx = rx[msg_pos + len(msg) :]
port_parse = re.compile("^([0-9]+).+?%s" % match.group(4))
port_parse = re.compile(r"^([0-9]+).+?%s" % match.group(4))
rfc2217_port = None
for line in rx.split("\r\n"):
g = port_parse.match(line)
......@@ -619,20 +619,20 @@ class TangoSerial(_BaseSerial):
self._device.DevSerSetNewline(eol_encode(self, eol))
self._last_eol = eol
buff = ""
buff = b""
while True:
line = self._device.DevSerReadLine() or ""
if line == "":
return ""
line = self._device.DevSerReadLine() or b""
if line == b"":
return b""
buff += line
if buff[-lg:] == eol:
return buff[:-lg]
def _raw_read(self, maxsize):
if maxsize:
return self._device.DevSerReadNChar(maxsize) or ""
return self._device.DevSerReadNChar(maxsize) or b""
else:
return self._device.DevSerReadRaw() or ""
return self._device.DevSerReadRaw() or b""
_read = _raw_read
......@@ -659,7 +659,7 @@ class Serial:
writeTimeout=None,
dsrdtr=False,
interCharTimeout=None,
eol="\n",
eol=b"\n",
):
self._serial_kwargs = {
......
......@@ -676,14 +676,14 @@ class Tcp(object):
def __new__(cls, url=None, **keys):
if url.lower().startswith("command://"):
parse = re.compile("^(command://)([^:/]+?):([0-9]+)$")
parse = re.compile(r"^(command://)([^:/]+?):([0-9]+)$")
match = parse.match(url)
if match is None:
raise TcpError("Command: url is not valid (%s)" % url)
host, port = match.group(2), int(match.group(3))
return Command(host, port, **keys)
else:
parse = re.compile("^(socket://)?([^:/]+?):([0-9]+)$")
parse = re.compile(r"^(socket://)?([^:/]+?):([0-9]+)$")
match = parse.match(url)
if match is None:
raise TcpError("Socket: url is not valid (%s)" % url)
......
......@@ -53,7 +53,7 @@ class Udp(object):
def __new__(cls, url=None, **keys):
# for now only one udp class
# no need to test...
parse = re.compile("^(socket://)?([^:/]+?):([0-9]+)$")
parse = re.compile(r"^(socket://)?([^:/]+?):([0-9]+)$")
match = parse.match(url)
if match is None:
raise UdpError("Socket: url is not valid (%s)" % url)
......
......@@ -1584,7 +1584,7 @@ class AxisState(object):
"""
#: state regular expression validator
STATE_VALIDATOR = re.compile("^[A-Z0-9]+\s*$")
STATE_VALIDATOR = re.compile(r"^[A-Z0-9]+\s*$")
_STANDARD_STATES = {
"READY": "Axis is READY",
......@@ -1768,7 +1768,7 @@ class AxisState(object):
# (copy constructor)
if "(" in state:
full_states = [s.strip() for s in state.split("|")]
p = re.compile("^([A-Z0-9]+)\s\((.+)\)", re.DOTALL)
p = re.compile(r"^([A-Z0-9]+)\s\((.+)\)", re.DOTALL)
for full_state in full_states:
m = p.match(full_state)
try:
......
......@@ -35,13 +35,12 @@ __all__ = (
+ ["SoftAxis", "SoftCounter", "edit_roi_counters"]
)
import collections
import itertools
import inspect
import logging
import functools
import itertools
import linecache
import gevent
import collections.abc
from six import print_
from gevent import sleep
......@@ -388,7 +387,7 @@ def _check_log_level(level):
def set_log_level(level=logging.root.level):
"""
Adjusts the log level
Without arguments, resets the level back to the one setup at
beginning of the session.
......@@ -421,7 +420,7 @@ def cntdict():
obj.controller.name if obj.controller else "None",
)
elif hasattr(obj, "counters") and isinstance(
obj.counters, collections.Iterable
obj.counters, collections.abc.Iterable
):
for cnt in obj.counters:
if isinstance(cnt, BaseCounter):
......
......@@ -14,10 +14,7 @@ import functools
import numpy
from bliss.common.event import saferef
try:
from collections import OrderedDict
except ImportError: # python2.6 compatibility
from ordereddict import OrderedDict
from collections import OrderedDict
class WrappedMethod(object):
......
......@@ -91,7 +91,7 @@ class Bus(AdvancedInstantiationInterface):
def __new__(cls, redis=None):
if redis is None:
redis = client.get_cache()
redis = client.get_redis_connection()
if redis not in cls._CACHE:
cls._CACHE[redis] = cls.instanciate(redis)
return cls._CACHE[redis]
......
......@@ -98,7 +98,7 @@ def get_cache_address(connection=None):
@check_connection
def get_cache(db=0, connection=None):
def get_redis_connection(db=0, connection=None):
return connection.get_redis_connection(db=db)
......
This diff is collapsed.
......@@ -364,6 +364,7 @@ def _send_config_db_files(client_id, message):
)
try:
for root, dirs, files in os.walk(look_path, followlinks=True):
files = sorted(files)
for filename in files:
if filename.startswith("."):
continue
......@@ -746,13 +747,7 @@ def main(args=None):
env["BEACON_HOST"] = "%s:%d" % ("localhost", beacon_port)
# Tango database executable
args = [sys.executable]
# Should be:
# args += ['-m', 'tango.databaseds.database']
# But because of a pytango bug:
code = "import tango.databaseds.db_access.beacon\n"
code += "import tango.databaseds.database\n"
code += "tango.databaseds.database.main()"
args += ["-c", code]
args += ["-m", "bliss.tango.servers.databaseds"]
# Arguments
args += ["-l", str(_options.tango_debug_level)]
args += ["--db_access", "beacon"]
......
......@@ -67,8 +67,8 @@ def pickle_loads(var):
return InvalidValue()
def get_cache():
return client.get_cache(db=0)
def get_redis_connection():
return client.get_redis_connection(db=0)
def ttl_func(cnx, name, value=-1):
......@@ -154,7 +154,7 @@ def write_decorator(func):
def scan(match="*", count=1000, connection=None):
if connection is None:
connection = get_cache()
connection = get_redis_connection()
cursor = 0
while 1:
cursor, values = connection.scan(cursor=cursor, match=match, count=count)
......@@ -174,7 +174,7 @@ class SimpleSetting(object):
default_value=None,
):
if connection is None:
connection = get_cache()
connection = get_redis_connection()
self._cnx = weakref.ref(connection)
self._name = name
self._read_type_conversion = read_type_conversion
......@@ -264,7 +264,7 @@ class SimpleSettingProp(object):
use_object_name=True,
):
self._name = name
self._cnx = connection or get_cache()
self._cnx = connection or get_redis_connection()
self._read_type_conversion = read_type_conversion
self._write_type_conversion = write_type_conversion
self._default_value = default_value
......@@ -313,7 +313,7 @@ class QueueSetting(object):
write_type_conversion=str,
):
if connection is None:
connection = get_cache()
connection = get_redis_connection()
self._cnx = weakref.ref(connection)
self._name = name
self._read_type_conversion = read_type_conversion
......@@ -461,7 +461,7 @@ class QueueSettingProp(object):
use_object_name=True,
):
self._name = name
self._cnx = connection or get_cache()
self._cnx = connection or get_redis_connection()
self._read_type_conversion = read_type_conversion
self._write_type_conversion = write_type_conversion
self._use_object_name = use_object_name
......@@ -505,7 +505,7 @@ class HashSetting(object):
default_values={},
):
if connection is None:
connection = get_cache()
connection = get_redis_connection()
self._cnx = weakref.ref(connection)
self._name = name
self._read_type_conversion = read_type_conversion
......@@ -669,7 +669,7 @@ class HashSettingProp(object):
use_object_name=True,
):
self._name = name
self._cnx = connection or get_cache()
self._cnx = connection or get_redis_connection()
self._read_type_conversion = read_type_conversion
self._write_type_conversion = write_type_conversion
self._default_values = default_values
......
......@@ -47,104 +47,24 @@ Accessing the configured elements from python is easy
import os
import gc
import yaml
import weakref
import functools
from collections import OrderedDict
if not hasattr(weakref, "WeakSet"):
import weakrefset
weakref.WeakSet = weakrefset.WeakSet
from .conductor import client
from ruamel import yaml
try:
from ruamel import yaml as ordered_yaml
from bliss.common.utils import OrderedDict as ordereddict
NodeDict = ordereddict
class RoundTripRepresenter(ordered_yaml.representer.RoundTripRepresenter):
def __init__(self, *args, **keys):
ordered_yaml.representer.RoundTripRepresenter.__init__(self, *args, **keys)
def represent_ordereddict(self, data):
return self.represent_mapping("tag:yaml.org,2002:map", data)
RoundTripRepresenter.add_representer(
ordereddict, RoundTripRepresenter.represent_ordereddict
)
class RoundTripDumper(
ordered_yaml.emitter.Emitter,
ordered_yaml.serializer.Serializer,
RoundTripRepresenter,
ordered_yaml.resolver.Resolver,
):
def __init__(
self,
stream,
default_style=None,
default_flow_style=None,
canonical=None,
indent=None,
width=None,
allow_unicode=None,
line_break=None,
encoding=None,
explicit_start=None,
explicit_end=None,
version=None,
tags=None,
**keys
):
ordered_yaml.emitter.Emitter.__init__(
self,
stream,
canonical=canonical,
indent=indent,
width=width,
allow_unicode=allow_unicode,
line_break=line_break,
)
ordered_yaml.serializer.Serializer.__init__(
self,
encoding=encoding,
explicit_start=explicit_start,
explicit_end=explicit_end,
version=version,
tags=tags,
)
RoundTripRepresenter.__init__(
self, default_style=default_style, default_flow_style=default_flow_style
)
ordered_yaml.resolver.Resolver.__init__(self)
except ImportError:
ordered_yaml = None
NodeDict = dict
from .conductor import client
CONFIG = None
if hasattr(yaml, "CLoader"):
yaml_load = functools.partial(yaml.load, Loader=yaml.CLoader)
else:
yaml_load = yaml.load
def load_cfg_fromstring(cfg_string):
return yaml.safe_load(cfg_string)
def load_cfg(filename):
cfg_string = client.get_config_file(filename)
if ordered_yaml:
return ordered_yaml.load(cfg_string, ordered_yaml.RoundTripLoader)
else:
return yaml_load(cfg_string)
def load_cfg_fromstring(cfg_string):
if ordered_yaml:
return ordered_yaml.load(cfg_string, ordered_yaml.RoundTripLoader)
else:
return yaml_load(cfg_string)
return load_cfg_fromstring(cfg_string)
def get_config(base_path="", timeout=3.):
......@@ -184,7 +104,7 @@ def get_config(base_path="", timeout=3.):
return CONFIG
class Node(NodeDict):
class Node(OrderedDict):
"""
Configuration Node. Do not instantiate this class directly.
......@@ -206,7 +126,7 @@ class Node(NodeDict):
"""
def __init__(self, config=None, parent=None, filename=None):
NodeDict.__init__(self)
super().__init__()
self._parent = parent
if config is None:
config = CONFIG
......@@ -304,12 +224,7 @@ class Node(NodeDict):
save_nodes = self._get_save_dict(node, filename)
else:
save_nodes = self._get_save_list(nodes_2_save, filename)
if ordered_yaml:
file_content = ordered_yaml.dump(
save_nodes, Dumper=RoundTripDumper, default_flow_style=False
)
else:
file_content = yaml.dump(save_nodes, default_flow_style=False)
file_content = yaml.dump(save_nodes, default_flow_style=False)
self._config.set_config_db_file(filename, file_content)
def deep_copy(self):
......@@ -363,7 +278,7 @@ class Node(NodeDict):
return new_list
def _get_save_dict(self, src_node, filename):
return_dict = NodeDict()
return_dict = OrderedDict()
for key, values in src_node.items():
if isinstance(values, Node):
if values.filename != filename:
......@@ -481,20 +396,12 @@ class Config(object):
if isinstance(fs_node, list):
continue
if ordered_yaml:
try:
d = ordered_yaml.load(file_content, ordered_yaml.RoundTripLoader)
except ordered_yaml.error.MarkedYAMLError as exp:
if exp.problem_mark is not None:
exp.problem_mark.name = path
raise
else:
try:
d = yaml_load(file_content)
except yaml.error.MarkedYAMLError as exp:
if exp.problem_mark is not None:
exp.problem_mark.name = path
raise
try:
d = yaml.safe_load(file_content)
except yaml.error.MarkedYAMLError as exp:
if exp.problem_mark is not None:
exp.problem_mark.name = path
raise
is_init_file = False
if file_name.startswith("__init__"):
......@@ -570,6 +477,8 @@ class Config(object):
if isinstance(fs_node, list):
continue
elif fs_key == "":
children = fs_node
else:
children = fs_node.get(fs_key)
......
......@@ -169,8 +169,7 @@ class Lima(object):
def get_mapped_path(self, path):
path = os.path.normpath(path)
for mapping in sorted(self.directories_mapping, reverse=True):
for mapping in reversed(self.directories_mapping):
base_path = mapping["path"]
replace_with = mapping["replace-with"]
# os.path.commonprefix function is broken as it returns common
......
......@@ -20,7 +20,7 @@ def camel_to_snake(camelCasedStr):
This function converts to snake_case from camelCase
"""
first_cap_re = re.compile(r"(.)([A-Z][a-z]+)")
all_cap_re = re.compile("([a-z0-9])([A-Z])")
all_cap_re = re.compile(r"([a-z0-9])([A-Z])")
sub1 = first_cap_re.sub(r"\1_\2", camelCasedStr)
snake_cased_str = all_cap_re.sub(r"\1_\2", sub1).lower()
return snake_cased_str.replace("__", "_")
......
......@@ -77,7 +77,7 @@ class RoiStatCounter(IntegratingCounter):
# it is calculated everty time because the roi id for a given roi name might
# change if rois are added/removed from lima
roi_id = self.controller._roi_ids[self.roi_name]
return self.roi_stat_id(roi_id, self.stat)
return numpy.asscalar(self.roi_stat_id(roi_id, self.stat))
@staticmethod
def roi_stat_id(roi_id, stat):
......@@ -126,7 +126,7 @@ class RoiCounterGroupReadHandler(IntegratingCounter.GroupedReadHandler):
raw_data = self.controller._proxy.readCounters(from_index)
if not raw_data.size:
return len(counters) * (numpy.array(()),)
raw_data.shape = (raw_data.size) / roi_counter_size, roi_counter_size
raw_data.shape = (raw_data.size) // roi_counter_size, roi_counter_size
result = OrderedDict([int(counter), []] for counter in counters)
for roi_counter in raw_data:
......
......@@ -376,12 +376,12 @@ class Icepap(Controller):
def get_event_positions(self, axis_or_encoder):
"""
For this controller this method should be use
for debugging purposed only...
for debugging purposed only...
"""
address = axis_or_encoder.address
# Get the number of positions
reply = _command(self._cnx, "%d:?ECAMDAT" % address)
reply_exp = re.compile("(\w+) +([+-]?\d+) +([+-]?\d+) +(\d+)")
reply_exp = re.compile(r"(\w+) +([+-]?\d+) +([+-]?\d+) +(\d+)")
m = reply_exp.match(reply)
if m is None:
raise RuntimeError("Reply Didn't expected: %s" % reply)
......@@ -395,7 +395,7 @@ class Icepap(Controller):
positions = numpy.zeros((nb,), dtype=numpy.int32)
if nb > 0:
reply_exp = re.compile(".+: +([+-]?\d+)")
reply_exp = re.compile(r".+: +([+-]?\d+)")
reply = _command(self._cnx, "%d:?ECAMDAT %d" % (address, nb))
for i, line in enumerate(reply.split("\n")):
m = reply_exp.match(line)
......@@ -526,7 +526,7 @@ class Icepap(Controller):
address = axis.address
# Get the number of positions
reply = _command(self._cnx, "%d:?LISTDAT" % address)
reply_exp = re.compile("(\d+) *(\w+)?")
reply_exp = re.compile(r"(\d+) *(\w+)?")
m = reply_exp.match(reply)
if m is None:
raise RuntimeError("Reply didn't expected: %s" % reply)
......@@ -534,7 +534,7 @@ class Icepap(Controller):
positions = numpy.zeros((nb,), dtype=numpy.int32)
cyclic = True if m.group(2) == "CYCLIC" else False
if nb > 0:
reply_exp = re.compile(".+: +([+-]?\d+)")
reply_exp = re.compile(r".+: +([+-]?\d+)")
reply = _command(self._cnx, "%d:?LISTDAT %d" % (address, nb))
for i, line in enumerate(reply.split("\n")):
m = reply_exp.match(line)
......@@ -596,7 +596,7 @@ class Icepap(Controller):
self._cnx.close()
_check_reply = re.compile("^[#?]|^[0-9]+:\?")
_check_reply = re.compile(r"^[#?]|^[0-9]+:\?")
PARAMETER, POSITION, SLOPE = (0x1000, 0x2000, 0x4000)
......
......@@ -98,7 +98,7 @@ class Switch(BaseSwitch):
def _get(self):
reply = _command(self.__controller._cnx, "?PMUX")
pattern = re.compile(".+B([0-9]+) +E%d" % self.__rack_connector_id)
pattern = re.compile(r".+B([0-9]+) +E%d" % self.__rack_connector_id)
for line in reply.split("\n"):
m = pattern.match(line)
if m:
......
......@@ -321,7 +321,7 @@ class HexapodProtocolV2(BaseHexapodProtocol):
#: Reply is either:
#: <CMD>:<CODE>
#: <CMD>:<CODE>,<DATA>
REPLY_RE = re.compile("(?P<cmd>[^:]+)\:(?P<code>[+\-0-9]+)(?P<data>.*)$")
REPLY_RE = re.compile(r"(?P<cmd>[^:]+)\:(?P<code>[+\-0-9]+)(?P<data>.*)$")
SYSTEM_STATUS_FIELDS = (
"error",
......
......@@ -17,7 +17,7 @@ def data_to_bytes(data):
if isinstance(data, numpy.ndarray):
return data.dumps()
else:
return data
return str(data).encode()
def data_from_pipeline(data, shape=None, dtype=None):
......
This diff is collapsed.
......@@ -13,8 +13,8 @@ import gevent
from bliss.common.tango import DeviceProxy
from bliss.common.task import task
from bliss.data.node import DataNode
from bliss.config.settings import HashSetting, QueueObjSetting
from bliss.data.edffile import EdfFile
from bliss.config.settings import QueueObjSetting
from silx.third_party.EdfFile import EdfFile
try:
import h5py
......@@ -27,7 +27,7 @@ HEADER_SIZE = struct.calcsize(VIDEO_HEADER_FORMAT)
class LimaImageChannelDataNode(DataNode):
class LimaDataView(object):
DataArrayMagic = struct.unpack(">I", "DTAY")[0]
DataArrayMagic = struct.unpack(">I", b"DTAY")[0]
def __init__(self, data, from_index, to_index, from_stream=False):
self.data = data
......@@ -350,7 +350,7 @@ class LimaImageChannelDataNode(DataNode):
def add_reference_data(self, ref_data):
"""Save reference data in database
In case of Lima, this corresponds to acquisition ref_data,
in particular saving data
"""
......
......@@ -102,7 +102,7 @@ def get_node(db_name, connection=None):
def get_nodes(*db_names, **keys):
connection = keys.get("connection")
if connection is None:
connection = client.get_cache(db=1)
connection = client.get_redis_connection(db=1)
pipeline = connection.pipeline()
for db_name in db_names:
data = Struct(db_name, connection=pipeline)
......@@ -120,13 +120,13 @@ def get_nodes(*db_names, **keys):
def _create_node(name, node_type=None, parent=None, connection=None, **keys):
if connection is None:
connection = client.get_cache(db=1)
connection = client.get_redis_connection(db=1)
return _get_node_object(node_type, name, parent, connection, create=True, **keys)
def _get_or_create_node(name, node_type=None, parent=None, connection=None, **keys):
if connection is None:
connection = client.get_cache(db=1)
connection = client.get_redis_connection(db=1)
db_name = DataNode.exists(name, parent, connection)
if db_name:
return get_node(db_name, connection=connection)
......@@ -135,8 +135,8 @@ def _get_or_create_node(name, node_type=None, parent=None, connection=None, **ke
class DataNodeIterator(object):
NEW_CHILD_REGEX = re.compile("^__keyspace@.*?:(.*)_children_list$")
NEW_DATA_IN_CHANNEL_REGEX = re.compile("^__keyspace@.*?:(.*)_data$")
NEW_CHILD_REGEX = re.compile(r"^__keyspace@.*?:(.*)_children_list$")
NEW_DATA_IN_CHANNEL_REGEX = re.compile(r"^__keyspace@.*?:(.*)_data$")
NEW_CHILD_EVENT, NEW_DATA_IN_CHANNEL_EVENT = list(range(2))
def __init__(self, node, last_child_id=None):
......@@ -368,7 +368,7 @@ class DataNode(object):
@staticmethod
def exists(name, parent=None, connection=None):
if connection is None:
connection = client.get_cache(db=1)
connection = client.get_redis_connection(db=1)
db_name = "%s:%s" % (parent.db_name, name) if parent else name
return db_name if connection.exists(db_name) else None
......@@ -377,7 +377,7 @@ class DataNode(object):
):
info_dict = keys.pop("info", {})
if connection is None:
connection = client.get_cache(db=1)
connection = client.get_redis_connection(db=1)
db_name = "%s:%s" % (parent.db_name, name) if parent else name
self._data = Struct(db_name, connection=connection)
info_hash_name = "%s_info" % db_name
......@@ -444,7 +444,7 @@ class DataNode(object):
def set_ttl(self):
db_names = set(self._get_db_names())
redis_conn = client.get_cache(db=1)
redis_conn = client.get_redis_connection(db=1)
pipeline = redis_conn.pipeline()
for name in db_names:
pipeline.expire(name, DataNode.default_time_to_live)
......
......@@ -31,14 +31,12 @@ from bliss.flint.executor import concurrent_to_gevent
from bliss.flint.executor import qt_safe
from bliss.flint.executor import QtSignalQueue
from bliss.config.conductor.client import get_default_connection
from bliss.config.conductor.client import get_cache_address
from bliss.config.conductor.client import get_redis_connection
try:
from PyQt4.QtCore import pyqtRemoveInputHook
from PyQt4 import QtGui
except ImportError:
from PyQt5.QtCore import pyqtRemoveInputHook
from PyQt5 import QtGui
with warnings.catch_warnings():
warnings.simplefilter("ignore")
......@@ -97,8 +95,7 @@ def safe_rpc_server(obj):
@contextlib.contextmanager
def maintain_value(key, value):
beacon = get_default_connection()
redis = beacon.get_redis_connection()
redis = get_redis_connection()
redis.lpush(key, value)
try:
yield
......@@ -111,7 +108,6 @@ def get_flint_key():
def background_task(flint, stop):
LivePlot1D.REDIS_CACHE = get_cache_address()
key = get_flint_key()
stop = concurrent_to_gevent(stop)
with safe_rpc_server(flint) as (task, url):
......@@ -209,6 +205,12 @@ class Flint:
self._last_event = dict()
self._refresh_task = None
connection = get_default_connection()
address = connection.get_redis_connection_address()
self._qt_redis_connection = qt_safe(connection.create_redis_connection)(
address=address
)
def new_live_scan_plots():
return {"0d": [], "1d": [], "2d": []}
......@@ -250,8 +252,7 @@ class Flint:
self._session_name = session_name
beacon = get_default_connection()
redis = beacon.get_redis_connection()
redis = get_redis_connection()
key = get_flint_key()
current_value = redis.lindex(key, 0).decode()
value = session_name + " " + current_value.split()[-1]
......@@ -300,7 +301,9 @@ class Flint:
scalars_plot_win = self.mdi_windows_dict.get(window_title)
if not scalars_plot_win:
scalars_plot_win = LivePlot1D(
data_dict=self.data_dict, session_name=self._session_name
data_dict=self.data_dict,
session_name=self._session_name,
redis_connection=self._qt_redis_connection,
)
scalars_plot_win.setWindowTitle(window_title)
scalars_plot_win.plot_id = next(self._id_generator)
......@@ -321,7 +324,9 @@ class Flint:
scatter_plot_win = self.mdi_windows_dict.get(window_title)
if not scatter_plot_win:
scatter_plot_win = LiveScatterPlot(
data_dict=self.data_dict, session_name=self._session_name
data_dict=self.data_dict,
session_name=self._session_name,
redis_connection=self._qt_redis_connection,
)
scatter_plot_win.setWindowTitle(window_title)
scatter_plot_win.plot_id = next(self._id_generator)
......
......@@ -6,21 +6,14 @@
# Distributed under the GNU LGPLv3. See LICENSE for more info.
import warnings
import logging
import weakref
import redis
import numpy
import re
try:
from PyQt4.QtCore import pyqtRemoveInputHook
except ImportError:
from PyQt5.QtCore import pyqtRemoveInputHook
with warnings.catch_warnings():
warnings.simplefilter("ignore")
from silx.gui import plot as silx_plot
from silx.gui.plot.Colormap import Colormap
from silx.gui import qt, colors
from silx.gui.plot import LegendSelector
......@@ -28,13 +21,11 @@ Plot1D = silx_plot.Plot1D
class LivePlot1D(qt.QWidget):
REDIS_CACHE = None
def __init__(self, *args, **kw):
self._data_dict = kw.pop("data_dict")
self._session_name = kw.pop("session_name")
self.plot_id = None # filled by caller
self.redis_cnx = LivePlot1D.get_redis_connection()
self.redis_cnx = kw.pop("redis_connection")
qt.QWidget.__init__(self, *args, **kw)
......@@ -116,7 +107,6 @@ class LivePlot1D(qt.QWidget):
x_select.setEditable(False)
items = [item_name, x_select]
gb = qt.QButtonGroup(self)
for k in range(1, 3):
item_select = qt.QStandardItem("")
item_select.setEditable(False)
......@@ -125,7 +115,7 @@ class LivePlot1D(qt.QWidget):
if y_selected_axis == k:
item_select.setCheckState(qt.Qt.Checked)
legend = "%s -> %s" % (x_axis, axis_name)
key = self.silx_plot.addCurve([], [], legend=legend, copy=False)
self.silx_plot.addCurve([], [], legend=legend, copy=False)
curve = self.silx_plot.getCurve(legend)
curve.setYAxis("left" if k == 2 else "right")
curve.sigItemChanged.connect(self._refresh_legend)
......@@ -313,20 +303,6 @@ class LivePlot1D(qt.QWidget):
def addXMarker(self, *args, **kwargs):
return self.silx_plot.addXMarker(*args, **kwargs)
@staticmethod
def get_redis_connection():
if LivePlot1D.REDIS_CACHE:
host, port = LivePlot1D.REDIS_CACHE
if host != "localhost":
return redis.Redis(host=host, port=port)
else:
return redis.Redis(unix_socket_path=port)
else:
raise RuntimeError(
"LivePlot1D is not initialized properly, missing \
redis connection information (REDIS_CACHE)."
)
# Ugly copy paste! Shame!
......@@ -336,7 +312,7 @@ class LiveScatterPlot(qt.QWidget):
self._data_dict = kw.pop("data_dict")
self._session_name = kw.pop("session_name")
self.plot_id = None # filled by caller
self.redis_cnx = LivePlot1D.get_redis_connection()
self.redis_cnx = kw.pop("redis_connection")
qt.QWidget.__init__(self, *args, **kw)
......@@ -415,7 +391,7 @@ class LiveScatterPlot(qt.QWidget):
"""
In this method, we will guess motors position ranges
"""
scan_name = re.compile("^(d|a?)\w+?\s+")
scan_name = re.compile(r"^(d|a?)\w+?\s+")
mot_name_params = re.compile(
"(\w+)\s+(-?\d+\.\d+|-?\d+)\s+(-?\d+\.\d+|-?\d+)\s(\d+)"
)
......
......@@ -57,7 +57,7 @@ this as soon as possible in the code of your application::
"""
from functools import wraps
from inspect import getargspec
from inspect import getfullargspec
import pint
......@@ -123,7 +123,7 @@ def units(**kwarg_units):
kwarg_units = values_to_units(kwarg_units)
def decorator(func):
arg_spec = getargspec(func).args
arg_spec = getfullargspec(func).args
if not set(arg_spec).issuperset(kwarg_units):
raise TypeError("units argument names differ from function argument names")
......
......@@ -272,13 +272,13 @@ class _StepTriggerMaster(AcquisitionMaster):
def __init__(self, *args, **keys):
trigger_type = keys.pop("trigger_type", AcquisitionMaster.SOFTWARE)
self.next_mv_cmd_arg = list()
self.next_mv_cmd_arg = []
if len(args) % 4:
raise TypeError(
"_StepTriggerMaster: argument is a mot1,start,stop,nb points,mot2,start2..."
)
self._motor_pos = list()
self._axes = list()
self._motor_pos = []
self._axes = []
for axis, start, stop, nb_point in grouped(args, 4):
self._axes.append(axis)
self._motor_pos.append(numpy.linspace(start, stop, nb_point))
......@@ -299,11 +299,9 @@ class _StepTriggerMaster(AcquisitionMaster):
return min((len(x) for x in self._motor_pos))
def __iter__(self):
iter_pos = [iter(x) for x in self._motor_pos]
while True:
self.next_mv_cmd_arg = list()
for axis, pos in zip(self._axes, iter_pos):
self.next_mv_cmd_arg.extend((axis, next(pos)))
for positions in zip(*self._motor_pos):
for axis, position in zip(self._axes, positions):
self.next_mv_cmd_arg += [axis, position]
yield self
def prepare(self):
......@@ -381,14 +379,14 @@ class VariableStepTriggerMaster(AcquisitionMaster):
def __init__(self, *args, **keys):
trigger_type = keys.pop("trigger_type", AcquisitionMaster.SOFTWARE)
self.next_mv_cmd_arg = list()
self.next_mv_cmd_arg = []
if len(args) % 2:
raise TypeError(
"_VariableStepTriggerMaster: argument is a mot, positions ..."
)
self._motor_pos = list()
self._axes = list()
self._motor_pos = []
self._axes = []
for _axis, pos_list in grouped(args, 2):
self._axes.append(_axis)
self._motor_pos.append(pos_list)
......@@ -408,11 +406,9 @@ class VariableStepTriggerMaster(AcquisitionMaster):
return min((len(x) for x in self._motor_pos))
def __iter__(self):
iter_pos = [iter(x) for x in self._motor_pos]
while True:
self.next_mv_cmd_arg = list()
for _axis, pos in zip(self._axes, iter_pos):
self.next_mv_cmd_arg.extend((_axis, next(pos)))
for positions in zip(*self._motor_pos):
for axis, position in zip(self._axes, positions):
self.next_mv_cmd_arg += [axis, position]
yield self
def prepare(self):
......@@ -697,9 +693,8 @@ class SweepMotorMaster(AcquisitionMaster):
return self._nb_points
def __iter__(self):
iter_pos = iter(self.start_pos)
while True:
self.next_start_pos = next(iter_pos)
for start_pos in self.start_pos:
self.next_start_pos = start_pos
yield self
def prepare(self):
......
......@@ -5,14 +5,15 @@
# Copyright (c) 2016 Beamline Control Unit, ESRF
# Distributed under the GNU LGPLv3. See LICENSE for more info.
import gevent
import time
import weakref
import collections
import logging
from treelib import Tree
import weakref
import collections.abc
from contextlib import contextmanager
import gevent
from treelib import Tree
from bliss.common.event import dispatcher
from bliss.common.cleanup import capture_exceptions
from bliss.common.greenlet_utils import KillMask
......@@ -571,7 +572,7 @@ class AcquisitionChainIter(object):
for preset in self._presets_list:
iterator = preset.get_iterator(self.acquisition_chain)
if isinstance(iterator, collections.Iterable):
if isinstance(iterator, collections.abc.Iterable):
self._preset_iterators_list.append(iterator)
self._current_preset_iterators_list = list()
......
......@@ -874,7 +874,6 @@ class Scan(object):
return ImagePlot(existing_id=plot_id)
def _next_scan_number(self):
redis = client.get_cache(db=1)
filename = self.writer.filename
last_filename = self.__scan_saving._last_scan_file
last_scan_number = self.__scan_saving._last_scan_number
......
......@@ -41,12 +41,11 @@ class Writer(FileWriter):
self.scan_entry = self.file.create_group(scan_name)
self.scan_entry.attrs["NX_class"] = "NXentry"
scan_title = scan_info.get("title", "untitled")
utf8_dt = h5py.special_dtype(vlen=str)
self.scan_entry["title"] = scan_title.encode("utf-8")
self.scan_entry["title"] = scan_title
timestamp = scan_info.get("start_timestamp")
local_time = datetime.datetime.fromtimestamp(timestamp).isoformat()
utc_time = local_time + "%+03d:00" % (time.altzone / 3600)
self.scan_entry["start_time"] = utc_time.encode("utf-8")
self.scan_entry["start_time"] = utc_time
self.measurement = self.scan_entry.create_group("measurement")
self.measurement.attrs["NX_class"] = "NXcollection"
instrument = self.measurement.create_group("instrument")
......
......@@ -571,9 +571,11 @@ def start(session_id, input_queue, output_queue, i):
if callable(x):
try:
if inspect.isfunction(x):
args = inspect.formatargspec(*inspect.getargspec(x))
args = inspect.formatargspec(
*inspect.getfullargspec(x)
)
elif inspect.ismethod(x):
argspec = inspect.getargspec(x)
argspec = inspect.getfullargspec(x)
args = inspect.formatargspec(
argspec.args[1:], *argspec[1:]
)
......
This diff is collapsed.
......@@ -15,6 +15,9 @@ import atexit
import gevent
import functools
# Gevent compatibility
_threading.Event = _threading.monkey.get_original("threading", "Event")
main_queue = _threading.Queue()
gevent_thread_lock = _threading.Lock()
gevent_thread_started = _threading.Event()
......
......@@ -26,7 +26,6 @@ import os
import sys
import time
import traceback
import types
import json
import itertools
......@@ -1310,10 +1309,8 @@ def initialize_bliss(info, db=None):
def __create_tango_axis_class(axis):
BlissAxisClass = BlissAxis.TangoClassClass
new_axis_class_class = types.ClassType(
"BlissAxisClass_%s" % axis.name, (BlissAxisClass,), {}
)
new_axis_class = types.ClassType("BlissAxis_%s" % axis.name, (BlissAxis,), {})
new_axis_class_class = type("BlissAxisClass_%s" % axis.name, (BlissAxisClass,), {})
new_axis_class = type("BlissAxis_%s" % axis.name, (BlissAxis,), {})
new_axis_class.TangoClassName = "BlissAxis_%s" % axis.name
new_axis_class.TangoClassClass = new_axis_class_class
......
......@@ -26,10 +26,8 @@ import io
import functools
import itertools
import traceback
import collections
import pickle
import base64
import datetime
import six
import gevent
......
"""Run the tango.databaseds.database server with bliss db_access."""
from tango.databaseds import db_access
from tango.databaseds.database import main as base_main
from bliss.tango import db_access as local_db_access
def main(args=None):
# Give priority to the bliss db_access module
db_access.__path__ = local_db_access.__path__ + db_access.__path__
# Safety check
from tango.databaseds.db_access import beacon
assert beacon.__file__.startswith(local_db_access.__path__[0])
# Run
base_main(args)
if __name__ == "__main__":
main()
......@@ -8,7 +8,8 @@
import sys
import tango
import TgGevent
from bliss.tango.servers import TgGevent
from bliss.controllers.temperature.eurotherm import nanodac
......
# Conda requirements file (python 2.7)
gevent >= 1.3.5
redis >= 2.8
PyYaml
jinja2 >= 2.7
flask
jedi
......
......@@ -94,7 +94,6 @@ def main():
install_requires = [
"redis >= 3",
"PyYaml",
"netifaces < 0.10.5",
"louie",
"jinja2 >= 2.7",
......@@ -109,7 +108,7 @@ def main():
"six >= 1.10",
"tabulate",
"pyserial > 2",
"ruamel.yaml == 0.11.15",
"ruamel.yaml",
"zerorpc",
"msgpack_numpy <= 0.4.3.1",
"blessings",
......
......@@ -75,7 +75,6 @@ def test_references(beacon):
def test_issue_451_infinite_recursion(beacon):
pytest.xfail() # This test appears to be non-deterministic
refs_cfg = beacon.get_config("refs_test")
refs_cfg.get_inherited(
......@@ -83,5 +82,6 @@ def test_issue_451_infinite_recursion(beacon):
) # key which does not exist, was causing infinite recursion
assert refs_cfg.parent == beacon.root
assert refs_cfg in beacon.root["__children__"]
assert beacon.root.parent is None
......@@ -22,7 +22,6 @@ from bliss.config.settings import QueueObjSetting
from bliss.data.scan import Scan as ScanNode
from bliss.data.node import get_node, DataNodeIterator, DataNode
from bliss.data.channel import ChannelDataNode
from bliss.data.edffile import EdfFile
@pytest.fixture
......
......@@ -148,7 +148,7 @@ def test_with_another_process(beacon, beacon_host_port):
del c
# Check channel is really not there anymore
redis = channels.client.get_cache()
redis = channels.client.get_redis_connection()
bus = channels.Bus._CACHE[redis]
assert "test_chan" not in bus._channels
......