Skip to content

Commit

Permalink
Merge branch 'develop' into mf4-io
Browse files Browse the repository at this point in the history
  • Loading branch information
hardbyte committed Nov 14, 2022
2 parents 42c850f + 4b1acde commit e048df9
Show file tree
Hide file tree
Showing 35 changed files with 782 additions and 319 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
"3.8",
"3.9",
"3.10",
"3.11.0-alpha - 3.11.0",
"3.11",
"pypy-3.7",
"pypy-3.8",
"pypy-3.9",
Expand Down Expand Up @@ -67,6 +67,9 @@ jobs:
- name: mypy 3.10
run: |
mypy --python-version 3.10 .
- name: mypy 3.11
run: |
mypy --python-version 3.11 .
- name: pylint
run: |
pylint --rcfile=.pylintrc \
Expand Down
74 changes: 74 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,77 @@
Version 4.1.0
====

Features
--------

### IO

* The canutils logger preserves message direction (#1244)
and uses common interface names (e.g. can0) instead of just
channel numbers (#1271).
* The ``can.logger`` script accepts the ``-a, --append`` option
to add new data to an existing log file (#1326, #1327, #1361).
Currently only the blf-, canutils- and csv-formats are supported.
* All CLI ``extra_args`` are passed to the bus, logger
and player initialisation (#1366).

### Type Annotations
* python-can now includes the ``py.typed`` marker to support type checking
according to PEP 561 (#1344).

### Interface Improvements
* The gs_usb interface can be selected by device index instead
of USB bus/address. Loopback frames are now correctly marked
with the ``is_rx`` flag (#1270).
* The PCAN interface can be selected by its device ID instead
of just the channel name (#1346).
* The PCAN Bus implementation supports auto bus-off reset (#1345).
* SocketCAN: Make ``find_available_interfaces()`` find slcanX interfaces (#1369).
* Vector: Add xlGetReceiveQueueLevel, xlGenerateSyncPulse and
xlFlushReceiveQueue to xldriver (#1387).
* Vector: Raise a CanInitializationError, if the CAN settings can not
be applied according to the arguments of ``VectorBus.__init__`` (#1426).

Bug Fixes
---------

* Improve robustness of USB2CAN serial number detection (#1129).
* Fix channel2int conversion (#1268, #1269).
* Fix BLF timestamp conversion (#1266, #1273).
* Fix timestamp handling in udp_multicast on macOS (#1275, #1278).
* Fix failure to initiate the Neousys DLL (#1281).
* Fix AttributeError in IscanError (#1292, #1293).
* Add missing vector devices (#1296).
* Fix error for DLC > 8 in ASCReader (#1299, #1301).
* Set default mode for FileIOMessageWriter to wt instead of rt (#1303).
* Fix conversion for port number from config file (#1309).
* Fix fileno error on Windows (#1312, #1313, #1333).
* Remove redundant ``writer.stop()`` call that throws error (#1316, #1317).
* Detect and cast types of CLI ``extra_args`` (#1280, #1328).
* Fix ASC/CANoe incompatibility due to timestamp format (#1315, #1362).
* Fix MessageSync timings (#1372, #1374).
* Fix file name for compressed files in SizedRotatingLogger (#1382, #1683).
* Fix memory leak in neoVI bus where message_receipts grows with no limit (#1427).
* Raise ValueError if gzip is used with incompatible log formats (#1429).

Miscellaneous
-------------

* Allow ICSApiError to be pickled and un-pickled (#1341)
* Sort interface names in CLI API to make documentation reproducible (#1342)
* Exclude repository-configuration from git-archive (#1343)
* Improve documentation (#1397, #1401, #1405, #1420, #1421)
* Officially support Python 3.11 (#1423)

Breaking Changes
----------------

* ``windows-curses`` was moved to optional dependencies (#1395).
Use ``pip install python-can[viewer]`` if you are using the ``can.viewer``
script on Windows.
* The attributes of ``can.interfaces.vector.VectorChannelConfig`` were renamed
from camelCase to snake_case (#1422).

Version 4.0.0
====

Expand Down
2 changes: 1 addition & 1 deletion can/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import logging
from typing import Dict, Any

__version__ = "4.0.0"
__version__ = "4.1.0.dev0"

log = logging.getLogger("can")

Expand Down
51 changes: 29 additions & 22 deletions can/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,37 +60,44 @@ class Bus(BusABC): # pylint: disable=abstract-method
Instantiates a CAN Bus of the given ``interface``, falls back to reading a
configuration file from default locations.
"""
@staticmethod
def __new__( # type: ignore # pylint: disable=keyword-arg-before-vararg
cls: Any, channel: Optional[Channel] = None, *args: Any, **kwargs: Any
) -> BusABC:
"""
Takes the same arguments as :class:`can.BusABC.__init__`.
Some might have a special meaning, see below.
:param channel:
Channel identification. Expected type is backend dependent.
Set to ``None`` to let it be resolved automatically from the default
:ref:`configuration`.
:param channel:
Set to ``None`` to let it be resolved automatically from the default
configuration. That might fail, see below.
:param interface:
See :ref:`interface names` for a list of supported interfaces.
Set to ``None`` to let it be resolved automatically from the default
:ref:`configuration`.
Expected type is backend dependent.
:param args:
``interface`` specific positional arguments.
:param dict kwargs:
Should contain an ``interface`` key with a valid interface name. If not,
it is completed using :meth:`can.util.load_config`.
:param kwargs:
``interface`` specific keyword arguments.
:raises: can.CanInterfaceNotImplementedError
if the ``interface`` isn't recognized or cannot be loaded
:raises ~can.exceptions.CanInterfaceNotImplementedError:
if the ``interface`` isn't recognized or cannot be loaded
:raises: can.CanInitializationError
if the bus cannot be instantiated
:raises ~can.exceptions.CanInitializationError:
if the bus cannot be instantiated
:raises: ValueError
if the ``channel`` could not be determined
"""
:raises ValueError:
if the ``channel`` could not be determined
"""

@staticmethod
def __new__( # type: ignore # pylint: disable=keyword-arg-before-vararg
cls: Any,
channel: Optional[Channel] = None,
interface: Optional[str] = None,
*args: Any,
**kwargs: Any,
) -> BusABC:
# figure out the rest of the configuration; this might raise an error
if interface is not None:
kwargs["interface"] = interface
if channel is not None:
kwargs["channel"] = channel
if "context" in kwargs:
Expand Down
2 changes: 1 addition & 1 deletion can/interfaces/cantact.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def __init__(
Bitrate in bits/s
:param bool monitor:
If true, operate in listen-only monitoring mode
:param BitTiming bit_timing
:param BitTiming bit_timing:
Optional BitTiming to use for custom bit timing setting. Overrides bitrate if not None.
"""

Expand Down
20 changes: 12 additions & 8 deletions can/interfaces/ics_neovi/neovi_bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,9 @@ def _process_msg_queue(self, timeout=0.1):
if is_tx:
if bool(ics_msg.StatusBitField & ics.SPY_STATUS_GLOBAL_ERR):
continue
if ics_msg.DescriptionID:
receipt_key = (ics_msg.ArbIDOrHeader, ics_msg.DescriptionID)

receipt_key = (ics_msg.ArbIDOrHeader, ics_msg.DescriptionID)
if ics_msg.DescriptionID and receipt_key in self.message_receipts:
self.message_receipts[receipt_key].set()
if not self._receive_own_messages:
continue
Expand Down Expand Up @@ -477,11 +478,10 @@ def send(self, msg, timeout=0):
else:
raise ValueError("msg.channel must be set when using multiple channels.")

msg_desc_id = next(description_id)
message.DescriptionID = msg_desc_id
receipt_key = (msg.arbitration_id, msg_desc_id)

if timeout != 0:
msg_desc_id = next(description_id)
message.DescriptionID = msg_desc_id
receipt_key = (msg.arbitration_id, msg_desc_id)
self.message_receipts[receipt_key].clear()

try:
Expand All @@ -492,5 +492,9 @@ def send(self, msg, timeout=0):
# If timeout is set, wait for ACK
# This requires a notifier for the bus or
# some other thread calling recv periodically
if timeout != 0 and not self.message_receipts[receipt_key].wait(timeout):
raise CanTimeoutError("Transmit timeout")
if timeout != 0:
got_receipt = self.message_receipts[receipt_key].wait(timeout)
# We no longer need this receipt, so no point keeping it in memory
del self.message_receipts[receipt_key]
if not got_receipt:
raise CanTimeoutError("Transmit timeout")
4 changes: 2 additions & 2 deletions can/interfaces/ixxat/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Ctypes wrapper module for IXXAT Virtual CAN Interface V3 on win32 systems
Ctypes wrapper module for IXXAT Virtual CAN Interface V4 on win32 systems
Copyright (C) 2016 Giuseppe Corbelli <giuseppe.corbelli@weightpack.com>
Copyright (C) 2016-2021 Giuseppe Corbelli <giuseppe.corbelli@weightpack.com>
"""

from can.interfaces.ixxat.canlib import IXXATBus
Expand Down
19 changes: 16 additions & 3 deletions can/interfaces/ixxat/canlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import can.interfaces.ixxat.canlib_vcinpl2 as vcinpl2

from can import BusABC, Message
from can.bus import BusState

from typing import Optional


Expand All @@ -11,7 +13,8 @@ class IXXATBus(BusABC):
Based on the C implementation of IXXAT, two different dlls are provided by IXXAT, one to work with CAN,
the other with CAN-FD.
This class only delegates to related implementation (in calib_vcinpl or canlib_vcinpl2) class depending on fd user option.
This class only delegates to related implementation (in calib_vcinpl or canlib_vcinpl2)
class depending on fd user option.
"""

def __init__(
Expand Down Expand Up @@ -140,8 +143,18 @@ def _recv_internal(self, timeout):
def send(self, msg: Message, timeout: Optional[float] = None) -> None:
return self.bus.send(msg, timeout)

def _send_periodic_internal(self, msg, period, duration=None):
return self.bus._send_periodic_internal(msg, period, duration)
def _send_periodic_internal(self, msgs, period, duration=None):
return self.bus._send_periodic_internal(msgs, period, duration)

def shutdown(self):
return self.bus.shutdown()

@property
def state(self) -> BusState:
"""
Return the current state of the hardware
"""
return self.bus.state


# ~class IXXATBus(BusABC): ---------------------------------------------------
Loading

0 comments on commit e048df9

Please sign in to comment.