diff --git a/.github/workflows/build_and_upload.yml b/.github/workflows/build_and_upload.yml index cd25f0f..a8b2f3d 100644 --- a/.github/workflows/build_and_upload.yml +++ b/.github/workflows/build_and_upload.yml @@ -19,16 +19,23 @@ jobs: - uses: "actions/checkout@v4" with: submodules: true + - name: "Set up QEMU" + if: matrix.os == 'ubuntu-latest' + uses: "docker/setup-qemu-action@v3" + with: + platforms: arm64 - name: "Build wheels" uses: "pypa/cibuildwheel@v2.21.1" env: CIBW_SKIP: "pp*" # FIXME + CIBW_ARCHS_LINUX: "auto aarch64" CIBW_TEST_REQUIRES: "pytest" CIBW_TEST_COMMAND: "pytest {project}/tests --doctest-modules" - - uses: "actions/upload-artifact@v3" + - uses: "actions/upload-artifact@v4" with: path: "./wheelhouse/*.whl" - + name: wheel-${{ matrix.os }} + make_sdist: name: "Build source distribution" runs-on: ubuntu-latest @@ -38,9 +45,10 @@ jobs: submodules: true - name: "Build source distribution" run: "pipx run build --sdist" - - uses: "actions/upload-artifact@v3" + - uses: "actions/upload-artifact@v4" with: path: "./dist/*.tar.gz" + name: sdist upload_to_pypi: name: "Upload to PyPI" @@ -50,11 +58,11 @@ jobs: - build_wheels - make_sdist steps: - - uses: "actions/download-artifact@v3" + - uses: "actions/download-artifact@v4" with: - name: artifact path: dist - - uses: "pypa/gh-action-pypi-publish@v1.8.10" + merge-multiple: true + - uses: "pypa/gh-action-pypi-publish@v1.13.0" with: user: __token__ password: ${{ secrets.PYPI_TOKEN }} diff --git a/pycrfsuite/_pycrfsuite.pyx b/pycrfsuite/_pycrfsuite.pyx index 09cc379..647f203 100644 --- a/pycrfsuite/_pycrfsuite.pyx +++ b/pycrfsuite/_pycrfsuite.pyx @@ -1,6 +1,6 @@ # cython: embedsignature=True # cython: c_string_type=str -# cython: c_string_encoding=ascii +# cython: c_string_encoding=utf-8 # cython: profile=False # distutils: language=c++ from . cimport crfsuite_api diff --git a/pyproject.toml b/pyproject.toml index 73c0598..b2dee39 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "python-crfsuite" -version = "0.9.10" +version = "0.9.11" description = "Python binding for CRFsuite" authors = [ {name = "Terry Peng", email = "pengtaoo@gmail.com"}, diff --git a/setup.py b/setup.py index 28363cb..ca958c4 100755 --- a/setup.py +++ b/setup.py @@ -6,8 +6,7 @@ from Cython.Build import cythonize from setuptools import Extension, setup -sources = ["pycrfsuite/_pycrfsuite.pyx", - "pycrfsuite/trainer_wrapper.cpp"] +sources = ["pycrfsuite/_pycrfsuite.pyx", "pycrfsuite/trainer_wrapper.cpp"] # crfsuite sources += glob.glob("crfsuite/lib/crf/src/*.c") @@ -34,10 +33,17 @@ def build_extensions(self): _compile = c._compile def c_compile(obj, src, ext, cc_args, extra_postargs, pp_opts): + cc_args = ( + cc_args + ["-D_POSIX_C_SOURCE=200112L"] + if src.startswith("crfsuite/") + else cc_args + ) cc_args = cc_args + ["-std=c99"] if src.endswith(".c") else cc_args return _compile(obj, src, ext, cc_args, extra_postargs, pp_opts) - if c.compiler_type == "unix" and "gcc" in c.compiler: + if c.compiler_type == "unix" and any( + item == "gcc" or item.endswith("-gcc") for item in c.compiler + ): c._compile = c_compile elif self.compiler.compiler_type == "msvc": @@ -58,5 +64,5 @@ def c_compile(obj, src, ext, cc_args, extra_postargs, pp_opts): ) ] ), - cmdclass={"build_ext": build_ext_check_gcc} + cmdclass={"build_ext": build_ext_check_gcc}, ) diff --git a/tests/conftest.py b/tests/conftest.py index 446b357..60a19d7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,6 +14,7 @@ def xseq(): {}, {"clean": 1}, {"солнце": "не светит".encode(), "clean": 1}, + {"world": 2}, ] @@ -30,6 +31,7 @@ def yseq(): "sunny", "rainy", "rainy", + "好", ] diff --git a/tests/test_tagger.py b/tests/test_tagger.py index 40c0218..3ebb021 100644 --- a/tests/test_tagger.py +++ b/tests/test_tagger.py @@ -177,11 +177,11 @@ def test_info(model_filename): > res.state_features[("walk", "rainy")] ) assert ("солнце:не светит", "rainy") in res.state_features - assert res.header["num_labels"] == "2" - assert set(res.labels.keys()) == {"sunny", "rainy"} - assert set(res.attributes.keys()) == { - "shop", "walk", "clean", "солнце:не светит" - } + assert res.header["num_labels"] == "3" + assert set(res.labels.keys()) == set(["sunny", "rainy", "好"]) + assert set(res.attributes.keys()) == set( + ["shop", "walk", "clean", "солнце:не светит", "world"] + ) # it shouldn't segfault on a closed tagger with pytest.raises(RuntimeError): @@ -227,13 +227,13 @@ def test_append_nested_dicts(tmpdir): with Tagger().open(model_filename) as tagger: info = tagger.info() assert set(info.attributes.keys()) == { - "foo:bar:baz", - "foo:spam", - "foo:egg:x", - "foo:egg:y", - "foo:ham:x", - "foo:ham:y", - "foo:bar:ham", + "foo:bar:baz", + "foo:spam", + "foo:egg:x", + "foo:egg:y", + "foo:ham:x", + "foo:ham:y", + "foo:bar:ham", } for feat in ["foo:bar:baz", "foo:spam", "foo:egg:x", "foo:egg:y"]: