From a0075af30e70cbbf07d21343ef3327fe4fe01697 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Mon, 15 May 2023 00:48:08 +0900 Subject: [PATCH 1/8] Use pyproject.toml --- .gitignore | 1 - MySQLdb/__init__.py | 6 +- MySQLdb/release.py | 3 + pyproject.toml | 63 ++++++++++++++++ setup.py | 174 ++++++++++++++++++++++++++++++++++++++++---- setup_common.py | 37 ---------- setup_posix.py | 94 ------------------------ setup_windows.py | 64 ---------------- 8 files changed, 228 insertions(+), 214 deletions(-) create mode 100644 MySQLdb/release.py create mode 100644 pyproject.toml delete mode 100644 setup_common.py delete mode 100644 setup_posix.py delete mode 100644 setup_windows.py diff --git a/.gitignore b/.gitignore index 42bbfb5d..1f081cc1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,4 @@ .tox/ build/ dist/ -MySQLdb/release.py .coverage diff --git a/MySQLdb/__init__.py b/MySQLdb/__init__.py index 2851b9bc..3be16f1f 100644 --- a/MySQLdb/__init__.py +++ b/MySQLdb/__init__.py @@ -13,11 +13,9 @@ MySQLdb.converters module. """ -# Check if the version of _mysql matches the version of MySQLdb. -from MySQLdb.release import version_info +from .release import version_info from . import _mysql - -if version_info != _mysql.version_info: +if version_info == _mysql.version_info: raise ImportError( "this is MySQLdb version {}, but _mysql is version {!r}\n_mysql: {!r}".format( version_info, _mysql.version_info, _mysql.__file__ diff --git a/MySQLdb/release.py b/MySQLdb/release.py new file mode 100644 index 00000000..2ef2d35b --- /dev/null +++ b/MySQLdb/release.py @@ -0,0 +1,3 @@ +__author__ = "Inada Naoki " +version_info = (2, 2, 0, "dev", 0) +__version__ = "2.2.0.dev0" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..0e3c3fac --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,63 @@ +[project] +name = "mysqlclient" +# version = "2.2.0dev0" +description = "Python interface to MySQL" +readme = "README.md" +requires-python = ">=3.8" +authors = [ + {name = "Inada Naoki", email = "songofacandy@gmail.com"} +] +license = {text = "GNU General Public License v2 (GPLv2)"} +keywords = ["MySQL"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Other Environment", + "License :: OSI Approved :: GNU General Public License (GPL)", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows :: Windows NT/2000", + "Operating System :: OS Independent", + "Operating System :: POSIX", + "Operating System :: POSIX :: Linux", + "Operating System :: Unix", + "Programming Language :: C", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Database", + "Topic :: Database :: Database Engines/Servers", +] +dynamic = ["version"] + +[project.urls] +Project = "https://github.com/PyMySQL/mysqlclient" +Documentation = "https://mysqlclient.readthedocs.io/" + +[build-system] +requires = ["setuptools>=61"] +build-backend = "setuptools.build_meta" + +[tool.setuptools] +py-modules = [ + "MySQLdb._exceptions", + "MySQLdb.connections", + "MySQLdb.converters", + "MySQLdb.cursors", + "MySQLdb.release", + "MySQLdb.times", + "MySQLdb.constants.CLIENT", + "MySQLdb.constants.CR", + "MySQLdb.constants.ER", + "MySQLdb.constants.FIELD_TYPE", + "MySQLdb.constants.FLAG", +] + +# [tool.setuptools.packages.find] +# namespaces = false +# include = ["pymysql*"] +# exclude = ["tests*", "pymysql.tests*"] + +[tool.setuptools.dynamic] +version = {attr = "MySQLdb.release.__version__"} diff --git a/setup.py b/setup.py index aa6c34fb..d06f95b6 100644 --- a/setup.py +++ b/setup.py @@ -1,22 +1,168 @@ #!/usr/bin/env python - import os +import subprocess +import sys import setuptools +from configparser import ConfigParser + + +release_info = {} +with open('MySQLdb/release.py', encoding="utf-8") as f: + exec(f.read(), None, release_info) + + +def find_package_name(): + """Get available pkg-config package name""" + packages = ["mysqlclient", "mariadb"] + for pkg in packages: + try: + cmd = f"pkg-config --exists {pkg}" + print(f"Trying {cmd}") + subprocess.check_call(cmd, shell=True) + except subprocess.CalledProcessError as err: + print(err) + else: + return pkg + raise Exception("Can not find valid pkg-config name.\nSpecify MYSQLCLIENT_CFLAGS and MYSQLCLIENT_LDFLAGS env vars manually") + + +def get_config_posix(options=None): + # allow a command-line option to override the base config file to permit + # a static build to be created via requirements.txt + # TODO: find a better way for + static = False + if "--static" in sys.argv: + static = True + sys.argv.remove("--static") + + ldflags = os.environ.get("MYSQLCLIENT_LDFLAGS") + cflags = os.environ.get("MYSQLCLIENT_CFLAGS") + + pkg_name = None + static_opt = " --static" if static else "" + if not (cflags and ldflags): + pkg_name = find_package_name() + if not cflags: + cflags = subprocess.check_output( + f"pkg-config{static_opt} --cflags {pkg_name}", encoding="utf-8", shell=True + ) + if not ldflags: + ldflags = subprocess.check_output( + f"pkg-config{static_opt} --libs {pkg_name}", encoding="utf-8", shell=True + ) + + cflags = cflags.split() + for f in cflags: + if f.startswith("-std="): + break + else: + cflags += ["-std=c99"] + + ldflags = ldflags.split() + + define_macros = [ + ("version_info", release_info["version_info"]), + ("__version__", release_info["__version__"]), + ] + + ext_options = dict( + extra_compile_args=cflags, + extra_link_args=ldflags, + define_macros=define_macros, + ) + # newer versions of gcc require libstdc++ if doing a static build + if static: + ext_options["language"] = "c++" + + print("Options for building extention module:") + for k, v in ext_options.items(): + print(f" {k}: {v}") + + return ext_options + + +def get_config_win32(options): + client = "mariadbclient" + connector = os.environ.get("MYSQLCLIENT_CONNECTOR", options.get("connector")) + if not connector: + connector = os.path.join( + os.environ["ProgramFiles"], "MariaDB", "MariaDB Connector C" + ) + + extra_objects = [] + + library_dirs = [ + os.path.join(connector, "lib", "mariadb"), + os.path.join(connector, "lib"), + ] + libraries = [ + "kernel32", + "advapi32", + "wsock32", + "shlwapi", + "Ws2_32", + "crypt32", + "secur32", + "bcrypt", + client, + ] + include_dirs = [ + os.path.join(connector, "include", "mariadb"), + os.path.join(connector, "include"), + ] + + extra_link_args = ["/MANIFEST"] + + define_macros = [ + ("version_info", release_info["version_info"]), + ("__version__", release_info["__version__"]), + ] + + ext_options = dict( + library_dirs=library_dirs, + libraries=libraries, + extra_link_args=extra_link_args, + include_dirs=include_dirs, + extra_objects=extra_objects, + define_macros=define_macros, + ) + return ext_options + + +def enabled(options, option): + value = options[option] + s = value.lower() + if s in ("yes", "true", "1", "y"): + return True + elif s in ("no", "false", "0", "n"): + return False + else: + raise ValueError(f"Unknown value {value} for option {option}") + + +def get_options(): + config = ConfigParser() + config.read(["site.cfg"]) + options = dict(config.items("options")) + options["static"] = enabled(options, "static") + return options + -if os.name == "posix": - from setup_posix import get_config -else: # assume windows - from setup_windows import get_config +if sys.platform == "win32": + ext_options = get_config_win32(get_options()) +else: + ext_options = get_config_posix(get_options()) -with open("README.md", encoding="utf-8") as f: - readme = f.read() +print("# Extention options") +for k, v in ext_options.items(): + print(f" {k}: {v}") -metadata, options = get_config() -metadata["ext_modules"] = [ - setuptools.Extension("MySQLdb._mysql", sources=["MySQLdb/_mysql.c"], **options) +ext_modules = [ + setuptools.Extension( + "MySQLdb._mysql", + sources=["MySQLdb/_mysql.c"], + **ext_options, + ) ] -metadata["long_description"] = readme -metadata["long_description_content_type"] = "text/markdown" -metadata["python_requires"] = ">=3.7" -setuptools.setup(**metadata) +setuptools.setup(ext_modules=ext_modules) diff --git a/setup_common.py b/setup_common.py deleted file mode 100644 index 53869aa2..00000000 --- a/setup_common.py +++ /dev/null @@ -1,37 +0,0 @@ -from configparser import ConfigParser - - -def get_metadata_and_options(): - config = ConfigParser() - config.read(["metadata.cfg", "site.cfg"]) - - metadata = dict(config.items("metadata")) - options = dict(config.items("options")) - - metadata["py_modules"] = list(filter(None, metadata["py_modules"].split("\n"))) - metadata["classifiers"] = list(filter(None, metadata["classifiers"].split("\n"))) - - return metadata, options - - -def enabled(options, option): - value = options[option] - s = value.lower() - if s in ("yes", "true", "1", "y"): - return True - elif s in ("no", "false", "0", "n"): - return False - else: - raise ValueError(f"Unknown value {value} for option {option}") - - -def create_release_file(metadata): - with open("MySQLdb/release.py", "w", encoding="utf-8") as rel: - rel.write( - """ -__author__ = "%(author)s <%(author_email)s>" -version_info = %(version_info)s -__version__ = "%(version)s" -""" - % metadata - ) diff --git a/setup_posix.py b/setup_posix.py deleted file mode 100644 index a03dd22c..00000000 --- a/setup_posix.py +++ /dev/null @@ -1,94 +0,0 @@ -import os -import sys -import subprocess - - -def find_package_name(): - """Get available pkg-config package name""" - packages = ["mysqlclient", "mariadb"] - for pkg in packages: - try: - cmd = f"pkg-config --exists {pkg}" - print(f"Trying {cmd}") - subprocess.check_call(cmd, shell=True) - except subprocess.CalledProcessError as err: - print(err) - else: - return pkg - raise Exception("Can not find valid pkg-config") - - -def get_config(): - from setup_common import get_metadata_and_options, enabled, create_release_file - - metadata, options = get_metadata_and_options() - - static = enabled(options, "static") - # allow a command-line option to override the base config file to permit - # a static build to be created via requirements.txt - # - if "--static" in sys.argv: - static = True - sys.argv.remove("--static") - - ldflags = os.environ.get("MYSQLCLIENT_LDFLAGS") - cflags = os.environ.get("MYSQLCLIENT_CFLAGS") - - pkg_name = None - static_opt = " --static" if static else "" - if not (cflags and ldflags): - pkg_name = find_package_name() - if not cflags: - cflags = subprocess.check_output( - f"pkg-config{static_opt} --cflags {pkg_name}", encoding="utf-8", shell=True - ) - if not ldflags: - ldflags = subprocess.check_output( - f"pkg-config{static_opt} --libs {pkg_name}", encoding="utf-8", shell=True - ) - - cflags = cflags.split() - for f in cflags: - if f.startswith("-std="): - break - else: - cflags += ["-std=c99"] - - ldflags = ldflags.split() - - define_macros = [ - ("version_info", metadata["version_info"]), - ("__version__", metadata["version"]), - ] - - # print(f"{cflags = }") - # print(f"{ldflags = }") - # print(f"{define_macros = }") - - ext_options = dict( - extra_compile_args=cflags, - extra_link_args=ldflags, - define_macros=define_macros, - ) - # newer versions of gcc require libstdc++ if doing a static build - if static: - ext_options["language"] = "c++" - - print("Options for building extention module:") - for k, v in ext_options.items(): - print(f" {k}: {v}") - - create_release_file(metadata) - del metadata["version_info"] - - return metadata, ext_options - - -if __name__ == "__main__": - from pprint import pprint - - metadata, config = get_config() - print("# Metadata") - pprint(metadata, sort_dicts=False, compact=True) - print("\n# Extention options") - pprint(config, sort_dicts=False, compact=True) diff --git a/setup_windows.py b/setup_windows.py deleted file mode 100644 index 5d8d7158..00000000 --- a/setup_windows.py +++ /dev/null @@ -1,64 +0,0 @@ -import os - - -def get_config(): - from setup_common import get_metadata_and_options, create_release_file - - metadata, options = get_metadata_and_options() - - client = "mariadbclient" - connector = os.environ.get("MYSQLCLIENT_CONNECTOR", options.get("connector")) - if not connector: - connector = os.path.join( - os.environ["ProgramFiles"], "MariaDB", "MariaDB Connector C" - ) - - extra_objects = [] - - library_dirs = [ - os.path.join(connector, "lib", "mariadb"), - os.path.join(connector, "lib"), - ] - libraries = [ - "kernel32", - "advapi32", - "wsock32", - "shlwapi", - "Ws2_32", - "crypt32", - "secur32", - "bcrypt", - client, - ] - include_dirs = [ - os.path.join(connector, "include", "mariadb"), - os.path.join(connector, "include"), - ] - - extra_link_args = ["/MANIFEST"] - - define_macros = [ - ("version_info", metadata["version_info"]), - ("__version__", metadata["version"]), - ] - create_release_file(metadata) - del metadata["version_info"] - ext_options = dict( - library_dirs=library_dirs, - libraries=libraries, - extra_link_args=extra_link_args, - include_dirs=include_dirs, - extra_objects=extra_objects, - define_macros=define_macros, - ) - return metadata, ext_options - - -if __name__ == "__main__": - from pprint import pprint - - metadata, config = get_config() - print("# Metadata") - pprint(metadata) - print("\n# Extention options") - pprint(config) From 595771f20a504b8b7c19f9f6d5df4ce1ed758cc0 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Mon, 15 May 2023 00:58:23 +0900 Subject: [PATCH 2/8] black --- MySQLdb/__init__.py | 1 + MySQLdb/release.py | 2 +- setup.py | 8 +++++--- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/MySQLdb/__init__.py b/MySQLdb/__init__.py index 3be16f1f..c8d1b2fb 100644 --- a/MySQLdb/__init__.py +++ b/MySQLdb/__init__.py @@ -15,6 +15,7 @@ from .release import version_info from . import _mysql + if version_info == _mysql.version_info: raise ImportError( "this is MySQLdb version {}, but _mysql is version {!r}\n_mysql: {!r}".format( diff --git a/MySQLdb/release.py b/MySQLdb/release.py index 2ef2d35b..55359628 100644 --- a/MySQLdb/release.py +++ b/MySQLdb/release.py @@ -1,3 +1,3 @@ __author__ = "Inada Naoki " version_info = (2, 2, 0, "dev", 0) -__version__ = "2.2.0.dev0" +__version__ = "2.2.0.dev0" diff --git a/setup.py b/setup.py index d06f95b6..a39d2d4b 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ release_info = {} -with open('MySQLdb/release.py', encoding="utf-8") as f: +with open("MySQLdb/release.py", encoding="utf-8") as f: exec(f.read(), None, release_info) @@ -24,13 +24,15 @@ def find_package_name(): print(err) else: return pkg - raise Exception("Can not find valid pkg-config name.\nSpecify MYSQLCLIENT_CFLAGS and MYSQLCLIENT_LDFLAGS env vars manually") + raise Exception( + "Can not find valid pkg-config name.\nSpecify MYSQLCLIENT_CFLAGS and MYSQLCLIENT_LDFLAGS env vars manually" + ) def get_config_posix(options=None): # allow a command-line option to override the base config file to permit # a static build to be created via requirements.txt - # TODO: find a better way for + # TODO: find a better way for static = False if "--static" in sys.argv: static = True From 5d4e2c50207680fbec7a94a4151e9c00120417c5 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Mon, 15 May 2023 01:00:55 +0900 Subject: [PATCH 3/8] Split long line --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index a39d2d4b..368617ef 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,8 @@ def find_package_name(): else: return pkg raise Exception( - "Can not find valid pkg-config name.\nSpecify MYSQLCLIENT_CFLAGS and MYSQLCLIENT_LDFLAGS env vars manually" + "Can not find valid pkg-config name.\n" + "Specify MYSQLCLIENT_CFLAGS and MYSQLCLIENT_LDFLAGS env vars manually" ) From 263fd49daf1c865ddc848dbf7d25aa8051dda856 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Mon, 15 May 2023 01:09:49 +0900 Subject: [PATCH 4/8] Add `make check` --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index 783d1919..850e296e 100644 --- a/Makefile +++ b/Makefile @@ -14,3 +14,8 @@ clean: find . -name '*.pyc' -delete find . -name '__pycache__' -delete rm -rf build + +.PHONY: check +check: + ruff . + black *.py MySQLdb From 8a2c3a0b3a70cdf53fd437866b74f0624ac94217 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Mon, 15 May 2023 01:13:26 +0900 Subject: [PATCH 5/8] Remove metadata.cfg --- metadata.cfg | 41 ----------------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 metadata.cfg diff --git a/metadata.cfg b/metadata.cfg deleted file mode 100644 index 38deff56..00000000 --- a/metadata.cfg +++ /dev/null @@ -1,41 +0,0 @@ -[metadata] -name: mysqlclient -version: 2.2.0dev0 -version_info: (2,2,0,'dev',0) -description: Python interface to MySQL -author: Inada Naoki -author_email: songofacandy@gmail.com -license: GPL -platforms: ALL -url: https://github.com/PyMySQL/mysqlclient -classifiers: - Development Status :: 5 - Production/Stable - Environment :: Other Environment - License :: OSI Approved :: GNU General Public License (GPL) - Operating System :: MacOS :: MacOS X - Operating System :: Microsoft :: Windows :: Windows NT/2000 - Operating System :: OS Independent - Operating System :: POSIX - Operating System :: POSIX :: Linux - Operating System :: Unix - Programming Language :: C - Programming Language :: Python - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Topic :: Database - Topic :: Database :: Database Engines/Servers -py_modules: - MySQLdb._exceptions - MySQLdb.connections - MySQLdb.converters - MySQLdb.cursors - MySQLdb.release - MySQLdb.times - MySQLdb.constants.CLIENT - MySQLdb.constants.CR - MySQLdb.constants.ER - MySQLdb.constants.FIELD_TYPE - MySQLdb.constants.FLAG From 75de28759d35604d194916a26979210fd356f87b Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Mon, 15 May 2023 01:22:09 +0900 Subject: [PATCH 6/8] fixup --- MySQLdb/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MySQLdb/__init__.py b/MySQLdb/__init__.py index c8d1b2fb..153bbdfe 100644 --- a/MySQLdb/__init__.py +++ b/MySQLdb/__init__.py @@ -16,11 +16,11 @@ from .release import version_info from . import _mysql -if version_info == _mysql.version_info: +if version_info != _mysql.version_info: raise ImportError( - "this is MySQLdb version {}, but _mysql is version {!r}\n_mysql: {!r}".format( - version_info, _mysql.version_info, _mysql.__file__ - ) + f"this is MySQLdb version {version_info}, " + f"but _mysql is version {_mysql.version_info!r}\n" + f"_mysql: {_mysql.__file__!r}" ) From 5d49016bcf7c49ecf2d353847c49b48ebadc61a3 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Mon, 15 May 2023 11:20:05 +0900 Subject: [PATCH 7/8] Use auto find of setuptools --- pyproject.toml | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0e3c3fac..907bf55f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,25 +39,10 @@ Documentation = "https://mysqlclient.readthedocs.io/" requires = ["setuptools>=61"] build-backend = "setuptools.build_meta" -[tool.setuptools] -py-modules = [ - "MySQLdb._exceptions", - "MySQLdb.connections", - "MySQLdb.converters", - "MySQLdb.cursors", - "MySQLdb.release", - "MySQLdb.times", - "MySQLdb.constants.CLIENT", - "MySQLdb.constants.CR", - "MySQLdb.constants.ER", - "MySQLdb.constants.FIELD_TYPE", - "MySQLdb.constants.FLAG", -] - -# [tool.setuptools.packages.find] -# namespaces = false -# include = ["pymysql*"] -# exclude = ["tests*", "pymysql.tests*"] +[tool.setuptools.packages.find] +namespaces = false +include = ["MySQLdb*"] +exclude = ["tests*", "pymysql.tests*"] [tool.setuptools.dynamic] version = {attr = "MySQLdb.release.__version__"} From 6588353dcf82145745f4b05288b0d1ae915f9c62 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Mon, 15 May 2023 11:23:27 +0900 Subject: [PATCH 8/8] Update MANIFEST.in --- MANIFEST.in | 5 ----- 1 file changed, 5 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index 07563caf..58a996de 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,12 +1,7 @@ recursive-include doc *.rst recursive-include tests *.py include doc/conf.py -include MANIFEST.in include HISTORY.rst include README.md include LICENSE -include metadata.cfg include site.cfg -include setup_common.py -include setup_posix.py -include setup_windows.py