diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1e97cf3..63bbcf2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,7 +3,7 @@ name: publish on: workflow_dispatch: inputs: - repository: + repository: description: 'The repository to upload the package to' required: true default: 'testpypi' @@ -24,11 +24,13 @@ jobs: python-version: '3.9' - name: Set up QEMU if: runner.os == 'Linux' - uses: docker/setup-qemu-action@v1.0.1 + # uses: docker/setup-qemu-action@v1.0.1 + uses: docker/setup-qemu-action@v1.2.0 with: platforms: arm64 - name: Build wheels - uses: joerick/cibuildwheel@v1.9.0 + # uses: joerick/cibuildwheel@v1.9.0 + uses: pypa/cibuildwheel@v2.9.0 with: output-dir: wheelhouse env: @@ -38,7 +40,7 @@ jobs: CIBW_ARCHS_MACOS: 'auto arm64' CIBW_TEST_REQUIRES: pytest CIBW_TEST_COMMAND: 'pytest -s {project}/tests' - CIBW_TEST_SKIP: '*-macosx_arm64' # Until the day Apple silicon instances are available on GitHub Actions + # CIBW_TEST_SKIP: '*-macosx_arm64' # Until the day Apple silicon instances are available on GitHub Actions - uses: actions/upload-artifact@v2 with: path: ./wheelhouse/*.whl diff --git a/pip-freeze.txt b/pip-freeze.txt index 02fb3ab..1e4832c 100644 --- a/pip-freeze.txt +++ b/pip-freeze.txt @@ -1,6 +1,6 @@ -attrs==21.4.0 +attrs==22.1.0 backcall==0.2.0 -Cython==0.29.28 +Cython==0.29.32 decorator==5.1.1 importlib-metadata==4.8.3 iniconfig==1.1.1 @@ -8,20 +8,19 @@ ipdb==0.13.9 ipython==7.16.3 ipython-genutils==0.2.0 jedi==0.17.2 --e git+ssh://git@github.com/escherba/python-metrohash.git@2a85565e5e49b9a36fded0b056d67060ff0e8a7d#egg=metrohash +-e git+https://github.com/escherba/python-metrohash@7df90e93a81300cead306e1b0dcd9ac178abcf44#egg=metrohash numpy==1.19.5 packaging==21.3 parso==0.7.1 pexpect==4.8.0 pickleshare==0.7.5 -pkg_resources==0.0.0 pluggy==1.0.0 -prompt-toolkit==3.0.28 +prompt-toolkit==3.0.31 ptyprocess==0.7.0 py==1.11.0 py-cpuinfo==8.0.0 -Pygments==2.11.2 -pyparsing==3.0.7 +Pygments==2.13.0 +pyparsing==3.0.9 pytest==7.0.1 six==1.16.0 toml==0.10.2 diff --git a/python.mk b/python.mk index 832178f..fa1fb7d 100644 --- a/python.mk +++ b/python.mk @@ -57,7 +57,6 @@ $(EXTENSION_OBJS): $(BUILD_STAMP) .PHONY: test test: build ## run Python unit tests $(PYENV) pytest - $(PYTHON) -m doctest README.md && echo "$(BOLD)doctests passed$(END)" .PHONY: nuke nuke: clean ## clean and remove virtual environment @@ -76,7 +75,7 @@ clean: ## remove temporary files .PHONY: install install: $(BUILD_STAMP) ## install package - $(PIP) install -e --force-reinstall . + $(PIP) install -e . .PRECIOUS: $(ENV_STAMP) .PHONY: env diff --git a/setup.py b/setup.py index 512ed4b..6307510 100644 --- a/setup.py +++ b/setup.py @@ -1,8 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -import struct import os -from os.path import join, dirname +import platform +import struct from setuptools import setup from setuptools.dist import Distribution @@ -62,19 +62,21 @@ def get_system_bits(): ] ) -# The "cibuildwheel" tool sets the variable below to -# something like x86_64, aarch64, i686, and so on. -TARGET_ARCH = os.environ.get("AUDITWHEEL_ARCH") +# The "cibuildwheel" tool sets AUDITWHEEL_ARCH variable to architecture strings +# such as 'x86_64', 'aarch64', 'i686', etc. If this variable is not set, we +# assume that the build is not a CI build and target current machine +# architecture. +TARGET_ARCH = os.environ.get("AUDITWHEEL_ARCH", platform.machine()) +print("building for target architecture:", TARGET_ARCH) -if HAVE_SSE42 and (TARGET_ARCH in [None, "x86_64"]) and (BITS == 64): +if HAVE_SSE42 and (TARGET_ARCH == "x86_64") and (BITS == 64): print("enabling SSE4.2 on compile") if SYSTEM == "nt": CXXFLAGS.append("/D__SSE4_2__") else: CXXFLAGS.append("-msse4.2") - -if HAVE_AES and (TARGET_ARCH in [None, "x86_64"]) and (BITS == 64): +if HAVE_AES and (TARGET_ARCH == "x86_64") and (BITS == 64): print("enabling AES on compile") if SYSTEM == "nt": CXXFLAGS.append("/D__AES__") @@ -104,7 +106,6 @@ def get_system_bits(): CMDCLASS = {} SRC_EXT = ".cpp" - EXT_MODULES = [ Extension( "metrohash", @@ -116,7 +117,7 @@ def get_system_bits(): ), ] -VERSION = "0.3.1" +VERSION = "0.3.2" URL = "https://github.com/escherba/python-metrohash" @@ -124,7 +125,7 @@ def get_long_description(relpath, encoding="utf-8"): _long_desc = """ """ - fname = join(dirname(__file__), relpath) + fname = os.path.join(os.path.dirname(__file__), relpath) try: with open(fname, "rb") as fh: return fh.read().decode(encoding) diff --git a/src/metrohash.cpp b/src/metrohash.cpp index 46b1ee2..1509c12 100644 --- a/src/metrohash.cpp +++ b/src/metrohash.cpp @@ -1,4 +1,4 @@ -/* Generated by Cython 0.29.28 */ +/* Generated by Cython 0.29.32 */ #ifndef PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN @@ -9,8 +9,8 @@ #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000) #error Cython requires Python 2.6+ or Python 3.3+. #else -#define CYTHON_ABI "0_29_28" -#define CYTHON_HEX_VERSION 0x001D1CF0 +#define CYTHON_ABI "0_29_32" +#define CYTHON_HEX_VERSION 0x001D20F0 #define CYTHON_FUTURE_DIVISION 1 #include #ifndef offsetof @@ -49,6 +49,7 @@ #define CYTHON_COMPILING_IN_PYPY 1 #define CYTHON_COMPILING_IN_PYSTON 0 #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_NOGIL 0 #undef CYTHON_USE_TYPE_SLOTS #define CYTHON_USE_TYPE_SLOTS 0 #undef CYTHON_USE_PYTYPE_LOOKUP @@ -85,10 +86,14 @@ #define CYTHON_USE_DICT_VERSIONS 0 #undef CYTHON_USE_EXC_INFO_STACK #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC (PYPY_VERSION_HEX >= 0x07030900) + #endif #elif defined(PYSTON_VERSION) #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYSTON 1 #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_NOGIL 0 #ifndef CYTHON_USE_TYPE_SLOTS #define CYTHON_USE_TYPE_SLOTS 1 #endif @@ -126,10 +131,59 @@ #define CYTHON_USE_DICT_VERSIONS 0 #undef CYTHON_USE_EXC_INFO_STACK #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif +#elif defined(PY_NOGIL) + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_PYSTON 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_NOGIL 1 + #ifndef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #ifndef CYTHON_USE_ASYNC_SLOTS + #define CYTHON_USE_ASYNC_SLOTS 1 + #endif + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 #else #define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYSTON 0 #define CYTHON_COMPILING_IN_CPYTHON 1 + #define CYTHON_COMPILING_IN_NOGIL 0 #ifndef CYTHON_USE_TYPE_SLOTS #define CYTHON_USE_TYPE_SLOTS 1 #endif @@ -179,7 +233,7 @@ #define CYTHON_FAST_THREAD_STATE 1 #endif #ifndef CYTHON_FAST_PYCALL - #define CYTHON_FAST_PYCALL (PY_VERSION_HEX < 0x030B00A1) + #define CYTHON_FAST_PYCALL (PY_VERSION_HEX < 0x030A0000) #endif #ifndef CYTHON_PEP489_MULTI_PHASE_INIT #define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000) @@ -196,6 +250,9 @@ #elif !defined(CYTHON_USE_EXC_INFO_STACK) #define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3) #endif + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif #endif #if !defined(CYTHON_FAST_PYCCALL) #define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1) @@ -661,8 +718,10 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { } __Pyx_PyAsyncMethodsStruct; #endif -#if defined(WIN32) || defined(MS_WINDOWS) - #define _USE_MATH_DEFINES +#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) + #if !defined(_USE_MATH_DEFINES) + #define _USE_MATH_DEFINES + #endif #endif #include #ifdef NAN @@ -1151,6 +1210,12 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args, #if CYTHON_FAST_PYCALL static size_t __pyx_pyframe_localsplus_offset = 0; #include "frameobject.h" +#if PY_VERSION_HEX >= 0x030b00a6 + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif #define __Pxy_PyFrame_Initialize_Offsets()\ ((void)__Pyx_BUILD_ASSERT_EXPR(sizeof(PyFrameObject) == offsetof(PyFrameObject, f_localsplus) + Py_MEMBER_SIZE(PyFrameObject, f_localsplus)),\ (void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus))) @@ -1468,7 +1533,7 @@ static const char __pyx_k_main[] = "__main__"; static const char __pyx_k_name[] = "__name__"; static const char __pyx_k_seed[] = "seed"; static const char __pyx_k_test[] = "__test__"; -static const char __pyx_k_0_3_1[] = "0.3.1"; +static const char __pyx_k_0_3_2[] = "0.3.2"; static const char __pyx_k_email[] = "__email__"; static const char __pyx_k_author[] = "__author__"; static const char __pyx_k_buffer[] = "buffer"; @@ -1505,7 +1570,7 @@ static const char __pyx_k_has_incorrect_type_expected[] = "' has incorrect type: static const char __pyx_k_escherba_metrohash_gmail_com[] = "escherba+metrohash@gmail.com"; static const char __pyx_k_Python_wrapper_for_MetroHash_a[] = "\nPython wrapper for MetroHash, a fast non-cryptographic hashing algorithm\n"; static const char __pyx_k_no_default___reduce___due_to_non[] = "no default __reduce__ due to non-trivial __cinit__"; -static PyObject *__pyx_kp_u_0_3_1; +static PyObject *__pyx_kp_u_0_3_2; static PyObject *__pyx_kp_u_Argument; static PyObject *__pyx_kp_u_Eugene_Scherba; static PyObject *__pyx_n_s_MemoryError; @@ -5514,7 +5579,7 @@ static struct PyModuleDef __pyx_moduledef = { #endif static __Pyx_StringTabEntry __pyx_string_tab[] = { - {&__pyx_kp_u_0_3_1, __pyx_k_0_3_1, sizeof(__pyx_k_0_3_1), 0, 1, 0, 0}, + {&__pyx_kp_u_0_3_2, __pyx_k_0_3_2, sizeof(__pyx_k_0_3_2), 0, 1, 0, 0}, {&__pyx_kp_u_Argument, __pyx_k_Argument, sizeof(__pyx_k_Argument), 0, 1, 0, 0}, {&__pyx_kp_u_Eugene_Scherba, __pyx_k_Eugene_Scherba, sizeof(__pyx_k_Eugene_Scherba), 0, 1, 0, 0}, {&__pyx_n_s_MemoryError, __pyx_k_MemoryError, sizeof(__pyx_k_MemoryError), 0, 0, 1, 1}, @@ -6036,7 +6101,7 @@ if (!__Pyx_RefNanny) { * * __author__ = "Eugene Scherba" # <<<<<<<<<<<<<< * __email__ = "escherba+metrohash@gmail.com" - * __version__ = "0.3.1" + * __version__ = "0.3.2" */ if (PyDict_SetItem(__pyx_d, __pyx_n_s_author, __pyx_kp_u_Eugene_Scherba) < 0) __PYX_ERR(0, 11, __pyx_L1_error) @@ -6044,7 +6109,7 @@ if (!__Pyx_RefNanny) { * * __author__ = "Eugene Scherba" * __email__ = "escherba+metrohash@gmail.com" # <<<<<<<<<<<<<< - * __version__ = "0.3.1" + * __version__ = "0.3.2" * __all__ = [ */ if (PyDict_SetItem(__pyx_d, __pyx_n_s_email, __pyx_kp_u_escherba_metrohash_gmail_com) < 0) __PYX_ERR(0, 12, __pyx_L1_error) @@ -6052,15 +6117,15 @@ if (!__Pyx_RefNanny) { /* "metrohash.pyx":13 * __author__ = "Eugene Scherba" * __email__ = "escherba+metrohash@gmail.com" - * __version__ = "0.3.1" # <<<<<<<<<<<<<< + * __version__ = "0.3.2" # <<<<<<<<<<<<<< * __all__ = [ * "MetroHash64", */ - if (PyDict_SetItem(__pyx_d, __pyx_n_s_version, __pyx_kp_u_0_3_1) < 0) __PYX_ERR(0, 13, __pyx_L1_error) + if (PyDict_SetItem(__pyx_d, __pyx_n_s_version, __pyx_kp_u_0_3_2) < 0) __PYX_ERR(0, 13, __pyx_L1_error) /* "metrohash.pyx":14 * __email__ = "escherba+metrohash@gmail.com" - * __version__ = "0.3.1" + * __version__ = "0.3.2" * __all__ = [ # <<<<<<<<<<<<<< * "MetroHash64", * "MetroHash128", @@ -7079,17 +7144,35 @@ static int __Pyx_setup_reduce_is_named(PyObject* meth, PyObject* name) { static int __Pyx_setup_reduce(PyObject* type_obj) { int ret = 0; PyObject *object_reduce = NULL; + PyObject *object_getstate = NULL; PyObject *object_reduce_ex = NULL; PyObject *reduce = NULL; PyObject *reduce_ex = NULL; PyObject *reduce_cython = NULL; PyObject *setstate = NULL; PyObject *setstate_cython = NULL; + PyObject *getstate = NULL; #if CYTHON_USE_PYTYPE_LOOKUP - if (_PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; + getstate = _PyType_Lookup((PyTypeObject*)type_obj, __pyx_n_s_getstate); #else - if (PyObject_HasAttr(type_obj, __pyx_n_s_getstate)) goto __PYX_GOOD; + getstate = __Pyx_PyObject_GetAttrStrNoError(type_obj, __pyx_n_s_getstate); + if (!getstate && PyErr_Occurred()) { + goto __PYX_BAD; + } #endif + if (getstate) { +#if CYTHON_USE_PYTYPE_LOOKUP + object_getstate = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_getstate); +#else + object_getstate = __Pyx_PyObject_GetAttrStrNoError((PyObject*)&PyBaseObject_Type, __pyx_n_s_getstate); + if (!object_getstate && PyErr_Occurred()) { + goto __PYX_BAD; + } +#endif + if (object_getstate != getstate) { + goto __PYX_GOOD; + } + } #if CYTHON_USE_PYTYPE_LOOKUP object_reduce_ex = _PyType_Lookup(&PyBaseObject_Type, __pyx_n_s_reduce_ex); if (!object_reduce_ex) goto __PYX_BAD; #else @@ -7134,6 +7217,8 @@ static int __Pyx_setup_reduce(PyObject* type_obj) { #if !CYTHON_USE_PYTYPE_LOOKUP Py_XDECREF(object_reduce); Py_XDECREF(object_reduce_ex); + Py_XDECREF(object_getstate); + Py_XDECREF(getstate); #endif Py_XDECREF(reduce); Py_XDECREF(reduce_ex); @@ -7330,6 +7415,12 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { #include "compile.h" #include "frameobject.h" #include "traceback.h" +#if PY_VERSION_HEX >= 0x030b00a6 + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( const char *funcname, int c_line, int py_line, const char *filename) { @@ -7393,14 +7484,24 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line, PyCodeObject *py_code = 0; PyFrameObject *py_frame = 0; PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject *ptype, *pvalue, *ptraceback; if (c_line) { c_line = __Pyx_CLineForTraceback(tstate, c_line); } py_code = __pyx_find_code_object(c_line ? -c_line : py_line); if (!py_code) { + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); py_code = __Pyx_CreateCodeObjectForTraceback( funcname, c_line, py_line, filename); - if (!py_code) goto bad; + if (!py_code) { + /* If the code object creation fails, then we should clear the + fetched exception references and propagate the new exception */ + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + goto bad; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); } py_frame = PyFrame_New( @@ -8205,11 +8306,33 @@ static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObj /* CheckBinaryVersion */ static int __Pyx_check_binary_version(void) { - char ctversion[4], rtversion[4]; - PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); - PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); - if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { + char ctversion[5]; + int same=1, i, found_dot; + const char* rt_from_call = Py_GetVersion(); + PyOS_snprintf(ctversion, 5, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); + found_dot = 0; + for (i = 0; i < 4; i++) { + if (!ctversion[i]) { + same = (rt_from_call[i] < '0' || rt_from_call[i] > '9'); + break; + } + if (rt_from_call[i] != ctversion[i]) { + same = 0; + break; + } + } + if (!same) { + char rtversion[5] = {'\0'}; char message[200]; + for (i=0; i<4; ++i) { + if (rt_from_call[i] == '.') { + if (found_dot) break; + found_dot = 1; + } else if (rt_from_call[i] < '0' || rt_from_call[i] > '9') { + break; + } + rtversion[i] = rt_from_call[i]; + } PyOS_snprintf(message, sizeof(message), "compiletime version %s of module '%.100s' " "does not match runtime version %s", diff --git a/src/metrohash.pyx b/src/metrohash.pyx index e031562..621135e 100644 --- a/src/metrohash.pyx +++ b/src/metrohash.pyx @@ -10,7 +10,7 @@ Python wrapper for MetroHash, a fast non-cryptographic hashing algorithm __author__ = "Eugene Scherba" __email__ = "escherba+metrohash@gmail.com" -__version__ = "0.3.1" +__version__ = "0.3.2" __all__ = [ "MetroHash64", "MetroHash128",