Skip to content

Commit

Permalink
build: use pyproject.toml (#598)
Browse files Browse the repository at this point in the history
* build: use pyproject.toml

* fix: fix build

* chore: pin build dependencies version and update dependabot

* ci: do not use coverage for compiled test

* ci: drop python 3.7

* fix: fix `apischema.typing.get_args`

* fix: make flake8 happy with setup.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix: fix scripts/generate_readme.py version retrieving

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
wyfo and pre-commit-ci[bot] authored Oct 18, 2023
1 parent 8a4da30 commit c58e402
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 151 deletions.
7 changes: 7 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ updates:
groups:
actions:
patterns: ["*"]
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "monthly"
groups:
build:
patterns: ["*"]
- package-ecosystem: "pip"
directory: "tests"
schedule:
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: scripts/cythonize.sh
- run: pipx run build --sdist
- uses: actions/upload-artifact@v3
with:
Expand All @@ -20,12 +19,10 @@ jobs:
name: Wheel on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v3
- run: scripts/cythonize.sh
- run: scripts/generate_tests_from_examples.py
- uses: pypa/cibuildwheel@v2.16.2
env:
Expand All @@ -34,6 +31,7 @@ jobs:
# TODO execute tests on Windows (https://github.com/wyfo/apischema/runs/4622330189)
CIBW_TEST_COMMAND_WINDOWS: python -c "import apischema"
CIBW_BEFORE_TEST: pip install -r tests/requirements.txt
# TODO is skipping still necessary?
CIBW_TEST_SKIP: "*universal2:arm64"
- uses: actions/upload-artifact@v3
with:
Expand Down
15 changes: 6 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', 'pypy-3.9']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', 'pypy-3.9', 'pypy-3.10']
include:
- python-version: '3.11'
- python-version: '3.12'
pytest-args: --cov=apischema --cov-branch --cov-report=xml --cov-report=html
steps:
- uses: actions/cache@v3.0.11
Expand Down Expand Up @@ -56,15 +56,12 @@ jobs:
path: |
coverage.xml
htmlcov
- name: Cythonize
run: scripts/cythonize.sh
if: matrix.python-version != 'pypy-3.9'
- name: Compile
run: python setup.py build_ext --inplace
if: matrix.python-version != 'pypy-3.9'
run: pip install -e .
if: matrix.python-version != 'pypy-3.9' && matrix.python-version != 'pypy-3.10'
- name: Run tests (compiled)
run: pytest tests ${{ matrix.pytest-args }}
if: matrix.python-version != 'pypy-3.9'
run: pytest tests
if: matrix.python-version != 'pypy-3.9' && matrix.python-version != 'pypy-3.10'

concurrency:
group: ci-${{ github.head_ref }}
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,6 @@ jobs:
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Cythonize
run: scripts/cythonize.sh
- name: Install apischema
run: pip install -e .
- name: Install requirements
Expand Down
2 changes: 1 addition & 1 deletion apischema/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def get_origin(tp):
def get_args(tp):
if isinstance(tp, _AnnotatedAlias):
return () if tp.__args__ is None else (tp.__args__[0], *tp.__metadata__)
res = tp.__args__
res = getattr(tp, "__args__", ())
if get_origin(tp) is Callable and res[0] is not Ellipsis:
res = (list(res[:-1]), res[-1])
return res
Expand Down
45 changes: 45 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[build-system]
requires = ["setuptools==68.2.2", "wheel==0.41.2", "Cython==3.0.3"]
build-backend = "setuptools.build_meta"

[project]
name = "apischema"
version = "0.18.1"
authors = [{ name = "Joseph Perez", email = "joperez@hotmail.fr" }]
license = { text = "MIT" }
description = "JSON (de)serialization, GraphQL and JSON schema generation using Python typing."
readme = "README.md"
requires-python = ">=3.7"
classifiers = [
"Development Status == 4 - Beta",
"Intended Audience == Developers",
"License == OSI Approved == MIT License",
"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 == Software Development == Libraries == Python Modules",
]

[project.urls]
Repository = "https://github.com/wyfo/apischema"
Documentation = "https://wyfo.github.io/apischema"

[project.optional-dependencies]
graphql = ["graphql-core>=3.0.0"]
examples = [
"graphql-core>=3.0.0",
"attrs",
"docstring_parser",
"bson",
"orjson",
"pydantic",
"pytest",
"sqlalchemy",
]

[tool.setuptools.package-data]
apischema = ["py.typed"]
scripts = ["cythonize.py"]
3 changes: 0 additions & 3 deletions scripts/cythonize.sh

This file was deleted.

10 changes: 7 additions & 3 deletions scripts/generate_readme.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
ROOT_DIR = pathlib.Path(__file__).parent.parent
README = ROOT_DIR / "README.md"
INDEX = ROOT_DIR / "docs" / "index.md"
SETUP = ROOT_DIR / "setup.py"
PYPROJECT = ROOT_DIR / "pyproject.toml"
QUICKSTART = ROOT_DIR / "examples" / "quickstart.py"

USED_FILES = {str(path.relative_to(ROOT_DIR)) for path in (INDEX, SETUP, QUICKSTART)}
USED_FILES = {
str(path.relative_to(ROOT_DIR)) for path in (INDEX, PYPROJECT, QUICKSTART)
}


def main():
version_match = re.search(r"version=\"(\d+\.\d+)", SETUP.read_text())
version_match = re.search(r"version = \"(\d+\.\d+)", PYPROJECT.read_text())
assert version_match is not None
version = version_match.group(1)
content = INDEX.read_text()
Expand All @@ -24,6 +26,7 @@ def main():
# Remove admonitions
content = re.sub(r"!!! note\n\s*(.*)\n", lambda m: f"> {m.group(1)}\n", content)
# Add chart
# TODO remove this unused part?
content = content.replace(
r"<!--insert chart-->",
"\n".join(
Expand All @@ -34,6 +37,7 @@ def main():
)
# Uncomment
content = re.sub(r"<!--\n(\s*(.|\n)*?\s*)\n-->", lambda m: m.group(1), content)
# TODO remove this unused part?
content = re.sub(
r"(\d+\.\d+)/benchmark_chart\.svg", f"{version}/benchmark_chart.svg", content
)
Expand Down
2 changes: 0 additions & 2 deletions scripts/requirements.cython.txt

This file was deleted.

146 changes: 18 additions & 128 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,131 +1,21 @@
import pathlib
import importlib
import os
import platform
import sys
import warnings

# The following code is copied from
# https://github.com/tornadoweb/tornado/blob/master/setup.py
# to support installing without the extension on platforms where
# no compiler is available.
from distutils.command.build_ext import build_ext

from setuptools import Extension, find_packages, setup


class custom_build_ext(build_ext):
"""Allow C extension building to fail.
The C extension speeds up (de)serialization, but is not essential.
"""

warning_message = """
********************************************************************
WARNING: %s could not
be compiled. No C extensions are essential for apischema to run,
although they do result in significant speed improvements for
(de)serialization.
%s
Here are some hints for popular operating systems:
If you are seeing this message on Linux you probably need to
install GCC and/or the Python development package for your
version of Python.
Debian and Ubuntu users should issue the following command:
$ sudo apt-get install build-essential python-dev
RedHat and CentOS users should issue the following command:
$ sudo yum install gcc python-devel
Fedora users should issue the following command:
$ sudo dnf install gcc python-devel
MacOS users should run:
$ xcode-select --install
********************************************************************
"""

def run(self):
try:
build_ext.run(self)
except Exception:
e = sys.exc_info()[1]
sys.stdout.write("%s\n" % str(e))
warnings.warn(
self.warning_message
% (
"Extension modules",
"There was an issue with "
"your platform configuration"
" - see above.",
)
)

def build_extension(self, ext):
name = ext.name
try:
build_ext.build_extension(self, ext)
except Exception:
e = sys.exc_info()[1]
sys.stdout.write("%s\n" % str(e))
warnings.warn(
self.warning_message
% (
"The %s extension " "module" % (name,),
"The output above "
"this warning shows how "
"the compilation "
"failed.",
)
)


ext_modules = None
# Cythonization makes apischema a lot slower using PyPy
if platform.python_implementation() != "PyPy":
ext_modules = [
Extension(
f"apischema.{package}.methods", sources=[f"apischema/{package}/methods.c"]
)
for package in ("deserialization", "serialization")
]

setup(
name="apischema",
version="0.18.1",
url="https://github.com/wyfo/apischema",
author="Joseph Perez",
author_email="joperez@hotmail.fr",
license="MIT",
packages=find_packages(include=["apischema*"]),
package_data={
"apischema": ["py.typed"],
"apischema.deserialization": ["methods.pyx"],
"apischema.serialization": ["methods.pyx"],
},
description="JSON (de)serialization, GraphQL and JSON schema generation using Python typing.",
long_description=pathlib.Path("README.md").read_text(),
long_description_content_type="text/markdown",
python_requires=">=3.7",
extras_require={
"graphql": ["graphql-core>=3.0.0"],
"examples": [
"graphql-core>=3.0.0",
"attrs",
"docstring_parser",
"bson",
"orjson",
"pydantic",
"pytest",
"sqlalchemy",
],
},
classifiers=[
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"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 :: Software Development :: Libraries :: Python Modules",
],
cmdclass={"build_ext": custom_build_ext},
ext_modules=ext_modules,
)
from setuptools import Extension, setup

sys.path.append(os.path.dirname(__file__))
importlib.import_module("scripts.cythonize").main()

ext_modules = [
Extension(
f"apischema.{package}.methods",
sources=[f"apischema/{package}/methods.c"],
optional=True,
)
for package in ("deserialization", "serialization")
# Cythonization makes apischema slower using PyPy
if platform.python_implementation() != "PyPy"
]
setup(ext_modules=ext_modules)

0 comments on commit c58e402

Please sign in to comment.