Skip to content
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
64 changes: 64 additions & 0 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python

name: bintablefile-package-build

on:
push:
branches: [ $default-branch ]
paths-ignore:
- '**.md'
pull_request:
branches: [ '**' ]
paths-ignore:
- '**.md'


jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest, ubuntu-24.04-arm ]
python-version: [ "3.10", "3.11","3.12", "3.13" ]

steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install flake8 pytest
pip install -e ".[dev]"
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
python -m unittest discover -s tests

build-container:
runs-on: ubuntu-latest
container:
image: python:3.12-bullseye
steps:
- uses: actions/checkout@v4
- name: Install dependencies in container
run: |
python -m pip install --upgrade pip
python -m pip install flake8 pytest
pip install -e ".[dev]"
- name: Lint with flake8 in container
run: |
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Run unittests in container
run: |
python -m unittest discover -s tests
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Binary Table File format
[![Build Status](https://github.com/eSAMTrade/bintablefile/actions/workflows/python-package.yml/badge.svg?branch=main)](https://github.com/eSAMTrade/bintablefile/actions/workflows/python-package.yml)


## Binary Table File - efficient binary file format to store and retrieve tabular data

Expand All @@ -21,4 +23,10 @@ pip install bintablefile
The library can be found on [PyPi](https://pypi.org/project/bintablefile/): https://pypi.org/project/bintablefile/


**Note**: We release directly v2.0 as v1.0 was used just internally and was not released to PyPI. The major improvement of V2 is a full-featured header, that allows to store metadata about the table, as well as store the number of records for ReadOnly compression formats like `idzip`.
**Note**: We release directly v2.0 as v1.0 was used just internally and was not released to PyPI. The major improvement of V2 is a full-featured header, that allows to store metadata about the table, as well as store the number of records for ReadOnly compression formats like `idzip`.


### Local development build
```bash
pip install -e ".[dev]"
```
2 changes: 2 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
-r requirements.txt

cython
wheel
twine
Expand Down
7 changes: 6 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ class build(build_orig):

def finalize_options(self):
super().finalize_options()
__builtins__.__NUMPY_SETUP__ = False
try:
__builtins__.__NUMPY_SETUP__ = False
except AttributeError:
print("Numpy is not installed, skipping numpy include dir")
import numpy
for extension in self.distribution.ext_modules:
extension.include_dirs.append(numpy.get_include())
Expand All @@ -33,6 +36,8 @@ def finalize_options(self):

with open("requirements-dev.txt") as fp:
dev_requires = fp.read().strip().split("\n")
# ignore the lines that starts with '#' or '-r '
dev_requires = [line for line in dev_requires if line and not line.startswith(("#", "-r"))]

setup(
ext_modules=exts,
Expand Down
46 changes: 46 additions & 0 deletions tests/test_bintablefile.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,52 @@ def setUp(self) -> None:
def tearDown(self) -> None:
self._tmp_dirpath.cleanup()

def test_structure(self):
import ctypes

def create_structure(fields):
"""
Dynamically creates a ctypes.Structure subclass with given fields.

:param fields: A list of tuples where each tuple contains the field name and ctype data type
:return: A new ctypes.Structure subclass with the specified fields
"""

class DynamicStructure(ctypes.Structure):
_fields_ = fields

return DynamicStructure

def create_structure_array(struct_cls, n):
"""
Creates an array of ctypes.Structure of type struct_cls with n elements.

:param struct_cls: The ctypes.Structure subclass
:param n: The number of elements in the array
:return: An instance of the ctypes.Array filled with structures of type struct_cls
"""
return (struct_cls * n)()

# Example usage:

# Define the list of field names and their ctypes types
fields = [
('id', ctypes.c_int),
('value', ctypes.c_float),
('name', ctypes.c_char * 20) # Example of a 20-char string
]

# Dynamically create the structure and array of structures
DynamicStruct = create_structure(fields)
StructArray = create_structure_array(DynamicStruct, 5) # Create an array of 5 elements

# Example of how to use the array
StructArray[0].id = 1
StructArray[0].value = 3.14
StructArray[0].name = b"Example"

print(StructArray[0].id, StructArray[0].value, StructArray[0].name)

def test_nominal_read_write_from_the_sameobject(self):
record_format = (int, bool, float, Decimal)
record_file = BinTableFile(self.fpath, record_format=record_format,
Expand Down