Copilot commented on code in PR #1264:
URL: 
https://github.com/apache/cassandra-python-driver/pull/1264#discussion_r2686415273


##########
setup.py:
##########
@@ -163,50 +52,8 @@ def eval_env_var_as_array(varname):
 
=================================================================================
 """
 
-is_pypy = "PyPy" in sys.version
-if is_pypy:
-    sys.stderr.write(pypy_unsupported_msg)
-
-is_supported_platform = sys.platform != "cli" and not 
sys.platform.startswith("java")
-is_supported_arch = sys.byteorder != "big"
-if not is_supported_platform:
-    sys.stderr.write(platform_unsupported_msg)
-elif not is_supported_arch:
-    sys.stderr.write(arch_unsupported_msg)
-
-try_extensions = "--no-extensions" not in sys.argv and is_supported_platform 
and is_supported_arch and not os.environ.get('CASS_DRIVER_NO_EXTENSIONS')
-try_murmur3 = try_extensions and "--no-murmur3" not in sys.argv
-try_libev = try_extensions and "--no-libev" not in sys.argv and not is_pypy 
and not os.environ.get('CASS_DRIVER_NO_LIBEV')
-try_cython = try_extensions and "--no-cython" not in sys.argv and not is_pypy 
and not os.environ.get('CASS_DRIVER_NO_CYTHON')
-try_cython &= 'egg_info' not in sys.argv  # bypass setup_requires for pip 
egg_info calls, which will never have --install-option"--no-cython" coming fomr 
pip
-
-sys.argv = [a for a in sys.argv if a not in ("--no-murmur3", "--no-libev", 
"--no-cython", "--no-extensions")]
-
-build_concurrency = int(os.environ.get('CASS_DRIVER_BUILD_CONCURRENCY', '0'))
-
-
-class NoPatchExtension(Extension):
-
-    # Older versions of setuptools.extension has a static flag which is set 
False before our
-    # setup_requires lands Cython. It causes our *.pyx sources to be renamed 
to *.c in
-    # the initializer.
-    # The other workaround would be to manually generate sources, but that 
bypasses a lot
-    # of the niceness cythonize embodies (setup build dir, conditional build, 
etc).
-    # Newer setuptools does not have this problem because it checks for cython 
dynamically.
-    # 
https://bitbucket.org/pypa/setuptools/commits/714c3144e08fd01a9f61d1c88411e76d2538b2e4
-
-    def __init__(self, *args, **kwargs):
-        # bypass the patched init if possible
-        if Extension.__bases__:
-            base, = Extension.__bases__
-            base.__init__(self, *args, **kwargs)
-        else:
-            Extension.__init__(self, *args, **kwargs)
-
-
-class build_extensions(build_ext):
-
-    error_message = """
+windows_compmile_error = \

Review Comment:
   Spelling error: "compmile" should be "compile".
   ```suggestion
   windows_compile_error = \
   ```



##########
pyproject.toml:
##########
@@ -0,0 +1,57 @@
+[build-system]
+build-backend = "setuptools.build_meta"
+requires = ["setuptools", "Cython>=3.0", "toml", "cassandra-driver"]

Review Comment:
   Critical circular dependency issue: The build-system requires 
"cassandra-driver" as a build dependency, but this is the package being built. 
This will cause build failures as pip cannot install cassandra-driver before 
building cassandra-driver. The "cassandra-driver" entry should be removed from 
the requires list.
   ```suggestion
   requires = ["setuptools", "Cython>=3.0", "toml"]
   ```



##########
pyproject.toml:
##########
@@ -0,0 +1,57 @@
+[build-system]
+build-backend = "setuptools.build_meta"
+requires = ["setuptools", "Cython>=3.0", "toml", "cassandra-driver"]
+
+[project]
+name = "cassandra-driver"
+description = "Apache Cassandra Python Driver"
+dependencies = ['geomet>=1.1']
+readme = "README.rst"
+authors = [{name = "DataStax"}]
+license = "Apache-2.0"
+license-files = ["LICENSE"]
+keywords = ["cassandra","cql","orm","dse","graph"]
+classifiers = [
+    "Development Status :: 5 - Production/Stable",
+    "Intended Audience :: Developers",
+    "Natural Language :: English",
+    "Operating System :: OS Independent",
+    "License :: OSI Approved :: Apache Software License",
+    "Programming Language :: Python",
+    "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",
+    "Programming Language :: Python :: Implementation :: CPython",
+    "Programming Language :: Python :: Implementation :: PyPy",
+    "Topic :: Software Development :: Libraries :: Python Modules"
+]
+dynamic = ["version"]
+
+[project.optional-dependencies]
+graph = ["gremlinpython==3.4.6"]
+cle = ["cryptography>=42.0"]
+test = ["pytest", "PyYAML", "pytz"]
+
+[project.urls]
+homepage = "https://github.com/apache/cassandra-python-driver/";
+documentation = "https://docs.datastax.com/en/developer/python-driver/latest/";
+source = "https://github.com/apache/cassandra-python-driver/";
+issues = 
"https://issues.apache.org/jira/issues/?jql=project%20%3D%20CASSPYTHON%20ORDER%20BY%20key%20DESC";
+changelog = 
"https://github.com/apache/cassandra-python-driver/blob/trunk/CHANGELOG.rst";
+
+[tool.setuptools.packages.find]
+include = ['cassandra', 'cassandra.io', 'cassandra.cqlengine', 
'cassandra.graph',
+'cassandra.datastax', 'cassandra.datastax.insights', 
'cassandra.datastax.graph',
+'cassandra.datastax.graph.fluent', 'cassandra.datastax.cloud',
+"cassandra.column_encryption"]
+
+[tool.cassandra-driver]
+build-extensions = true
+build-murmur3-extension = true
+build-libev-extension = true
+build-cython-extensions = true
+libev-includes = []
+libev-libs = []

Review Comment:
   The pyproject.toml configuration uses "libev-libs" (line 56) but this should 
more accurately be named "libev-libdirs" to match the semantics of library 
directories, consistent with the `library_dirs` parameter used in the Extension 
definition. While not technically incorrect, this naming could be confusing as 
"libs" might suggest library names rather than library directories.
   ```suggestion
   libev-libdirs = []
   ```



##########
setup.py:
##########
@@ -254,193 +104,78 @@ class build_extensions(build_ext):
     $ brew install libev
 
 ===============================================================================
-    """
-
-    def run(self):
-        try:
-            self._setup_extensions()
-            build_ext.run(self)
-        except DistutilsPlatformError as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            warnings.warn(self.error_message % "C extensions.")
-
-    def build_extensions(self):
-        if build_concurrency > 1:
-            self.check_extensions_list(self.extensions)
-
-            import multiprocessing.pool
-            
multiprocessing.pool.ThreadPool(processes=build_concurrency).map(self.build_extension,
 self.extensions)
-        else:
-            build_ext.build_extensions(self)
-
-    def build_extension(self, ext):
-        try:
-            build_ext.build_extension(self, ext)
-        except (CCompilerError, DistutilsExecError,
-                DistutilsPlatformError, IOError) as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            name = "The %s extension" % (ext.name,)
-            warnings.warn(self.error_message % (name,))
-
-    def _setup_extensions(self):
-        # We defer extension setup until this command to leveraage 
'setup_requires' pulling in Cython before we
-        # attempt to import anything
-        self.extensions = []
-
-        if try_murmur3:
-            self.extensions.append(murmur3_ext)
-
-        if try_libev:
-            sys.stderr.write("Appending libev extension %s" % libev_ext)
-            self.extensions.append(libev_ext)
-
-        if try_cython:
-            try:
-                from Cython.Build import cythonize
-                cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
-                                     'pool', 'protocol', 'query', 'util']
-                compile_args = [] if is_windows else ['-Wno-unused-function']
-                self.extensions.extend(cythonize(
-                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
-                               extra_compile_args=compile_args)
-                        for m in cython_candidates],
-                    nthreads=build_concurrency,
-                    exclude_failures=True))
-
-                self.extensions.extend(cythonize(NoPatchExtension("*", 
["cassandra/*.pyx"], extra_compile_args=compile_args),
-                                                 nthreads=build_concurrency))
-            except Exception:
-                sys.stderr.write("Failed to cythonize one or more modules. 
These will not be compiled as extensions (optional).\n")
-
-
-def pre_build_check():
-    """
-    Try to verify build tools
-    """
-    if os.environ.get('CASS_DRIVER_NO_PRE_BUILD_CHECK'):
-        return True
-
-    try:
-        from distutils.ccompiler import new_compiler
-        from distutils.sysconfig import customize_compiler
-        from distutils.dist import Distribution
-
-        # base build_ext just to emulate compiler option setup
-        be = build_ext(Distribution())
-        be.initialize_options()
-        be.finalize_options()
+"""
 
-        # First, make sure we have a Python include directory
-        have_python_include = any(os.path.isfile(os.path.join(p, 'Python.h')) 
for p in be.include_dirs)
-        if not have_python_include:
-            sys.stderr.write("Did not find 'Python.h' in %s.\n" % 
(be.include_dirs,))
-            return False
+# ========================== A few upfront checks ==========================
+if is_pypy:
+    sys.stderr.write(pypy_unsupported_msg)
+if not is_supported_platform:
+    sys.stderr.write(platform_unsupported_msg)
+elif not is_supported_arch:
+    sys.stderr.write(arch_unsupported_msg)
 
-        compiler = new_compiler(compiler=be.compiler)
-        customize_compiler(compiler)
+# ========================== Extensions ==========================
+pyproject_toml = Path(__file__).parent / "pyproject.toml"
+pyproject_data = toml.load(pyproject_toml)
+driver_project_data = pyproject_data["tool"]["cassandra-driver"]
 
-        try:
-            # We must be able to initialize the compiler if it has that method
-            if hasattr(compiler, "initialize"):
-                compiler.initialize()
-        except OSError:
-            return False
+murmur3_ext = Extension('cassandra.cmurmur3', sources=['cassandra/cmurmur3.c'])
 
-        executables = []
-        if compiler.compiler_type in ('unix', 'cygwin'):
-            executables = [compiler.executables[exe][0] for exe in 
('compiler_so', 'linker_so')]
-        elif compiler.compiler_type == 'nt':
-            executables = [getattr(compiler, exe) for exe in ('cc', 'linker')]
+DEFAULT_LIBEV_INCLUDES = ['/usr/include/libev', '/usr/local/include', 
'/opt/local/include', '/usr/include']
+DEFAULT_LIBEV_LIBS = ['/usr/local/lib', '/opt/local/lib', '/usr/lib64']
+libev_includes = driver_project_data["libev-includes"] or 
DEFAULT_LIBEV_INCLUDES
+libev_libs = driver_project_data["libev-libs"] or DEFAULT_LIBEV_LIBS
+if is_macos:
+    libev_includes.extend(['/opt/homebrew/include', 
os.path.expanduser('~/homebrew/include')])
+    libev_libs.extend(['/opt/homebrew/lib'])
+libev_ext = Extension('cassandra.io.libevwrapper',
+                      sources=['cassandra/io/libevwrapper.c'],
+                      include_dirs=libev_includes,
+                      libraries=['ev'],
+                      library_dirs=libev_libs)
 
-        if executables:
-            from distutils.spawn import find_executable
-            for exe in executables:
-                if not find_executable(exe):
-                    sys.stderr.write("Failed to find %s for compiler type 
%s.\n" % (exe, compiler.compiler_type))
-                    return False
+try_extensions = driver_project_data["build-extensions"] and 
is_supported_platform and is_supported_arch
+try_murmur3 = driver_project_data["build-murmur3-extension"]
+try_libev = driver_project_data["build-libev-extension"]
+try_cython = driver_project_data["build-cython-extensions"] and not is_pypy
 
-    except Exception as exc:
-        sys.stderr.write('%s\n' % str(exc))
-        sys.stderr.write("Failed pre-build check. Attempting anyway.\n")
+build_concurrency = driver_project_data["build-concurrency"]
 
-    # if we are unable to positively id the compiler type, or one of these 
assumptions fails,
-    # just proceed as we would have without the check
-    return True
+def build_extension_list():
 
+    rv = []
 
-def run_setup(extensions):
+    if try_murmur3:
+        sys.stderr.write("Appending murmur extension %s\n" % murmur3_ext)
+        rv.append(murmur3_ext)
 
-    kw = {'cmdclass': {'doc': DocCommand}}
-    kw['cmdclass']['build_ext'] = build_extensions
-    kw['ext_modules'] = [Extension('DUMMY', [])]  # dummy extension makes sure 
build_ext is called for install
+    if try_libev:
+        sys.stderr.write("Appending libev extension %s\n" % libev_ext)
+        rv.append(libev_ext)
 
     if try_cython:
-        # precheck compiler before adding to setup_requires
-        # we don't actually negate try_cython because:
-        # 1.) build_ext eats errors at compile time, letting the install 
complete while producing useful feedback
-        # 2.) there could be a case where the python environment has cython 
installed but the system doesn't have build tools
-        if pre_build_check():
-            cython_dep = 'Cython>=3.0'
-            user_specified_cython_version = 
os.environ.get('CASS_DRIVER_ALLOWED_CYTHON_VERSION')
-            if user_specified_cython_version is not None:
-                cython_dep = 'Cython==%s' % (user_specified_cython_version,)
-            kw['setup_requires'] = [cython_dep]
-        else:
-            sys.stderr.write("Bypassing Cython setup requirement\n")
-
-    dependencies = ['geomet>=1.1']
-
-    _EXTRAS_REQUIRE = {
-        'graph': ['gremlinpython==3.4.6'],
-        'cle': ['cryptography>=42.0']
-    }
-
-    setup(
-        name='cassandra-driver',
-        version=__version__,
-        description='Apache Cassandra Python Driver',
-        long_description=long_description,
-        long_description_content_type='text/x-rst',
-        url='http://github.com/datastax/python-driver',
-        project_urls={
-            'Documentation': 
'https://docs.datastax.com/en/developer/python-driver/latest/',
-            'Source': 'https://github.com/datastax/python-driver/',
-            'Issues': 'https://datastax-oss.atlassian.net/browse/PYTHON',
-        },
-        author='DataStax',
-        packages=[
-            'cassandra', 'cassandra.io', 'cassandra.cqlengine', 
'cassandra.graph',
-            'cassandra.datastax', 'cassandra.datastax.insights', 
'cassandra.datastax.graph',
-            'cassandra.datastax.graph.fluent', 'cassandra.datastax.cloud',
-            "cassandra.column_encryption"
-        ],
-        keywords='cassandra,cql,orm,dse,graph',
-        include_package_data=True,
-        install_requires=dependencies,
-        extras_require=_EXTRAS_REQUIRE,
-        tests_require=['pytest', 'PyYAML', 'pytz'],
-        classifiers=[
-            'Development Status :: 5 - Production/Stable',
-            'Intended Audience :: Developers',
-            'License :: OSI Approved :: Apache Software License',
-            'Natural Language :: English',
-            'Operating System :: OS Independent',
-            'Programming Language :: Python',
-            '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',
-            'Programming Language :: Python :: Implementation :: CPython',
-            'Programming Language :: Python :: Implementation :: PyPy',
-            'Topic :: Software Development :: Libraries :: Python Modules'
-        ],
-        **kw)
-
-
-run_setup(None)
-
-if has_cqlengine:
-    warnings.warn("\n#######\n'cqlengine' package is present on path: %s\n"
-                  "cqlengine is now an integrated sub-package of this 
driver.\n"
-                  "It is recommended to remove this package to reduce the 
chance for conflicting usage" % cqlengine.__file__)
+        sys.stderr.write("Trying Cython builds in order to append Cython 
extensions\n")
+        try:
+            from Cython.Build import cythonize
+            cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
+                                 'pool', 'protocol', 'query', 'util']
+            compile_args = [] if is_windows else ['-Wno-unused-function']
+            rv.extend(cythonize(
+                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
+                                extra_compile_args=compile_args)
+                        for m in cython_candidates],
+                    nthreads=build_concurrency,
+                    exclude_failures=True))
+
+            rv.extend(cythonize(Extension("*", ["cassandra/*.pyx"], 
extra_compile_args=compile_args),
+                                          nthreads=build_concurrency))
+        except Exception:
+            sys.stderr.write("Failed to cythonize one or more modules. These 
will not be compiled as extensions (optional).\n")
+    
+    return rv
+
+# ========================== And finally setup() itself 
==========================
+setup(
+    version = __version__,
+    ext_modules = build_extension_list()
+)

Review Comment:
   The refactored code removes the `pre_build_check` function that verified the 
availability of build tools (compiler, Python.h headers, etc.) before 
attempting to build extensions. This function provided early feedback to users 
about missing build dependencies. Without this check, users may encounter less 
clear error messages during the build process. Consider whether this 
verification is still valuable or if the modern build system handles this 
adequately.



##########
setup.py:
##########
@@ -254,193 +104,78 @@ class build_extensions(build_ext):
     $ brew install libev
 
 ===============================================================================
-    """
-
-    def run(self):
-        try:
-            self._setup_extensions()
-            build_ext.run(self)
-        except DistutilsPlatformError as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            warnings.warn(self.error_message % "C extensions.")
-
-    def build_extensions(self):
-        if build_concurrency > 1:
-            self.check_extensions_list(self.extensions)
-
-            import multiprocessing.pool
-            
multiprocessing.pool.ThreadPool(processes=build_concurrency).map(self.build_extension,
 self.extensions)
-        else:
-            build_ext.build_extensions(self)
-
-    def build_extension(self, ext):
-        try:
-            build_ext.build_extension(self, ext)
-        except (CCompilerError, DistutilsExecError,
-                DistutilsPlatformError, IOError) as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            name = "The %s extension" % (ext.name,)
-            warnings.warn(self.error_message % (name,))
-
-    def _setup_extensions(self):
-        # We defer extension setup until this command to leveraage 
'setup_requires' pulling in Cython before we
-        # attempt to import anything
-        self.extensions = []
-
-        if try_murmur3:
-            self.extensions.append(murmur3_ext)
-
-        if try_libev:
-            sys.stderr.write("Appending libev extension %s" % libev_ext)
-            self.extensions.append(libev_ext)
-
-        if try_cython:
-            try:
-                from Cython.Build import cythonize
-                cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
-                                     'pool', 'protocol', 'query', 'util']
-                compile_args = [] if is_windows else ['-Wno-unused-function']
-                self.extensions.extend(cythonize(
-                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
-                               extra_compile_args=compile_args)
-                        for m in cython_candidates],
-                    nthreads=build_concurrency,
-                    exclude_failures=True))
-
-                self.extensions.extend(cythonize(NoPatchExtension("*", 
["cassandra/*.pyx"], extra_compile_args=compile_args),
-                                                 nthreads=build_concurrency))
-            except Exception:
-                sys.stderr.write("Failed to cythonize one or more modules. 
These will not be compiled as extensions (optional).\n")
-
-
-def pre_build_check():
-    """
-    Try to verify build tools
-    """
-    if os.environ.get('CASS_DRIVER_NO_PRE_BUILD_CHECK'):
-        return True
-
-    try:
-        from distutils.ccompiler import new_compiler
-        from distutils.sysconfig import customize_compiler
-        from distutils.dist import Distribution
-
-        # base build_ext just to emulate compiler option setup
-        be = build_ext(Distribution())
-        be.initialize_options()
-        be.finalize_options()
+"""
 
-        # First, make sure we have a Python include directory
-        have_python_include = any(os.path.isfile(os.path.join(p, 'Python.h')) 
for p in be.include_dirs)
-        if not have_python_include:
-            sys.stderr.write("Did not find 'Python.h' in %s.\n" % 
(be.include_dirs,))
-            return False
+# ========================== A few upfront checks ==========================
+if is_pypy:
+    sys.stderr.write(pypy_unsupported_msg)
+if not is_supported_platform:
+    sys.stderr.write(platform_unsupported_msg)
+elif not is_supported_arch:
+    sys.stderr.write(arch_unsupported_msg)
 
-        compiler = new_compiler(compiler=be.compiler)
-        customize_compiler(compiler)
+# ========================== Extensions ==========================
+pyproject_toml = Path(__file__).parent / "pyproject.toml"
+pyproject_data = toml.load(pyproject_toml)
+driver_project_data = pyproject_data["tool"]["cassandra-driver"]
 
-        try:
-            # We must be able to initialize the compiler if it has that method
-            if hasattr(compiler, "initialize"):
-                compiler.initialize()
-        except OSError:
-            return False
+murmur3_ext = Extension('cassandra.cmurmur3', sources=['cassandra/cmurmur3.c'])
 
-        executables = []
-        if compiler.compiler_type in ('unix', 'cygwin'):
-            executables = [compiler.executables[exe][0] for exe in 
('compiler_so', 'linker_so')]
-        elif compiler.compiler_type == 'nt':
-            executables = [getattr(compiler, exe) for exe in ('cc', 'linker')]
+DEFAULT_LIBEV_INCLUDES = ['/usr/include/libev', '/usr/local/include', 
'/opt/local/include', '/usr/include']
+DEFAULT_LIBEV_LIBS = ['/usr/local/lib', '/opt/local/lib', '/usr/lib64']
+libev_includes = driver_project_data["libev-includes"] or 
DEFAULT_LIBEV_INCLUDES
+libev_libs = driver_project_data["libev-libs"] or DEFAULT_LIBEV_LIBS
+if is_macos:
+    libev_includes.extend(['/opt/homebrew/include', 
os.path.expanduser('~/homebrew/include')])
+    libev_libs.extend(['/opt/homebrew/lib'])
+libev_ext = Extension('cassandra.io.libevwrapper',
+                      sources=['cassandra/io/libevwrapper.c'],
+                      include_dirs=libev_includes,
+                      libraries=['ev'],
+                      library_dirs=libev_libs)
 
-        if executables:
-            from distutils.spawn import find_executable
-            for exe in executables:
-                if not find_executable(exe):
-                    sys.stderr.write("Failed to find %s for compiler type 
%s.\n" % (exe, compiler.compiler_type))
-                    return False
+try_extensions = driver_project_data["build-extensions"] and 
is_supported_platform and is_supported_arch
+try_murmur3 = driver_project_data["build-murmur3-extension"]
+try_libev = driver_project_data["build-libev-extension"]
+try_cython = driver_project_data["build-cython-extensions"] and not is_pypy

Review Comment:
   The logic for `try_murmur3` and `try_libev` does not respect the 
`try_extensions` flag. These extensions could be built even when 
`try_extensions` is False (e.g., on unsupported platforms). These variables 
should be combined with `try_extensions` similar to how it was done in the 
original code. For example: `try_murmur3 = try_extensions and 
driver_project_data["build-murmur3-extension"]`.
   ```suggestion
   try_murmur3 = try_extensions and 
driver_project_data["build-murmur3-extension"]
   try_libev = try_extensions and driver_project_data["build-libev-extension"]
   try_cython = try_extensions and 
driver_project_data["build-cython-extensions"] and not is_pypy
   ```



##########
setup.py:
##########
@@ -254,193 +104,78 @@ class build_extensions(build_ext):
     $ brew install libev
 
 ===============================================================================
-    """
-
-    def run(self):
-        try:
-            self._setup_extensions()
-            build_ext.run(self)
-        except DistutilsPlatformError as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            warnings.warn(self.error_message % "C extensions.")
-
-    def build_extensions(self):
-        if build_concurrency > 1:
-            self.check_extensions_list(self.extensions)
-
-            import multiprocessing.pool
-            
multiprocessing.pool.ThreadPool(processes=build_concurrency).map(self.build_extension,
 self.extensions)
-        else:
-            build_ext.build_extensions(self)
-
-    def build_extension(self, ext):
-        try:
-            build_ext.build_extension(self, ext)
-        except (CCompilerError, DistutilsExecError,
-                DistutilsPlatformError, IOError) as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            name = "The %s extension" % (ext.name,)
-            warnings.warn(self.error_message % (name,))
-
-    def _setup_extensions(self):
-        # We defer extension setup until this command to leveraage 
'setup_requires' pulling in Cython before we
-        # attempt to import anything
-        self.extensions = []
-
-        if try_murmur3:
-            self.extensions.append(murmur3_ext)
-
-        if try_libev:
-            sys.stderr.write("Appending libev extension %s" % libev_ext)
-            self.extensions.append(libev_ext)
-
-        if try_cython:
-            try:
-                from Cython.Build import cythonize
-                cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
-                                     'pool', 'protocol', 'query', 'util']
-                compile_args = [] if is_windows else ['-Wno-unused-function']
-                self.extensions.extend(cythonize(
-                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
-                               extra_compile_args=compile_args)
-                        for m in cython_candidates],
-                    nthreads=build_concurrency,
-                    exclude_failures=True))
-
-                self.extensions.extend(cythonize(NoPatchExtension("*", 
["cassandra/*.pyx"], extra_compile_args=compile_args),
-                                                 nthreads=build_concurrency))
-            except Exception:
-                sys.stderr.write("Failed to cythonize one or more modules. 
These will not be compiled as extensions (optional).\n")
-
-
-def pre_build_check():
-    """
-    Try to verify build tools
-    """
-    if os.environ.get('CASS_DRIVER_NO_PRE_BUILD_CHECK'):
-        return True
-
-    try:
-        from distutils.ccompiler import new_compiler
-        from distutils.sysconfig import customize_compiler
-        from distutils.dist import Distribution
-
-        # base build_ext just to emulate compiler option setup
-        be = build_ext(Distribution())
-        be.initialize_options()
-        be.finalize_options()
+"""
 
-        # First, make sure we have a Python include directory
-        have_python_include = any(os.path.isfile(os.path.join(p, 'Python.h')) 
for p in be.include_dirs)
-        if not have_python_include:
-            sys.stderr.write("Did not find 'Python.h' in %s.\n" % 
(be.include_dirs,))
-            return False
+# ========================== A few upfront checks ==========================
+if is_pypy:
+    sys.stderr.write(pypy_unsupported_msg)
+if not is_supported_platform:
+    sys.stderr.write(platform_unsupported_msg)
+elif not is_supported_arch:
+    sys.stderr.write(arch_unsupported_msg)
 
-        compiler = new_compiler(compiler=be.compiler)
-        customize_compiler(compiler)
+# ========================== Extensions ==========================
+pyproject_toml = Path(__file__).parent / "pyproject.toml"
+pyproject_data = toml.load(pyproject_toml)
+driver_project_data = pyproject_data["tool"]["cassandra-driver"]
 
-        try:
-            # We must be able to initialize the compiler if it has that method
-            if hasattr(compiler, "initialize"):
-                compiler.initialize()
-        except OSError:
-            return False
+murmur3_ext = Extension('cassandra.cmurmur3', sources=['cassandra/cmurmur3.c'])
 
-        executables = []
-        if compiler.compiler_type in ('unix', 'cygwin'):
-            executables = [compiler.executables[exe][0] for exe in 
('compiler_so', 'linker_so')]
-        elif compiler.compiler_type == 'nt':
-            executables = [getattr(compiler, exe) for exe in ('cc', 'linker')]
+DEFAULT_LIBEV_INCLUDES = ['/usr/include/libev', '/usr/local/include', 
'/opt/local/include', '/usr/include']
+DEFAULT_LIBEV_LIBS = ['/usr/local/lib', '/opt/local/lib', '/usr/lib64']
+libev_includes = driver_project_data["libev-includes"] or 
DEFAULT_LIBEV_INCLUDES
+libev_libs = driver_project_data["libev-libs"] or DEFAULT_LIBEV_LIBS
+if is_macos:
+    libev_includes.extend(['/opt/homebrew/include', 
os.path.expanduser('~/homebrew/include')])
+    libev_libs.extend(['/opt/homebrew/lib'])
+libev_ext = Extension('cassandra.io.libevwrapper',
+                      sources=['cassandra/io/libevwrapper.c'],
+                      include_dirs=libev_includes,
+                      libraries=['ev'],
+                      library_dirs=libev_libs)
 
-        if executables:
-            from distutils.spawn import find_executable
-            for exe in executables:
-                if not find_executable(exe):
-                    sys.stderr.write("Failed to find %s for compiler type 
%s.\n" % (exe, compiler.compiler_type))
-                    return False
+try_extensions = driver_project_data["build-extensions"] and 
is_supported_platform and is_supported_arch
+try_murmur3 = driver_project_data["build-murmur3-extension"]
+try_libev = driver_project_data["build-libev-extension"]
+try_cython = driver_project_data["build-cython-extensions"] and not is_pypy
 

Review Comment:
   The refactored code removes support for command-line arguments that were 
present in the original: `--no-murmur3`, `--no-libev`, `--no-cython`, and 
`--no-extensions`. This is a breaking change that could affect users and build 
scripts that relied on these flags to control extension building. Consider 
either maintaining backward compatibility or documenting this breaking change 
clearly.
   ```suggestion
   
   # Backwards-compatible support for legacy command-line flags that used to
   # control extension building. These flags override the configuration in
   # pyproject.toml and are removed from sys.argv so that setuptools and other
   # tooling do not see them.
   legacy_flag_map = {
       "--no-murmur3": "murmur3",
       "--no-libev": "libev",
       "--no-cython": "cython",
       "--no-extensions": "all",
   }
   
   cleaned_argv = []
   for _arg in sys.argv:
       flag_type = legacy_flag_map.get(_arg)
       if flag_type is None:
           cleaned_argv.append(_arg)
           continue
   
       if flag_type == "murmur3":
           try_murmur3 = False
       elif flag_type == "libev":
           try_libev = False
       elif flag_type == "cython":
           try_cython = False
       elif flag_type == "all":
           try_murmur3 = False
           try_libev = False
           try_cython = False
   
   sys.argv = cleaned_argv
   ```



##########
pyproject.toml:
##########
@@ -0,0 +1,57 @@
+[build-system]
+build-backend = "setuptools.build_meta"
+requires = ["setuptools", "Cython>=3.0", "toml", "cassandra-driver"]

Review Comment:
   The build-system requires "Cython>=3.0" unconditionally, but in the original 
code, Cython was only added to setup_requires when actually needed (when 
try_cython was True and pre_build_check passed). This means Cython will now 
always be installed during the build process, even if the user doesn't want to 
build Cython extensions. This could increase build time and dependencies 
unnecessarily. Consider making Cython an optional build dependency or 
documenting why it's now always required.



##########
setup.py:
##########
@@ -254,193 +104,78 @@ class build_extensions(build_ext):
     $ brew install libev
 
 ===============================================================================
-    """
-
-    def run(self):
-        try:
-            self._setup_extensions()
-            build_ext.run(self)
-        except DistutilsPlatformError as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            warnings.warn(self.error_message % "C extensions.")
-
-    def build_extensions(self):
-        if build_concurrency > 1:
-            self.check_extensions_list(self.extensions)
-
-            import multiprocessing.pool
-            
multiprocessing.pool.ThreadPool(processes=build_concurrency).map(self.build_extension,
 self.extensions)
-        else:
-            build_ext.build_extensions(self)
-
-    def build_extension(self, ext):
-        try:
-            build_ext.build_extension(self, ext)
-        except (CCompilerError, DistutilsExecError,
-                DistutilsPlatformError, IOError) as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            name = "The %s extension" % (ext.name,)
-            warnings.warn(self.error_message % (name,))
-
-    def _setup_extensions(self):
-        # We defer extension setup until this command to leveraage 
'setup_requires' pulling in Cython before we
-        # attempt to import anything
-        self.extensions = []
-
-        if try_murmur3:
-            self.extensions.append(murmur3_ext)
-
-        if try_libev:
-            sys.stderr.write("Appending libev extension %s" % libev_ext)
-            self.extensions.append(libev_ext)
-
-        if try_cython:
-            try:
-                from Cython.Build import cythonize
-                cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
-                                     'pool', 'protocol', 'query', 'util']
-                compile_args = [] if is_windows else ['-Wno-unused-function']
-                self.extensions.extend(cythonize(
-                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
-                               extra_compile_args=compile_args)
-                        for m in cython_candidates],
-                    nthreads=build_concurrency,
-                    exclude_failures=True))
-
-                self.extensions.extend(cythonize(NoPatchExtension("*", 
["cassandra/*.pyx"], extra_compile_args=compile_args),
-                                                 nthreads=build_concurrency))
-            except Exception:
-                sys.stderr.write("Failed to cythonize one or more modules. 
These will not be compiled as extensions (optional).\n")
-
-
-def pre_build_check():
-    """
-    Try to verify build tools
-    """
-    if os.environ.get('CASS_DRIVER_NO_PRE_BUILD_CHECK'):
-        return True
-
-    try:
-        from distutils.ccompiler import new_compiler
-        from distutils.sysconfig import customize_compiler
-        from distutils.dist import Distribution
-
-        # base build_ext just to emulate compiler option setup
-        be = build_ext(Distribution())
-        be.initialize_options()
-        be.finalize_options()
+"""
 
-        # First, make sure we have a Python include directory
-        have_python_include = any(os.path.isfile(os.path.join(p, 'Python.h')) 
for p in be.include_dirs)
-        if not have_python_include:
-            sys.stderr.write("Did not find 'Python.h' in %s.\n" % 
(be.include_dirs,))
-            return False
+# ========================== A few upfront checks ==========================
+if is_pypy:
+    sys.stderr.write(pypy_unsupported_msg)
+if not is_supported_platform:
+    sys.stderr.write(platform_unsupported_msg)
+elif not is_supported_arch:
+    sys.stderr.write(arch_unsupported_msg)
 
-        compiler = new_compiler(compiler=be.compiler)
-        customize_compiler(compiler)
+# ========================== Extensions ==========================
+pyproject_toml = Path(__file__).parent / "pyproject.toml"
+pyproject_data = toml.load(pyproject_toml)
+driver_project_data = pyproject_data["tool"]["cassandra-driver"]
 
-        try:
-            # We must be able to initialize the compiler if it has that method
-            if hasattr(compiler, "initialize"):
-                compiler.initialize()
-        except OSError:
-            return False
+murmur3_ext = Extension('cassandra.cmurmur3', sources=['cassandra/cmurmur3.c'])
 
-        executables = []
-        if compiler.compiler_type in ('unix', 'cygwin'):
-            executables = [compiler.executables[exe][0] for exe in 
('compiler_so', 'linker_so')]
-        elif compiler.compiler_type == 'nt':
-            executables = [getattr(compiler, exe) for exe in ('cc', 'linker')]
+DEFAULT_LIBEV_INCLUDES = ['/usr/include/libev', '/usr/local/include', 
'/opt/local/include', '/usr/include']
+DEFAULT_LIBEV_LIBS = ['/usr/local/lib', '/opt/local/lib', '/usr/lib64']
+libev_includes = driver_project_data["libev-includes"] or 
DEFAULT_LIBEV_INCLUDES
+libev_libs = driver_project_data["libev-libs"] or DEFAULT_LIBEV_LIBS
+if is_macos:
+    libev_includes.extend(['/opt/homebrew/include', 
os.path.expanduser('~/homebrew/include')])
+    libev_libs.extend(['/opt/homebrew/lib'])
+libev_ext = Extension('cassandra.io.libevwrapper',
+                      sources=['cassandra/io/libevwrapper.c'],
+                      include_dirs=libev_includes,
+                      libraries=['ev'],
+                      library_dirs=libev_libs)
 
-        if executables:
-            from distutils.spawn import find_executable
-            for exe in executables:
-                if not find_executable(exe):
-                    sys.stderr.write("Failed to find %s for compiler type 
%s.\n" % (exe, compiler.compiler_type))
-                    return False
+try_extensions = driver_project_data["build-extensions"] and 
is_supported_platform and is_supported_arch
+try_murmur3 = driver_project_data["build-murmur3-extension"]
+try_libev = driver_project_data["build-libev-extension"]
+try_cython = driver_project_data["build-cython-extensions"] and not is_pypy
 
-    except Exception as exc:
-        sys.stderr.write('%s\n' % str(exc))
-        sys.stderr.write("Failed pre-build check. Attempting anyway.\n")
+build_concurrency = driver_project_data["build-concurrency"]
 
-    # if we are unable to positively id the compiler type, or one of these 
assumptions fails,
-    # just proceed as we would have without the check
-    return True
+def build_extension_list():
 
+    rv = []
 
-def run_setup(extensions):
+    if try_murmur3:
+        sys.stderr.write("Appending murmur extension %s\n" % murmur3_ext)
+        rv.append(murmur3_ext)
 
-    kw = {'cmdclass': {'doc': DocCommand}}
-    kw['cmdclass']['build_ext'] = build_extensions
-    kw['ext_modules'] = [Extension('DUMMY', [])]  # dummy extension makes sure 
build_ext is called for install
+    if try_libev:
+        sys.stderr.write("Appending libev extension %s\n" % libev_ext)
+        rv.append(libev_ext)
 
     if try_cython:
-        # precheck compiler before adding to setup_requires
-        # we don't actually negate try_cython because:
-        # 1.) build_ext eats errors at compile time, letting the install 
complete while producing useful feedback
-        # 2.) there could be a case where the python environment has cython 
installed but the system doesn't have build tools
-        if pre_build_check():
-            cython_dep = 'Cython>=3.0'
-            user_specified_cython_version = 
os.environ.get('CASS_DRIVER_ALLOWED_CYTHON_VERSION')
-            if user_specified_cython_version is not None:
-                cython_dep = 'Cython==%s' % (user_specified_cython_version,)
-            kw['setup_requires'] = [cython_dep]
-        else:
-            sys.stderr.write("Bypassing Cython setup requirement\n")
-
-    dependencies = ['geomet>=1.1']
-
-    _EXTRAS_REQUIRE = {
-        'graph': ['gremlinpython==3.4.6'],
-        'cle': ['cryptography>=42.0']
-    }
-
-    setup(
-        name='cassandra-driver',
-        version=__version__,
-        description='Apache Cassandra Python Driver',
-        long_description=long_description,
-        long_description_content_type='text/x-rst',
-        url='http://github.com/datastax/python-driver',
-        project_urls={
-            'Documentation': 
'https://docs.datastax.com/en/developer/python-driver/latest/',
-            'Source': 'https://github.com/datastax/python-driver/',
-            'Issues': 'https://datastax-oss.atlassian.net/browse/PYTHON',
-        },
-        author='DataStax',
-        packages=[
-            'cassandra', 'cassandra.io', 'cassandra.cqlengine', 
'cassandra.graph',
-            'cassandra.datastax', 'cassandra.datastax.insights', 
'cassandra.datastax.graph',
-            'cassandra.datastax.graph.fluent', 'cassandra.datastax.cloud',
-            "cassandra.column_encryption"
-        ],
-        keywords='cassandra,cql,orm,dse,graph',
-        include_package_data=True,
-        install_requires=dependencies,
-        extras_require=_EXTRAS_REQUIRE,
-        tests_require=['pytest', 'PyYAML', 'pytz'],
-        classifiers=[
-            'Development Status :: 5 - Production/Stable',
-            'Intended Audience :: Developers',
-            'License :: OSI Approved :: Apache Software License',
-            'Natural Language :: English',
-            'Operating System :: OS Independent',
-            'Programming Language :: Python',
-            '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',
-            'Programming Language :: Python :: Implementation :: CPython',
-            'Programming Language :: Python :: Implementation :: PyPy',
-            'Topic :: Software Development :: Libraries :: Python Modules'
-        ],
-        **kw)
-
-
-run_setup(None)
-
-if has_cqlengine:
-    warnings.warn("\n#######\n'cqlengine' package is present on path: %s\n"
-                  "cqlengine is now an integrated sub-package of this 
driver.\n"
-                  "It is recommended to remove this package to reduce the 
chance for conflicting usage" % cqlengine.__file__)
+        sys.stderr.write("Trying Cython builds in order to append Cython 
extensions\n")
+        try:
+            from Cython.Build import cythonize
+            cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
+                                 'pool', 'protocol', 'query', 'util']
+            compile_args = [] if is_windows else ['-Wno-unused-function']
+            rv.extend(cythonize(
+                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
+                                extra_compile_args=compile_args)
+                        for m in cython_candidates],
+                    nthreads=build_concurrency,
+                    exclude_failures=True))
+
+            rv.extend(cythonize(Extension("*", ["cassandra/*.pyx"], 
extra_compile_args=compile_args),
+                                          nthreads=build_concurrency))

Review Comment:
   The `build_concurrency` value is read from pyproject.toml and used directly 
in `cythonize()` calls (lines 167, 171). However, the original code defaulted 
to 0 when the environment variable was not set or invalid, and values > 1 
triggered parallel builds. The new code doesn't handle the case where 
build_concurrency is 0, which is the default value in pyproject.toml. When 0 is 
passed to cythonize's nthreads parameter, it may not behave as expected. 
Consider documenting the meaning of 0 or defaulting to None for sequential 
builds.
   ```suggestion
               # Normalize build_concurrency for cythonize: 0 means sequential 
/ default behavior
               nthreads = None if build_concurrency == 0 else build_concurrency
               rv.extend(cythonize(
                       [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
                                   extra_compile_args=compile_args)
                           for m in cython_candidates],
                       nthreads=nthreads,
                       exclude_failures=True))
   
               rv.extend(cythonize(Extension("*", ["cassandra/*.pyx"], 
extra_compile_args=compile_args),
                                             nthreads=nthreads))
   ```



##########
setup.py:
##########
@@ -254,193 +104,78 @@ class build_extensions(build_ext):
     $ brew install libev
 
 ===============================================================================
-    """
-
-    def run(self):
-        try:
-            self._setup_extensions()
-            build_ext.run(self)
-        except DistutilsPlatformError as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            warnings.warn(self.error_message % "C extensions.")
-
-    def build_extensions(self):
-        if build_concurrency > 1:
-            self.check_extensions_list(self.extensions)
-
-            import multiprocessing.pool
-            
multiprocessing.pool.ThreadPool(processes=build_concurrency).map(self.build_extension,
 self.extensions)
-        else:
-            build_ext.build_extensions(self)
-
-    def build_extension(self, ext):
-        try:
-            build_ext.build_extension(self, ext)
-        except (CCompilerError, DistutilsExecError,
-                DistutilsPlatformError, IOError) as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            name = "The %s extension" % (ext.name,)
-            warnings.warn(self.error_message % (name,))
-
-    def _setup_extensions(self):
-        # We defer extension setup until this command to leveraage 
'setup_requires' pulling in Cython before we
-        # attempt to import anything
-        self.extensions = []
-
-        if try_murmur3:
-            self.extensions.append(murmur3_ext)
-
-        if try_libev:
-            sys.stderr.write("Appending libev extension %s" % libev_ext)
-            self.extensions.append(libev_ext)
-
-        if try_cython:
-            try:
-                from Cython.Build import cythonize
-                cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
-                                     'pool', 'protocol', 'query', 'util']
-                compile_args = [] if is_windows else ['-Wno-unused-function']
-                self.extensions.extend(cythonize(
-                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
-                               extra_compile_args=compile_args)
-                        for m in cython_candidates],
-                    nthreads=build_concurrency,
-                    exclude_failures=True))
-
-                self.extensions.extend(cythonize(NoPatchExtension("*", 
["cassandra/*.pyx"], extra_compile_args=compile_args),
-                                                 nthreads=build_concurrency))
-            except Exception:
-                sys.stderr.write("Failed to cythonize one or more modules. 
These will not be compiled as extensions (optional).\n")
-
-
-def pre_build_check():
-    """
-    Try to verify build tools
-    """
-    if os.environ.get('CASS_DRIVER_NO_PRE_BUILD_CHECK'):
-        return True
-
-    try:
-        from distutils.ccompiler import new_compiler
-        from distutils.sysconfig import customize_compiler
-        from distutils.dist import Distribution
-
-        # base build_ext just to emulate compiler option setup
-        be = build_ext(Distribution())
-        be.initialize_options()
-        be.finalize_options()
+"""
 
-        # First, make sure we have a Python include directory
-        have_python_include = any(os.path.isfile(os.path.join(p, 'Python.h')) 
for p in be.include_dirs)
-        if not have_python_include:
-            sys.stderr.write("Did not find 'Python.h' in %s.\n" % 
(be.include_dirs,))
-            return False
+# ========================== A few upfront checks ==========================
+if is_pypy:
+    sys.stderr.write(pypy_unsupported_msg)
+if not is_supported_platform:
+    sys.stderr.write(platform_unsupported_msg)
+elif not is_supported_arch:
+    sys.stderr.write(arch_unsupported_msg)
 
-        compiler = new_compiler(compiler=be.compiler)
-        customize_compiler(compiler)
+# ========================== Extensions ==========================
+pyproject_toml = Path(__file__).parent / "pyproject.toml"
+pyproject_data = toml.load(pyproject_toml)
+driver_project_data = pyproject_data["tool"]["cassandra-driver"]
 
-        try:
-            # We must be able to initialize the compiler if it has that method
-            if hasattr(compiler, "initialize"):
-                compiler.initialize()
-        except OSError:
-            return False
+murmur3_ext = Extension('cassandra.cmurmur3', sources=['cassandra/cmurmur3.c'])
 
-        executables = []
-        if compiler.compiler_type in ('unix', 'cygwin'):
-            executables = [compiler.executables[exe][0] for exe in 
('compiler_so', 'linker_so')]
-        elif compiler.compiler_type == 'nt':
-            executables = [getattr(compiler, exe) for exe in ('cc', 'linker')]
+DEFAULT_LIBEV_INCLUDES = ['/usr/include/libev', '/usr/local/include', 
'/opt/local/include', '/usr/include']
+DEFAULT_LIBEV_LIBS = ['/usr/local/lib', '/opt/local/lib', '/usr/lib64']
+libev_includes = driver_project_data["libev-includes"] or 
DEFAULT_LIBEV_INCLUDES
+libev_libs = driver_project_data["libev-libs"] or DEFAULT_LIBEV_LIBS
+if is_macos:
+    libev_includes.extend(['/opt/homebrew/include', 
os.path.expanduser('~/homebrew/include')])
+    libev_libs.extend(['/opt/homebrew/lib'])
+libev_ext = Extension('cassandra.io.libevwrapper',
+                      sources=['cassandra/io/libevwrapper.c'],
+                      include_dirs=libev_includes,
+                      libraries=['ev'],
+                      library_dirs=libev_libs)
 
-        if executables:
-            from distutils.spawn import find_executable
-            for exe in executables:
-                if not find_executable(exe):
-                    sys.stderr.write("Failed to find %s for compiler type 
%s.\n" % (exe, compiler.compiler_type))
-                    return False
+try_extensions = driver_project_data["build-extensions"] and 
is_supported_platform and is_supported_arch
+try_murmur3 = driver_project_data["build-murmur3-extension"]
+try_libev = driver_project_data["build-libev-extension"]
+try_cython = driver_project_data["build-cython-extensions"] and not is_pypy
 
-    except Exception as exc:
-        sys.stderr.write('%s\n' % str(exc))
-        sys.stderr.write("Failed pre-build check. Attempting anyway.\n")
+build_concurrency = driver_project_data["build-concurrency"]
 
-    # if we are unable to positively id the compiler type, or one of these 
assumptions fails,
-    # just proceed as we would have without the check
-    return True
+def build_extension_list():
 
+    rv = []
 
-def run_setup(extensions):
+    if try_murmur3:
+        sys.stderr.write("Appending murmur extension %s\n" % murmur3_ext)
+        rv.append(murmur3_ext)
 
-    kw = {'cmdclass': {'doc': DocCommand}}
-    kw['cmdclass']['build_ext'] = build_extensions
-    kw['ext_modules'] = [Extension('DUMMY', [])]  # dummy extension makes sure 
build_ext is called for install
+    if try_libev:
+        sys.stderr.write("Appending libev extension %s\n" % libev_ext)
+        rv.append(libev_ext)
 
     if try_cython:
-        # precheck compiler before adding to setup_requires
-        # we don't actually negate try_cython because:
-        # 1.) build_ext eats errors at compile time, letting the install 
complete while producing useful feedback
-        # 2.) there could be a case where the python environment has cython 
installed but the system doesn't have build tools
-        if pre_build_check():
-            cython_dep = 'Cython>=3.0'
-            user_specified_cython_version = 
os.environ.get('CASS_DRIVER_ALLOWED_CYTHON_VERSION')
-            if user_specified_cython_version is not None:
-                cython_dep = 'Cython==%s' % (user_specified_cython_version,)
-            kw['setup_requires'] = [cython_dep]
-        else:
-            sys.stderr.write("Bypassing Cython setup requirement\n")
-
-    dependencies = ['geomet>=1.1']
-
-    _EXTRAS_REQUIRE = {
-        'graph': ['gremlinpython==3.4.6'],
-        'cle': ['cryptography>=42.0']
-    }
-
-    setup(
-        name='cassandra-driver',
-        version=__version__,
-        description='Apache Cassandra Python Driver',
-        long_description=long_description,
-        long_description_content_type='text/x-rst',
-        url='http://github.com/datastax/python-driver',
-        project_urls={
-            'Documentation': 
'https://docs.datastax.com/en/developer/python-driver/latest/',
-            'Source': 'https://github.com/datastax/python-driver/',
-            'Issues': 'https://datastax-oss.atlassian.net/browse/PYTHON',
-        },
-        author='DataStax',
-        packages=[
-            'cassandra', 'cassandra.io', 'cassandra.cqlengine', 
'cassandra.graph',
-            'cassandra.datastax', 'cassandra.datastax.insights', 
'cassandra.datastax.graph',
-            'cassandra.datastax.graph.fluent', 'cassandra.datastax.cloud',
-            "cassandra.column_encryption"
-        ],
-        keywords='cassandra,cql,orm,dse,graph',
-        include_package_data=True,
-        install_requires=dependencies,
-        extras_require=_EXTRAS_REQUIRE,
-        tests_require=['pytest', 'PyYAML', 'pytz'],
-        classifiers=[
-            'Development Status :: 5 - Production/Stable',
-            'Intended Audience :: Developers',
-            'License :: OSI Approved :: Apache Software License',
-            'Natural Language :: English',
-            'Operating System :: OS Independent',
-            'Programming Language :: Python',
-            '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',
-            'Programming Language :: Python :: Implementation :: CPython',
-            'Programming Language :: Python :: Implementation :: PyPy',
-            'Topic :: Software Development :: Libraries :: Python Modules'
-        ],
-        **kw)
-
-
-run_setup(None)
-
-if has_cqlengine:
-    warnings.warn("\n#######\n'cqlengine' package is present on path: %s\n"
-                  "cqlengine is now an integrated sub-package of this 
driver.\n"
-                  "It is recommended to remove this package to reduce the 
chance for conflicting usage" % cqlengine.__file__)
+        sys.stderr.write("Trying Cython builds in order to append Cython 
extensions\n")
+        try:
+            from Cython.Build import cythonize
+            cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
+                                 'pool', 'protocol', 'query', 'util']
+            compile_args = [] if is_windows else ['-Wno-unused-function']
+            rv.extend(cythonize(
+                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
+                                extra_compile_args=compile_args)
+                        for m in cython_candidates],
+                    nthreads=build_concurrency,
+                    exclude_failures=True))
+
+            rv.extend(cythonize(Extension("*", ["cassandra/*.pyx"], 
extra_compile_args=compile_args),
+                                          nthreads=build_concurrency))
+        except Exception:
+            sys.stderr.write("Failed to cythonize one or more modules. These 
will not be compiled as extensions (optional).\n")
+    
+    return rv
+
+# ========================== And finally setup() itself 
==========================
+setup(
+    version = __version__,
+    ext_modules = build_extension_list()
+)

Review Comment:
   The refactored code removes the check that warned users if the old 
standalone `cqlengine` package was installed alongside the driver. This warning 
helped prevent conflicts since cqlengine is now integrated into the driver. 
Removing this check could lead to confusing behavior for users who have both 
packages installed. Consider whether this warning is still needed or if it can 
be safely removed.



##########
setup.py:
##########
@@ -254,193 +104,78 @@ class build_extensions(build_ext):
     $ brew install libev
 
 ===============================================================================
-    """
-
-    def run(self):
-        try:
-            self._setup_extensions()
-            build_ext.run(self)
-        except DistutilsPlatformError as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            warnings.warn(self.error_message % "C extensions.")
-
-    def build_extensions(self):
-        if build_concurrency > 1:
-            self.check_extensions_list(self.extensions)
-
-            import multiprocessing.pool
-            
multiprocessing.pool.ThreadPool(processes=build_concurrency).map(self.build_extension,
 self.extensions)
-        else:
-            build_ext.build_extensions(self)
-
-    def build_extension(self, ext):
-        try:
-            build_ext.build_extension(self, ext)
-        except (CCompilerError, DistutilsExecError,
-                DistutilsPlatformError, IOError) as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            name = "The %s extension" % (ext.name,)
-            warnings.warn(self.error_message % (name,))
-
-    def _setup_extensions(self):
-        # We defer extension setup until this command to leveraage 
'setup_requires' pulling in Cython before we
-        # attempt to import anything
-        self.extensions = []
-
-        if try_murmur3:
-            self.extensions.append(murmur3_ext)
-
-        if try_libev:
-            sys.stderr.write("Appending libev extension %s" % libev_ext)
-            self.extensions.append(libev_ext)
-
-        if try_cython:
-            try:
-                from Cython.Build import cythonize
-                cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
-                                     'pool', 'protocol', 'query', 'util']
-                compile_args = [] if is_windows else ['-Wno-unused-function']
-                self.extensions.extend(cythonize(
-                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
-                               extra_compile_args=compile_args)
-                        for m in cython_candidates],
-                    nthreads=build_concurrency,
-                    exclude_failures=True))
-
-                self.extensions.extend(cythonize(NoPatchExtension("*", 
["cassandra/*.pyx"], extra_compile_args=compile_args),
-                                                 nthreads=build_concurrency))
-            except Exception:
-                sys.stderr.write("Failed to cythonize one or more modules. 
These will not be compiled as extensions (optional).\n")
-
-
-def pre_build_check():
-    """
-    Try to verify build tools
-    """
-    if os.environ.get('CASS_DRIVER_NO_PRE_BUILD_CHECK'):
-        return True
-
-    try:
-        from distutils.ccompiler import new_compiler
-        from distutils.sysconfig import customize_compiler
-        from distutils.dist import Distribution
-
-        # base build_ext just to emulate compiler option setup
-        be = build_ext(Distribution())
-        be.initialize_options()
-        be.finalize_options()
+"""
 
-        # First, make sure we have a Python include directory
-        have_python_include = any(os.path.isfile(os.path.join(p, 'Python.h')) 
for p in be.include_dirs)
-        if not have_python_include:
-            sys.stderr.write("Did not find 'Python.h' in %s.\n" % 
(be.include_dirs,))
-            return False
+# ========================== A few upfront checks ==========================
+if is_pypy:
+    sys.stderr.write(pypy_unsupported_msg)
+if not is_supported_platform:
+    sys.stderr.write(platform_unsupported_msg)
+elif not is_supported_arch:
+    sys.stderr.write(arch_unsupported_msg)
 
-        compiler = new_compiler(compiler=be.compiler)
-        customize_compiler(compiler)
+# ========================== Extensions ==========================
+pyproject_toml = Path(__file__).parent / "pyproject.toml"
+pyproject_data = toml.load(pyproject_toml)
+driver_project_data = pyproject_data["tool"]["cassandra-driver"]
 
-        try:
-            # We must be able to initialize the compiler if it has that method
-            if hasattr(compiler, "initialize"):
-                compiler.initialize()
-        except OSError:
-            return False
+murmur3_ext = Extension('cassandra.cmurmur3', sources=['cassandra/cmurmur3.c'])
 
-        executables = []
-        if compiler.compiler_type in ('unix', 'cygwin'):
-            executables = [compiler.executables[exe][0] for exe in 
('compiler_so', 'linker_so')]
-        elif compiler.compiler_type == 'nt':
-            executables = [getattr(compiler, exe) for exe in ('cc', 'linker')]
+DEFAULT_LIBEV_INCLUDES = ['/usr/include/libev', '/usr/local/include', 
'/opt/local/include', '/usr/include']
+DEFAULT_LIBEV_LIBS = ['/usr/local/lib', '/opt/local/lib', '/usr/lib64']
+libev_includes = driver_project_data["libev-includes"] or 
DEFAULT_LIBEV_INCLUDES
+libev_libs = driver_project_data["libev-libs"] or DEFAULT_LIBEV_LIBS
+if is_macos:
+    libev_includes.extend(['/opt/homebrew/include', 
os.path.expanduser('~/homebrew/include')])
+    libev_libs.extend(['/opt/homebrew/lib'])
+libev_ext = Extension('cassandra.io.libevwrapper',
+                      sources=['cassandra/io/libevwrapper.c'],
+                      include_dirs=libev_includes,
+                      libraries=['ev'],
+                      library_dirs=libev_libs)
 
-        if executables:
-            from distutils.spawn import find_executable
-            for exe in executables:
-                if not find_executable(exe):
-                    sys.stderr.write("Failed to find %s for compiler type 
%s.\n" % (exe, compiler.compiler_type))
-                    return False
+try_extensions = driver_project_data["build-extensions"] and 
is_supported_platform and is_supported_arch
+try_murmur3 = driver_project_data["build-murmur3-extension"]
+try_libev = driver_project_data["build-libev-extension"]
+try_cython = driver_project_data["build-cython-extensions"] and not is_pypy
 
-    except Exception as exc:
-        sys.stderr.write('%s\n' % str(exc))
-        sys.stderr.write("Failed pre-build check. Attempting anyway.\n")
+build_concurrency = driver_project_data["build-concurrency"]
 
-    # if we are unable to positively id the compiler type, or one of these 
assumptions fails,
-    # just proceed as we would have without the check
-    return True
+def build_extension_list():
 
+    rv = []
 
-def run_setup(extensions):
+    if try_murmur3:
+        sys.stderr.write("Appending murmur extension %s\n" % murmur3_ext)
+        rv.append(murmur3_ext)
 
-    kw = {'cmdclass': {'doc': DocCommand}}
-    kw['cmdclass']['build_ext'] = build_extensions
-    kw['ext_modules'] = [Extension('DUMMY', [])]  # dummy extension makes sure 
build_ext is called for install
+    if try_libev:
+        sys.stderr.write("Appending libev extension %s\n" % libev_ext)
+        rv.append(libev_ext)
 
     if try_cython:
-        # precheck compiler before adding to setup_requires
-        # we don't actually negate try_cython because:
-        # 1.) build_ext eats errors at compile time, letting the install 
complete while producing useful feedback
-        # 2.) there could be a case where the python environment has cython 
installed but the system doesn't have build tools
-        if pre_build_check():
-            cython_dep = 'Cython>=3.0'
-            user_specified_cython_version = 
os.environ.get('CASS_DRIVER_ALLOWED_CYTHON_VERSION')
-            if user_specified_cython_version is not None:
-                cython_dep = 'Cython==%s' % (user_specified_cython_version,)
-            kw['setup_requires'] = [cython_dep]
-        else:
-            sys.stderr.write("Bypassing Cython setup requirement\n")
-
-    dependencies = ['geomet>=1.1']
-
-    _EXTRAS_REQUIRE = {
-        'graph': ['gremlinpython==3.4.6'],
-        'cle': ['cryptography>=42.0']
-    }
-
-    setup(
-        name='cassandra-driver',
-        version=__version__,
-        description='Apache Cassandra Python Driver',
-        long_description=long_description,
-        long_description_content_type='text/x-rst',
-        url='http://github.com/datastax/python-driver',
-        project_urls={
-            'Documentation': 
'https://docs.datastax.com/en/developer/python-driver/latest/',
-            'Source': 'https://github.com/datastax/python-driver/',
-            'Issues': 'https://datastax-oss.atlassian.net/browse/PYTHON',
-        },
-        author='DataStax',
-        packages=[
-            'cassandra', 'cassandra.io', 'cassandra.cqlengine', 
'cassandra.graph',
-            'cassandra.datastax', 'cassandra.datastax.insights', 
'cassandra.datastax.graph',
-            'cassandra.datastax.graph.fluent', 'cassandra.datastax.cloud',
-            "cassandra.column_encryption"
-        ],
-        keywords='cassandra,cql,orm,dse,graph',
-        include_package_data=True,
-        install_requires=dependencies,
-        extras_require=_EXTRAS_REQUIRE,
-        tests_require=['pytest', 'PyYAML', 'pytz'],
-        classifiers=[
-            'Development Status :: 5 - Production/Stable',
-            'Intended Audience :: Developers',
-            'License :: OSI Approved :: Apache Software License',
-            'Natural Language :: English',
-            'Operating System :: OS Independent',
-            'Programming Language :: Python',
-            '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',
-            'Programming Language :: Python :: Implementation :: CPython',
-            'Programming Language :: Python :: Implementation :: PyPy',
-            'Topic :: Software Development :: Libraries :: Python Modules'
-        ],
-        **kw)
-
-
-run_setup(None)
-
-if has_cqlengine:
-    warnings.warn("\n#######\n'cqlengine' package is present on path: %s\n"
-                  "cqlengine is now an integrated sub-package of this 
driver.\n"
-                  "It is recommended to remove this package to reduce the 
chance for conflicting usage" % cqlengine.__file__)
+        sys.stderr.write("Trying Cython builds in order to append Cython 
extensions\n")
+        try:
+            from Cython.Build import cythonize
+            cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
+                                 'pool', 'protocol', 'query', 'util']
+            compile_args = [] if is_windows else ['-Wno-unused-function']
+            rv.extend(cythonize(
+                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
+                                extra_compile_args=compile_args)
+                        for m in cython_candidates],
+                    nthreads=build_concurrency,
+                    exclude_failures=True))
+
+            rv.extend(cythonize(Extension("*", ["cassandra/*.pyx"], 
extra_compile_args=compile_args),
+                                          nthreads=build_concurrency))
+        except Exception:
+            sys.stderr.write("Failed to cythonize one or more modules. These 
will not be compiled as extensions (optional).\n")
+    
+    return rv

Review Comment:
   The refactored code removes the custom error handling and warning messages 
that were present in the original `build_extensions` class. The original code 
caught `CCompilerError`, `DistutilsExecError`, `DistutilsPlatformError`, and 
`IOError` during extension building and displayed helpful error messages 
(windows_compile_error or non_windows_compile_error). Without this error 
handling, build failures may be less user-friendly. Consider adding similar 
error handling or explaining why it's no longer needed.



##########
setup.py:
##########
@@ -16,131 +16,20 @@
 
 import os
 import sys
-import warnings
 
-import ez_setup
-ez_setup.use_setuptools()
-
-from setuptools import setup
-from distutils.command.build_ext import build_ext
-from distutils.core import Extension
-from distutils.errors import (CCompilerError, DistutilsPlatformError,
-                              DistutilsExecError)
-from distutils.cmd import Command
-
-try:
-    import subprocess
-    has_subprocess = True
-except ImportError:
-    has_subprocess = False
+from pathlib import Path
+from setuptools import setup, Extension
+import toml

Review Comment:
   The code imports and uses the `toml` library, which is also listed as a 
build dependency. However, for Python 3.11+, the standard library includes 
`tomllib` for reading TOML files. For Python 3.9-3.10, the recommended approach 
is to use `tomli` (the backport of tomllib) rather than the older `toml` 
package. Consider using `tomllib` (with `tomli` as a fallback for older Python 
versions) for better compatibility and future-proofing.
   ```suggestion
   try:
       import tomllib as toml
   except ImportError:
       import tomli as toml
   ```



##########
pyproject.toml:
##########
@@ -0,0 +1,57 @@
+[build-system]
+build-backend = "setuptools.build_meta"
+requires = ["setuptools", "Cython>=3.0", "toml", "cassandra-driver"]
+
+[project]
+name = "cassandra-driver"
+description = "Apache Cassandra Python Driver"
+dependencies = ['geomet>=1.1']
+readme = "README.rst"
+authors = [{name = "DataStax"}]
+license = "Apache-2.0"
+license-files = ["LICENSE"]
+keywords = ["cassandra","cql","orm","dse","graph"]
+classifiers = [
+    "Development Status :: 5 - Production/Stable",
+    "Intended Audience :: Developers",
+    "Natural Language :: English",
+    "Operating System :: OS Independent",
+    "License :: OSI Approved :: Apache Software License",
+    "Programming Language :: Python",
+    "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",
+    "Programming Language :: Python :: Implementation :: CPython",
+    "Programming Language :: Python :: Implementation :: PyPy",
+    "Topic :: Software Development :: Libraries :: Python Modules"
+]
+dynamic = ["version"]
+
+[project.optional-dependencies]
+graph = ["gremlinpython==3.4.6"]
+cle = ["cryptography>=42.0"]
+test = ["pytest", "PyYAML", "pytz"]
+
+[project.urls]
+homepage = "https://github.com/apache/cassandra-python-driver/";
+documentation = "https://docs.datastax.com/en/developer/python-driver/latest/";
+source = "https://github.com/apache/cassandra-python-driver/";
+issues = 
"https://issues.apache.org/jira/issues/?jql=project%20%3D%20CASSPYTHON%20ORDER%20BY%20key%20DESC";
+changelog = 
"https://github.com/apache/cassandra-python-driver/blob/trunk/CHANGELOG.rst";
+
+[tool.setuptools.packages.find]
+include = ['cassandra', 'cassandra.io', 'cassandra.cqlengine', 
'cassandra.graph',
+'cassandra.datastax', 'cassandra.datastax.insights', 
'cassandra.datastax.graph',
+'cassandra.datastax.graph.fluent', 'cassandra.datastax.cloud',
+"cassandra.column_encryption"]

Review Comment:
   The `[tool.setuptools.packages.find]` configuration uses `include` with an 
explicit list of packages. However, this approach means that any new 
subpackages added in the future would need to be manually added to this list, 
which is error-prone. The original setup.py also used an explicit list, but 
consider using `where` and `exclude` patterns instead for better 
maintainability, or document why the explicit list approach is preferred.



##########
setup.py:
##########
@@ -254,193 +104,78 @@ class build_extensions(build_ext):
     $ brew install libev
 
 ===============================================================================
-    """
-
-    def run(self):
-        try:
-            self._setup_extensions()
-            build_ext.run(self)
-        except DistutilsPlatformError as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            warnings.warn(self.error_message % "C extensions.")
-
-    def build_extensions(self):
-        if build_concurrency > 1:
-            self.check_extensions_list(self.extensions)
-
-            import multiprocessing.pool
-            
multiprocessing.pool.ThreadPool(processes=build_concurrency).map(self.build_extension,
 self.extensions)
-        else:
-            build_ext.build_extensions(self)
-
-    def build_extension(self, ext):
-        try:
-            build_ext.build_extension(self, ext)
-        except (CCompilerError, DistutilsExecError,
-                DistutilsPlatformError, IOError) as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            name = "The %s extension" % (ext.name,)
-            warnings.warn(self.error_message % (name,))
-
-    def _setup_extensions(self):
-        # We defer extension setup until this command to leveraage 
'setup_requires' pulling in Cython before we
-        # attempt to import anything
-        self.extensions = []
-
-        if try_murmur3:
-            self.extensions.append(murmur3_ext)
-
-        if try_libev:
-            sys.stderr.write("Appending libev extension %s" % libev_ext)
-            self.extensions.append(libev_ext)
-
-        if try_cython:
-            try:
-                from Cython.Build import cythonize
-                cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
-                                     'pool', 'protocol', 'query', 'util']
-                compile_args = [] if is_windows else ['-Wno-unused-function']
-                self.extensions.extend(cythonize(
-                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
-                               extra_compile_args=compile_args)
-                        for m in cython_candidates],
-                    nthreads=build_concurrency,
-                    exclude_failures=True))
-
-                self.extensions.extend(cythonize(NoPatchExtension("*", 
["cassandra/*.pyx"], extra_compile_args=compile_args),
-                                                 nthreads=build_concurrency))
-            except Exception:
-                sys.stderr.write("Failed to cythonize one or more modules. 
These will not be compiled as extensions (optional).\n")
-
-
-def pre_build_check():
-    """
-    Try to verify build tools
-    """
-    if os.environ.get('CASS_DRIVER_NO_PRE_BUILD_CHECK'):
-        return True
-
-    try:
-        from distutils.ccompiler import new_compiler
-        from distutils.sysconfig import customize_compiler
-        from distutils.dist import Distribution
-
-        # base build_ext just to emulate compiler option setup
-        be = build_ext(Distribution())
-        be.initialize_options()
-        be.finalize_options()
+"""
 
-        # First, make sure we have a Python include directory
-        have_python_include = any(os.path.isfile(os.path.join(p, 'Python.h')) 
for p in be.include_dirs)
-        if not have_python_include:
-            sys.stderr.write("Did not find 'Python.h' in %s.\n" % 
(be.include_dirs,))
-            return False
+# ========================== A few upfront checks ==========================
+if is_pypy:
+    sys.stderr.write(pypy_unsupported_msg)
+if not is_supported_platform:
+    sys.stderr.write(platform_unsupported_msg)
+elif not is_supported_arch:
+    sys.stderr.write(arch_unsupported_msg)
 
-        compiler = new_compiler(compiler=be.compiler)
-        customize_compiler(compiler)
+# ========================== Extensions ==========================
+pyproject_toml = Path(__file__).parent / "pyproject.toml"
+pyproject_data = toml.load(pyproject_toml)
+driver_project_data = pyproject_data["tool"]["cassandra-driver"]
 
-        try:
-            # We must be able to initialize the compiler if it has that method
-            if hasattr(compiler, "initialize"):
-                compiler.initialize()
-        except OSError:
-            return False
+murmur3_ext = Extension('cassandra.cmurmur3', sources=['cassandra/cmurmur3.c'])
 
-        executables = []
-        if compiler.compiler_type in ('unix', 'cygwin'):
-            executables = [compiler.executables[exe][0] for exe in 
('compiler_so', 'linker_so')]
-        elif compiler.compiler_type == 'nt':
-            executables = [getattr(compiler, exe) for exe in ('cc', 'linker')]
+DEFAULT_LIBEV_INCLUDES = ['/usr/include/libev', '/usr/local/include', 
'/opt/local/include', '/usr/include']
+DEFAULT_LIBEV_LIBS = ['/usr/local/lib', '/opt/local/lib', '/usr/lib64']
+libev_includes = driver_project_data["libev-includes"] or 
DEFAULT_LIBEV_INCLUDES
+libev_libs = driver_project_data["libev-libs"] or DEFAULT_LIBEV_LIBS
+if is_macos:
+    libev_includes.extend(['/opt/homebrew/include', 
os.path.expanduser('~/homebrew/include')])
+    libev_libs.extend(['/opt/homebrew/lib'])
+libev_ext = Extension('cassandra.io.libevwrapper',
+                      sources=['cassandra/io/libevwrapper.c'],
+                      include_dirs=libev_includes,
+                      libraries=['ev'],
+                      library_dirs=libev_libs)
 
-        if executables:
-            from distutils.spawn import find_executable
-            for exe in executables:
-                if not find_executable(exe):
-                    sys.stderr.write("Failed to find %s for compiler type 
%s.\n" % (exe, compiler.compiler_type))
-                    return False
+try_extensions = driver_project_data["build-extensions"] and 
is_supported_platform and is_supported_arch
+try_murmur3 = driver_project_data["build-murmur3-extension"]
+try_libev = driver_project_data["build-libev-extension"]
+try_cython = driver_project_data["build-cython-extensions"] and not is_pypy
 
-    except Exception as exc:
-        sys.stderr.write('%s\n' % str(exc))
-        sys.stderr.write("Failed pre-build check. Attempting anyway.\n")
+build_concurrency = driver_project_data["build-concurrency"]

Review Comment:
   The refactored code removes support for several environment variables that 
were present in the original code: `CASS_DRIVER_NO_EXTENSIONS`, 
`CASS_DRIVER_NO_LIBEV`, `CASS_DRIVER_NO_CYTHON`, 
`CASS_DRIVER_BUILD_CONCURRENCY`, `CASS_DRIVER_LIBEV_INCLUDES`, and 
`CASS_DRIVER_LIBEV_LIBS`. This is a breaking change that could affect users who 
relied on these environment variables to control build behavior. Consider 
either maintaining backward compatibility or documenting this breaking change 
clearly.



##########
pyproject.toml:
##########
@@ -0,0 +1,57 @@
+[build-system]
+build-backend = "setuptools.build_meta"
+requires = ["setuptools", "Cython>=3.0", "toml", "cassandra-driver"]
+
+[project]
+name = "cassandra-driver"
+description = "Apache Cassandra Python Driver"
+dependencies = ['geomet>=1.1']
+readme = "README.rst"
+authors = [{name = "DataStax"}]
+license = "Apache-2.0"
+license-files = ["LICENSE"]
+keywords = ["cassandra","cql","orm","dse","graph"]
+classifiers = [
+    "Development Status :: 5 - Production/Stable",
+    "Intended Audience :: Developers",
+    "Natural Language :: English",
+    "Operating System :: OS Independent",
+    "License :: OSI Approved :: Apache Software License",
+    "Programming Language :: Python",
+    "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",
+    "Programming Language :: Python :: Implementation :: CPython",
+    "Programming Language :: Python :: Implementation :: PyPy",
+    "Topic :: Software Development :: Libraries :: Python Modules"
+]

Review Comment:
   The pyproject.toml is missing a `requires-python` field to specify the 
minimum Python version required. While the classifiers list Python 3.9-3.13, 
the `requires-python` field should be explicitly set (e.g., `requires-python = 
">=3.9"`) to ensure pip enforces this requirement during installation.
   ```suggestion
   ]
   requires-python = ">=3.9"
   ```



##########
setup.py:
##########
@@ -254,193 +104,78 @@ class build_extensions(build_ext):
     $ brew install libev
 
 ===============================================================================
-    """
-
-    def run(self):
-        try:
-            self._setup_extensions()
-            build_ext.run(self)
-        except DistutilsPlatformError as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            warnings.warn(self.error_message % "C extensions.")
-
-    def build_extensions(self):
-        if build_concurrency > 1:
-            self.check_extensions_list(self.extensions)
-
-            import multiprocessing.pool
-            
multiprocessing.pool.ThreadPool(processes=build_concurrency).map(self.build_extension,
 self.extensions)
-        else:
-            build_ext.build_extensions(self)
-
-    def build_extension(self, ext):
-        try:
-            build_ext.build_extension(self, ext)
-        except (CCompilerError, DistutilsExecError,
-                DistutilsPlatformError, IOError) as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            name = "The %s extension" % (ext.name,)
-            warnings.warn(self.error_message % (name,))
-
-    def _setup_extensions(self):
-        # We defer extension setup until this command to leveraage 
'setup_requires' pulling in Cython before we
-        # attempt to import anything
-        self.extensions = []
-
-        if try_murmur3:
-            self.extensions.append(murmur3_ext)
-
-        if try_libev:
-            sys.stderr.write("Appending libev extension %s" % libev_ext)
-            self.extensions.append(libev_ext)
-
-        if try_cython:
-            try:
-                from Cython.Build import cythonize
-                cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
-                                     'pool', 'protocol', 'query', 'util']
-                compile_args = [] if is_windows else ['-Wno-unused-function']
-                self.extensions.extend(cythonize(
-                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
-                               extra_compile_args=compile_args)
-                        for m in cython_candidates],
-                    nthreads=build_concurrency,
-                    exclude_failures=True))
-
-                self.extensions.extend(cythonize(NoPatchExtension("*", 
["cassandra/*.pyx"], extra_compile_args=compile_args),
-                                                 nthreads=build_concurrency))
-            except Exception:
-                sys.stderr.write("Failed to cythonize one or more modules. 
These will not be compiled as extensions (optional).\n")
-
-
-def pre_build_check():
-    """
-    Try to verify build tools
-    """
-    if os.environ.get('CASS_DRIVER_NO_PRE_BUILD_CHECK'):
-        return True
-
-    try:
-        from distutils.ccompiler import new_compiler
-        from distutils.sysconfig import customize_compiler
-        from distutils.dist import Distribution
-
-        # base build_ext just to emulate compiler option setup
-        be = build_ext(Distribution())
-        be.initialize_options()
-        be.finalize_options()
+"""
 
-        # First, make sure we have a Python include directory
-        have_python_include = any(os.path.isfile(os.path.join(p, 'Python.h')) 
for p in be.include_dirs)
-        if not have_python_include:
-            sys.stderr.write("Did not find 'Python.h' in %s.\n" % 
(be.include_dirs,))
-            return False
+# ========================== A few upfront checks ==========================
+if is_pypy:
+    sys.stderr.write(pypy_unsupported_msg)
+if not is_supported_platform:
+    sys.stderr.write(platform_unsupported_msg)
+elif not is_supported_arch:
+    sys.stderr.write(arch_unsupported_msg)
 
-        compiler = new_compiler(compiler=be.compiler)
-        customize_compiler(compiler)
+# ========================== Extensions ==========================
+pyproject_toml = Path(__file__).parent / "pyproject.toml"
+pyproject_data = toml.load(pyproject_toml)
+driver_project_data = pyproject_data["tool"]["cassandra-driver"]
 
-        try:
-            # We must be able to initialize the compiler if it has that method
-            if hasattr(compiler, "initialize"):
-                compiler.initialize()
-        except OSError:
-            return False
+murmur3_ext = Extension('cassandra.cmurmur3', sources=['cassandra/cmurmur3.c'])
 
-        executables = []
-        if compiler.compiler_type in ('unix', 'cygwin'):
-            executables = [compiler.executables[exe][0] for exe in 
('compiler_so', 'linker_so')]
-        elif compiler.compiler_type == 'nt':
-            executables = [getattr(compiler, exe) for exe in ('cc', 'linker')]
+DEFAULT_LIBEV_INCLUDES = ['/usr/include/libev', '/usr/local/include', 
'/opt/local/include', '/usr/include']
+DEFAULT_LIBEV_LIBS = ['/usr/local/lib', '/opt/local/lib', '/usr/lib64']
+libev_includes = driver_project_data["libev-includes"] or 
DEFAULT_LIBEV_INCLUDES
+libev_libs = driver_project_data["libev-libs"] or DEFAULT_LIBEV_LIBS
+if is_macos:
+    libev_includes.extend(['/opt/homebrew/include', 
os.path.expanduser('~/homebrew/include')])
+    libev_libs.extend(['/opt/homebrew/lib'])
+libev_ext = Extension('cassandra.io.libevwrapper',
+                      sources=['cassandra/io/libevwrapper.c'],
+                      include_dirs=libev_includes,
+                      libraries=['ev'],
+                      library_dirs=libev_libs)
 
-        if executables:
-            from distutils.spawn import find_executable
-            for exe in executables:
-                if not find_executable(exe):
-                    sys.stderr.write("Failed to find %s for compiler type 
%s.\n" % (exe, compiler.compiler_type))
-                    return False
+try_extensions = driver_project_data["build-extensions"] and 
is_supported_platform and is_supported_arch
+try_murmur3 = driver_project_data["build-murmur3-extension"]
+try_libev = driver_project_data["build-libev-extension"]
+try_cython = driver_project_data["build-cython-extensions"] and not is_pypy
 
-    except Exception as exc:
-        sys.stderr.write('%s\n' % str(exc))
-        sys.stderr.write("Failed pre-build check. Attempting anyway.\n")
+build_concurrency = driver_project_data["build-concurrency"]
 
-    # if we are unable to positively id the compiler type, or one of these 
assumptions fails,
-    # just proceed as we would have without the check
-    return True
+def build_extension_list():
 
+    rv = []
 
-def run_setup(extensions):
+    if try_murmur3:
+        sys.stderr.write("Appending murmur extension %s\n" % murmur3_ext)
+        rv.append(murmur3_ext)
 
-    kw = {'cmdclass': {'doc': DocCommand}}
-    kw['cmdclass']['build_ext'] = build_extensions
-    kw['ext_modules'] = [Extension('DUMMY', [])]  # dummy extension makes sure 
build_ext is called for install
+    if try_libev:
+        sys.stderr.write("Appending libev extension %s\n" % libev_ext)
+        rv.append(libev_ext)
 
     if try_cython:
-        # precheck compiler before adding to setup_requires
-        # we don't actually negate try_cython because:
-        # 1.) build_ext eats errors at compile time, letting the install 
complete while producing useful feedback
-        # 2.) there could be a case where the python environment has cython 
installed but the system doesn't have build tools
-        if pre_build_check():
-            cython_dep = 'Cython>=3.0'
-            user_specified_cython_version = 
os.environ.get('CASS_DRIVER_ALLOWED_CYTHON_VERSION')
-            if user_specified_cython_version is not None:
-                cython_dep = 'Cython==%s' % (user_specified_cython_version,)
-            kw['setup_requires'] = [cython_dep]
-        else:
-            sys.stderr.write("Bypassing Cython setup requirement\n")
-
-    dependencies = ['geomet>=1.1']
-
-    _EXTRAS_REQUIRE = {
-        'graph': ['gremlinpython==3.4.6'],
-        'cle': ['cryptography>=42.0']
-    }
-
-    setup(
-        name='cassandra-driver',
-        version=__version__,
-        description='Apache Cassandra Python Driver',
-        long_description=long_description,
-        long_description_content_type='text/x-rst',
-        url='http://github.com/datastax/python-driver',
-        project_urls={
-            'Documentation': 
'https://docs.datastax.com/en/developer/python-driver/latest/',
-            'Source': 'https://github.com/datastax/python-driver/',
-            'Issues': 'https://datastax-oss.atlassian.net/browse/PYTHON',
-        },
-        author='DataStax',
-        packages=[
-            'cassandra', 'cassandra.io', 'cassandra.cqlengine', 
'cassandra.graph',
-            'cassandra.datastax', 'cassandra.datastax.insights', 
'cassandra.datastax.graph',
-            'cassandra.datastax.graph.fluent', 'cassandra.datastax.cloud',
-            "cassandra.column_encryption"
-        ],
-        keywords='cassandra,cql,orm,dse,graph',
-        include_package_data=True,
-        install_requires=dependencies,
-        extras_require=_EXTRAS_REQUIRE,
-        tests_require=['pytest', 'PyYAML', 'pytz'],
-        classifiers=[
-            'Development Status :: 5 - Production/Stable',
-            'Intended Audience :: Developers',
-            'License :: OSI Approved :: Apache Software License',
-            'Natural Language :: English',
-            'Operating System :: OS Independent',
-            'Programming Language :: Python',
-            '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',
-            'Programming Language :: Python :: Implementation :: CPython',
-            'Programming Language :: Python :: Implementation :: PyPy',
-            'Topic :: Software Development :: Libraries :: Python Modules'
-        ],
-        **kw)
-
-
-run_setup(None)
-
-if has_cqlengine:
-    warnings.warn("\n#######\n'cqlengine' package is present on path: %s\n"
-                  "cqlengine is now an integrated sub-package of this 
driver.\n"
-                  "It is recommended to remove this package to reduce the 
chance for conflicting usage" % cqlengine.__file__)
+        sys.stderr.write("Trying Cython builds in order to append Cython 
extensions\n")
+        try:
+            from Cython.Build import cythonize
+            cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
+                                 'pool', 'protocol', 'query', 'util']
+            compile_args = [] if is_windows else ['-Wno-unused-function']
+            rv.extend(cythonize(
+                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
+                                extra_compile_args=compile_args)
+                        for m in cython_candidates],
+                    nthreads=build_concurrency,
+                    exclude_failures=True))
+
+            rv.extend(cythonize(Extension("*", ["cassandra/*.pyx"], 
extra_compile_args=compile_args),
+                                          nthreads=build_concurrency))
+        except Exception:
+            sys.stderr.write("Failed to cythonize one or more modules. These 
will not be compiled as extensions (optional).\n")

Review Comment:
   The exception handler at line 172 catches all exceptions with a bare `except 
Exception:`, which will silently suppress all errors during Cythonization. 
While this matches the original behavior, it would be better to log the actual 
exception details (e.g., using `sys.stderr.write(str(exc))`) to help users 
diagnose build issues rather than just printing a generic message.
   ```suggestion
           except Exception as exc:
               sys.stderr.write("Failed to cythonize one or more modules. These 
will not be compiled as extensions (optional).\n")
               sys.stderr.write("Cythonization error: %s\n" % (exc,))
   ```



##########
setup.py:
##########
@@ -254,193 +104,78 @@ class build_extensions(build_ext):
     $ brew install libev
 
 ===============================================================================
-    """
-
-    def run(self):
-        try:
-            self._setup_extensions()
-            build_ext.run(self)
-        except DistutilsPlatformError as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            warnings.warn(self.error_message % "C extensions.")
-
-    def build_extensions(self):
-        if build_concurrency > 1:
-            self.check_extensions_list(self.extensions)
-
-            import multiprocessing.pool
-            
multiprocessing.pool.ThreadPool(processes=build_concurrency).map(self.build_extension,
 self.extensions)
-        else:
-            build_ext.build_extensions(self)
-
-    def build_extension(self, ext):
-        try:
-            build_ext.build_extension(self, ext)
-        except (CCompilerError, DistutilsExecError,
-                DistutilsPlatformError, IOError) as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            name = "The %s extension" % (ext.name,)
-            warnings.warn(self.error_message % (name,))
-
-    def _setup_extensions(self):
-        # We defer extension setup until this command to leveraage 
'setup_requires' pulling in Cython before we
-        # attempt to import anything
-        self.extensions = []
-
-        if try_murmur3:
-            self.extensions.append(murmur3_ext)
-
-        if try_libev:
-            sys.stderr.write("Appending libev extension %s" % libev_ext)
-            self.extensions.append(libev_ext)
-
-        if try_cython:
-            try:
-                from Cython.Build import cythonize
-                cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
-                                     'pool', 'protocol', 'query', 'util']
-                compile_args = [] if is_windows else ['-Wno-unused-function']
-                self.extensions.extend(cythonize(
-                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
-                               extra_compile_args=compile_args)
-                        for m in cython_candidates],
-                    nthreads=build_concurrency,
-                    exclude_failures=True))
-
-                self.extensions.extend(cythonize(NoPatchExtension("*", 
["cassandra/*.pyx"], extra_compile_args=compile_args),
-                                                 nthreads=build_concurrency))
-            except Exception:
-                sys.stderr.write("Failed to cythonize one or more modules. 
These will not be compiled as extensions (optional).\n")
-
-
-def pre_build_check():
-    """
-    Try to verify build tools
-    """
-    if os.environ.get('CASS_DRIVER_NO_PRE_BUILD_CHECK'):
-        return True
-
-    try:
-        from distutils.ccompiler import new_compiler
-        from distutils.sysconfig import customize_compiler
-        from distutils.dist import Distribution
-
-        # base build_ext just to emulate compiler option setup
-        be = build_ext(Distribution())
-        be.initialize_options()
-        be.finalize_options()
+"""
 
-        # First, make sure we have a Python include directory
-        have_python_include = any(os.path.isfile(os.path.join(p, 'Python.h')) 
for p in be.include_dirs)
-        if not have_python_include:
-            sys.stderr.write("Did not find 'Python.h' in %s.\n" % 
(be.include_dirs,))
-            return False
+# ========================== A few upfront checks ==========================
+if is_pypy:
+    sys.stderr.write(pypy_unsupported_msg)
+if not is_supported_platform:
+    sys.stderr.write(platform_unsupported_msg)
+elif not is_supported_arch:
+    sys.stderr.write(arch_unsupported_msg)
 
-        compiler = new_compiler(compiler=be.compiler)
-        customize_compiler(compiler)
+# ========================== Extensions ==========================
+pyproject_toml = Path(__file__).parent / "pyproject.toml"
+pyproject_data = toml.load(pyproject_toml)
+driver_project_data = pyproject_data["tool"]["cassandra-driver"]
 
-        try:
-            # We must be able to initialize the compiler if it has that method
-            if hasattr(compiler, "initialize"):
-                compiler.initialize()
-        except OSError:
-            return False
+murmur3_ext = Extension('cassandra.cmurmur3', sources=['cassandra/cmurmur3.c'])
 
-        executables = []
-        if compiler.compiler_type in ('unix', 'cygwin'):
-            executables = [compiler.executables[exe][0] for exe in 
('compiler_so', 'linker_so')]
-        elif compiler.compiler_type == 'nt':
-            executables = [getattr(compiler, exe) for exe in ('cc', 'linker')]
+DEFAULT_LIBEV_INCLUDES = ['/usr/include/libev', '/usr/local/include', 
'/opt/local/include', '/usr/include']
+DEFAULT_LIBEV_LIBS = ['/usr/local/lib', '/opt/local/lib', '/usr/lib64']
+libev_includes = driver_project_data["libev-includes"] or 
DEFAULT_LIBEV_INCLUDES
+libev_libs = driver_project_data["libev-libs"] or DEFAULT_LIBEV_LIBS
+if is_macos:
+    libev_includes.extend(['/opt/homebrew/include', 
os.path.expanduser('~/homebrew/include')])
+    libev_libs.extend(['/opt/homebrew/lib'])
+libev_ext = Extension('cassandra.io.libevwrapper',
+                      sources=['cassandra/io/libevwrapper.c'],
+                      include_dirs=libev_includes,
+                      libraries=['ev'],
+                      library_dirs=libev_libs)
 
-        if executables:
-            from distutils.spawn import find_executable
-            for exe in executables:
-                if not find_executable(exe):
-                    sys.stderr.write("Failed to find %s for compiler type 
%s.\n" % (exe, compiler.compiler_type))
-                    return False
+try_extensions = driver_project_data["build-extensions"] and 
is_supported_platform and is_supported_arch
+try_murmur3 = driver_project_data["build-murmur3-extension"]
+try_libev = driver_project_data["build-libev-extension"]
+try_cython = driver_project_data["build-cython-extensions"] and not is_pypy
 
-    except Exception as exc:
-        sys.stderr.write('%s\n' % str(exc))
-        sys.stderr.write("Failed pre-build check. Attempting anyway.\n")
+build_concurrency = driver_project_data["build-concurrency"]
 
-    # if we are unable to positively id the compiler type, or one of these 
assumptions fails,
-    # just proceed as we would have without the check
-    return True
+def build_extension_list():
 
+    rv = []
 
-def run_setup(extensions):
+    if try_murmur3:
+        sys.stderr.write("Appending murmur extension %s\n" % murmur3_ext)
+        rv.append(murmur3_ext)
 
-    kw = {'cmdclass': {'doc': DocCommand}}
-    kw['cmdclass']['build_ext'] = build_extensions
-    kw['ext_modules'] = [Extension('DUMMY', [])]  # dummy extension makes sure 
build_ext is called for install
+    if try_libev:
+        sys.stderr.write("Appending libev extension %s\n" % libev_ext)
+        rv.append(libev_ext)
 
     if try_cython:
-        # precheck compiler before adding to setup_requires
-        # we don't actually negate try_cython because:
-        # 1.) build_ext eats errors at compile time, letting the install 
complete while producing useful feedback
-        # 2.) there could be a case where the python environment has cython 
installed but the system doesn't have build tools
-        if pre_build_check():
-            cython_dep = 'Cython>=3.0'
-            user_specified_cython_version = 
os.environ.get('CASS_DRIVER_ALLOWED_CYTHON_VERSION')
-            if user_specified_cython_version is not None:
-                cython_dep = 'Cython==%s' % (user_specified_cython_version,)
-            kw['setup_requires'] = [cython_dep]
-        else:
-            sys.stderr.write("Bypassing Cython setup requirement\n")
-
-    dependencies = ['geomet>=1.1']
-
-    _EXTRAS_REQUIRE = {
-        'graph': ['gremlinpython==3.4.6'],
-        'cle': ['cryptography>=42.0']
-    }
-
-    setup(
-        name='cassandra-driver',
-        version=__version__,
-        description='Apache Cassandra Python Driver',
-        long_description=long_description,
-        long_description_content_type='text/x-rst',
-        url='http://github.com/datastax/python-driver',
-        project_urls={
-            'Documentation': 
'https://docs.datastax.com/en/developer/python-driver/latest/',
-            'Source': 'https://github.com/datastax/python-driver/',
-            'Issues': 'https://datastax-oss.atlassian.net/browse/PYTHON',
-        },
-        author='DataStax',
-        packages=[
-            'cassandra', 'cassandra.io', 'cassandra.cqlengine', 
'cassandra.graph',
-            'cassandra.datastax', 'cassandra.datastax.insights', 
'cassandra.datastax.graph',
-            'cassandra.datastax.graph.fluent', 'cassandra.datastax.cloud',
-            "cassandra.column_encryption"
-        ],
-        keywords='cassandra,cql,orm,dse,graph',
-        include_package_data=True,
-        install_requires=dependencies,
-        extras_require=_EXTRAS_REQUIRE,
-        tests_require=['pytest', 'PyYAML', 'pytz'],
-        classifiers=[
-            'Development Status :: 5 - Production/Stable',
-            'Intended Audience :: Developers',
-            'License :: OSI Approved :: Apache Software License',
-            'Natural Language :: English',
-            'Operating System :: OS Independent',
-            'Programming Language :: Python',
-            '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',
-            'Programming Language :: Python :: Implementation :: CPython',
-            'Programming Language :: Python :: Implementation :: PyPy',
-            'Topic :: Software Development :: Libraries :: Python Modules'
-        ],
-        **kw)
-
-
-run_setup(None)
-
-if has_cqlengine:
-    warnings.warn("\n#######\n'cqlengine' package is present on path: %s\n"
-                  "cqlengine is now an integrated sub-package of this 
driver.\n"
-                  "It is recommended to remove this package to reduce the 
chance for conflicting usage" % cqlengine.__file__)
+        sys.stderr.write("Trying Cython builds in order to append Cython 
extensions\n")
+        try:
+            from Cython.Build import cythonize
+            cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
+                                 'pool', 'protocol', 'query', 'util']
+            compile_args = [] if is_windows else ['-Wno-unused-function']
+            rv.extend(cythonize(
+                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
+                                extra_compile_args=compile_args)
+                        for m in cython_candidates],
+                    nthreads=build_concurrency,
+                    exclude_failures=True))
+
+            rv.extend(cythonize(Extension("*", ["cassandra/*.pyx"], 
extra_compile_args=compile_args),
+                                          nthreads=build_concurrency))
+        except Exception:
+            sys.stderr.write("Failed to cythonize one or more modules. These 
will not be compiled as extensions (optional).\n")
+    
+    return rv
+
+# ========================== And finally setup() itself 
==========================
+setup(
+    version = __version__,
+    ext_modules = build_extension_list()
+)

Review Comment:
   The refactored code removes the `DocCommand` custom command that was used to 
generate and test documentation via `python setup.py doc` or `python setup.py 
doc --test`. This is a breaking change that could affect documentation build 
workflows. Consider either maintaining this functionality or documenting the 
migration path for documentation building.



##########
setup.py:
##########
@@ -254,193 +104,78 @@ class build_extensions(build_ext):
     $ brew install libev
 
 ===============================================================================
-    """
-
-    def run(self):
-        try:
-            self._setup_extensions()
-            build_ext.run(self)
-        except DistutilsPlatformError as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            warnings.warn(self.error_message % "C extensions.")
-
-    def build_extensions(self):
-        if build_concurrency > 1:
-            self.check_extensions_list(self.extensions)
-
-            import multiprocessing.pool
-            
multiprocessing.pool.ThreadPool(processes=build_concurrency).map(self.build_extension,
 self.extensions)
-        else:
-            build_ext.build_extensions(self)
-
-    def build_extension(self, ext):
-        try:
-            build_ext.build_extension(self, ext)
-        except (CCompilerError, DistutilsExecError,
-                DistutilsPlatformError, IOError) as exc:
-            sys.stderr.write('%s\n' % str(exc))
-            name = "The %s extension" % (ext.name,)
-            warnings.warn(self.error_message % (name,))
-
-    def _setup_extensions(self):
-        # We defer extension setup until this command to leveraage 
'setup_requires' pulling in Cython before we
-        # attempt to import anything
-        self.extensions = []
-
-        if try_murmur3:
-            self.extensions.append(murmur3_ext)
-
-        if try_libev:
-            sys.stderr.write("Appending libev extension %s" % libev_ext)
-            self.extensions.append(libev_ext)
-
-        if try_cython:
-            try:
-                from Cython.Build import cythonize
-                cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
-                                     'pool', 'protocol', 'query', 'util']
-                compile_args = [] if is_windows else ['-Wno-unused-function']
-                self.extensions.extend(cythonize(
-                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
-                               extra_compile_args=compile_args)
-                        for m in cython_candidates],
-                    nthreads=build_concurrency,
-                    exclude_failures=True))
-
-                self.extensions.extend(cythonize(NoPatchExtension("*", 
["cassandra/*.pyx"], extra_compile_args=compile_args),
-                                                 nthreads=build_concurrency))
-            except Exception:
-                sys.stderr.write("Failed to cythonize one or more modules. 
These will not be compiled as extensions (optional).\n")
-
-
-def pre_build_check():
-    """
-    Try to verify build tools
-    """
-    if os.environ.get('CASS_DRIVER_NO_PRE_BUILD_CHECK'):
-        return True
-
-    try:
-        from distutils.ccompiler import new_compiler
-        from distutils.sysconfig import customize_compiler
-        from distutils.dist import Distribution
-
-        # base build_ext just to emulate compiler option setup
-        be = build_ext(Distribution())
-        be.initialize_options()
-        be.finalize_options()
+"""
 
-        # First, make sure we have a Python include directory
-        have_python_include = any(os.path.isfile(os.path.join(p, 'Python.h')) 
for p in be.include_dirs)
-        if not have_python_include:
-            sys.stderr.write("Did not find 'Python.h' in %s.\n" % 
(be.include_dirs,))
-            return False
+# ========================== A few upfront checks ==========================
+if is_pypy:
+    sys.stderr.write(pypy_unsupported_msg)
+if not is_supported_platform:
+    sys.stderr.write(platform_unsupported_msg)
+elif not is_supported_arch:
+    sys.stderr.write(arch_unsupported_msg)
 
-        compiler = new_compiler(compiler=be.compiler)
-        customize_compiler(compiler)
+# ========================== Extensions ==========================
+pyproject_toml = Path(__file__).parent / "pyproject.toml"
+pyproject_data = toml.load(pyproject_toml)
+driver_project_data = pyproject_data["tool"]["cassandra-driver"]
 
-        try:
-            # We must be able to initialize the compiler if it has that method
-            if hasattr(compiler, "initialize"):
-                compiler.initialize()
-        except OSError:
-            return False
+murmur3_ext = Extension('cassandra.cmurmur3', sources=['cassandra/cmurmur3.c'])
 
-        executables = []
-        if compiler.compiler_type in ('unix', 'cygwin'):
-            executables = [compiler.executables[exe][0] for exe in 
('compiler_so', 'linker_so')]
-        elif compiler.compiler_type == 'nt':
-            executables = [getattr(compiler, exe) for exe in ('cc', 'linker')]
+DEFAULT_LIBEV_INCLUDES = ['/usr/include/libev', '/usr/local/include', 
'/opt/local/include', '/usr/include']
+DEFAULT_LIBEV_LIBS = ['/usr/local/lib', '/opt/local/lib', '/usr/lib64']
+libev_includes = driver_project_data["libev-includes"] or 
DEFAULT_LIBEV_INCLUDES
+libev_libs = driver_project_data["libev-libs"] or DEFAULT_LIBEV_LIBS
+if is_macos:
+    libev_includes.extend(['/opt/homebrew/include', 
os.path.expanduser('~/homebrew/include')])
+    libev_libs.extend(['/opt/homebrew/lib'])
+libev_ext = Extension('cassandra.io.libevwrapper',
+                      sources=['cassandra/io/libevwrapper.c'],
+                      include_dirs=libev_includes,
+                      libraries=['ev'],
+                      library_dirs=libev_libs)
 
-        if executables:
-            from distutils.spawn import find_executable
-            for exe in executables:
-                if not find_executable(exe):
-                    sys.stderr.write("Failed to find %s for compiler type 
%s.\n" % (exe, compiler.compiler_type))
-                    return False
+try_extensions = driver_project_data["build-extensions"] and 
is_supported_platform and is_supported_arch
+try_murmur3 = driver_project_data["build-murmur3-extension"]
+try_libev = driver_project_data["build-libev-extension"]
+try_cython = driver_project_data["build-cython-extensions"] and not is_pypy
 
-    except Exception as exc:
-        sys.stderr.write('%s\n' % str(exc))
-        sys.stderr.write("Failed pre-build check. Attempting anyway.\n")
+build_concurrency = driver_project_data["build-concurrency"]
 
-    # if we are unable to positively id the compiler type, or one of these 
assumptions fails,
-    # just proceed as we would have without the check
-    return True
+def build_extension_list():
 
+    rv = []
 
-def run_setup(extensions):
+    if try_murmur3:
+        sys.stderr.write("Appending murmur extension %s\n" % murmur3_ext)
+        rv.append(murmur3_ext)
 
-    kw = {'cmdclass': {'doc': DocCommand}}
-    kw['cmdclass']['build_ext'] = build_extensions
-    kw['ext_modules'] = [Extension('DUMMY', [])]  # dummy extension makes sure 
build_ext is called for install
+    if try_libev:
+        sys.stderr.write("Appending libev extension %s\n" % libev_ext)
+        rv.append(libev_ext)
 
     if try_cython:
-        # precheck compiler before adding to setup_requires
-        # we don't actually negate try_cython because:
-        # 1.) build_ext eats errors at compile time, letting the install 
complete while producing useful feedback
-        # 2.) there could be a case where the python environment has cython 
installed but the system doesn't have build tools
-        if pre_build_check():
-            cython_dep = 'Cython>=3.0'
-            user_specified_cython_version = 
os.environ.get('CASS_DRIVER_ALLOWED_CYTHON_VERSION')
-            if user_specified_cython_version is not None:
-                cython_dep = 'Cython==%s' % (user_specified_cython_version,)
-            kw['setup_requires'] = [cython_dep]
-        else:
-            sys.stderr.write("Bypassing Cython setup requirement\n")
-
-    dependencies = ['geomet>=1.1']
-
-    _EXTRAS_REQUIRE = {
-        'graph': ['gremlinpython==3.4.6'],
-        'cle': ['cryptography>=42.0']
-    }
-
-    setup(
-        name='cassandra-driver',
-        version=__version__,
-        description='Apache Cassandra Python Driver',
-        long_description=long_description,
-        long_description_content_type='text/x-rst',
-        url='http://github.com/datastax/python-driver',
-        project_urls={
-            'Documentation': 
'https://docs.datastax.com/en/developer/python-driver/latest/',
-            'Source': 'https://github.com/datastax/python-driver/',
-            'Issues': 'https://datastax-oss.atlassian.net/browse/PYTHON',
-        },
-        author='DataStax',
-        packages=[
-            'cassandra', 'cassandra.io', 'cassandra.cqlengine', 
'cassandra.graph',
-            'cassandra.datastax', 'cassandra.datastax.insights', 
'cassandra.datastax.graph',
-            'cassandra.datastax.graph.fluent', 'cassandra.datastax.cloud',
-            "cassandra.column_encryption"
-        ],
-        keywords='cassandra,cql,orm,dse,graph',
-        include_package_data=True,
-        install_requires=dependencies,
-        extras_require=_EXTRAS_REQUIRE,
-        tests_require=['pytest', 'PyYAML', 'pytz'],
-        classifiers=[
-            'Development Status :: 5 - Production/Stable',
-            'Intended Audience :: Developers',
-            'License :: OSI Approved :: Apache Software License',
-            'Natural Language :: English',
-            'Operating System :: OS Independent',
-            'Programming Language :: Python',
-            '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',
-            'Programming Language :: Python :: Implementation :: CPython',
-            'Programming Language :: Python :: Implementation :: PyPy',
-            'Topic :: Software Development :: Libraries :: Python Modules'
-        ],
-        **kw)
-
-
-run_setup(None)
-
-if has_cqlengine:
-    warnings.warn("\n#######\n'cqlengine' package is present on path: %s\n"
-                  "cqlengine is now an integrated sub-package of this 
driver.\n"
-                  "It is recommended to remove this package to reduce the 
chance for conflicting usage" % cqlengine.__file__)
+        sys.stderr.write("Trying Cython builds in order to append Cython 
extensions\n")
+        try:
+            from Cython.Build import cythonize
+            cython_candidates = ['cluster', 'concurrent', 'connection', 
'cqltypes', 'metadata',
+                                 'pool', 'protocol', 'query', 'util']
+            compile_args = [] if is_windows else ['-Wno-unused-function']
+            rv.extend(cythonize(
+                    [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
+                                extra_compile_args=compile_args)
+                        for m in cython_candidates],
+                    nthreads=build_concurrency,
+                    exclude_failures=True))
+
+            rv.extend(cythonize(Extension("*", ["cassandra/*.pyx"], 
extra_compile_args=compile_args),
+                                          nthreads=build_concurrency))
+        except Exception:
+            sys.stderr.write("Failed to cythonize one or more modules. These 
will not be compiled as extensions (optional).\n")
+    

Review Comment:
   Trailing whitespace detected on this line.
   ```suggestion
   
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to