PYTHON-4451 Use Hatch as Build Backend (#1644)

This commit is contained in:
Steven Silvester 2024-06-07 06:24:18 -05:00 committed by GitHub
parent d6bf0e1e78
commit 2b030018e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 102 additions and 102 deletions

View File

@ -158,6 +158,7 @@ if [ -n "$TEST_ENCRYPTION" ] || [ -n "$TEST_FLE_AZURE_AUTO" ] || [ -n "$TEST_FLE
if [ ! -d "libmongocrypt_git" ]; then
git clone https://github.com/mongodb/libmongocrypt.git libmongocrypt_git
fi
python -m pip install -U setuptools
python -m pip install ./libmongocrypt_git/bindings/python
python -c "import pymongocrypt; print('pymongocrypt version: '+pymongocrypt.__version__)"
python -c "import pymongocrypt; print('libmongocrypt version: '+pymongocrypt.libmongocrypt_version())"

View File

@ -66,7 +66,7 @@ createvirtualenv () {
export PIP_QUIET=1
python -m pip install --upgrade pip
python -m pip install --upgrade setuptools tox
python -m pip install --upgrade tox
}
# Usage:

View File

@ -31,12 +31,10 @@ jobs:
- name: Run linters
run: |
tox -m lint-manual
- name: Check Manifest
run: |
tox -m manifest
- name: Run compilation
run: |
pip install -e .
export PYMONGO_C_EXT_MUST_BUILD=1
pip install -v -e .
python tools/fail_if_no_c.py
- name: Run typecheck
run: |

View File

@ -1,34 +0,0 @@
include README.md
include LICENSE
include THIRD-PARTY-NOTICES
include *.ini
include sbom.json
include requirements.txt
exclude .coveragerc
exclude .git-blame-ignore-revs
exclude .pre-commit-config.yaml
exclude .readthedocs.yaml
exclude CONTRIBUTING.md
exclude RELEASE.md
recursive-include doc *.rst
recursive-include doc *.py
recursive-include doc *.conf
recursive-include doc *.css
recursive-include doc *.js
recursive-include doc *.png
include doc/Makefile
include doc/_templates/layout.html
include doc/make.bat
include doc/static/periodic-executor-refs.dot
recursive-include requirements *.txt
recursive-include tools *.py
recursive-include tools *.sh
include tools/README.rst
include green_framework_test.py
recursive-include test *.pem
recursive-include test *.py
recursive-include test *.json
recursive-include bson *.h
prune test/mod_wsgi_test
prune test/lambda
prune .evergreen

View File

@ -78,12 +78,6 @@ PyMongo can be installed with [pip](http://pypi.python.org/pypi/pip):
python -m pip install pymongo
```
Or `easy_install` from [setuptools](http://pypi.python.org/pypi/setuptools):
```bash
python -m easy_install pymongo
```
You can also download the project source and do:
```bash

36
hatch_build.py Normal file
View File

@ -0,0 +1,36 @@
"""A custom hatch build hook for pymongo."""
from __future__ import annotations
import os
import subprocess
import sys
from pathlib import Path
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
class CustomHook(BuildHookInterface):
"""The pymongo build hook."""
def initialize(self, version, build_data):
"""Initialize the hook."""
if self.target_name == "sdist":
return
here = Path(__file__).parent.resolve()
sys.path.insert(0, str(here))
subprocess.check_call([sys.executable, "setup.py", "build_ext", "-i"])
# Ensure wheel is marked as binary and contains the binary files.
build_data["infer_tag"] = True
build_data["pure_python"] = False
if os.name == "nt":
patt = ".pyd"
else:
patt = ".so"
for pkg in ["bson", "pymongo"]:
dpath = here / pkg
for fpath in dpath.glob(f"*{patt}"):
relpath = os.path.relpath(fpath, here)
build_data["artifacts"].append(relpath)
build_data["force_include"][relpath] = relpath

View File

@ -15,16 +15,29 @@
"""Current version of PyMongo."""
from __future__ import annotations
from typing import Tuple, Union
import re
from typing import List, Tuple, Union
version_tuple: Tuple[Union[int, str], ...] = (4, 8, 0, ".dev0")
__version__ = "4.8.0.dev1"
def get_version_tuple(version: str) -> Tuple[Union[int, str], ...]:
pattern = r"(?P<major>\d+).(?P<minor>\d+).(?P<patch>\d+)(?P<rest>.*)"
match = re.match(pattern, version)
if match:
parts: List[Union[int, str]] = [int(match[part]) for part in ["major", "minor", "patch"]]
if match["rest"]:
parts.append(match["rest"])
elif re.match(r"\d+.\d+", version):
parts = [int(part) for part in version.split(".")]
else:
raise ValueError("Could not parse version")
return tuple(parts)
version_tuple = get_version_tuple(__version__)
version = __version__
def get_version_string() -> str:
if isinstance(version_tuple[-1], str):
return ".".join(map(str, version_tuple[:-1])) + version_tuple[-1]
return ".".join(map(str, version_tuple))
__version__: str = get_version_string()
version = __version__
return __version__

View File

@ -1,6 +1,6 @@
[build-system]
requires = ["setuptools>=63.0"]
build-backend = "setuptools.build_meta"
requires = ["hatchling>1.24","setuptools>=65.0","hatch-requirements-txt>=0.4.1"]
build-backend = "hatchling.build"
[project]
name = "pymongo"
@ -45,16 +45,27 @@ Documentation = "https://pymongo.readthedocs.io"
Source = "https://github.com/mongodb/mongo-python-driver"
Tracker = "https://jira.mongodb.org/projects/PYTHON/issues"
[tool.setuptools.dynamic]
version = {attr = "pymongo._version.__version__"}
# Used to call hatch_build.py
[tool.hatch.build.hooks.custom]
[tool.setuptools.packages.find]
include = ["bson","gridfs", "gridfs.asynchronous", "gridfs.synchronous", "pymongo", "pymongo.asynchronous", "pymongo.synchronous"]
[tool.hatch.version]
path = "pymongo/_version.py"
[tool.setuptools.package-data]
bson=["py.typed", "*.pyi"]
pymongo=["py.typed", "*.pyi"]
gridfs=["py.typed", "*.pyi"]
[tool.hatch.build.targets.wheel]
packages = ["bson","gridfs", "pymongo"]
[tool.hatch.metadata.hooks.requirements_txt]
files = ["requirements.txt"]
[tool.hatch.metadata.hooks.requirements_txt.optional-dependencies]
aws = ["requirements/aws.txt"]
docs = ["requirements/docs.txt"]
encryption = ["requirements/encryption.txt"]
gssapi = ["requirements/gssapi.txt"]
ocsp = ["requirements/ocsp.txt"]
snappy = ["requirements/snappy.txt"]
test = ["requirements/test.txt"]
zstd = ["requirements/zstd.txt"]
[tool.pytest.ini_options]
minversion = "7"
@ -179,6 +190,7 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?)|dummy.*)$"
"UP031", "F401", "B023", "F811"]
"tools/*.py" = ["T201"]
"green_framework_test.py" = ["T201"]
"hatch_build.py" = ["S"]
[tool.coverage.run]
branch = true

View File

@ -136,32 +136,8 @@ by this python implementation.\n
)
ext_modules = []
def parse_reqs_file(fname):
with open(fname) as fid:
lines = [li.strip() for li in fid.readlines()]
return [li for li in lines if li and not li.startswith("#")]
dependencies = parse_reqs_file("requirements.txt")
extras_require = dict(
aws=parse_reqs_file("requirements/aws.txt"),
encryption=parse_reqs_file("requirements/encryption.txt"),
gssapi=parse_reqs_file("requirements/gssapi.txt"),
ocsp=parse_reqs_file("requirements/ocsp.txt"),
snappy=parse_reqs_file("requirements/snappy.txt"),
# PYTHON-3423 Removed in 4.3 but kept here to avoid pip warnings.
srv=[],
tls=[],
# PYTHON-2133 Removed in 4.0 but kept here to avoid pip warnings.
zstd=parse_reqs_file("requirements/zstd.txt"),
test=parse_reqs_file("requirements/test.txt"),
)
setup(
cmdclass={"build_ext": custom_build_ext},
install_requires=dependencies,
extras_require=extras_require,
ext_modules=ext_modules,
packages=["bson", "pymongo", "gridfs"],
) # type:ignore

View File

@ -22,6 +22,7 @@ sys.path[0:0] = [""]
from test import unittest
import pymongo
from pymongo._version import get_version_tuple
class TestPyMongo(unittest.TestCase):
@ -29,6 +30,14 @@ class TestPyMongo(unittest.TestCase):
# Testing that pymongo module imports mongo_client.MongoClient
self.assertEqual(pymongo.MongoClient, pymongo.synchronous.mongo_client.MongoClient)
def test_get_version_tuple(self):
self.assertEqual(get_version_tuple("4.8.0.dev1"), (4, 8, 0, ".dev1"))
self.assertEqual(get_version_tuple("4.8.1"), (4, 8, 1))
self.assertEqual(get_version_tuple("5.0.0rc1"), (5, 0, 0, "rc1"))
self.assertEqual(get_version_tuple("5.0"), (5, 0))
with self.assertRaises(ValueError):
get_version_tuple("5")
if __name__ == "__main__":
unittest.main()

View File

@ -29,6 +29,14 @@ import bson # noqa: E402
import pymongo # noqa: E402
if not pymongo.has_c() or not bson.has_c():
try:
from pymongo import _cmessage # type:ignore[attr-defined] # noqa: F401
except Exception as e:
print(e)
try:
from bson import _cbson # type:ignore[attr-defined] # noqa: F401
except Exception as e:
print(e)
sys.exit("could not load C extensions")
if os.environ.get("ENSURE_UNIVERSAL2") == "1":

13
tox.ini
View File

@ -31,8 +31,6 @@ envlist =
doc-test,
# Linkcheck sphinx docs
linkcheck
# Check the sdist integrity.
manifest
labels = # Use labels and -m instead of -e so that tox -m <label> fails instantly if the label does not exist
test = test
@ -51,7 +49,6 @@ labels = # Use labels and -m instead of -e so that tox -m <label> fails instantl
linkcheck = linkcheck
test-mockupdb = test-mockupdb
aws-secrets = aws-secrets
manifest = manifest
[testenv]
package = editable
@ -71,8 +68,6 @@ commands =
description = run tests using run-tests.sh Evergreen script
passenv = *
extras = test
deps =
setuptools
allowlist_externals =
bash
commands =
@ -184,14 +179,6 @@ allowlist_externals =
commands =
{[testenv:test]commands} ./test/mockupdb
[testenv:manifest]
description = ensure the sdist manifest is correct
skip_install = true
deps =
check-manifest
commands =
python -m check_manifest -v
[testenv:setup-encryption]
description = set up encryption assets and servers
skip_install = true