diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 61d5e23..1152ab5 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -13,10 +13,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10"] - exclude: - - os: windows-latest - python-version: 2.7 + python-version: ["3.6", "3.7", "3.8", "3.9", "3.10"] runs-on: ${{ matrix.os }} steps: @@ -56,12 +53,10 @@ jobs: python-version: 3.8 - name: Install dependencies run: | - python -m pip install setuptools wheel cython cibuildwheel + python -m pip install setuptools wheel cython cibuildwheel==2.3.0 - name: Build wheels run: | python -m cibuildwheel --output-dir wheelhouse - env: - CIBW_SKIP: cp27-win* - uses: actions/upload-artifact@v2 with: path: ./wheelhouse/*.whl diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..404e81e --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,35 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.0.1 + hooks: + - id: check-json + - id: check-toml + - id: check-yaml + - id: check-case-conflict + - id: check-added-large-files + - id: debug-statements + - id: end-of-file-fixer + - id: mixed-line-ending + args: ["--fix=no"] + - id: requirements-txt-fixer + - id: trailing-whitespace + args: ["--markdown-linebreak-ext=md"] + - repo: https://github.com/asottile/pyupgrade + rev: 'v2.29.1' + hooks: + - id: pyupgrade + args: ["--py36-plus"] + - repo: https://github.com/psf/black + rev: '21.11b1' + hooks: + - id: black + language_version: python3 # Should be a command that runs python3.6+ + - repo: https://github.com/PyCQA/isort + rev: '5.10.1' + hooks: + - id: isort + language_version: python3 + - repo: https://gitlab.com/pycqa/flake8 + rev: 4.0.1 + hooks: + - id: flake8 diff --git a/README.md b/README.md index df7318e..64b854e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Python bindings for the fast non-cryptograpical hash function MetroHash. MetroHa ## Requirements -The library has been tested on Linux Python 2.7 and 3.6, and on Windows Python 3.5, 3.6, 3.7. +The library has been tested on Linux Python 3.6, and on Windows Python 3.6, 3.7. ## Install diff --git a/metrohash.pyx b/metrohash.pyx index f7c7805..86cb336 100644 --- a/metrohash.pyx +++ b/metrohash.pyx @@ -1,9 +1,11 @@ # distutils: language=c++ import sys -from libcpp cimport bool -from libc.stdint cimport uint64_t, uint8_t + from cython.operator cimport dereference as deref +from libc.stdint cimport uint8_t, uint64_t +from libcpp cimport bool + cdef extern from "metrohash.h" nogil: diff --git a/pyproject.toml b/pyproject.toml index d6eb448..010de90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,10 @@ [build-system] requires = ["setuptools", "wheel", "Cython"] +[tool.black] +line-length = 120 + [tool.isort] -indent = "tab" +profile = "black" +src_paths = ["."] line_length = 120 diff --git a/setup.py b/setup.py index 017fc35..10cc2fa 100644 --- a/setup.py +++ b/setup.py @@ -1,63 +1,60 @@ +import platform import sys -from io import open from Cython.Build import cythonize -import platform from setuptools import Extension, setup EXT_SOURCES = [ - "MetroHash/src/metrohash64.cpp", - "MetroHash/src/metrohash128.cpp", + "MetroHash/src/metrohash64.cpp", + "MetroHash/src/metrohash128.cpp", ] -INT_SOURCES = [ - "metrohash.pyx" -] +INT_SOURCES = ["metrohash.pyx"] if sys.platform == "win32": - cflags = ["/O2", "/arch:AVX2"] + cflags = ["/O2", "/arch:AVX2"] else: - if platform.machine().lower() in ("x86_64", "amd64"): - cflags = ["-O3", "-msse4.2"] - else: - cflags = ["-O3", "-march=native"] - -extensions = [Extension( - "metrohash", - sources=EXT_SOURCES + INT_SOURCES, - extra_compile_args=cflags, - include_dirs=["MetroHash/src"], - language="c++" -)] + if platform.machine().lower() in ("x86_64", "amd64"): + cflags = ["-O3", "-msse4.2"] + else: + cflags = ["-O3", "-march=native"] + +extensions = [ + Extension( + "metrohash", + sources=EXT_SOURCES + INT_SOURCES, + extra_compile_args=cflags, + include_dirs=["MetroHash/src"], + language="c++", + ) +] -with open("README.md", "r", encoding="utf-8") as fr: - long_description = fr.read() +with open("README.md", encoding="utf-8") as fr: + long_description = fr.read() setup( - author="Dobatymo", - name="metrohash-python", - version="1.1.3.3", - url="https://github.com/Dobatymo/metrohash-python", - description="Python bindings for MetroHash", - long_description=long_description, - long_description_content_type="text/markdown", - classifiers=[ - "Development Status :: 4 - Beta", - "Intended Audience :: Developers", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: ISC License (ISCL)", - "Operating System :: OS Independent", - "Programming Language :: C++", - "Programming Language :: Cython", - "Programming Language :: Python :: 2", - "Programming Language :: Python :: 3", - "Topic :: Internet", - "Topic :: Scientific/Engineering", - "Topic :: Utilities" - ], - - ext_modules=cythonize(extensions), - python_requires=">=2.7", - use_2to3=False, - zip_safe=False, + author="Dobatymo", + name="metrohash-python", + version="1.1.3.3", + url="https://github.com/Dobatymo/metrohash-python", + description="Python bindings for MetroHash", + long_description=long_description, + long_description_content_type="text/markdown", + classifiers=[ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: ISC License (ISCL)", + "Operating System :: OS Independent", + "Programming Language :: C++", + "Programming Language :: Cython", + "Programming Language :: Python :: 3", + "Topic :: Internet", + "Topic :: Scientific/Engineering", + "Topic :: Utilities", + ], + ext_modules=cythonize(extensions), + python_requires=">=3.6", + use_2to3=False, + zip_safe=False, ) diff --git a/test.py b/test.py index 7b03267..5e5f3ce 100644 --- a/test.py +++ b/test.py @@ -1,99 +1,102 @@ import unittest -from metrohash import metrohash64, metrohash128, MetroHash64, MetroHash128, bytes2hex + +from metrohash import MetroHash64, MetroHash128, bytes2hex, metrohash64, metrohash128 + class TestMetrohash(unittest.TestCase): - test_key_63 = b"012345678901234567890123456789012345678901234567890123456789012" - - def test_metrohash64(self): - for cls, input, seed, truth in [ - (MetroHash64, self.test_key_63, 0, "6b753dae06704bad"), - (MetroHash64, self.test_key_63, 1, "3b0d481cf4b9b8df"), - ]: - h = cls(seed) - h.update(input) - - self.assertEqual(truth, bytes2hex(h.digest())) - self.assertEqual(truth, h.hexdigest()) - - def test_metrohash64_update(self): - for cls, input, seed, truth in [ - (MetroHash64, self.test_key_63, 0, "6b753dae06704bad"), - (MetroHash64, self.test_key_63, 1, "3b0d481cf4b9b8df"), - ]: - h = cls(seed) - for i in range(0, len(input), 4): - h.digest() - h.update(input[i:i+4]) - - self.assertEqual(truth, bytes2hex(h.digest())) - self.assertEqual(truth, h.hexdigest()) - - def test_metrohash64_copy(self): - for cls, input, seed, truth in [ - (MetroHash64, self.test_key_63, 0, "6b753dae06704bad"), - (MetroHash64, self.test_key_63, 1, "3b0d481cf4b9b8df"), - ]: - h = cls(seed) - for i in range(0, len(input), 4): - h.update(input[i:i+4]) - h = h.copy() - - self.assertEqual(truth, bytes2hex(h.digest())) - self.assertEqual(truth, h.hexdigest()) - - def test_metrohash64_convenience(self): - for func, input, seed, truth in [ - (metrohash64, self.test_key_63, 0, "6b753dae06704bad"), - (metrohash64, self.test_key_63, 1, "3b0d481cf4b9b8df"), - ]: - result = bytes2hex(func(input, seed)) - self.assertEqual(truth, result) - - def test_metrohash128(self): - for cls, input, seed, truth in [ - (MetroHash128, self.test_key_63, 0, "c77ce2bfa4ed9f9b0548b2ac5074a297"), - (MetroHash128, self.test_key_63, 1, "45a3cdb838199d7fbdd68d867a14ecef"), - ]: - h = cls(seed) - h.update(input) - - self.assertEqual(truth, bytes2hex(h.digest())) - self.assertEqual(truth, h.hexdigest()) - - def test_metrohash128_update(self): - for cls, input, seed, truth in [ - (MetroHash128, self.test_key_63, 0, "c77ce2bfa4ed9f9b0548b2ac5074a297"), - (MetroHash128, self.test_key_63, 1, "45a3cdb838199d7fbdd68d867a14ecef"), - ]: - h = cls(seed) - for i in range(0, len(input), 4): - h.digest() - h.update(input[i:i+4]) - - self.assertEqual(truth, bytes2hex(h.digest())) - self.assertEqual(truth, h.hexdigest()) - - def test_metrohash128_copy(self): - for cls, input, seed, truth in [ - (MetroHash128, self.test_key_63, 0, "c77ce2bfa4ed9f9b0548b2ac5074a297"), - (MetroHash128, self.test_key_63, 1, "45a3cdb838199d7fbdd68d867a14ecef"), - ]: - h = cls(seed) - for i in range(0, len(input), 4): - h.update(input[i:i+4]) - h = h.copy() - - self.assertEqual(truth, bytes2hex(h.digest())) - self.assertEqual(truth, h.hexdigest()) - - def test_metrohash128_convenience(self): - for func, input, seed, truth in [ - (metrohash128, self.test_key_63, 0, "c77ce2bfa4ed9f9b0548b2ac5074a297"), - (metrohash128, self.test_key_63, 1, "45a3cdb838199d7fbdd68d867a14ecef"), - ]: - result = bytes2hex(func(input, seed)) - self.assertEqual(truth, result) + test_key_63 = b"012345678901234567890123456789012345678901234567890123456789012" + + def test_metrohash64(self): + for cls, input, seed, truth in [ + (MetroHash64, self.test_key_63, 0, "6b753dae06704bad"), + (MetroHash64, self.test_key_63, 1, "3b0d481cf4b9b8df"), + ]: + h = cls(seed) + h.update(input) + + self.assertEqual(truth, bytes2hex(h.digest())) + self.assertEqual(truth, h.hexdigest()) + + def test_metrohash64_update(self): + for cls, input, seed, truth in [ + (MetroHash64, self.test_key_63, 0, "6b753dae06704bad"), + (MetroHash64, self.test_key_63, 1, "3b0d481cf4b9b8df"), + ]: + h = cls(seed) + for i in range(0, len(input), 4): + h.digest() + h.update(input[i : i + 4]) + + self.assertEqual(truth, bytes2hex(h.digest())) + self.assertEqual(truth, h.hexdigest()) + + def test_metrohash64_copy(self): + for cls, input, seed, truth in [ + (MetroHash64, self.test_key_63, 0, "6b753dae06704bad"), + (MetroHash64, self.test_key_63, 1, "3b0d481cf4b9b8df"), + ]: + h = cls(seed) + for i in range(0, len(input), 4): + h.update(input[i : i + 4]) + h = h.copy() + + self.assertEqual(truth, bytes2hex(h.digest())) + self.assertEqual(truth, h.hexdigest()) + + def test_metrohash64_convenience(self): + for func, input, seed, truth in [ + (metrohash64, self.test_key_63, 0, "6b753dae06704bad"), + (metrohash64, self.test_key_63, 1, "3b0d481cf4b9b8df"), + ]: + result = bytes2hex(func(input, seed)) + self.assertEqual(truth, result) + + def test_metrohash128(self): + for cls, input, seed, truth in [ + (MetroHash128, self.test_key_63, 0, "c77ce2bfa4ed9f9b0548b2ac5074a297"), + (MetroHash128, self.test_key_63, 1, "45a3cdb838199d7fbdd68d867a14ecef"), + ]: + h = cls(seed) + h.update(input) + + self.assertEqual(truth, bytes2hex(h.digest())) + self.assertEqual(truth, h.hexdigest()) + + def test_metrohash128_update(self): + for cls, input, seed, truth in [ + (MetroHash128, self.test_key_63, 0, "c77ce2bfa4ed9f9b0548b2ac5074a297"), + (MetroHash128, self.test_key_63, 1, "45a3cdb838199d7fbdd68d867a14ecef"), + ]: + h = cls(seed) + for i in range(0, len(input), 4): + h.digest() + h.update(input[i : i + 4]) + + self.assertEqual(truth, bytes2hex(h.digest())) + self.assertEqual(truth, h.hexdigest()) + + def test_metrohash128_copy(self): + for cls, input, seed, truth in [ + (MetroHash128, self.test_key_63, 0, "c77ce2bfa4ed9f9b0548b2ac5074a297"), + (MetroHash128, self.test_key_63, 1, "45a3cdb838199d7fbdd68d867a14ecef"), + ]: + h = cls(seed) + for i in range(0, len(input), 4): + h.update(input[i : i + 4]) + h = h.copy() + + self.assertEqual(truth, bytes2hex(h.digest())) + self.assertEqual(truth, h.hexdigest()) + + def test_metrohash128_convenience(self): + for func, input, seed, truth in [ + (metrohash128, self.test_key_63, 0, "c77ce2bfa4ed9f9b0548b2ac5074a297"), + (metrohash128, self.test_key_63, 1, "45a3cdb838199d7fbdd68d867a14ecef"), + ]: + result = bytes2hex(func(input, seed)) + self.assertEqual(truth, result) + if __name__ == "__main__": - unittest.main() + unittest.main() diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..09ade95 --- /dev/null +++ b/tox.ini @@ -0,0 +1,3 @@ +[flake8] +max-line-length = 120 +select = E7, E9, W2, W6, F