Skip to content

Add guide for new io formats #548

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion can/io/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# coding: utf-8

"""
Read and Write CAN bus messages using a range of Readers
Read and write CAN bus messages using a range of Readers
and Writers based off the file extension.
"""

Expand Down
14 changes: 11 additions & 3 deletions doc/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ https://github.com/hardbyte/python-can
There is also a `python-can <https://groups.google.com/forum/#!forum/python-can>`__
mailing list for development discussion.

Some more information about the internals of this library can be found
in the chapter :ref:`internalapi`.
There is also additional information on extending the ``can.io`` module.



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



Code Structure
--------------

Expand Down Expand Up @@ -84,4 +89,7 @@ Creating a new Release
- Upload with twine ``twine upload dist/python-can-X.Y.Z*``.
- In a new virtual env check that the package can be installed with pip: ``pip install python-can==X.Y.Z``.
- Create a new tag in the repository.
- Check the release on PyPi, Read the Docs and GitHub.
- Check the release on
`PyPi <https://pypi.org/project/python-can/#history>`__,
`Read the Docs <https://readthedocs.org/projects/python-can/versions/>`__ and
`GitHub <https://github.com/hardbyte/python-can/releases>`__.
45 changes: 40 additions & 5 deletions doc/internal-api.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _internalapi:

Internal API
============

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



Concrete instances are usually created by :class:`can.Bus` which takes the users
configuration into account.

Expand All @@ -66,19 +67,53 @@ methods:



About the IO module
-------------------

Handling of the different file formats is implemented in :mod:`can.io`.
Each file/IO type is within a separate module and ideally implements both a *Reader* and a *Writer*.
The reader usually extends :class:`can.io.generic.BaseIOHandler`, while
the writer often additionally extends :class:`can.Listener`,
to be able to be passed directly to a :class:`can.Notifier`.



Adding support for new file formats
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This assumes that you want to add a new file format, called *canstore*.
Ideally add both reading and writing support for the new file format, although this is not strictly required.

1. Create a new module: *can/io/canstore.py*
(*or* simply copy some existing one like *can/io/csv.py*)
2. Implement a reader ``CanstoreReader`` (which often extends :class:`can.io.generic.BaseIOHandler`, but does not have to).
Besides from a constructor, only ``__iter__(self)`` needs to be implemented.
3. Implement a writer ``CanstoreWriter`` (which often extends :class:`can.io.generic.BaseIOHandler` and :class:`can.Listener`, but does not have to).
Besides from a constructor, only ``on_message_received(self, msg)`` needs to be implemented.
4. Document the two new classes (and possibly additional helpers) with docstrings and comments.
Please mention features and limitations of the implementation.
5. Add a short section to the bottom of *doc/listeners.rst*.
6. Add tests where appropriate, for example by simply adding a test case called
`class TestCanstoreFileFormat(ReaderWriterTest)` to *test/logformats_test.py*.
That should already handle all of the general testing.
Just follow the way the other tests in there do it.
7. Add imports to *can/__init__py* and *can/io/__init__py* so that the
new classes can be simply imported as *from can import CanstoreReader, CanstoreWriter*.



IO Utilities
------------
~~~~~~~~~~~~


.. automodule:: can.io.generic
:members:



Other Util
----------
Other Utilities
---------------


.. automodule:: can.util
:members: