| 1464 | self._warn_or_fail_if_strict(f"Unknown config option: {key}\n") |
| 1465 | |
| 1466 | def _validate_plugins(self) -> None: |
| 1467 | required_plugins = sorted(self.getini("required_plugins")) |
| 1468 | if not required_plugins: |
| 1469 | return |
| 1470 | |
| 1471 | # Imported lazily to improve start-up time. |
| 1472 | from packaging.requirements import InvalidRequirement |
| 1473 | from packaging.requirements import Requirement |
| 1474 | from packaging.version import Version |
| 1475 | |
| 1476 | plugin_info = self.pluginmanager.list_plugin_distinfo() |
| 1477 | plugin_dist_info = {dist.project_name: dist.version for _, dist in plugin_info} |
| 1478 | |
| 1479 | missing_plugins = [] |
| 1480 | for required_plugin in required_plugins: |
| 1481 | try: |
| 1482 | req = Requirement(required_plugin) |
| 1483 | except InvalidRequirement: |
| 1484 | missing_plugins.append(required_plugin) |
| 1485 | continue |
| 1486 | |
| 1487 | if req.name not in plugin_dist_info: |
| 1488 | missing_plugins.append(required_plugin) |
| 1489 | elif not req.specifier.contains( |
| 1490 | Version(plugin_dist_info[req.name]), prereleases=True |
| 1491 | ): |
| 1492 | missing_plugins.append(required_plugin) |
| 1493 | |
| 1494 | if missing_plugins: |
| 1495 | raise UsageError( |
| 1496 | "Missing required plugins: {}".format(", ".join(missing_plugins)), |
| 1497 | ) |
| 1498 | |
| 1499 | def _warn_or_fail_if_strict(self, message: str) -> None: |
| 1500 | strict_config = self.getini("strict_config") |