|
15 | 15 | from .pkgconf_cache import PkgconfCache |
16 | 16 | from .pyproject import PyProject |
17 | 17 |
|
| 18 | +import toposort |
| 19 | + |
18 | 20 |
|
19 | 21 | @dataclasses.dataclass |
20 | 22 | class Entrypoint: |
@@ -150,10 +152,7 @@ def generate(self): |
150 | 152 | # Generate extension modules |
151 | 153 | # |
152 | 154 |
|
153 | | - for package_name, extension in projectcfg.extension_modules.items(): |
154 | | - if extension.ignore: |
155 | | - continue |
156 | | - |
| 155 | + for package_name, extension in self._sorted_extension_modules(): |
157 | 156 | try: |
158 | 157 | yield from self._process_extension_module(package_name, extension) |
159 | 158 | except Exception as e: |
@@ -215,6 +214,32 @@ def _process_export_type_caster(self, name: str, caster_cfg: TypeCasterConfig): |
215 | 214 | # store it so it can be used elsewhere |
216 | 215 | self.local_caster_targets[name] = BuildTargetOutput(caster_target, 0) |
217 | 216 |
|
| 217 | + def _sorted_extension_modules( |
| 218 | + self, |
| 219 | + ) -> T.Generator[T.Tuple[str, ExtensionModuleConfig], None, None]: |
| 220 | + # sort extension modules by dependencies, that way modules can depend on other modules |
| 221 | + # also declared in pyproject.toml without needing to worry about ordering in the file |
| 222 | + by_name = {} |
| 223 | + to_sort: T.Dict[str, T.Set[str]] = {} |
| 224 | + |
| 225 | + for package_name, extension in self.pyproject.project.extension_modules.items(): |
| 226 | + if extension.ignore: |
| 227 | + continue |
| 228 | + |
| 229 | + name = extension.name or package_name.replace(".", "_") |
| 230 | + by_name[name] = (package_name, extension) |
| 231 | + |
| 232 | + deps = to_sort.setdefault(name, set()) |
| 233 | + for dep in extension.wraps: |
| 234 | + deps.add(dep) |
| 235 | + for dep in extension.depends: |
| 236 | + deps.add(dep) |
| 237 | + |
| 238 | + for name in toposort.toposort_flatten(to_sort, sort=True): |
| 239 | + data = by_name.get(name) |
| 240 | + if data: |
| 241 | + yield data |
| 242 | + |
218 | 243 | def _process_extension_module( |
219 | 244 | self, package_name: str, extension: ExtensionModuleConfig |
220 | 245 | ): |
|
0 commit comments