Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

When re-exporting entities from a package-level __init__.py, always use the form import ... as ... even if the name is not changed, to signal static analysis tools that the name is intended to be re-exported (unless the aliased name starts with an underscore). This is enforceable with MyPy.

Excepting the above described case of package-level API re-export, do not import specific entities; instead, import only the module itself and then use verbose references, as shown below. If you really need to import a specific entity, consider prefixing it with an underscore to prevent scope leakage. Exception applies to well-encapsulated submodules which are not part of the package API (i.e., prefixed with an underscore) – you can import whatever you want provided that the visibility scope of the module is sufficiently narrow. Example:

Code Block
languagepy
from pyuavcan.transport import Transport    # Don't do this.
import pyuavcan.transport                   # Good. Use like: pyuavcan.transport.Transport

Semantic and behavioral conventions

...

Code Block
languagepy
def write(self, data: typing.Union[bytes, str], timeout: typing.Optional[float] = None) -> int:
    """
    This method can be invoked concurrently from multiple threads, even if there are other threads blocked on
    any of the reading methods.
    :param data:        Data to transmit.
    :param timeout:     Timeout in seconds, None for infinity.
    :return:            Number of bytes written -- always either len(data) or 0 on timeout.
    """
    if isinstance(data, str):
        data = data.encode()
     if not isinstance(data, bytes):
        raise ValueError('Invalid data type: %r' % type(data))
     try:
        if len(data) > 0:
            self._txq.put(data, timeout=timeout)
    except queue.Full:
        return 0
    else:
        return len(data)

...

Keep simple test cases as close to the tested code as possible: either in doctest or in test functions; in the latter case, use the function name pattern _unittest_*. Move all complex test code outside of the main codebase into a dedicated package (usually named tests).

Misc

Write all new code in Python 3.7.

The recommended IDE for Python development is JetBrains PyCharm.