From 4a48bc8157019d40486e3292f34792810ecb7436 Mon Sep 17 00:00:00 2001 From: Simon Pichugin Date: Sat, 12 Jul 2025 22:56:12 -0700 Subject: [PATCH 1/3] Package python-ldap with pyproject.toml --- .coveragerc | 27 ------- .gitignore | 2 - Doc/installing.rst | 30 ++++++-- Doc/spelling_wordlist.txt | 4 + INSTALL | 4 +- MANIFEST.in | 2 +- Makefile | 1 - pyproject.toml | 153 +++++++++++++++++++++++++++++++++++++- setup.py | 74 +----------------- tox.ini | 7 +- 10 files changed, 189 insertions(+), 115 deletions(-) delete mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 738d86fa..00000000 --- a/.coveragerc +++ /dev/null @@ -1,27 +0,0 @@ -[run] -branch = True -source = - ldap - ldif - ldapurl - slapdtest - -[paths] -source = - Lib/ - .tox/*/lib/python*/site-packages/ - -[report] -ignore_errors = False -precision = 1 -exclude_lines = - pragma: no cover - raise NotImplementedError - if 0: - if __name__ == .__main__.: - if PY2 - if not PY2 - -[html] -directory = build/htmlcov -title = python-ldap coverage report diff --git a/.gitignore b/.gitignore index bab21878..75a13538 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,6 @@ *.pyc __pycache__/ .tox -.coverage* -!.coveragerc /.cache /.pytest_cache diff --git a/Doc/installing.rst b/Doc/installing.rst index 03e7a295..1c7ec8c3 100644 --- a/Doc/installing.rst +++ b/Doc/installing.rst @@ -76,12 +76,23 @@ The CVS repository of FreeBSD contains the package macOS ----- -You can install directly with pip:: +You can install directly with pip. First install Xcode command line tools:: $ xcode-select --install - $ pip install python-ldap \ - --global-option=build_ext \ - --global-option="-I$(xcrun --show-sdk-path)/usr/include/sasl" + +Then install python-ldap:: + + $ pip install python-ldap + +For custom installations, you may need to set environment variables:: + + $ export CPPFLAGS="-I$(xcrun --show-sdk-path)/usr/include/sasl" + $ pip install python-ldap + +If using Homebrew:: + + $ brew install openldap + $ pip install python-ldap .. _install-source: @@ -90,11 +101,14 @@ Installing from Source ====================== -python-ldap is built and installed using the Python setuptools. -From a source repository:: +python-ldap is built and installed using modern Python packaging standards +with pyproject.toml configuration. From a source repository:: + + $ pip install . + +For development installation with editable mode:: - $ python -m pip install setuptools - $ python setup.py install + $ pip install -e . If you have more than one Python interpreter installed locally, you should use the same one you plan to use python-ldap with. diff --git a/Doc/spelling_wordlist.txt b/Doc/spelling_wordlist.txt index e2150d9a..4381ebee 100644 --- a/Doc/spelling_wordlist.txt +++ b/Doc/spelling_wordlist.txt @@ -60,6 +60,7 @@ func Gohlke GPG Heimdal +Homebrew hostport hrefTarget hrefText @@ -106,6 +107,7 @@ previousDN processResultsCount Proxied py +pyproject pytest rdn readthedocs @@ -146,6 +148,7 @@ syncrepl syntaxes timelimit TLS +toml tracebacks tuple tuples @@ -162,5 +165,6 @@ userPassword usr uuids Valgrind +Xcode whitespace workflow diff --git a/INSTALL b/INSTALL index b9b13d2d..abccfd56 100644 --- a/INSTALL +++ b/INSTALL @@ -1,8 +1,8 @@ Quick build instructions: edit setup.cfg (see Build/ for platform-specific examples) - python setup.py build - python setup.py install + python -m build + pip install . Detailed instructions are in Doc/installing.rst, or online at: diff --git a/MANIFEST.in b/MANIFEST.in index 687d2b0c..bedea8d6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,5 @@ include MANIFEST.in Makefile CHANGES INSTALL LICENCE README TODO -include tox.ini .coveragerc +include tox.ini include Modules/*.c Modules/*.h recursive-include Build *.cfg* recursive-include Lib *.py diff --git a/Makefile b/Makefile index 2b52ddf5..da23b374 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,6 @@ Modules/constants_generated.h: Lib/ldap/constants.py .PHONY: clean clean: rm -rf build dist *.egg-info .tox MANIFEST - rm -f .coverage .coverage.* find . \( -name '*.py[co]' -or -name '*.so*' -or -name '*.dylib' \) \ -delete find . -depth -name __pycache__ -exec rm -rf {} \; diff --git a/pyproject.toml b/pyproject.toml index 75f7c06a..73ad03fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,4 +1,151 @@ +[build-system] +requires = [ + "setuptools", + "wheel", + "setuptools-scm", +] +build-backend = "setuptools.build_meta" + +[project] +name = "python-ldap" +license.text = "python-ldap" # Replace with 'license' once Python 3.8 is dropped +dynamic = ["version"] +description = "Python modules for implementing LDAP clients" +authors = [ + {name = "python-ldap project", email = "python-ldap@python.org"}, +] +readme = "README" +requires-python = ">=3.6" +keywords = ["ldap", "directory", "authentication"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "Operating System :: OS Independent", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Programming Language :: C", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.6", + "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", + "Programming Language :: Python :: 3.13", + "Topic :: Database", + "Topic :: Internet", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP", + "License :: OSI Approved :: Python Software Foundation License", +] +dependencies = [ + "pyasn1 >= 0.3.7", + "pyasn1_modules >= 0.1.5", +] + +[project.urls] +Homepage = "https://www.python-ldap.org/" +Documentation = "https://python-ldap.readthedocs.io/" +Repository = "https://github.com/python-ldap/python-ldap" +Download = "https://pypi.org/project/python-ldap/" +Changelog = "https://github.com/python-ldap/python-ldap/blob/main/CHANGES" + +[project.optional-dependencies] +dev = [ + "tox", + "pytest", + "coverage", + "black", + "isort", +] +doc = [ + "docutils", + "markdown", + "sphinx", + "sphinxcontrib-spelling", +] + +[tool.setuptools] +zip-safe = false +include-package-data = true +license-files = ["LICENCE", "LICENCE.MIT"] +# Explicitly list all Python modules +py-modules = ["ldapurl", "ldif"] + +[tool.setuptools.dynamic] +version = {attr = "ldap.pkginfo.__version__"} + +[tool.setuptools.packages.find] +where = ["Lib"] + +[tool.setuptools.package-dir] +"" = "Lib" + +[tool.black] +line-length = 88 +target-version = ['py36', 'py37', 'py38', 'py39', 'py310', 'py311', 'py312', 'py313'] +extend-exclude = ''' +/( + \.eggs + | \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | _build + | buck-out + | build + | dist + | Modules +)/ +''' + [tool.isort] -line_length=88 -known_first_party=['ldap', '_ldap', 'ldapurl', 'ldif', 'slapdtest'] -sections=['FUTURE', 'STDLIB', 'THIRDPARTY', 'FIRSTPARTY', 'LOCALFOLDER'] +profile = "black" +line_length = 88 +known_first_party = ["ldap", "_ldap", "ldapurl", "ldif", "slapdtest"] +sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"] +skip_glob = ["Modules/*"] + +[tool.pytest.ini_options] +testpaths = ["Tests"] +python_files = ["t_*.py"] +filterwarnings = [ + "error", + "ignore::ldap.LDAPBytesWarning", +] + +[tool.coverage.run] +branch = true +source = [ + "ldap", + "ldif", + "ldapurl", + "slapdtest", +] + +[tool.coverage.paths] +source = [ + "Lib/", + ".tox/*/lib/python*/site-packages/", +] + +[tool.coverage.report] +ignore_errors = false +precision = 1 +exclude_lines = [ + "pragma: no cover", + "raise NotImplementedError", + "if 0:", + "if __name__ == .__main__.:", + "if PY2", + "if not PY2", +] + +[tool.coverage.html] +directory = "build/htmlcov" +title = "python-ldap coverage report" diff --git a/setup.py b/setup.py index ea7364cd..f2e816be 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,9 @@ """ -setup.py - Setup package with the help Python's DistUtils +setup.py - C extension module configuration for python-ldap See https://www.python-ldap.org/ for details. +This file handles only the C extension modules (_ldap) configuration, +while pyproject.toml handles all project metadata, dependencies, and other settings. """ import sys,os @@ -54,52 +56,8 @@ class OpenLDAP2: LDAP_CLASS.extra_link_args.append('-pg') LDAP_CLASS.libs.append('gcov') -#-- Let distutils/setuptools do the rest -name = 'python-ldap' - +#-- C extension modules configuration only setup( - #-- Package description - name = name, - license=pkginfo.__license__, - version=pkginfo.__version__, - description = 'Python modules for implementing LDAP clients', - long_description = """python-ldap: - python-ldap provides an object-oriented API to access LDAP directory servers - from Python programs. Mainly it wraps the OpenLDAP 2.x libs for that purpose. - Additionally the package contains modules for other LDAP-related stuff - (e.g. processing LDIF, LDAPURLs, LDAPv3 schema, LDAPv3 extended operations - and controls, etc.). - """, - author = 'python-ldap project', - author_email = 'python-ldap@python.org', - url = 'https://www.python-ldap.org/', - download_url = 'https://pypi.org/project/python-ldap/', - classifiers = [ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'Intended Audience :: System Administrators', - 'Operating System :: OS Independent', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX', - 'Programming Language :: C', - - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.13', - # Note: when updating Python versions, also change tox.ini and .github/workflows/* - - 'Topic :: Database', - 'Topic :: Internet', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP', - 'License :: OSI Approved :: Python Software Foundation License', - ], - #-- C extension modules ext_modules = [ Extension( '_ldap', @@ -135,28 +93,4 @@ class OpenLDAP2: ] ), ], - #-- Python "stand alone" modules - py_modules = [ - 'ldapurl', - 'ldif', - - ], - packages = [ - 'ldap', - 'ldap.controls', - 'ldap.extop', - 'ldap.schema', - 'slapdtest', - 'slapdtest.certs', - ], - package_dir = {'': 'Lib',}, - data_files = LDAP_CLASS.extra_files, - include_package_data=True, - install_requires=[ - 'pyasn1 >= 0.3.7', - 'pyasn1_modules >= 0.1.5', - ], - zip_safe=False, - python_requires='>=3.9', - test_suite = 'Tests', ) diff --git a/tox.ini b/tox.ini index 0b284a4e..794549a7 100644 --- a/tox.ini +++ b/tox.ini @@ -5,7 +5,7 @@ [tox] # Note: when updating Python versions, also change setup.py and .github/worlflows/* -envlist = py{39,310,311,312},py3-nosasltls,doc,py3-trace,pypy3.9 +envlist = py{39,310,311,312,313},py3-nosasltls,doc,py3-trace,pypy3.9 minver = 1.8 [gh-actions] @@ -33,6 +33,11 @@ commands = {envpython} -bb -Werror \ setenv = CFLAGS=-Wno-int-in-bool-context -Werror -std=c99 +[testenv:py313] +# Python 3.13 headers are incompatible with declaration-after-statement +setenv = + CFLAGS=-Wno-int-in-bool-context -Werror -std=c99 + [testenv:py3-nosasltls] basepython = python3 # don't install, install dependencies manually From c84a4d9b45ff4980671e796c8872fa43df1c7736 Mon Sep 17 00:00:00 2001 From: Simon Pichugin Date: Mon, 11 Aug 2025 21:07:13 -0700 Subject: [PATCH 2/3] Fix review comments --- INSTALL | 1 - pyproject.toml | 16 +--------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/INSTALL b/INSTALL index abccfd56..224df4a4 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,6 @@ Quick build instructions: edit setup.cfg (see Build/ for platform-specific examples) - python -m build pip install . Detailed instructions are in Doc/installing.rst, or online at: diff --git a/pyproject.toml b/pyproject.toml index 73ad03fe..d9c6e739 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,6 @@ [build-system] requires = [ "setuptools", - "wheel", "setuptools-scm", ] build-backend = "setuptools.build_meta" @@ -54,20 +53,7 @@ Repository = "https://github.com/python-ldap/python-ldap" Download = "https://pypi.org/project/python-ldap/" Changelog = "https://github.com/python-ldap/python-ldap/blob/main/CHANGES" -[project.optional-dependencies] -dev = [ - "tox", - "pytest", - "coverage", - "black", - "isort", -] -doc = [ - "docutils", - "markdown", - "sphinx", - "sphinxcontrib-spelling", -] + [tool.setuptools] zip-safe = false From 5d6974aabeeb05a3dd4b466961c385b81bc666fb Mon Sep 17 00:00:00 2001 From: Simon Pichugin Date: Tue, 12 Aug 2025 09:44:37 -0700 Subject: [PATCH 3/3] Clean up --- pyproject.toml | 29 ----------------------------- tox.ini | 6 +----- 2 files changed, 1 insertion(+), 34 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d9c6e739..8781155d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,39 +71,10 @@ where = ["Lib"] [tool.setuptools.package-dir] "" = "Lib" -[tool.black] -line-length = 88 -target-version = ['py36', 'py37', 'py38', 'py39', 'py310', 'py311', 'py312', 'py313'] -extend-exclude = ''' -/( - \.eggs - | \.git - | \.hg - | \.mypy_cache - | \.tox - | \.venv - | _build - | buck-out - | build - | dist - | Modules -)/ -''' - [tool.isort] -profile = "black" line_length = 88 known_first_party = ["ldap", "_ldap", "ldapurl", "ldif", "slapdtest"] sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"] -skip_glob = ["Modules/*"] - -[tool.pytest.ini_options] -testpaths = ["Tests"] -python_files = ["t_*.py"] -filterwarnings = [ - "error", - "ignore::ldap.LDAPBytesWarning", -] [tool.coverage.run] branch = true diff --git a/tox.ini b/tox.ini index 794549a7..0741ef29 100644 --- a/tox.ini +++ b/tox.ini @@ -5,7 +5,7 @@ [tox] # Note: when updating Python versions, also change setup.py and .github/worlflows/* -envlist = py{39,310,311,312,313},py3-nosasltls,doc,py3-trace,pypy3.9 +envlist = py{39,310,311,312},py3-nosasltls,doc,py3-trace,pypy3.9 minver = 1.8 [gh-actions] @@ -33,10 +33,6 @@ commands = {envpython} -bb -Werror \ setenv = CFLAGS=-Wno-int-in-bool-context -Werror -std=c99 -[testenv:py313] -# Python 3.13 headers are incompatible with declaration-after-statement -setenv = - CFLAGS=-Wno-int-in-bool-context -Werror -std=c99 [testenv:py3-nosasltls] basepython = python3