diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 0000000..3468577 --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,24 @@ +######################################################### +# Build arm64 wheels for OSX on Cirrus CI +######################################################### + +cirrus_wheels_macos_arm64_task: + name: Build macOS arm64 wheels. + trigger_type: manual + macos_instance: + image: ghcr.io/cirruslabs/macos-monterey-xcode:latest + env: + PATH: /opt/homebrew/opt/python@3.10/bin:$PATH + CIBW_ARCHS_MACOS: arm64 + install_pre_requirements_script: + - brew install python@3.10 + - ln -s python3 /opt/homebrew/opt/python@3.10/bin/python + - which python + - python --version + install_cibuildwheel_script: + - python -m pip install cibuildwheel + run_cibuildwheel_script: + - CIBW_BUILD_VERBOSITY=3 CIBW_SKIP="*-win32 *-manylinux_* *-musllinux_*" CIBW_ARCHS_MACOS="arm64" CIBW_BUILD="cp39-* cp310-* cp311-*" CIBW_BEFORE_ALL_MACOS="brew tap fbkarsdorp/homebrew-lamachine && brew install icu4c libxml2 frog" cibuildwheel --platform macos + wheels_artifacts: + path: "wheelhouse/*" + diff --git a/.github/workflows/python-frog.yml b/.github/workflows/python-frog.yml index 2b42f1f..ae9919d 100644 --- a/.github/workflows/python-frog.yml +++ b/.github/workflows/python-frog.yml @@ -136,7 +136,7 @@ jobs: CXX: ${{ matrix.compiler }} run: | git clone https://github.com/LanguageMachines/frog; - cd frogdata; + cd frog; bash bootstrap.sh; ./configure; make; diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml new file mode 100644 index 0000000..2df8e3c --- /dev/null +++ b/.github/workflows/wheels.yml @@ -0,0 +1,86 @@ +#Note: This script does not used build-wheels.sh nor the Makefile included in this repo (that's for local usage) + +name: Build Wheels + +on: [workflow_dispatch] + +jobs: + build_wheels: + name: Build wheels on for ${{matrix.python.cp}}-${{ matrix.buildplat.sys }} + runs-on: ${{ matrix.buildplat.runs_on }} + strategy: + matrix: + buildplat: + - { runs_on: ubuntu-22.04, sys: manylinux, arch: x86_64, benv: "" } + - { runs_on: ubuntu-22.04, sys: musllinux, arch: x86_64, benv: "" } + - { runs_on: macos-14, sys: macosx, arch: arm64, benv: "14.0" } + python: + - { cp: "cp39", rel: "3.9" } + - { cp: "cp310", rel: "3.10" } + - { cp: "cp311", rel: "3.11" } + - { cp: "cp312", rel: "3.12" } + - { cp: "cp313", rel: "3.13" } + - { cp: "cp314", rel: "3.14" } + + steps: + - uses: actions/checkout@v4.1.1 + + # Used to host cibuildwheel + - uses: actions/setup-python@v5 + with: + python-version: 3.11 + + - name: Install cibuildwheel + run: python -m pip install cibuildwheel + + - name: Build wheels (Linux glibc) + if: ${{ matrix.buildplat.sys == 'manylinux' }} + run: python -m cibuildwheel --output-dir wheelhouse + env: + CIBW_BUILD: ${{ matrix.python.cp }}-${{ matrix.buildplat.sys }}* + CIBW_ARCHS_LINUX: "x86_64" + CIBW_BEFORE_ALL_LINUX: > + if command -v apt-get; then + apt-get -y git libicu-dev libxml2-dev libexttextcat-dev libxslt1-dev libbz2-dev zlib1g-dev autoconf automake autoconf-archive libtool autotools-dev gcc g++ make + elif command -v yum; then + yum install -y git libicu-devel libxml2-devel libxslt-devel libexttextcat zlib-devel bzip2-devel libtool autoconf-archive autoconf automake m4 wget + #on CentOS 7 we also have libtar-devel libexttextcat-devel which will be installed by build-deps.sh, on 8 they are missing and will be installed from source or otherwise + elif command -v apk; then + apk add build-base git autoconf-archive autoconf automake libtool bzip2-dev icu-dev libxml2-dev libexttextcat-dev libtool rsync && + rsync -av --ignore-existing /usr/share/aclocal/*.m4 /usr/local/share/aclocal/ + fi && + ./build-deps.sh + CIBW_MANYLINUX_X86_64_IMAGE: quay.io/pypa/manylinux_2_28_x86_64 + CIBW_SKIP: "*-win* *-manylinux_i686 pp*" + + - name: Build wheels (Linux musl) + if: ${{ matrix.buildplat.sys == 'musllinux' }} + run: python -m cibuildwheel --output-dir wheelhouse + env: + CIBW_BUILD: ${{ matrix.python.cp }}-${{ matrix.buildplat.sys }}* + CIBW_ARCHS_LINUX: "x86_64" + CIBW_BEFORE_ALL_LINUX: > + apk add build-base git autoconf-archive autoconf automake libtool bzip2-dev icu-dev libxml2-dev libexttextcat-dev libtool rsync && + mkdir -p /usr/local/share/aclocal/ && rsync -av --ignore-existing /usr/share/aclocal/*.m4 /usr/local/share/aclocal/ && + ./build-deps.sh + CIBW_MUSLLINUX_X86_64_IMAGE: quay.io/pypa/musllinux_1_2_x86_64 + CIBW_MUSLLINUX_AARCH64_IMAGE: quay.io/pypa/musllinux_1_2_aarch64 + CIBW_SKIP: "*-win* *-manylinux_i686 pp*" + + - name: Build wheels (macOS) + if: ${{ runner.os == 'macOS' && matrix.python.cp != 'cp38' }} + run: python -m cibuildwheel --output-dir wheelhouse + env: + CIBW_BUILD: ${{ matrix.python.cp }}-${{ matrix.buildplat.sys }}* + CIBW_ARCHS: ${{ matrix.buildplat.arch }} + CIBW_ENVIRONMENT: "MACOSX_DEPLOYMENT_TARGET=${{ matrix.buildplat.benv }}" + CIBW_BEFORE_ALL_MACOS: > + brew trust fbkarsdorp/lamachine && + brew tap fbkarsdorp/homebrew-lamachine && + brew install frog + + - uses: actions/upload-artifact@v4 + if: ${{ ! (runner.os == 'macOS' && matrix.python.cp == '3.8') }} + with: + name: ${{matrix.python.cp}}-${{matrix.buildplat.sys}}-${{matrix.buildplat.arch}} + path: ./wheelhouse/*.whl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40da0e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +__pycache__/ +build/ +env/ +*.egg-info/ +*.py[cod] +*~ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..75e328f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM proycon/frog +LABEL org.opencontainers.image.authors="Maarten van Gompel " +LABEL description="Frog - A Tagger-Lemmatizer-Morphological-Analyzer-Dependency-Parser for Dutch, container image with the Python binding" + + +COPY . /usr/src/python-frog +RUN BUILD_PACKAGES="build-base libtool libtar-dev bzip2-dev icu-dev libxml2-dev libexttextcat-dev python3-dev" &&\ + mkdir -p /usr/src/python-frog &&\ + apk add python3 py3-wheel py3-pip cython $BUILD_PACKAGES &&\ + cd /usr/src/python-frog && pip install . && apk del $BUILD_PACKAGES && rm -Rf /usr/src/python-frog + +ENTRYPOINT [ "python3" ] diff --git a/Makefile b/Makefile index b8cd3d8..a7bee70 100644 --- a/Makefile +++ b/Makefile @@ -1,21 +1,32 @@ -PY_VERSIONS=cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310 +PY_VERSIONS=cp36-cp36m cp37-cp37m cp38-cp38 cp39-cp39 cp310-cp310 cp311-cp311 BUILD_REQUIREMENTS=cython #system packages (yum, manylinux_2_28 uses AlmaLinux) -SYSTEM_PACKAGES=libicu-devel libxml2-devel libxslt-devel libexttextcat zlib-devel bzip2-devel libtool autoconf-archive autoconf automake m4 wget +SYSTEM_PACKAGES_RHEL=libicu-devel libxml2-devel libxslt-devel libexttextcat zlib-devel bzip2-devel libtool autoconf-archive autoconf automake m4 wget +#musllinux_1_1_x86_64 builds on Alpine v3.12 +SYSTEM_PACKAGES_ALPINE=icu-dev libxml2-dev libxslt-dev libexttextcat-dev zlib-dev bzip2-dev libtool autoconf-archive autoconf automake m4 wget PRE_BUILD_COMMAND=/io/build-deps.sh PACKAGE_PATH= PIP_WHEEL_ARGS=-w ./dist --no-deps +TAG=latest .PHONY: wheels -wheels: - docker pull quay.io/pypa/manylinux_2_28_x86_64 - docker run --rm -e PLAT=manylinux_2_28_x86_64 -v `pwd`:/io quay.io/pypa/manylinux_2_28_x86_64 /io/build-wheels.sh "${PY_VERSIONS}" "${BUILD_REQUIREMENTS}" "${SYSTEM_PACKAGES}" "${PRE_BUILD_COMMAND}" "${PACKAGE_PATH}" "${PIP_WHEEL_ARGS}" +wheels: manywheels muslwheels + +.PHONY: manywheels +manywheels: + docker pull quay.io/pypa/manylinux_2_28_x86_64:${TAG} + docker run --rm -e PLAT=manylinux_2_28_x86_64 -v `pwd`:/io quay.io/pypa/manylinux_2_28_x86_64:${TAG} /io/build-wheels.sh "${PY_VERSIONS}" "${BUILD_REQUIREMENTS}" "${SYSTEM_PACKAGES_RHEL}" "${PRE_BUILD_COMMAND}" "${PACKAGE_PATH}" "${PIP_WHEEL_ARGS}" + +.PHONY: muslwheels +muslwheels: + docker pull quay.io/pypa/musllinux_1_1_x86_64:${TAG} + docker run --rm -e PLAT=musllinux_1_1_x86_64 -v `pwd`:/io quay.io/pypa/musllinux_1_1_x86_64:${TAG} /io/build-wheels.sh "${PY_VERSIONS}" "${BUILD_REQUIREMENTS}" "${SYSTEM_PACKAGES_ALPINE}" "${PRE_BUILD_COMMAND}" "${PACKAGE_PATH}" "${PIP_WHEEL_ARGS}" .PHONY: devwheels devwheels: #builds against latest development versions of everything, these wheels should NOT be published! - docker pull quay.io/pypa/manylinux_2_28_x86_64 - docker run --rm -e PLAT=manylinux_2_28_x86_64 -v `pwd`:/io quay.io/pypa/manylinux_2_28_x86_64 /io/build-wheels.sh "${PY_VERSIONS}" "${BUILD_REQUIREMENTS}" "${SYSTEM_PACKAGES}" "${PRE_BUILD_COMMAND} --devel" "${PACKAGE_PATH}" "${PIP_WHEEL_ARGS}" + docker pull quay.io/pypa/manylinux_2_28_x86_64:${TAG} + docker run --rm -e PLAT=manylinux_2_28_x86_64 -v `pwd`:/io quay.io/pypa/manylinux_2_28_x86_64:${TAG} /io/build-wheels.sh "${PY_VERSIONS}" "${BUILD_REQUIREMENTS}" "${SYSTEM_PACKAGES_RHEL}" "${PRE_BUILD_COMMAND} --devel" "${PACKAGE_PATH}" "${PIP_WHEEL_ARGS}" echo "Built against development versions, DO NOT PUBLISH these wheels!" .PHONY: install diff --git a/README.rst b/README.rst index 82446a6..f567510 100644 --- a/README.rst +++ b/README.rst @@ -17,17 +17,19 @@ morphological analysis, named entity recognition, shallow parsing, and dependency parsing. The tool itself is implemented in C++ (https://languagemachines.github.io/frog). The binding requires Python 3.6 or higher. +Demo +------------------ + +.. image:: https://raw.githubusercontent.com/CLARIAH/wp3-demos/master/python-frog.gif + Installation ---------------- -Linux -~~~~~~~~~~ - -On modern Linux distributions, we recommend you use a Python virtual environment and install using ``pip``:: +We recommend you use a Python virtual environment and install using ``pip``:: pip install python-frog -When possible on your system (glibc >= 2.28, x86_64), this will install the binary +When possible on your system, this will install the binary Python wheels *that include Frog and all necessary dependencies* **except for** frogdata. To download and install the data (in ``~/.config/frog``) you then only need to run the following once:: @@ -38,35 +40,31 @@ If you want language detection support, ensure you the have `libexttextcat` package (if provided by your distribution) installed prior to executing the above command. -If the binary wheels are not available for your distribution, you will need to first install Frog yourself. - -Alpine Linux -~~~~~~~~~~~~~~ - -First install Cython and Frog (``apk add cython frog frog-dev``), then ``pip install python-frog`` (preferably in a Python virtual environment) - -Arch Linux -~~~~~~~~~~~~~~ +If the binary wheels are not available for your system, you will need to first +install `Frog `_ yourself and then +run ``pip install python-frog`` to install this python binding, it will then be +compiled from source. The following instructions apply in that case: -You can alternatively use the `AUR package `_ . +On Arch Linux, you can alternatively use the `AUR package `_ . +On macOS; first use `homebrew `_ to install `Frog `_:: -macOS -~~~~~~~~ + brew tap fbkarsdorp/homebrew-lamachine + brew install ucto -First use `homebrew `_ to install `Frog `_:: +On Alpine Linux, run: ``apk add cython frog frog-dev`` - brew tap fbkarsdorp/homebrew-lamachine - brew install frog +Windows is not supported natively at all, but you should be able to use the Ucto python binding if you use WSL, or using Docker containers (see below). -Then install this binding using ``pip`` (preferably in a Python virtual environment):: +Docker/OCI Containers +~~~~~~~~~~~~~~~~~~~~~~~ - pip install python-frog +A Docker/OCI container image is available containing Python, frog, and python-frog:: -Windows -~~~~~~~~~~ + docker pull proycon/python-frog + docker run -t -i proycon/python-frog -Not supported natively, but you should be able to use the Frog python binding if you use WSL. +You can also build the container from scratch from this repository with the included `Dockerfile`. Usage ------------------ @@ -75,9 +73,9 @@ Example: .. code:: python - import frog + from frog import Frog, FrogOptions - frog = frog.Frog(frog.FrogOptions(parser=False)) + frog = Frog(FrogOptions(parser=False)) output = frog.process_raw("Dit is een test") print("RAW OUTPUT=",output) output = frog.process("Dit is nog een test.") @@ -131,14 +129,14 @@ used: .. code:: python - frog = frog.Frog(frog.FrogOptions(parser=False), "/path/to/your/frog.cfg") + frog = Frog(FrogOptions(parser=False), "/path/to/your/frog.cfg") A third parameter, a dictionary, can be used to override specific configuration values (same syntax as Frog's ``--override`` option), you may want to leave the second parameter empty if you want to load the default configuration: .. code:: python - frog = frog.Frog(frog.FrogOptions(parser=False), "", { "tokenizer.rulesFile": "tokconfig-nld-twitter" }) + frog = Frog(FrogOptions(parser=False), "", { "tokenizer.rulesFile": "tokconfig-nld-twitter" }) FoLiA support ------------------ @@ -168,5 +166,3 @@ An example can be found below: for word in output.words(): print(word.text() + " " + word.pos() + " " + word.lemma()) - - diff --git a/build-deps.sh b/build-deps.sh index 56b2d20..0173d14 100755 --- a/build-deps.sh +++ b/build-deps.sh @@ -1,11 +1,14 @@ #!/bin/sh # Builds dependencies (latest stable releases) from source -# Used for building wheels +# Used for building wheels. Invoke via 'make wheels' rather +# than directly! set -e . /etc/os-release +echo "OS: $ID">&2 +echo "VERSION: $VERSION_ID">&2 get_latest_version() { #Finds the latest git tag or falls back to returning the git default branch (usually master or main) @@ -20,18 +23,39 @@ get_latest_version() { fi } -if [ "$ID" = "almalinux" ] && [ -d /usr/local/share/aclocal ]; then - #needed for manylinux_2_28 container which ships custom autoconf - export ACLOCAL_PATH=/usr/share/aclocal -fi +[ -z "$PREFIX" ] && PREFIX="/usr/local/" if [ "$ID" = "almalinux" ] || [ "$ID" = "centos" ] || [ "$ID" = "rhel" ]; then - #they forgot to package libexttextcat-devel? grab one manually: - wget https://github.com/proycon/LaMachine/raw/master/deps/centos8/libexttextcat-devel-3.4.5-2.el8.x86_64.rpm - yum install -y libexttextcat-devel-3.4.5-2.el8.x86_64.rpm + if [ -d /usr/local/share/aclocal ]; then + #needed for manylinux_2_28 container which ships custom autoconf, possibly others too? + export ACLOCAL_PATH=/usr/share/aclocal + fi + case $VERSION_ID in + 7*) + yum install -y libexttextcat-devel + if [ -d /opt/rh/devtoolset-10/root/usr/lib ]; then + #we are running in the manylinux2014 image + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:/opt/rh/devtoolset-10/root/usr/lib + #libxml2 is out of date, compile and install a new one + yum install -y xz + wget https://download.gnome.org/sources/libxml2/2.9/libxml2-2.9.14.tar.xz + unxz libxml2-2.9.14.tar.xz + tar -xf libxml2-2.9.14.tar + cd libxml2-2.9.14 && ./configure --prefix=$PREFIX --without-python && make && make install + cd .. + fi + ;; + 8*) + #they forgot to package libexttextcat-devel? grab one manually: + wget https://github.com/proycon/LaMachine/raw/master/deps/centos8/libexttextcat-devel-3.4.5-2.el8.x86_64.rpm + yum install -y libexttextcat-devel-3.4.5-2.el8.x86_64.rpm + ;; + esac fi -[ -z "$PREFIX" ] && PREFIX="/usr/local/" -for PACKAGE in tklauser/libtar LanguageMachines/ticcutils LanguageMachines/libfolia LanguageMachines/uctodata LanguageMachines/ucto LanguageMachines/timbl LanguageMachines/mbt LanguageMachines/frogdata LanguageMachines/frog; do +PWD="$(pwd)" +BUILDDIR="$(mktemp -dt "build-deps.XXXXXX")" +cd "$BUILDDIR" +for PACKAGE in LanguageMachines/ticcutils LanguageMachines/libfolia LanguageMachines/uctodata LanguageMachines/ucto LanguageMachines/timbl LanguageMachines/mbt LanguageMachines/frogdata LanguageMachines/frog; do echo "Git cloning $PACKAGE ">&2 git clone https://github.com/$PACKAGE PACKAGE="$(basename $PACKAGE)" @@ -56,5 +80,6 @@ for PACKAGE in tklauser/libtar LanguageMachines/ticcutils LanguageMachines/libfo make install cd .. done - +cd $PWD +[ -n "$BUILDDIR" ] && rm -Rf "$BUILDDIR" echo "Dependencies installed" >&2 diff --git a/build-wheels.sh b/build-wheels.sh index a9fe7e8..d086eb8 100755 --- a/build-wheels.sh +++ b/build-wheels.sh @@ -14,7 +14,6 @@ SYSTEM_PACKAGES=$3 PRE_BUILD_COMMAND=$4 PACKAGE_PATH=$5 PIP_WHEEL_ARGS=$6 -BUILD_DEPS_OPTS=$7 # Temporary workaround for LD_LIBRARY_PATH issue. See # https://github.com/RalfG/python-wheels-manylinux-build/issues/26 @@ -28,6 +27,9 @@ if [ -n "$SYSTEM_PACKAGES" ]; then apt-get install -y $SYSTEM_PACKAGES || { echo "Installing apt package(s) failed."; exit 1; } elif command -v yum >/dev/null; then yum install -y $SYSTEM_PACKAGES || { echo "Installing yum package(s) failed."; exit 1; } + elif command -v apk >/dev/null; then + apk add $SYSTEM_PACKAGES rsync || { echo "Installing apk package(s) failed."; exit 1; } + rsync -av --ignore-existing /usr/share/aclocal/*.m4 /usr/local/share/aclocal/ #the image has it's own aclocal installation, copy autoconf-archive files that do not exist yet (and hope for the best) else echo "Package managers apt or yum not found."; exit 1; fi @@ -69,4 +71,8 @@ if [[ -f "$failed_wheels" ]]; then fi echo "Succesfully build wheels:" -find . -type f -iname "*-manylinux*.whl" +if command -v apk >/dev/null; then + find . -type f -iname "*-musllinux*.whl" +else + find . -type f -iname "*-manylinux*.whl" +fi diff --git a/codemeta-harvest.json b/codemeta-harvest.json new file mode 100644 index 0000000..767e19e --- /dev/null +++ b/codemeta-harvest.json @@ -0,0 +1,19 @@ +{ + "funding": { + "@type": "Grant", + "name": "CLARIAH-PLUS (NWO grant 184.034.023)", + "funder": { + "@type": "Organization", + "name": "NWO", + "url": "https://www.nwo.nl" + } + }, + "producer": { + "@type": "Organization", + "name": "KNAW Humanities Cluster", + "url": "https://huc.knaw.nl" + }, + "contIntegration": "https://github.com/proycon/python-frog/actions/workflows/python-frog.yml", + "applicationCategory": [ "https://vocabs.dariah.eu/tadirah/annotating", "https://vocabs.dariah.eu/tadirah/tagging", "https://vocabs.dariah.eu/tadirah/namedEntityRecognition", "https://vocabs.dariah.eu/tadirah/posTagging", "https://vocabs.dariah.eu/tadirah/segmenting", "https://vocabs.dariah.eu/tadirah/treeTagging", "https://vocabs.dariah.eu/tadirah/contextualizing" , "https://w3id.org/nwo-research-fields#Linguistics", "https://w3id.org/nwo-research-fields#TextualAndContentAnalysis" ], + "developmentStatus": [ "https://www.repostatus.org/#active", "https://w3id.org/research-technology-readiness-levels#Level9Proven" ] +} diff --git a/frog_wrapper.pyx b/frog_wrapper.pyx index 50db6d7..8da1948 100644 --- a/frog_wrapper.pyx +++ b/frog_wrapper.pyx @@ -20,8 +20,8 @@ import sys cimport libfolia_classes cimport frog_classes -FROGDATAVERSION = "0.20" -UCTODATAVERSION = "0.8" +FROGDATAVERSION = "0.22" +UCTODATAVERSION = "0.9.1" try: from folia.main import Document as FoliaPyDocument @@ -122,9 +122,15 @@ cdef class FrogOptions: elif key.lower() in ('debug','debugflag'): if value: self.capi.insert(b"d", b"1", False) elif key.lower() in ('docid','id'): - self.capi.insert(b"id", value) + if isinstance(value, bytes): + self.capi.insert(b"id", value) + else: + self.capi.insert(b"id", value.encode('utf-8')) elif key.lower() in ('numthreads','threads'): - self.capi.insert(b"threads",value) + if isinstance(value, int): + self.capi.insert(b"threads",str(value).encode('utf-8')) + else: + self.capi.insert(b"threads",value) else: if key == 'x': self.shadow['xmlin'] = True @@ -255,11 +261,17 @@ def installdata(targetdir=None, frogdataversion=FROGDATAVERSION, uctodataversion raise Exception("Installation of frogdata failed") print(f"Installation of frogdata {frogdataversion} complete", file=sys.stderr) - if os.path.isdir("/usr/share/libexttextcat"): + textcatpath = os.environ.get("TEXTCATPATH","/usr/share/libexttextcat") + if os.path.isdir(textcatpath): if os.system(f"cd {uctodir} && wget -O textcat.cfg https://raw.githubusercontent.com/LanguageMachines/ucto/master/config/textcat.cfg") != 0: raise Exception("Installation of textcat.cfg failed.") + if textcatpath[-1] == '/': textcatpath = textcatpath[:-1] + if textcatpath != "/usr/share/libexttextcat": + data = open(f"{uctodir}/textcat.cfg",'r',encoding='utf-8').read() + with open(f"{uctodir}/textcat.cfg",'w',encoding='utf-8') as f: + f.write(data.replace("/usr/share/libexttextcat", textcatpath)) else: - print("Language detection will not be available unless you install libexttextcat and rerun installdata()", file=sys.stderr) + print("Language detection will not be available unless you install libexttextcat and rerun installdata(). Libexttextcat was not found. If it is in a non-standard location, set environment variable TEXTCATPATH (defaults to /usr/share/libexttextcat) prior to calling installdata()", file=sys.stderr) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..fb4a3f0 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,8 @@ +[build-system] +requires = [ + "setuptools>=42", + "wheel", + "Cython" +] + +build-backend = "setuptools.build_meta" diff --git a/setup.py b/setup.py index a305093..07826c0 100755 --- a/setup.py +++ b/setup.py @@ -4,17 +4,34 @@ from Cython.Build import cythonize import platform import os +import sys includedirs = [] libdirs = [] +print(f"system={platform.system()} machine={platform.machine()}", file=sys.stderr) if platform.system() == "Darwin": - #we are running on Mac OS X with homebrew, stuff is in specific locations: - libdirs.append("/usr/local/opt/icu4c/lib") - includedirs.append("/usr/local/opt/icu4c/include") - libdirs.append("/usr/local/opt/libxml2/lib") - includedirs.append("/usr/local/opt/libxml2/include") - includedirs.append("/usr/local/opt/libxml2/include/libxml2") + #we are running on Mac OS X (with homebrew hopefully), stuff is in specific locations: + if platform.machine().lower() == "arm64": + print("(macos arm64 detected)", file=sys.stderr) + libdirs.append("/opt/homebrew/lib") + includedirs.append("/opt/homebrew/include") + libdirs.append("/opt/homebrew/icu4c/lib") + includedirs.append("/opt/homebrew/icu4c/include") + libdirs.append("/opt/homebrew/libxml2/lib") + includedirs.append("/opt/homebrew/libxml2/include") + includedirs.append("/opt/homebrew/libxml2/include/libxml2") + libdirs.append("/opt/homebrew/opt/icu4c/lib") + includedirs.append("/opt/homebrew/opt/icu4c/include") + libdirs.append("/opt/homebrew/opt/libxml2/lib") + includedirs.append("/opt/homebrew/opt/libxml2/include") + else: + #we are running on Mac OS X with homebrew, stuff is in specific locations: + libdirs.append("/usr/local/opt/icu4c/lib") + includedirs.append("/usr/local/opt/icu4c/include") + libdirs.append("/usr/local/opt/libxml2/lib") + includedirs.append("/usr/local/opt/libxml2/include") + includedirs.append("/usr/local/opt/libxml2/include/libxml2") #add some common default paths includedirs += ['/usr/include/', '/usr/include/libxml2','/usr/local/include/' ] @@ -32,14 +49,16 @@ else: extra_options = ['-D U_USING_ICU_NAMESPACE=1'] +print(f"include_dirs={' '.join(includedirs)} library_dirs={' '.join(libdirs)} extra_options={' '.join(extra_options)}", file=sys.stderr) + extensions = cythonize([ Extension("frog", - [ "libfolia_classes.pxd", "frog_classes.pxd", "frog_wrapper.pyx"], + [ "frog_wrapper.pyx"], language='c++', include_dirs=includedirs, library_dirs=libdirs, libraries=['frog','ucto','folia'], - extra_compile_args=['--std=c++0x'] + extra_options) + extra_compile_args=['--std=c++17'] + extra_options) ], compiler_directives={"language_level": "3"} ) @@ -47,17 +66,18 @@ setup( name = 'python-frog', - version = '0.6.0', #also ensure UCTODATAVERSION and FROGDATAVERSION are good in frog_wrapper.pyx + version = '0.6.13', #also ensure UCTODATAVERSION and FROGDATAVERSION are good in frog_wrapper.pyx author = "Maarten van Gompel", author_email = "proycon@anaproy.nl", - description = ("Python binding to FROG, an NLP suite for Dutch doing part-of-speech tagging, lemmatisation, morphological analysis, named-entity recognition, shallow parsing, and dependency parsing."), - license = "GPLv3", + description = ("Python binding to Frog, an NLP suite for Dutch doing part-of-speech tagging, lemmatisation, morphological analysis, named-entity recognition, shallow parsing, and dependency parsing."), + license = "GPL-3.0-only", keywords = "nlp computational_linguistics dutch pos lemmatizer", url = "https://github.com/proycon/python-frog", ext_modules = extensions, cmdclass = {'build_ext': build_ext}, - requires = ['frog (>=0.25)'], + requires = ['frog (>=0.30)','ucto (>=0.29)'], install_requires=['Cython'], + data_files = [("sources",["frog_wrapper.pyx"])], classifiers=[ "Development Status :: 5 - Production/Stable", "Topic :: Text Processing :: Linguistic", @@ -66,6 +86,5 @@ "Operating System :: POSIX", "Intended Audience :: Developers", "Intended Audience :: Science/Research", - "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", ], )