diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 036efc8..aeb0b49 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,13 +52,12 @@ jobs: fetch-depth: 50 submodules: true - - name: Set up Python - uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0 + - name: Install the latest version of uv + uses: astral-sh/setup-uv@eb1897b8dc4b5d5bfe39a428a8f2304605e0983c # 7.0.0 - name: Build source distribution run: | - python -m pip install -U setuptools wheel pip - python setup.py sdist + uv build --sdist - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: @@ -73,12 +72,12 @@ jobs: os: [ubuntu-latest, macos-latest, windows-latest] cibw_arch: ["auto64", "aarch64", "universal2"] cibw_python: - - "cp38" - "cp39" - "cp310" - "cp311" - "cp312" - "cp313" + - "cp314" exclude: - os: ubuntu-latest cibw_arch: universal2 @@ -108,7 +107,7 @@ jobs: with: platforms: arm64 - - uses: pypa/cibuildwheel@7940a4c0e76eb2030e473a5f864f291f63ee879b # v2.21.3 + - uses: pypa/cibuildwheel@7c619efba910c04005a835b110b057fc28fd6e93 # v3.2.0 env: CIBW_BUILD_VERBOSITY: 1 CIBW_BUILD: ${{ matrix.cibw_python }}-* diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7c85de3..20c9145 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] os: [windows-latest, ubuntu-latest, macos-latest] env: @@ -46,5 +46,6 @@ jobs: if: steps.release.outputs.version == 0 run: | python -m pip install -U pip setuptools wheel - python -m pip install -e .[test] - python -m unittest -v tests.suite + python -m pip install .[test] + cd tests + python -m unittest -v diff --git a/Makefile b/Makefile index b34b26e..9a2596a 100644 --- a/Makefile +++ b/Makefile @@ -3,27 +3,26 @@ PYTHON ?= python3 ROOT = $(dir $(realpath $(firstword $(MAKEFILE_LIST)))) - +UV := $(shell command -v uv 2> /dev/null) +ifdef UV + PYTHON := uv run + PIP := uv pip +else + PIP := pip +endif compile: - python3 setup.py build_ext --inplace - - -release: compile test - python3 setup.py sdist upload - + $(PIP) install -e . test: compile - python3 -m unittest -v + $(PYTHON) -m unittest -v clean: find $(ROOT)/httptools/parser -name '*.c' | xargs rm -f + find $(ROOT)/httptools/parser -name '*.so' | xargs rm -f find $(ROOT)/httptools/parser -name '*.html' | xargs rm -f + rm -rf build distclean: clean git --git-dir="$(ROOT)/vendor/http-parser/.git" clean -dfx git --git-dir="$(ROOT)/vendor/llhttp/.git" clean -dfx - - -testinstalled: - cd /tmp && $(PYTHON) $(ROOT)/tests/__init__.py \ No newline at end of file diff --git a/README.md b/README.md index 759de77..d30a324 100644 --- a/README.md +++ b/README.md @@ -99,9 +99,7 @@ def parse_url(url: bytes): 3. Activate the environment with `source envname/bin/activate` -4. Install development requirements with `pip install -e .[test]` - -5. Run `make` and `make test`. +4. Run `make` and `make test`. # License diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..659db31 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,29 @@ +[build-system] +build-backend = "setuptools.build_meta" +requires = ["setuptools==80.9.0"] + +[project] +name = "httptools" +dynamic = ["version"] +classifiers = [ + "Intended Audience :: Developers", + "Programming Language :: Python :: 3", + "Operating System :: POSIX", + "Operating System :: MacOS :: MacOS X", + "Environment :: Web Environment", + "Development Status :: 5 - Production/Stable", +] +requires-python = ">=3.9" +authors = [ + {name = "Yury Selivanov", email="yury@magic.io"}, +] +license = "MIT" +license-files = ["LICENSE"] +description = "A collection of framework independent HTTP protocol utils." +readme = "README.md" + +[project.urls] +Homepage = "https://github.com/MagicStack/httptools" + +[project.optional-dependencies] +test = [] # for backward compatibility diff --git a/setup.py b/setup.py index adca1f8..bc28b50 100644 --- a/setup.py +++ b/setup.py @@ -1,21 +1,17 @@ import sys -vi = sys.version_info -if vi < (3, 8): - raise RuntimeError('httptools require Python 3.8 or greater') -else: - import os.path - import pathlib +import os.path +import pathlib - from setuptools import setup, Extension - from setuptools.command.build_ext import build_ext as build_ext +from setuptools import setup, Extension +from setuptools.command.build_ext import build_ext as build_ext CFLAGS = ['-O2'] ROOT = pathlib.Path(__file__).parent -CYTHON_DEPENDENCY = 'Cython>=0.29.24' +CYTHON_DEPENDENCY = 'Cython>=3.1.0' class httptools_build_ext(build_ext): @@ -52,6 +48,8 @@ def initialize_options(self): self.cython_always = False self.cython_annotate = None self.cython_directives = None + if 'editable_wheel' in sys.argv: + self.inplace = True def finalize_options(self): # finalize_options() may be called multiple times on the @@ -82,12 +80,9 @@ def finalize_options(self): try: import Cython except ImportError: - raise RuntimeError( - 'please install Cython to compile httptools from source') + import setuptools.build_meta - if Cython.__version__ < '0.29': - raise RuntimeError( - 'httptools requires Cython version 0.29 or greater') + raise setuptools.build_meta.SetupRequirementsError([CYTHON_DEPENDENCY]) from Cython.Build import cythonize @@ -145,10 +140,6 @@ def build_extensions(self): super().build_extensions() -with open(str(ROOT / 'README.md')) as f: - long_description = f.read() - - with open(str(ROOT / 'httptools' / '_version.py')) as f: for line in f: if line.startswith('__version__ ='): @@ -160,36 +151,10 @@ def build_extensions(self): 'unable to read the version from httptools/_version.py') -setup_requires = [] - -if (not (ROOT / 'httptools' / 'parser' / 'parser.c').exists() or - '--cython-always' in sys.argv): - # No Cython output, require Cython to build. - setup_requires.append(CYTHON_DEPENDENCY) - - setup( - name='httptools', version=VERSION, - description='A collection of framework independent HTTP protocol utils.', - long_description=long_description, - long_description_content_type='text/markdown', - url='https://github.com/MagicStack/httptools', - classifiers=[ - 'License :: OSI Approved :: MIT License', - 'Intended Audience :: Developers', - 'Programming Language :: Python :: 3', - 'Operating System :: POSIX', - 'Operating System :: MacOS :: MacOS X', - 'Environment :: Web Environment', - 'Development Status :: 5 - Production/Stable', - ], platforms=['macOS', 'POSIX', 'Windows'], - python_requires='>=3.8.0', zip_safe=False, - author='Yury Selivanov', - author_email='yury@magic.io', - license='MIT', packages=['httptools', 'httptools.parser'], cmdclass={ 'build_ext': httptools_build_ext, @@ -212,11 +177,4 @@ def build_extensions(self): ], include_package_data=True, exclude_package_data={"": ["*.c", "*.h"]}, - test_suite='tests.suite', - setup_requires=setup_requires, - extras_require={ - 'test': [ - CYTHON_DEPENDENCY - ] - } ) diff --git a/vendor/llhttp b/vendor/llhttp index 610a87d..86b83a5 160000 --- a/vendor/llhttp +++ b/vendor/llhttp @@ -1 +1 @@ -Subproject commit 610a87d755f6bae466cd871c2ba97574ccac5483 +Subproject commit 86b83a59786caebd581f38d613c64c9e8c52c79e