Skip to content

Commit cfb5721

Browse files
felixdivohardbyte
authored andcommitted
Add guide for new io formats (#548)
* better developer docs * Add section "About the IO module" * add note about newly added section * Update doc/internal-api.rst
1 parent a2f07fb commit cfb5721

File tree

3 files changed

+52
-9
lines changed

3 files changed

+52
-9
lines changed

can/io/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# coding: utf-8
22

33
"""
4-
Read and Write CAN bus messages using a range of Readers
4+
Read and write CAN bus messages using a range of Readers
55
and Writers based off the file extension.
66
"""
77

doc/development.rst

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ https://github.com/hardbyte/python-can
1111
There is also a `python-can <https://groups.google.com/forum/#!forum/python-can>`__
1212
mailing list for development discussion.
1313

14+
Some more information about the internals of this library can be found
15+
in the chapter :ref:`internalapi`.
16+
There is also additional information on extending the ``can.io`` module.
17+
18+
1419

1520
Building & Installing
1621
---------------------
@@ -35,7 +40,8 @@ These steps are a guideline on how to add a new backend to python-can.
3540
- Create a module (either a ``*.py`` or an entire subdirectory depending
3641
on the complexity) inside ``can.interfaces``
3742
- Implement the central part of the backend: the bus class that extends
38-
:class:`can.BusABC`. See :ref:`businternals` for more info on this one!
43+
:class:`can.BusABC`.
44+
See :ref:`businternals` for more info on this one!
3945
- Register your backend bus class in ``can.interface.BACKENDS`` and
4046
``can.interfaces.VALID_INTERFACES`` in ``can.interfaces.__init__.py``.
4147
- Add docs where appropriate. At a minimum add to ``doc/interfaces.rst`` and add
@@ -44,7 +50,6 @@ These steps are a guideline on how to add a new backend to python-can.
4450
- Add tests in ``test/*`` where appropriate.
4551

4652

47-
4853
Code Structure
4954
--------------
5055

@@ -84,4 +89,7 @@ Creating a new Release
8489
- Upload with twine ``twine upload dist/python-can-X.Y.Z*``.
8590
- In a new virtual env check that the package can be installed with pip: ``pip install python-can==X.Y.Z``.
8691
- Create a new tag in the repository.
87-
- Check the release on PyPi, Read the Docs and GitHub.
92+
- Check the release on
93+
`PyPi <https://pypi.org/project/python-can/#history>`__,
94+
`Read the Docs <https://readthedocs.org/projects/python-can/versions/>`__ and
95+
`GitHub <https://github.com/hardbyte/python-can/releases>`__.

doc/internal-api.rst

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.. _internalapi:
2+
13
Internal API
24
============
35

@@ -46,7 +48,6 @@ They **might** implement the following:
4648
and thus might not provide message filtering:
4749

4850

49-
5051
Concrete instances are usually created by :class:`can.Bus` which takes the users
5152
configuration into account.
5253

@@ -66,19 +67,53 @@ methods:
6667

6768

6869

70+
About the IO module
71+
-------------------
72+
73+
Handling of the different file formats is implemented in :mod:`can.io`.
74+
Each file/IO type is within a separate module and ideally implements both a *Reader* and a *Writer*.
75+
The reader usually extends :class:`can.io.generic.BaseIOHandler`, while
76+
the writer often additionally extends :class:`can.Listener`,
77+
to be able to be passed directly to a :class:`can.Notifier`.
78+
79+
80+
81+
Adding support for new file formats
82+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
83+
84+
This assumes that you want to add a new file format, called *canstore*.
85+
Ideally add both reading and writing support for the new file format, although this is not strictly required.
86+
87+
1. Create a new module: *can/io/canstore.py*
88+
(*or* simply copy some existing one like *can/io/csv.py*)
89+
2. Implement a reader ``CanstoreReader`` (which often extends :class:`can.io.generic.BaseIOHandler`, but does not have to).
90+
Besides from a constructor, only ``__iter__(self)`` needs to be implemented.
91+
3. Implement a writer ``CanstoreWriter`` (which often extends :class:`can.io.generic.BaseIOHandler` and :class:`can.Listener`, but does not have to).
92+
Besides from a constructor, only ``on_message_received(self, msg)`` needs to be implemented.
93+
4. Document the two new classes (and possibly additional helpers) with docstrings and comments.
94+
Please mention features and limitations of the implementation.
95+
5. Add a short section to the bottom of *doc/listeners.rst*.
96+
6. Add tests where appropriate, for example by simply adding a test case called
97+
`class TestCanstoreFileFormat(ReaderWriterTest)` to *test/logformats_test.py*.
98+
That should already handle all of the general testing.
99+
Just follow the way the other tests in there do it.
100+
7. Add imports to *can/__init__py* and *can/io/__init__py* so that the
101+
new classes can be simply imported as *from can import CanstoreReader, CanstoreWriter*.
102+
103+
104+
69105
IO Utilities
70-
------------
106+
~~~~~~~~~~~~
71107

72108

73109
.. automodule:: can.io.generic
74110
:members:
75111

76112

77113

78-
Other Util
79-
----------
114+
Other Utilities
115+
---------------
80116

81117

82118
.. automodule:: can.util
83119
:members:
84-

0 commit comments

Comments
 (0)