Ensure that all cython extension are imported by the compied detection logic.
This is required since cython extensions moduels are marked as optional
in the install, so it's possible that only some of them are compiled.
The extensions are enabled only if all of them are correctly compiled
Change-Id: I355cbac06f5c7a47d35661f42ebab3b0156c1965
-# mypy: allow-untyped-defs, allow-untyped-calls
+# Copyright (C) 2005-2022 the SQLAlchemy authors and contributors
+# <see AUTHORS file>
+#
+# This module is part of SQLAlchemy and is released under
+# the MIT License: https://www.opensource.org/licenses/mit-license.php
+# mypy: ignore-errors
import os
import typing
+
+def _import_cy_extensions():
+ # all cython extension extension modules are treated as optional by the
+ # setup, so to ensure that all are compiled, all should be imported here
+ from ..cyextension import collections
+ from ..cyextension import immutabledict
+ from ..cyextension import processors
+ from ..cyextension import resultproxy
+ from ..cyextension import util
+
+ return (collections, immutabledict, processors, resultproxy, util)
+
+
if not typing.TYPE_CHECKING:
if os.environ.get("DISABLE_SQLALCHEMY_CEXT_RUNTIME"):
HAS_CYEXTENSION = False
else:
try:
- from ..cyextension import util # noqa
+ _import_cy_extensions()
except ImportError:
HAS_CYEXTENSION = False
else:
assert _cy_Extension is not None
assert _cy_build_ext is not None
+ # when adding a cython module, also update the imports in _has_cy
cython_files = [
"collections.pyx",
"immutabledict.pyx",
import copy
import inspect
+from pathlib import Path
import pickle
import sys
from sqlalchemy.util import preloaded
from sqlalchemy.util import WeakSequence
from sqlalchemy.util._collections import merge_lists_w_ordering
+from sqlalchemy.util._has_cy import _import_cy_extensions
+from sqlalchemy.util._has_cy import HAS_CYEXTENSION
class WeakSequenceTest(fixtures.TestBase):
pass
is_true(util.method_is_overridden(HoHo(), Bat.bar))
+
+
+class CyExtensionTest(fixtures.TestBase):
+ @testing.only_if(lambda: HAS_CYEXTENSION, "No Cython")
+ def test_all_cyext_imported(self):
+ ext = _import_cy_extensions()
+ lib_folder = (Path(__file__).parent / ".." / ".." / "lib").resolve()
+ sa_folder = lib_folder / "sqlalchemy"
+ cython_files = [f.resolve() for f in sa_folder.glob("**/*.pyx")]
+ eq_(len(ext), len(cython_files))
+ names = {
+ ".".join(f.relative_to(lib_folder).parts).replace(".pyx", "")
+ for f in cython_files
+ }
+ eq_({m.__name__ for m in ext}, set(names))