diff --git a/can/bus.py b/can/bus.py index 9e70cb67e..f0f44ae7d 100644 --- a/can/bus.py +++ b/can/bus.py @@ -28,7 +28,7 @@ class BusABC(object): channel_info = 'unknown' @abstractmethod - def __init__(self, channel=None, can_filters=None, **config): + def __init__(self, channel, can_filters=None, **config): """Construct and open a CAN bus instance of the specified type. Subclasses should call though this method with all given parameters diff --git a/can/interface.py b/can/interface.py index 6bae7c0fc..291fec268 100644 --- a/can/interface.py +++ b/can/interface.py @@ -12,6 +12,7 @@ import sys import importlib import logging +import re import can from .bus import BusABC @@ -72,14 +73,21 @@ def _get_class_for_interface(interface): class Bus(BusABC): """ - Instantiates a CAN Bus of the given `bustype`, falls back to reading a + Instantiates a CAN Bus of the given ``interface``, falls back to reading a configuration file from default locations. """ @staticmethod - def __new__(cls, *args, **config): + def __new__(cls, channel=None, *args, **config): """ - Takes the same arguments as :class:`can.BusABC.__init__` with the addition of: + Takes the same arguments as :class:`can.BusABC.__init__`. + Some might have a special meaning, see below. + + :param channel: + Set to ``None`` to let it be reloved automatically from the default + configuration. That might fail, see below. + + Expected type is backend dependent. :param dict config: Should contain an ``interface`` key with a valid interface name. If not, @@ -93,6 +101,8 @@ def __new__(cls, *args, **config): """ # figure out the rest of the configuration; this might raise an error + if channel is not None: + config['channel'] = channel config = load_config(config=config) # resolve the bus class to use for that interface @@ -101,12 +111,14 @@ def __new__(cls, *args, **config): # remove the 'interface' key so it doesn't get passed to the backend del config['interface'] - # make sure the bus can handle this config + # make sure the bus can handle this config format if 'channel' not in config: - raise ValueError("channel argument missing") + raise ValueError("'channel' argument missing") + else: + channel = config['channel'] + del config['channel'] - # the channel attribute should be present in **config - return cls(*args, **config) + return cls(channel, *args, **config) def detect_available_configs(interfaces=None): diff --git a/can/interfaces/ics_neovi/neovi_bus.py b/can/interfaces/ics_neovi/neovi_bus.py index 18ec93e96..68eef460f 100644 --- a/can/interfaces/ics_neovi/neovi_bus.py +++ b/can/interfaces/ics_neovi/neovi_bus.py @@ -82,7 +82,7 @@ class NeoViBus(BusABC): https://github.com/intrepidcs/python_ics """ - def __init__(self, channel=None, can_filters=None, **config): + def __init__(self, channel, can_filters=None, **config): """ :param int channel: The Channel id to create this bus with. diff --git a/can/interfaces/nican.py b/can/interfaces/nican.py index a2364767d..b9f01159b 100644 --- a/can/interfaces/nican.py +++ b/can/interfaces/nican.py @@ -130,8 +130,7 @@ class NicanBus(BusABC): """ - def __init__(self, channel, can_filters=None, bitrate=None, log_errors=True, - **kwargs): + def __init__(self, channel, can_filters=None, bitrate=None, log_errors=True, **kwargs): """ :param str channel: Name of the object to open (e.g. 'CAN0') diff --git a/can/interfaces/socketcan/socketcan_ctypes.py b/can/interfaces/socketcan/socketcan_ctypes.py index f859a78d6..044ae8d53 100644 --- a/can/interfaces/socketcan/socketcan_ctypes.py +++ b/can/interfaces/socketcan/socketcan_ctypes.py @@ -45,10 +45,7 @@ class SocketcanCtypes_Bus(BusABC): Implements :meth:`can.BusABC._detect_available_configs`. """ - def __init__(self, - channel='vcan0', - receive_own_messages=False, - *args, **kwargs): + def __init__(self, channel, receive_own_messages=False, *args, **kwargs): """ :param str channel: The can interface name with which to create this bus. An example channel diff --git a/test/back2back_test.py b/test/back2back_test.py index 304bec690..da715de4b 100644 --- a/test/back2back_test.py +++ b/test/back2back_test.py @@ -23,9 +23,9 @@ TIMEOUT = 0.1 INTERFACE_1 = 'virtual' -CHANNEL_1 = 'vcan0' +CHANNEL_1 = 'virtual_channel_0' INTERFACE_2 = 'virtual' -CHANNEL_2 = 'vcan0' +CHANNEL_2 = 'virtual_channel_0' class Back2BackTestCase(unittest.TestCase): @@ -35,16 +35,16 @@ class Back2BackTestCase(unittest.TestCase): """ def setUp(self): - self.bus1 = can.interface.Bus(channel=CHANNEL_1, - bustype=INTERFACE_1, - bitrate=BITRATE, - fd=TEST_CAN_FD, - single_handle=True) - self.bus2 = can.interface.Bus(channel=CHANNEL_2, - bustype=INTERFACE_2, - bitrate=BITRATE, - fd=TEST_CAN_FD, - single_handle=True) + self.bus1 = can.Bus(channel=CHANNEL_1, + bustype=INTERFACE_1, + bitrate=BITRATE, + fd=TEST_CAN_FD, + single_handle=True) + self.bus2 = can.Bus(channel=CHANNEL_2, + bustype=INTERFACE_2, + bitrate=BITRATE, + fd=TEST_CAN_FD, + single_handle=True) def tearDown(self): self.bus1.shutdown() @@ -146,14 +146,14 @@ def setUp(self): print("testing python-can's socketcan version:", socketcan_version) - self.bus1 = can.interface.Bus(channel="vcan0", - bustype=socketcan_version, - bitrate=250000, - fd=TEST_CAN_FD) - self.bus2 = can.interface.Bus(channel="vcan0", - bustype=socketcan_version, - bitrate=250000, - fd=TEST_CAN_FD) + self.bus1 = can.Bus(channel="vcan0", + bustype=socketcan_version, + bitrate=250000, + fd=TEST_CAN_FD) + self.bus2 = can.Bus(channel="vcan0", + bustype=socketcan_version, + bitrate=250000, + fd=TEST_CAN_FD) def tearDown(self): self.bus1.shutdown() diff --git a/test/listener_test.py b/test/listener_test.py index 2df0ab9a8..b2a80382c 100644 --- a/test/listener_test.py +++ b/test/listener_test.py @@ -4,7 +4,7 @@ """ """ -from __future__ import absolute_import +from __future__ import absolute_import, print_function from time import sleep import unittest @@ -18,12 +18,12 @@ from .data.example_data import generate_message -channel = 'vcan0' +channel = 'virtual_channel_0' can.rc['interface'] = 'virtual' logging.getLogger('').setLevel(logging.DEBUG) -# make tests more reproducible +# makes the random number generator deterministic random.seed(13339115) @@ -54,7 +54,7 @@ def testClassesImportable(self): self.assertTrue(hasattr(can, 'LogReader')) - self.assertTrue(hasattr(can.io.player, 'MessageSync')) + self.assertTrue(hasattr(can, 'MessageSync')) class BusTest(unittest.TestCase): @@ -106,7 +106,7 @@ def test_filetype_to_instance(extension, klass): # test file extensions that are not supported with self.assertRaisesRegexp(NotImplementedError, "xyz_42"): test_filetype_to_instance("xyz_42", can.Printer) - with self.assertRaises(BaseException): + with self.assertRaises(Exception): test_filetype_to_instance(None, can.Printer) def testLoggerTypeResolution(self):