diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 51ac29395..cea71dc23 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,35 +11,29 @@ jobs: python-version: ["3.12"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install packages run: | - pip install build numpy wheel setuptools - pip install -r requirements_exe_build.txt - python setup.py bdist_wheel - pip install -e . --no-deps - pip install cmerg + pip install -r requirements_exe_build.txt + python -m build --wheel - name: Build an executable shell: bash if: ${{ matrix.python-version == '3.12' }} run: | - pip install build numpy wheel setuptools - pip install -r requirements_exe_build.txt - python setup.py bdist_wheel - pip install -e . --no-deps - pip install cmerg - pyinstaller asammdf.spec --distpath dist/${RUNNER_OS} --noconfirm --clean + pip install -r requirements_exe_build.txt + python -m build --wheel + pyinstaller asammdf.spec --distpath dist/${RUNNER_OS} --noconfirm --clean # see: https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts - name: Archive dist artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: dist path: dist/** diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml index 0face9f41..89dc5255d 100644 --- a/.github/workflows/build_linux.yml +++ b/.github/workflows/build_linux.yml @@ -11,32 +11,29 @@ jobs: python-version: ["3.10"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install packages run: | - pip install build numpy wheel - pip install -r requirements_exe_build.txt - python setup.py bdist_wheel - pip install -e . --no-deps - pip install cmerg + pip install -r requirements_exe_build.txt + python -m build --wheel - name: Build an executable shell: bash if: ${{ matrix.python-version == '3.10' }} run: | - sudo apt update - sudo apt install libegl1 libopengl0 - pyinstaller asammdf.spec --distpath dist/${RUNNER_OS} --noconfirm --clean + sudo apt update + sudo apt install libegl1 libopengl0 + pyinstaller asammdf.spec --distpath dist/${RUNNER_OS} --noconfirm --clean # see: https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts - name: Archive dist artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: dist path: dist/** diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml index 8589ddf57..3e608810f 100644 --- a/.github/workflows/build_windows.yml +++ b/.github/workflows/build_windows.yml @@ -11,35 +11,29 @@ jobs: python-version: ["3.12"] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install packages run: | - pip install build numpy wheel setuptools - pip install -r requirements_exe_build.txt - python setup.py bdist_wheel - pip install -e . --no-deps - pip install cmerg + pip install -r requirements_exe_build.txt + python -m build --wheel - name: Build an executable shell: bash if: ${{ matrix.python-version == '3.12' }} run: | - pip install build numpy wheel setuptools - pip install -r requirements_exe_build.txt - python setup.py bdist_wheel - pip install -e . --no-deps - pip install cmerg - pyinstaller asammdf.spec --distpath dist/${RUNNER_OS} --noconfirm --clean + pip install -r requirements_exe_build.txt + python -m build --wheel + pyinstaller asammdf.spec --distpath dist/${RUNNER_OS} --noconfirm --clean # see: https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts - name: Archive dist artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: dist path: dist/** diff --git a/.github/workflows/coveralls.yml b/.github/workflows/coveralls.yml index cf90dac68..a65d2a41c 100644 --- a/.github/workflows/coveralls.yml +++ b/.github/workflows/coveralls.yml @@ -11,10 +11,10 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.12" @@ -22,14 +22,14 @@ jobs: shell: bash run: | pip install tox coveralls - if [ "$RUNNER_OS" == "Linux" ]; then - sudo apt update - sudo apt-get install libegl1 libopengl0 - sudo apt-get install '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev - sudo apt-get install libxcb-xinerama0 - sudo apt-get install libxkbcommon-x11-0 - sudo apt-get install xorg - sudo apt-get install -y xvfb + if [ "$RUNNER_OS" = "Linux" ]; then + sudo apt update + sudo apt-get install libegl1 libopengl0 + sudo apt-get install '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev + sudo apt-get install libxcb-xinerama0 + sudo apt-get install libxkbcommon-x11-0 + sudo apt-get install xorg + sudo apt-get install -y xvfb fi - name: Start Xvfb diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4ddad2b54..48b1c8570 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -4,22 +4,22 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -on: [ push, pull_request ] +on: [push, pull_request] jobs: test: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ windows-latest, ubuntu-22.04, macos-latest ] - python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13" ] + os: [windows-latest, ubuntu-22.04, macos-latest] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] fail-fast: false steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -28,14 +28,14 @@ jobs: shell: bash run: | pip install tox tox-gh-actions - if [ "$RUNNER_OS" == "Linux" ]; then - sudo apt update - sudo apt-get install libegl1 libopengl0 - sudo apt-get install '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev - sudo apt-get install libxcb-xinerama0 - sudo apt-get install libxkbcommon-x11-0 - sudo apt-get install xorg - sudo apt-get install -y xvfb + if [ "$RUNNER_OS" = "Linux" ]; then + sudo apt update + sudo apt-get install libegl1 libopengl0 + sudo apt-get install '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev + sudo apt-get install libxcb-xinerama0 + sudo apt-get install libxkbcommon-x11-0 + sudo apt-get install xorg + sudo apt-get install -y xvfb fi - name: Start Xvfb @@ -53,9 +53,9 @@ jobs: run: tox - uses: actions/upload-artifact@v4 - if: failure() && matrix.os == 'windows-latest' # 'ubuntu-22.04' or 'windows-latest' + if: failure() && matrix.os == 'windows-latest' # 'ubuntu-22.04' or 'windows-latest' with: - path: '**/screenshots/**' + path: "**/screenshots/**" name: ${{ matrix.python-version }} - name: Stop Xvfb @@ -72,4 +72,3 @@ jobs: run: | pip install junitparser python -c "from ci import report_tests; report_tests(header='## Unit-tests Report:')" - diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 7e3b15925..bc48423b5 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -12,10 +12,10 @@ jobs: fail-fast: false steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 # Used to host cibuildwheel - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" @@ -27,29 +27,30 @@ jobs: env: CIBW_TEST_COMMAND: "pytest {project}/test --ignore={project}/test/asammdf/gui" run: | - if [ "$RUNNER_OS" == "Linux" ]; then - sudo apt update - sudo apt-get install libegl1 libopengl0 libxml2 libxml2-dev libxslt1-dev libxslt1.1 + if [ "$RUNNER_OS" = "Linux" ]; then + sudo apt update + sudo apt-get install libegl1 libopengl0 libxml2 libxml2-dev libxslt1-dev libxslt1.1 fi python -m cibuildwheel --output-dir wheelhouse - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: + name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} path: ./wheelhouse/*.whl build_sdist: name: Build source distribution runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: "3.10" - name: Build sdist run: pipx run build --sdist - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: path: dist/*.tar.gz diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d88213da6..82e749045 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,10 +1,10 @@ repos: - - repo: https://github.com/ambv/black - rev: 24.1.1 + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 24.10.0 hooks: - id: black - - repo: https://github.com/charliermarsh/ruff-pre-commit - # Ruff version. - rev: v0.2.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.7.4 hooks: - - id: ruff \ No newline at end of file + - id: ruff + args: [--fix] diff --git a/.readthedocs.yml b/.readthedocs.yml index 014b21909..ea06d6d14 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -19,8 +19,7 @@ formats: # Optionally set the version of Python and requirements required to build your docs python: - version: 3.8 install: - method: pip path: . - - requirements: doc/requirements.txt \ No newline at end of file + - requirements: doc/requirements.txt diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..f954697f5 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,20 @@ +{ + "recommendations": [ + "benspaulding.python-manifest-template", + "charliermarsh.ruff", + "esbenp.prettier-vscode", + "fill-labs.dependi", + "github.vscode-github-actions", + "lextudio.restructuredtext", + "ms-python.black-formatter", + "ms-python.debugpy", + "ms-python.python", + "ms-python.vscode-pylance", + "njpwerner.autodocstring", + "redhat.vscode-yaml", + "swyddfa.esbonio", + "tamasfe.even-better-toml", + "trond-snekvik.simple-rst", + "twixes.pypi-assistant" + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 898031cd7..a7c870b07 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,9 +1,11 @@ -# The basics +# Contributing + +## The basics Your help is appreciated and welcome! -The _master_ branch is meant to hold the release code. At any time this should be -identical to the code available on PyPI. +The _master_ branch is meant to hold the release code. At any time this should be +identical to the code available on PyPI. PR's will be pushed on the _development_ branch if the actual package code is changed. When the time comes this branch will be merged to the _master_ branch and a new release will be issued. @@ -11,10 +13,23 @@ will be merged to the _master_ branch and a new release will be issued. PR's that deal with documentation, and other adjacent files (README for example) can be pushed to the _master_ branch. When submitting PR's please take into account: -* the project's goals -* PEP8 and the style guide below -# Testing +- the project's goals +- PEP8 and the style guide below + +## Developer Instructions + +Clone the repository, then install the development dependencies (we recommend using a virtual environment): + +```bash +python -m venv .venv # create virtual environment in .venv +source .venv/bin/activate # activate virtual environment +pip install --requirement requirements.txt # install development dependencies (includes asammdf in editable mode) +``` + +Now you can start developing. If you are using VSCode, the virtual environment should be detected automatically. If not, open the command panel `Ctrl + Shift + P` and search for `Python: Select Interpreter`. + +## Testing You can use tox to run tests locally. Example for the unit tests with Python version 3.10: @@ -24,8 +39,8 @@ tox -e py310 Otherwise, you can just push and the tests will be run by GitHub Actions. -# Style guide +## Style guide -Just run [*black*](https://black.readthedocs.io) on modified files before sending the PR. There is no need to reinvent the wheel here! +Just run [_black_](https://black.readthedocs.io) on modified files before sending the PR. There is no need to reinvent the wheel here! -**Tip**: Add a pre-commit hook with `pip install pre-commit && pre-commit install` +**Tip**: install Git hooks using pre-commit `pre-commit install --install-hooks` diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 339640f00..f4f6da30d 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -1,5 +1,7 @@ # Python version + _Please run the following snippet and write the output here_ + ```python import platform import sys @@ -20,20 +22,24 @@ try: except ImportError: pass ``` -# Code - ## MDF version - _please write here the file version (you can run ``print(MDF(file).version)``) +# Code + +## MDF version + +_please write here the file version (you can run `print(MDF(file).version)`)_ + +## Code snippet + +_please write here the code snippet that triggers the error_ + +## Traceback + +_please write here the error traceback_ - ## Code snippet - _please write here the code snippet that triggers the error_ - - ## Traceback - _please write here the error traceback_ - # Description -The fastest way to debug is to have the original file. For data protection you can use the static +The fastest way to debug is to have the original file. For data protection you can use the static method _scramble_ to scramble all text blocks, and send the scrambled file by e-mail. _Please describe the issue here._ diff --git a/MANIFEST.in b/MANIFEST.in index 454d446fa..ae0b7d69a 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,4 @@ include LICENSE -include requirements.txt recursive-include src/asammdf *.ui recursive-include src/asammdf *.c -recursive-include src/asammdf *.qrc \ No newline at end of file +recursive-include src/asammdf *.qrc diff --git a/README.md b/README.md index 6c139ca17..8d79e5ac5 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,26 @@ +# - +logo of asammdf -

+_asammdf_ is a fast parser and editor for ASAM (Association for Standardization of Automation and Measuring Systems) MDF (Measurement Data Format) files. -*asammdf* is a fast parser and editor for ASAM (Association for Standardization of Automation and Measuring Systems) MDF (Measurement Data Format) files. +_asammdf_ supports MDF versions 2 (.dat), 3 (.mdf) and 4 (.mf4). -*asammdf* supports MDF versions 2 (.dat), 3 (.mdf) and 4 (.mf4). +_asammdf_ works on Python >= 3.9 -*asammdf* works on Python >= 3.8 +![PyPI - Downloads](https://img.shields.io/pypi/dm/asammdf) +![PyPI - License](https://img.shields.io/pypi/l/asammdf) +![PyPI - Python Version](https://img.shields.io/pypi/pyversions/asammdf) +![PyPI - Version](https://img.shields.io/pypi/v/asammdf) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit) +[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) -

+--- - +![screenshot of the graphical user interface](https://raw.githubusercontent.com/danielhrisca/asammdf/master/gui.png) -# Status +## Status | Continuous Integration | Coveralls | Codacy | ReadTheDocs | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- | @@ -23,75 +30,76 @@ | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | | [![PyPI version](https://badge.fury.io/py/asammdf.svg)](https://badge.fury.io/py/asammdf) | [![conda-forge version](https://anaconda.org/conda-forge/asammdf/badges/version.svg)](https://anaconda.org/conda-forge/asammdf) | -# Project goals +## Project goals + The main goals for this library are: -* to be faster than the other Python based mdf libraries -* to have clean and easy to understand code base -* to have minimal 3-rd party dependencies - -# Features - -* create new mdf files from scratch -* append new channels -* read unsorted MDF v3 and v4 files -* read CAN and LIN bus logging files -* extract CAN and LIN signals from anonymous bus logging measurements -* filter a subset of channels from original mdf file -* cut measurement to specified time interval -* convert to different mdf version -* export to HDF5, Matlab (v7.3), CSV and parquet -* merge multiple files sharing the same internal structure -* read and save mdf version 4.10 files containing zipped data blocks -* space optimizations for saved files (no duplicated blocks) -* split large data blocks (configurable size) for mdf version 4 -* full support (read, append, save) for the following map types (multidimensional array channels): - - * mdf version 3 channels with CDBLOCK - * mdf version 4 structure channel composition - * mdf version 4 channel arrays with CNTemplate storage and one of the array types: - - * 0 - array - * 1 - scaling axis - * 2 - look-up - -* add and extract attachments for mdf version 4 -* handle large files (for example merging two fileas, each with 14000 channels and 5GB size, on a RaspberryPi) -* extract channel data, master channel and extra channel information as *Signal* objects for unified operations with v3 and v4 files -* time domain operation using the *Signal* class - - * Pandas data frames are good if all the channels have the same time based - * a measurement will usually have channels from different sources at different rates - * the *Signal* class facilitates operations with such channels - - * graphical interface to visualize channels and perform operations with the files - -# Major features not implemented (yet) - -* for version 3 - - * functionality related to sample reduction block: the samples reduction blocks are simply ignored - -* for version 4 - - * experimental support for MDF v4.20 column oriented storage - * functionality related to sample reduction block: the samples reduction blocks are simply ignored - * handling of channel hierarchy: channel hierarchy is ignored - * full handling of bus logging measurements: currently only CAN and LIN bus logging are implemented with the - ability to *get* signals defined in the attached CAN/LIN database (.arxml or .dbc). Signals can also - be extracted from an anonymous bus logging measurement by providing a CAN or LIN database (.dbc or .arxml) - * handling of unfinished measurements (mdf 4): finalization is attempted when the file is loaded, however the - not all the finalization steps are supported - * full support for remaining mdf 4 channel arrays types - * xml schema for MDBLOCK: most metadata stored in the comment blocks will not be available - * full handling of event blocks: events are transferred to the new files (in case of calling methods - that return new *MDF* objects) but no new events can be created - * channels with default X axis: the default X axis is ignored and the channel group's master channel - is used - * attachment encryption/decryption using user provided encryption/decryption functions; this is not - part of the MDF v4 spec and is only supported by this library - -# Usage +- to be faster than the other Python based mdf libraries +- to have clean and easy to understand code base +- to have minimal 3-rd party dependencies + +## Features + +- create new mdf files from scratch +- append new channels +- read unsorted MDF v3 and v4 files +- read CAN and LIN bus logging files +- extract CAN and LIN signals from anonymous bus logging measurements +- filter a subset of channels from original mdf file +- cut measurement to specified time interval +- convert to different mdf version +- export to HDF5, Matlab (v7.3), CSV and parquet +- merge multiple files sharing the same internal structure +- read and save mdf version 4.10 files containing zipped data blocks +- space optimizations for saved files (no duplicated blocks) +- split large data blocks (configurable size) for mdf version 4 +- full support (read, append, save) for the following map types (multidimensional array channels): + + - mdf version 3 channels with CDBLOCK + - mdf version 4 structure channel composition + - mdf version 4 channel arrays with CNTemplate storage and one of the array types: + + - 0 - array + - 1 - scaling axis + - 2 - look-up + +- add and extract attachments for mdf version 4 +- handle large files (for example merging two fileas, each with 14000 channels and 5GB size, on a RaspberryPi) +- extract channel data, master channel and extra channel information as _Signal_ objects for unified operations with v3 and v4 files +- time domain operation using the _Signal_ class + + - Pandas data frames are good if all the channels have the same time based + - a measurement will usually have channels from different sources at different rates + - the _Signal_ class facilitates operations with such channels + +- graphical interface to visualize channels and perform operations with the files + +## Major features not implemented (yet) + +- for version 3 + + - functionality related to sample reduction block: the samples reduction blocks are simply ignored + +- for version 4 + + - experimental support for MDF v4.20 column oriented storage + - functionality related to sample reduction block: the samples reduction blocks are simply ignored + - handling of channel hierarchy: channel hierarchy is ignored + - full handling of bus logging measurements: currently only CAN and LIN bus logging are implemented with the + ability to _get_ signals defined in the attached CAN/LIN database (.arxml or .dbc). Signals can also + be extracted from an anonymous bus logging measurement by providing a CAN or LIN database (.dbc or .arxml) + - handling of unfinished measurements (mdf 4): finalization is attempted when the file is loaded, however the + not all the finalization steps are supported + - full support for remaining mdf 4 channel arrays types + - xml schema for MDBLOCK: most metadata stored in the comment blocks will not be available + - full handling of event blocks: events are transferred to the new files (in case of calling methods + that return new _MDF_ objects) but no new events can be created + - channels with default X axis: the default X axis is ignored and the channel group's master channel + is used + - attachment encryption/decryption using user provided encryption/decryption functions; this is not + part of the MDF v4 spec and is only supported by this library + +## Usage ```python from asammdf import MDF @@ -110,43 +118,46 @@ short.convert('4.10').save('important signals.mf4') # plot some channels from a huge file efficient = MDF('huge.mf4') for signal in efficient.select(['Sensor1', 'Voltage3']): - signal.plot() + signal.plot() ``` -Check the *examples* folder for extended usage demo, or the documentation -http://asammdf.readthedocs.io/en/master/examples.html +Check the _examples_ folder for extended usage demo, or the documentation + -https://canlogger.csselectronics.com/canedge-getting-started/ce3/log-file-tools/asammdf-gui/ + +## Documentation -# Documentation -http://asammdf.readthedocs.io/en/master + And a nicely written tutorial on the [CSS Electronics site](https://canlogger.csselectronics.com/canedge-getting-started/ce3/log-file-tools/asammdf-gui/) -# Contributing & Support +## Contributing & Support + Please have a look over the [contributing guidelines](CONTRIBUTING.md) If you enjoy this library please consider making a donation to the -[numpy project](https://numfocus.org/donate-to-numpy) or to [danielhrisca using liberapay](https://liberapay.com/danielhrisca/donate) +[numpy project](https://numfocus.org/donate-to-numpy) or to [danielhrisca using liberapay](https://liberapay.com/danielhrisca/donate). + +[![Donate using Liberapay](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/danielhrisca/donate) -## Contributors -Thanks to all who contributed with commits to *asammdf*: +### Contributors - - - +Thanks to all who contributed with commits to _asammdf_: -# Installation -*asammdf* is available on +[![profile pictures of the contributors](https://contrib.rocks/image?repo=danielhrisca/asammdf)](https://github.com/danielhrisca/asammdf/graphs/contributors) -* github: https://github.com/danielhrisca/asammdf/ -* PyPI: https://pypi.org/project/asammdf/ -* conda-forge: https://anaconda.org/conda-forge/asammdf +## Installation + +_asammdf_ is available on + +- github: +- PyPI: +- conda-forge: ```shell pip install asammdf -# for the GUI +# for the GUI pip install asammdf[gui] # or for anaconda conda install -c conda-forge asammdf @@ -154,40 +165,41 @@ conda install -c conda-forge asammdf In case a wheel is not present for you OS/Python versions and you lack the proper compiler setup to compile the c-extension code, then -you can simply copy-paste the package code to your site-packages. In this +you can simply copy-paste the package code to your site-packages. In this way the python fallback code will be used instead of the compiled c-extension code. -# Dependencies +## Dependencies + asammdf uses the following libraries -* numpy : the heart that makes all tick -* numexpr : for algebraic and rational channel conversions -* wheel : for installation in virtual environments -* pandas : for DataFrame export -* canmatrix : to handle CAN/LIN bus logging measurements -* natsort -* lxml : for canmatrix arxml support -* lz4 : to speed up the disk IO performance -* python-dateutil : measurement start time handling +- numpy : the heart that makes all tick +- numexpr : for algebraic and rational channel conversions +- wheel : for installation in virtual environments +- pandas : for DataFrame export +- canmatrix : to handle CAN/LIN bus logging measurements +- natsort +- lxml : for canmatrix arxml support +- lz4 : to speed up the disk IO performance +- python-dateutil : measurement start time handling optional dependencies needed for exports -* h5py : for HDF5 export -* hdf5storage : for Matlab v7.3 .mat export -* pyarrow : for parquet export -* scipy: for Matlab v4 and v5 .mat export +- h5py : for HDF5 export +- hdf5storage : for Matlab v7.3 .mat export +- pyarrow : for parquet export +- scipy: for Matlab v4 and v5 .mat export other optional dependencies -* PySide6 : for GUI tool -* pyqtgraph : for GUI tool and Signal plotting -* matplotlib : as fallback for Signal plotting -* faust-cchardet : to detect non-standard Unicode encodings -* chardet : to detect non-standard Unicode encodings -* pyqtlet2 : for the GPS window -* isal : for faster zlib compression/decompression -* fsspec : access files stored in the cloud +- PySide6 : for GUI tool +- pyqtgraph : for GUI tool and Signal plotting +- matplotlib : as fallback for Signal plotting +- faust-cchardet : to detect non-standard Unicode encodings +- chardet : to detect non-standard Unicode encodings +- pyqtlet2 : for the GPS window +- isal : for faster zlib compression/decompression +- fsspec : access files stored in the cloud -# Benchmarks +## Benchmarks -http://asammdf.readthedocs.io/en/master/benchmarks.html + diff --git a/bdist_wheel.bat b/bdist_wheel.bat index b9a428064..cfd6e599d 100644 --- a/bdist_wheel.bat +++ b/bdist_wheel.bat @@ -1,2 +1,2 @@ run_black_and_ruff.bat && ^ -python setup.py bdist_wheel \ No newline at end of file +python -m build --wheel diff --git a/benchmarks/requirements.txt b/benchmarks/requirements.txt index c227e90c2..30bef2ce1 100644 --- a/benchmarks/requirements.txt +++ b/benchmarks/requirements.txt @@ -1,7 +1,5 @@ numpy matplotlib asammdf -mdfreader -blosc -numpexpr -psutil \ No newline at end of file +mdfreader[compression] +psutil diff --git a/ci/requirements.txt b/ci/requirements.txt new file mode 100644 index 000000000..e4dd9eec8 --- /dev/null +++ b/ci/requirements.txt @@ -0,0 +1 @@ +junitparser diff --git a/doc/conf.py b/doc/conf.py index 15e2b79bf..9c5ebac46 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -17,17 +17,11 @@ # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # -import os -import sys # BASE_DIR = os.path.abspath("..") # sys.path.insert(0, BASE_DIR) -with open(os.path.join("..", "src", "asammdf", "version.py"), "r") as f: - for line in f: - if line.startswith("__version__"): - asam_version = line.split("=")[-1].strip().strip("'") - break +from asammdf.version import __version__ as asam_version print("version", asam_version) @@ -77,7 +71,7 @@ # General information about the project. project = "asammdf" -copyright = "2018, Daniel Hrisca" +copyright = "2024, Daniel Hrisca" author = "Daniel Hrisca" # The version info for the project you're documenting, acts as replacement for @@ -136,20 +130,20 @@ # -- Options for LaTeX output --------------------------------------------- -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} +# latex_elements = { +# # The paper size ('letterpaper' or 'a4paper'). +# # +# # 'papersize': 'letterpaper', +# # The font size ('10pt', '11pt' or '12pt'). +# # +# # 'pointsize': '10pt', +# # Additional stuff for the LaTeX preamble. +# # +# # 'preamble': '', +# # Latex figure (float) alignment +# # +# # 'figure_align': 'htbp', +# } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, diff --git a/doc/index.rst b/doc/index.rst index 9bfa71577..0d4693506 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -6,16 +6,16 @@ Welcome to asammdf's documentation! =================================== -*asammdf* is a fast parser and editor for ASAM (Association for Standardization of Automation and Measuring Systems) MDF (Measurement Data Format) files. +*asammdf* is a fast parser and editor for ASAM (Association for Standardization of Automation and Measuring Systems) MDF (Measurement Data Format) files. -*asammdf* supports MDF versions 2 (.dat), 3 (.mdf) and 4 (.mf4). +*asammdf* supports MDF versions 2 (.dat), 3 (.mdf) and 4 (.mf4). -*asammdf* works on Python >= 3.7 (for Python 2.7, 3.4 and 3.5 see the 4.x.y releases) +*asammdf* works on Python >= 3.9 (for Python 2.7, 3.4 and 3.5 see the 4.x.y releases) .. toctree:: :maxdepth: 4 - + intro api buslogging diff --git a/doc/requirements.txt b/doc/requirements.txt index 28c8fc710..31ce1261b 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -4,13 +4,4 @@ sphinx sphinx-argparse sphinx-rtd-theme sphinxcontrib-mermaid -# canmatrix ImportError workaround -PyYAML -xlrd -XlsxWriter -xlwt -canmatrix -pandas -numexpr -lz4 numpy>=1.23.0 diff --git a/pre_commit.bat b/pre_commit.bat deleted file mode 100644 index 20d9e5109..000000000 --- a/pre_commit.bat +++ /dev/null @@ -1 +0,0 @@ -isort . && black . diff --git a/pylint.cfg b/pylint.cfg deleted file mode 100644 index c51749c9b..000000000 --- a/pylint.cfg +++ /dev/null @@ -1,370 +0,0 @@ -[MASTER] -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=.git, venv - -# Pickle collected data for later comparisons. -persistent=yes - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - -# Use multiple processes to speed up Pylint. -jobs=8 - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code -extension-pkg-whitelist= - -# Allow optimization of some AST trees. This will activate a peephole AST -# optimizer, which will apply various small optimizations. For instance, it can -# be used to obtain the result of joining multiple strings with the addition -# operator. Joining a lot of strings can lead to a maximum recursion error in -# Pylint and this flag can prevent that. It has one side effect, the resulting -# AST will be different than the one from reality. -optimize-ast=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED -confidence= - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time. See also the "--disable" option for examples. -#enable= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once).You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use"--disable=all --enable=classes -# --disable=W" -disable=import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating - - -[REPORTS] - -# Set the output format. Available formats are text, parseable, colorized, msvs -# (visual studio) and html. You can also give a reporter class, eg -# mypackage.mymodule.MyReporterClass. -output-format=parseable - -# Put messages in a separate file for each module / package specified on the -# command line instead of printing them on stdout. Reports (if any) will be -# written in a file name "pylint_global.[txt|html]". -files-output=yes - -# Tells whether to display a full report or only the messages -reports=yes - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details -#msg-template= - - -[SPELLING] - -# Spelling dictionary name. Available dictionaries: none. To make it working -# install python-enchant package. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to indicated private dictionary in -# --spelling-private-dict-file option instead of raising a message. -spelling-store-unknown-words=no - - -[SIMILARITIES] - -# Minimum lines number of a similarity. -min-similarity-lines=4 - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME,TODO - - -[BASIC] - -# List of builtins function names that should not be used, separated by a comma -bad-functions=map,filter,input - -# Good variable names which should always be accepted, separated by a comma -good-names=i,j,k,ex,Run,_ - -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Include a hint for the correct naming format with invalid-name -include-naming-hint=no - -# Regular expression matching correct function names -function-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for function names -function-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct variable names -variable-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for variable names -variable-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct constant names -const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Naming hint for constant names -const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Regular expression matching correct attribute names -attr-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for attribute names -attr-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct argument names -argument-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for argument names -argument-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct class attribute names -class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Naming hint for class attribute names -class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Regular expression matching correct inline iteration names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Naming hint for inline iteration names -inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ - -# Regular expression matching correct class names -class-rgx=[A-Z_][a-zA-Z0-9]+$ - -# Naming hint for class names -class-name-hint=[A-Z_][a-zA-Z0-9]+$ - -# Regular expression matching correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Naming hint for module names -module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Regular expression matching correct method names -method-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for method names -method-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - - -[ELIF] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - - -[FORMAT] - -# Maximum number of characters on a single line. -max-line-length=100 - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma,dict-separator - -# Maximum number of lines in a module -max-module-lines=1000 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format=LF - - -[TYPECHECK] - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis. It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= - -# List of classes names for which member attributes should not be checked -# (useful for classes with attributes dynamically set). This supports can work -# with qualified names. -ignored-classes= - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - - -[VARIABLES] - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# A regular expression matching the name of dummy variables (i.e. expectedly -# not used). -dummy-variables-rgx=_$|dummy - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_,_cb - - -[LOGGING] - -# Logging modules to check that the string format arguments are in logging -# function parameter format -logging-modules=logging - - -[IMPORTS] - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=regsub,TERMIOS,Bastion,rexec - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=mcs - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict,_fields,_replace,_source,_make - - -[DESIGN] - -# Maximum number of arguments for function / method -max-args=5 - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=_.* - -# Maximum number of locals for function / method body -max-locals=15 - -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of branch for function / method body -max-branches=12 - -# Maximum number of statements in function / method body -max-statements=50 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of boolean expressions in a if statement -max-bool-expr=5 - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=Exception diff --git a/pyproject.toml b/pyproject.toml index d430a7b7b..edf595d57 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,12 @@ [build-system] -requires = ["numpy", "setuptools", "wheel"] +requires = ["numpy", "setuptools"] build-backend = "setuptools.build_meta" [tool.black] line-length = 120 +required-version = "24" target-version = ['py39'] -extend-exclude = ''' +force-exclude = ''' ^/src/asammdf/gui/ui ''' @@ -18,33 +19,35 @@ manylinux-x86_64-image = "manylinux_2_28" test-requires = "pytest" test-command = "pytest {project}/test" build-frontend = "build" -archs = ["auto64"] # only build for 64bit architectures -skip = ["pp*", "*_ppc64le", "*-musllinux*", "*_s390x"] # skip pypy and irrelevant architectures +archs = ["auto64"] # only build for 64bit architectures +# skip pypy and irrelevant architectures +skip = ["pp*", "*_ppc64le", "*-musllinux*", "*_s390x"] [tool.ruff] target-version = "py39" -exclude = ["./src/asammdf/gui/ui"] +extend-exclude = ["benchmarks", "ci", "doc", "examples", "./src/asammdf/gui/ui"] +force-exclude = true [tool.ruff.lint] select = [ - "B", # flake8-bugbear + "B", # flake8-bugbear "C4", # flake8-comprehensions - "F", # pyflakes + "F", # pyflakes "UP", # pyupgrade - "I", # isort - "PIE", # flake8-pie + "I", # isort + "PIE", # flake8-pie "PL", # pylint - "RUF", # Ruff-specific rules + "RUF", # Ruff-specific rules ] ignore = [ - "B007", # unused-loop-control-variable - "F841", # unused-variable - "PLC0414", # useless-import-alias - "PLR09", # too-many-this, too-many-that - "PLR2004", # magic-value-comparison - "PLR5501", # collapsible-else-if - "PLW0603", # global-statement - "PLW2901", # redefined-loop-name + "B007", # unused-loop-control-variable + "F841", # unused-variable + "PLC0414", # useless-import-alias + "PLR09", # too-many-this, too-many-that + "PLR2004", # magic-value-comparison + "PLR5501", # collapsible-else-if + "PLW0603", # global-statement + "PLW2901", # redefined-loop-name "RUF012", # mutable-class-default "RUF015", # unnecessary-iterable-allocation-for-first-element ] @@ -52,4 +55,4 @@ ignore = [ [tool.ruff.lint.isort] known-first-party = ["asammdf"] order-by-type = false -force-sort-within-sections = true \ No newline at end of file +force-sort-within-sections = true diff --git a/requirements.txt b/requirements.txt index cb16f7b80..9dc408b33 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,11 @@ -canmatrix[arxml,dbc]>=1.0 -lz4 -numexpr -numpy>=1.23.0 -pandas -typing_extensions -python-dateutil -isal; platform_machine == "x86_64" or platform_machine == "AMD64" -lxml>=4.9.3 +# Development dependencies +--editable .[decode,encryption,export,export_matlab_v5,filesystem,gui,symbolic_math] +--requirement benchmarks/requirements.txt +--requirement ci/requirements.txt +--requirement doc/requirements.txt +--requirement test/requirements.txt +black~=24.1 # Aligned with .pre-commit-config.yaml +build +pre-commit +ruff~=0.7.0 # Aligned with .pre-commit-config.yaml +tox diff --git a/requirements_exe_build.txt b/requirements_exe_build.txt index cbe41a4a6..b305c6596 100644 --- a/requirements_exe_build.txt +++ b/requirements_exe_build.txt @@ -1,25 +1,5 @@ -canmatrix[arxml,dbc]>=1.0 -lz4 -numexpr -numpy -pandas -typing_extensions -isal; platform_machine == "x86_64" or platform_machine == "AMD64" -lxml -natsort -PySide6==6.7.3 -pyqtgraph -QtPy -pyqtlet2 +--editable .[decode,encryption,export,export_matlab_v5,gui,symbolic_math] +build +cmerg pyopengl -h5py -hdf5storage -snappy -faust-cchardet -chardet -cryptography -keyring pyinstaller -scipy -sympy -pyarrow diff --git a/run_black_and_ruff.bat b/run_black_and_ruff.bat index 074e7ade0..37d653766 100644 --- a/run_black_and_ruff.bat +++ b/run_black_and_ruff.bat @@ -1,8 +1,3 @@ -pip install -U black ruff && ^ -black --config pyproject.toml ./src && ^ -black --config pyproject.toml ./test && ^ -black --config pyproject.toml asammdf.spec && ^ -black --config pyproject.toml setup.py && ^ -ruff check --fix ./src && ^ -ruff check --fix ./test && ^ -ruff check --fix ./setup.py +pip install --upgrade black~=24.1 ruff~=0.7.0 && ^ +black --config pyproject.toml . asammdf.spec && ^ +ruff check --fix diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 60c2cd10f..000000000 --- a/setup.cfg +++ /dev/null @@ -1,32 +0,0 @@ -[aliases] -test=pytest - -[tool:pytest] -norecursedirs = .git - venv - .tox - .eggs - dist - build -addopts = - --tb=long -flake8-ignore = D401 -flake8-max-line-length = 160 -flake8-max-complexity = 10 -flake8-show-source = true -flake8-extensions = .py -flake8-exclude = .git, venv, .tox, .eggs, dist, build -flake8-accept-encodings = utf-8p -pep8maxlinelength = 160 - -[pycodestyle] -exclude = .git, venv, .tox, .eggs, dist, build -max-line-length = 160 - -[flake8] -accept-encodings = utf-8 -exclude = .git, venv, .tox, .eggs, dist, build -max-line-length = 160 -max_complexity = 10 -ignore = D401 -doctests = True diff --git a/setup.py b/setup.py index 86c1d4232..682d6db59 100644 --- a/setup.py +++ b/setup.py @@ -11,10 +11,6 @@ PROJECT_PATH = Path(__file__).parent -with (PROJECT_PATH / "requirements.txt").open() as f: - install_requires = [l.strip() for l in f.readlines()] - - def _get_version(): with PROJECT_PATH.joinpath("src", "asammdf", "version.py").open() as f: line = next(line for line in f if line.startswith("__version__")) @@ -95,7 +91,17 @@ def _get_ext_modules(): # your project is installed. For an analysis of "install_requires" vs pip's # requirements files see: # https://packaging.python.org/en/latest/requirements.html - install_requires=install_requires, + install_requires=[ + "canmatrix[arxml,dbc]>=1.0", + "isal; platform_machine == 'x86_64' or platform_machine == 'AMD64'", + "lxml>=4.9.3", + "lz4", + "numexpr", + "numpy>=1.23.0", + "pandas", + "python-dateutil", + "typing-extensions", + ], # List additional groups of dependencies here (e.g. development # dependencies). You can install these using the following syntax, # for example: @@ -110,7 +116,7 @@ def _get_ext_modules(): ], "export_matlab_v5": "scipy", "gui": [ - "lxml>=4.9.2", + "asammdf[decode,export]", "natsort", "PySide6", "pyqtgraph", @@ -135,6 +141,6 @@ def _get_ext_modules(): # To provide executable scripts, use entry points in preference to the # "scripts" keyword. Entry points provide cross-platform support and allow # pip to create the appropriate form of executable for the target platform. - entry_points={"console_scripts": ["asammdf = asammdf.app.asammdfgui:main [gui,export,decode]"]}, + entry_points={"console_scripts": ["asammdf = asammdf.app.asammdfgui:main [gui]"]}, ext_modules=_get_ext_modules(), ) diff --git a/src/asammdf/gui/widgets/main.py b/src/asammdf/gui/widgets/main.py index b2fae4850..5bd035334 100644 --- a/src/asammdf/gui/widgets/main.py +++ b/src/asammdf/gui/widgets/main.py @@ -1520,8 +1520,8 @@ def show_about(self): * PySide6 {pyside6_version} * CPython {cpython} - -Copyright © 2018-2023 Daniel Hrisca""", + +Copyright © 2018-2024 Daniel Hrisca""", markdown=True, ) diff --git a/src/asammdf/mdf.py b/src/asammdf/mdf.py index bdaa10cbd..2a069967a 100644 --- a/src/asammdf/mdf.py +++ b/src/asammdf/mdf.py @@ -148,7 +148,7 @@ def get_temporary_filename(path: Path = Path("temporary.mf4"), dir: str | Path | class MDF: - """Unified access to MDF v3 and v4 files. Underlying _mdf's attributes and + r"""Unified access to MDF v3 and v4 files. Underlying _mdf's attributes and methods are linked to the `MDF` object via *setattr*. This is done to expose them to the user code and for performance considerations. @@ -176,26 +176,26 @@ class MDF: .. versionchanged:: 6.3.0 make the default None - use_display_names (\*\*kwargs) : bool + use_display_names (**kwargs) : bool keyword only argument: for MDF4 files parse the XML channel comment to search for the display name; XML parsing is quite expensive so setting this to *False* can decrease the loading times very much; default *True* - remove_source_from_channel_names (\*\*kwargs) : bool - remove source from channel names ("Speed\XCP3" -> "Speed") - copy_on_get (\*\*kwargs) : bool + remove_source_from_channel_names (**kwargs) : bool + remove source from channel names ("Speed\\XCP3" -> "Speed") + copy_on_get (**kwargs) : bool copy arrays in the get method; default *True* - expand_zippedfile (\*\*kwargs) : bool + expand_zippedfile (**kwargs) : bool only for bz2.BZ2File and gzip.GzipFile, load the file content into a BytesIO before parsing (avoids the huge performance penalty of doing random reads from the zipped file); default *True* - raise_on_multiple_occurrences (\*\*kwargs) : bool + raise_on_multiple_occurrences (**kwargs) : bool raise exception when there are multiple channel occurrences in the file and the `get` call is ambiguous; default True .. versionadded:: 7.0.0 - temporary_folder (\*\*kwargs) : str | pathlib.Path + temporary_folder (**kwargs) : str | pathlib.Path folder to use for temporary files .. versionadded:: 7.0.0 @@ -1126,7 +1126,7 @@ def export( filename : string | pathlib.Path export file name - \*\*kwargs + **kwargs * `single_time_base`: resample all channels to common time base, default *False* diff --git a/test/requirements.txt b/test/requirements.txt index 2a68db549..10251ca4f 100644 --- a/test/requirements.txt +++ b/test/requirements.txt @@ -1,16 +1,5 @@ -natsort -numexpr -numpy -pandas -psutil -pyautogui -python-xlib; sys_platform=="linux" +PyAutoGUI pytest pytest-cov -canmatrix[arxml,dbc]>=1.0 -lz4 -typing_extensions -PySide6==6.7.3 -pyqtgraph -python-dateutil -isal; platform_machine == "x86_64" or platform_machine == "AMD64" +pytest-timeout +xmlrunner; python_version < "3.12" diff --git a/tox.ini b/tox.ini index 0fbad4541..d52aff87d 100644 --- a/tox.ini +++ b/tox.ini @@ -5,40 +5,43 @@ [tox] isolated_build = true -envlist = py39, py310, py311, py312, py313, style, doc +envlist = py39, py310, py311, py312, py313, black, ruff, doc [testenv:{py39,py310,py311,py312,py313}] deps = - -rtest/requirements.txt - coverage - pytest-timeout - pyautogui; sys_platform != "win32" - pywin32; sys_platform == "win32" + --requirement test/requirements.txt +extras = + gui passenv = DISPLAY,XAUTHORITY setenv = DISPLAY = :0 QT_DEBUG_PLUGINS = 1 commands = - coverage run --rcfile=pyproject.toml --module pytest - coverage report --rcfile=pyproject.toml + pytest --cov -[testenv:style] +[testenv:black] deps = - black - ruff + black~=24.1 # Aligned with .pre-commit-config.yaml +skip_install = true commands = - black --config pyproject.toml --check . - ruff check ./src + black --config pyproject.toml --check . asammdf.spec + +[testenv:ruff] +deps = + ruff~=0.7.0 # Aligned with .pre-commit-config.yaml +skip_install = true +commands = + ruff check [testenv:doc] deps = - -rdoc/requirements.txt + --requirement doc/requirements.txt commands = - sphinx-build -b html doc doc/_build/html + sphinx-build --builder html --nitpicky doc doc/_build/html [gh-actions] python = - 3.9: py39, style, doc + 3.9: py39, black, ruff, doc 3.10: py310 3.11: py311 3.12: py312