Last active
October 9, 2025 10:48
-
-
Save jacobtylerwalls/2bcd3db07a129e2a6f8d07c94bac1d30 to your computer and use it in GitHub Desktop.
Report feature flag values per database
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import ast | |
| from dataclasses import dataclass | |
| from typing import Any | |
| import django.db.backends.base.features as BaseFeatureModule | |
| from django.utils.functional import cached_property | |
| from django.db.backends.base.features import BaseDatabaseFeatures | |
| from django.db.backends.mysql.features import DatabaseFeatures as MySqlFeatures | |
| from django.db.backends.oracle.features import DatabaseFeatures as OracleFeatures | |
| from django.db.backends.postgresql.features import DatabaseFeatures as PostgresFeatures | |
| import django.db.backends.sqlite3.base # to avoid partial import | |
| from django.db.backends.sqlite3.features import DatabaseFeatures as SqliteFeatures | |
| BACKENDS = { | |
| "postgres": PostgresFeatures, | |
| "sqlite": SqliteFeatures, | |
| "oracle": OracleFeatures, | |
| "mysql": MySqlFeatures, | |
| } | |
| MAYBE = "maybe" | |
| NOT_FLAGS = { | |
| "minimum_database_version", | |
| } | |
| def is_supported(value): | |
| match value: | |
| case int(): | |
| return value > 0 | |
| case bool(): | |
| return value | |
| case property(): | |
| return MAYBE | |
| case _: | |
| return bool(value) | |
| # consider cached_property | |
| @dataclass | |
| class DatabaseFeatureFlag(): | |
| attribute_name: str | |
| description: str | |
| value: Any | |
| min_version: tuple[int, ...] | |
| # details: ... | |
| def __get__(self): | |
| return self.value | |
| def parse_ast(): | |
| with open(BaseFeatureModule.__file__, 'r') as module_file: | |
| module_text = module_file.read() | |
| module = ast.parse(module_text) | |
| klass = [elem for elem in module.body if isinstance(elem, ast.ClassDef)][0] | |
| return klass | |
| def get_comment_for_feature_flag(class_node, feature_flag): | |
| """If a docstring exists underneath the feature flag, return the value.""" | |
| # searches every time... | |
| found = False | |
| for body_node in class_node.body: | |
| if found: | |
| if isinstance(body_node, ast.Expr): | |
| return body_node.value.value | |
| if isinstance(body_node, ast.Assign): | |
| if body_node.targets[0].id == feature_flag: | |
| if hasattr(body_node.value, "value"): | |
| found = True | |
| def report_features(class_node): | |
| for feature_flag, default_value in vars(BaseDatabaseFeatures).items(): | |
| if ( | |
| not ( | |
| isinstance(default_value, (list, set, tuple, bool, int, property)) | |
| or default_value is None | |
| ) | |
| or feature_flag.startswith("__") | |
| or "test" in feature_flag | |
| or feature_flag in NOT_FLAGS | |
| ): | |
| # skipping methods for now | |
| continue | |
| print(feature_flag, ": ", get_comment_for_feature_flag(class_node, feature_flag)) | |
| for name, backend in BACKENDS.items(): | |
| got = getattr(backend, feature_flag) | |
| print("\t", f"{name}: ", is_supported(got)) | |
| if __name__ == "__main__": | |
| class_node = parse_ast() | |
| report_features(class_node=class_node) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment