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
15 changes: 8 additions & 7 deletions .github/workflows/pip-test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Testing on linux, windows, macos, for python versions 3.7, 3.8, 3.9, 3.10, 3.11, 3.12
# Testing on linux, windows, macos, for python versions 3.8, 3.9, 3.10, 3.11, 3.12
# Note: Python 3.7 support was dropped as it reached End of Life (EOL) on June 27, 2023

name: Test pip install

Expand All @@ -8,20 +9,19 @@ on:

jobs:
build:

strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
os: ["ubuntu-latest", "windows-latest", "macos-latest"]
runs-on: ${{ matrix.os }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Version check
Expand All @@ -32,5 +32,6 @@ jobs:
pip install "Cython>=0.29.23" "coveralls"
- name: Install package
run: |
python setup.py sdist
pip install dist/py-stringmatching-0.4.6.tar.gz
pip install build
python -m build --sdist
python -c "import glob, subprocess, sys; files = glob.glob('dist/*.tar.gz'); assert files, 'No .tar.gz files found in dist/'; subprocess.check_call([sys.executable, '-m', 'pip', 'install'] + files)"
12 changes: 6 additions & 6 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Testing on linux, windows, macos, for python versions 3.7, 3.8, 3.9, 3.10, 3.11, 3.12
# Testing on linux, windows, macos, for python versions 3.8, 3.9, 3.10, 3.11, 3.12
# Note: Python 3.7 support was dropped as it reached End of Life (EOL) on June 27, 2023

name: Unit testing

Expand All @@ -8,20 +9,19 @@ on:

jobs:
build:

strategy:
fail-fast: false
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
os: ["ubuntu-latest", "windows-latest", "macos-latest"]
runs-on: ${{ matrix.os }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Version check
Expand All @@ -31,7 +31,7 @@ jobs:
python -m pip install --upgrade pip
pip install "numpy<2.0" "Cython>=0.29.23" "coveralls"
- name: Install package
run: python setup.py build_ext --inplace
run: pip install -e .
- name: Run tests
run: |
python -m unittest -v
5 changes: 5 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
v0.4.7 - 2/14/2026
* Migrated build to pyproject.toml (PEP 517/621); setup.py retained for Cython extensions only.
* Dropped custom build_ext and setuptools auto-install; use numpy.get_include() for extension builds.
* Dropped Testing support for Python 3.7 as it reached End of Life (EOL) on June 27, 2023.

v0.4.6 - 7/5/2024
* Limited Numpy to <2.0 in setup.py, due to compatibility issues
* Added preliminary testing of pip install to Github Actions workflow
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ include README.rst
include CHANGES.txt
include requirements.txt
include LICENSE
include pyproject.toml
recursive-include LICENSES *
3 changes: 2 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ Important links
Dependencies
============

py_stringmatching has been tested on each Python version between 3.7 and 3.12, inclusive.
py_stringmatching has been tested on each Python version between 3.8 and 3.12, inclusive.
Note: Python 3.7 support was dropped as it reached End of Life (EOL) on June 27, 2023.

The required dependencies to build the package are NumPy 1.7.0 or higher, but lower than 2.0,
and a C or C++ compiler. For the development version, you will also need Cython.
Expand Down
2 changes: 1 addition & 1 deletion docs/Installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Installation

Requirements
------------
* Python 3.7-3.11
* Python 3.8-3.11 (Python 3.7 support was dropped as it reached End of Life (EOL) on June 27, 2023)
* C or C++ compiler (parts of the package are in Cython for efficiency reasons, and you need C or C++ compiler to compile these parts)

Platforms
Expand Down
2 changes: 1 addition & 1 deletion py_stringmatching/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "0.4.6"
__version__ = "0.4.7"

# Import tokenizers
from py_stringmatching.tokenizer.alphabetic_tokenizer import AlphabeticTokenizer
Expand Down
55 changes: 55 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
[build-system]
requires = [
"setuptools>=64",
"wheel",
"Cython>=0.29",
"numpy>=1.7.0,<2.0"
]
build-backend = "setuptools.build_meta"

[project]
name = "py-stringmatching"
version = "0.4.7"
description = "Python library for string matching."
readme = "README.rst"
license = {text = "BSD"}
authors = [
{name = "UW Magellan Team", email = "uwmagellan@gmail.com"}
]
requires-python = ">=3.7"
classifiers = [
"Development Status :: 4 - Beta",
"Environment :: Console",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"Intended Audience :: Education",
"License :: OSI Approved :: BSD License",
"Operating System :: POSIX",
"Operating System :: Unix",
"Operating System :: MacOS",
"Operating System :: Microsoft :: Windows",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Scientific/Engineering",
"Topic :: Utilities",
"Topic :: Software Development :: Libraries",
]
dependencies = [
"numpy>=1.7.0,<2.0",
]

[project.urls]
Homepage = "https://sites.google.com/site/anhaidgroup/projects/magellan/py_stringmatching"

[tool.setuptools]
include-package-data = true
zip-safe = false

[tool.setuptools.packages.find]
exclude = ["benchmarks", "benchmarks.custom_benchmarks"]
196 changes: 71 additions & 125 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,148 +1,94 @@
import subprocess
import sys
"""
Minimal setup.py for building Cython extensions.
Most configuration is now in pyproject.toml.
"""
import os
import sys
from setuptools import setup, Extension

# check if pip is installed. If not, raise an ImportError
PIP_INSTALLED = True

try:
import pip
except ImportError:
PIP_INSTALLED = False

def install_and_import(package):
import importlib
try:
importlib.import_module(package)
except ImportError:
if not PIP_INSTALLED:
raise ImportError('pip is not installed.')
pip.main(['install', package])
finally:
globals()[package] = importlib.import_module(package)

# check if setuptools is installed. If not, install setuptools
# automatically using pip.
install_and_import('setuptools')

from setuptools.command.build_ext import build_ext as _build_ext

class build_ext(_build_ext):
def build_extensions(self):
import pkg_resources
numpy_incl = pkg_resources.resource_filename('numpy', 'core/include')

for ext in self.extensions:
if (hasattr(ext, 'include_dirs') and
not numpy_incl in ext.include_dirs):
ext.include_dirs.append(numpy_incl)
_build_ext.build_extensions(self)

def generate_cython():

"""Generate C files from Cython sources."""
from Cython.Build import cythonize

module_list = ["py_stringmatching/similarity_measure/cython/cython_affine.pyx",
"py_stringmatching/similarity_measure/cython/cython_jaro.pyx",
"py_stringmatching/similarity_measure/cython/cython_jaro_winkler.pyx",
"py_stringmatching/similarity_measure/cython/cython_levenshtein.pyx",
"py_stringmatching/similarity_measure/cython/cython_needleman_wunsch.pyx",
"py_stringmatching/similarity_measure/cython/cython_smith_waterman.pyx",
"py_stringmatching/similarity_measure/cython/cython_utils.pyx"
]
module_list = [
"py_stringmatching/similarity_measure/cython/cython_affine.pyx",
"py_stringmatching/similarity_measure/cython/cython_jaro.pyx",
"py_stringmatching/similarity_measure/cython/cython_jaro_winkler.pyx",
"py_stringmatching/similarity_measure/cython/cython_levenshtein.pyx",
"py_stringmatching/similarity_measure/cython/cython_needleman_wunsch.pyx",
"py_stringmatching/similarity_measure/cython/cython_smith_waterman.pyx",
"py_stringmatching/similarity_measure/cython/cython_utils.pyx"
]

p = cythonize(module_list)

if not p:
raise RuntimeError("Running cythonize failed!")


cmdclass = {"build_ext": build_ext}

def get_numpy_include():
"""Get numpy include directory using modern approach."""
import numpy
return numpy.get_include()

if __name__ == "__main__":

def main():
# Check if we need to generate Cython sources
no_frills = (len(sys.argv) >= 2 and ('--help' in sys.argv[1:] or
sys.argv[1] in ('--help-commands',
'egg_info', '--version',
'clean')))

cwd = os.path.abspath(os.path.dirname(__file__))
if not os.path.exists(os.path.join(cwd, 'PKG-INFO')) and not no_frills:
# Generate Cython sources, unless building from source release
generate_cython()

# Get numpy include directory
numpy_incl = get_numpy_include()

# Define extensions
extensions = [
Extension(
"py_stringmatching.similarity_measure.cython.cython_levenshtein",
["py_stringmatching/similarity_measure/cython/cython_levenshtein.c"],
include_dirs=[numpy_incl]
),
Extension(
"py_stringmatching.similarity_measure.cython.cython_jaro",
["py_stringmatching/similarity_measure/cython/cython_jaro.c"],
include_dirs=[numpy_incl]
),
Extension(
"py_stringmatching.similarity_measure.cython.cython_jaro_winkler",
["py_stringmatching/similarity_measure/cython/cython_jaro_winkler.c"],
include_dirs=[numpy_incl]
),
Extension(
"py_stringmatching.similarity_measure.cython.cython_utils",
["py_stringmatching/similarity_measure/cython/cython_utils.c"],
include_dirs=[numpy_incl]
),
Extension(
"py_stringmatching.similarity_measure.cython.cython_needleman_wunsch",
["py_stringmatching/similarity_measure/cython/cython_needleman_wunsch.c"],
include_dirs=[numpy_incl]
),
Extension(
"py_stringmatching.similarity_measure.cython.cython_smith_waterman",
["py_stringmatching/similarity_measure/cython/cython_smith_waterman.c"],
include_dirs=[numpy_incl]
),
Extension(
"py_stringmatching.similarity_measure.cython.cython_affine",
["py_stringmatching/similarity_measure/cython/cython_affine.c"],
include_dirs=[numpy_incl]
)
]

setup(ext_modules=extensions)

# specify extensions that need to be compiled
extensions = [setuptools.Extension("py_stringmatching.similarity_measure.cython.cython_levenshtein",
["py_stringmatching/similarity_measure/cython/cython_levenshtein.c"],
include_dirs=[]),
setuptools.Extension("py_stringmatching.similarity_measure.cython.cython_jaro",
["py_stringmatching/similarity_measure/cython/cython_jaro.c"],
include_dirs=[]),
setuptools.Extension("py_stringmatching.similarity_measure.cython.cython_jaro_winkler",
["py_stringmatching/similarity_measure/cython/cython_jaro_winkler.c"],
include_dirs=[]),
setuptools.Extension("py_stringmatching.similarity_measure.cython.cython_utils",
["py_stringmatching/similarity_measure/cython/cython_utils.c"],
include_dirs=[]),
setuptools.Extension("py_stringmatching.similarity_measure.cython.cython_needleman_wunsch",
["py_stringmatching/similarity_measure/cython/cython_needleman_wunsch.c"],
include_dirs=[]),
setuptools.Extension("py_stringmatching.similarity_measure.cython.cython_smith_waterman",
["py_stringmatching/similarity_measure/cython/cython_smith_waterman.c"],
include_dirs=[]),
setuptools.Extension("py_stringmatching.similarity_measure.cython.cython_affine",
["py_stringmatching/similarity_measure/cython/cython_affine.c"],
include_dirs=[])

]

# find packages to be included. exclude benchmarks.
packages = setuptools.find_packages(exclude=["benchmarks", "benchmarks.custom_benchmarks"])

with open('README.rst') as f:
LONG_DESCRIPTION = f.read()

setuptools.setup(
name='py-stringmatching',
version='0.4.6',
description='Python library for string matching.',
long_description=LONG_DESCRIPTION,
url='https://sites.google.com/site/anhaidgroup/projects/magellan/py_stringmatching',
author='UW Magellan Team',
author_email='uwmagellan@gmail.com',
license='BSD',
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Console',
'Intended Audience :: Developers',
'Intended Audience :: Science/Research',
'Intended Audience :: Education',
'License :: OSI Approved :: BSD License',
'Operating System :: POSIX',
'Operating System :: Unix',
'Operating System :: MacOS',
'Operating System :: Microsoft :: Windows',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Topic :: Scientific/Engineering',
'Topic :: Utilities',
'Topic :: Software Development :: Libraries',
],
packages=packages,
install_requires=[
'numpy >= 1.7.0,<2.0',
],
setup_requires=[
'numpy >= 1.7.0,<2.0'
],
ext_modules=extensions,
cmdclass=cmdclass,
include_package_data=True,
zip_safe=False
)
if __name__ == "__main__":
main()
Loading