The Pokémon API
This report summarizes scanner evidence for PokeAPI/pokeapi, a Python project with 5,441 GitHub stars. SynthScan examined 42,205 lines of code across 476 source files, recording 186 pattern matches distributed across 10 syntactic categories. The legacy adjusted pattern signal is 3.8 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 159 finding(s).
Are imports declared and package/API names verified? 21 finding(s).
Are wrappers, guards, and repeated structures necessary? 150 finding(s).
Which changes need focused human review? 186 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 186 distinct pattern matches across 10 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | …ces/scripts/data/new_language/validate_new_language.py | 75 | def check_exact_language_names( | CODE |
| LOW | …ces/scripts/data/new_language/validate_new_language.py | 158 | def check_copied_table_coverage( | CODE |
| LOW | pokemon_v2/serializers.py | 747 | def get_region_version_groups(self, obj: Region) -> ReturnList[ReturnDict[str, Any]]: | CODE |
| LOW | pokemon_v2/serializers.py | 991 | def get_encounter_pokemon_details(self, obj: Encounter) -> ReturnDict[str, Any] | None: | CODE |
| LOW | pokemon_v2/serializers.py | 1039 | def get_encounter_pokemon_details(self, obj: Encounter) -> ReturnDict[str, Any] | None: | CODE |
| LOW | pokemon_v2/serializers.py | 1992 | def get_type_past_relationships(self, obj: Type) -> list[dict[str, Any]]: | CODE |
| LOW | pokemon_v2/serializers.py | 2653 | def get_pokemon_form_pokemon_names(self, obj: PokemonForm) -> ReturnList[ReturnDict[str, Any]]: | CODE |
| LOW | pokemon_v2/serializers.py | 2689 | def get_pokemon_form_triggers_conditions(self, obj: PokemonForm) -> list[dict[str, Any]]: | CODE |
| LOW | pokemon_v2/serializers.py | 2766 | def get_method_version_groups(self, obj: MoveLearnMethod) -> ReturnList[ReturnDict[str, Any]]: | CODE |
| LOW | pokemon_v2/serializers.py | 3093 | def get_past_pokemon_abilities(self, obj: Pokemon) -> list[dict[str, Any]]: | CODE |
| LOW | pokemon_v2/serializers.py | 3440 | def _serialized_evolution_variables(self) -> list[tuple[str, dict[str, Any]]]: | CODE |
| LOW | pokemon_v2/serializers.py | 3685 | def get_pokedex_version_groups(self, obj: Pokedex) -> ReturnList[ReturnDict[str, Any]]: | CODE |
| LOW | pokemon_v2/serializers.py | 3742 | def get_version_group_regions(self, obj: VersionGroup) -> ReturnList[ReturnDict[str, Any]]: | CODE |
| LOW | pokemon_v2/serializers.py | 3758 | def get_version_groups_pokedexes(self, obj: VersionGroup) -> ReturnList[ReturnDict[str, Any]]: | CODE |
| LOW | pokemon_v2/test_models.py | 27 | def test_unique_encounter_pokemon_details(self): | CODE |
| LOW | pokemon_v2/test_models.py | 46 | def test_required_and_evolved_pokemon_form_foreign_keys(self): | CODE |
| LOW | pokemon_v2/test_models.py | 70 | def test_evolution_triggers_foreign_keys(self): | CODE |
| LOW | pokemon_v2/test_models.py | 87 | def test_evolution_variables_integrity(self): | CODE |
| LOW | pokemon_v2/test_models.py | 111 | def test_all_csv_identifiers_are_ascii_slugs(self): | CODE |
| LOW | pokemon_v2/test_models.py | 198 | def test_identifier_pattern_examples(self): | CODE |
| LOW | pokemon_v2/test_models.py | 237 | def test_generation_vi_sprite_group_keys_and_paths(self): | CODE |
| LOW | pokemon_v2/test_models.py | 252 | def test_form_sprite_lookup_falls_back_to_pokemon_id_for_default_forms(self): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 223 | def setup_item_attribute_map_data(cls, item, item_attribute): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 230 | def setup_item_fling_effect_data(cls, name="itm flng efct"): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 239 | def setup_item_fling_effect_effect_text_data(cls, item_fling_effect, effect="itm flng efct efct txt"): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 372 | def setup_contest_type_name_data(cls, contest_type, name="cntst tp nm"): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 381 | def setup_contest_effect_data(cls, appeal=2, jam=0): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 388 | def setup_contest_effect_flavor_text_data(cls, contest_effect, flavor_text="cntst efct flvr txt"): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 442 | def setup_berry_flavor_name_data(cls, berry_flavor, name="bry flvr nm"): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 451 | def setup_berry_firmness_data(cls, name="bry frmns"): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 460 | def setup_berry_firmness_name_data(cls, berry_firmness, name="bry frmns nm"): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 850 | def setup_version_group_move_learn_method_data(cls, version_group=None, move_learn_method=None): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 859 | def setup_super_contest_combo_data(cls, first_move, second_move): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 866 | def setup_move_flavor_text_data(cls, move, flavor_text="move flvr txt"): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 1055 | def setup_move_stat_change_data(cls, move, stat=None, change=1): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 1064 | def setup_pokeathlon_stat_data(cls, name="pkathln stt"): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 1071 | def setup_pokeathlon_stat_name_data(cls, pokeathlon_stat, name="pkathln stt nm"): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 1197 | def setup_pokedex_version_group_data(cls, pokedex, version_group=None): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 1207 | def setup_pokemon_habitat_data(cls, name="pkm hbtt"): | CODE |
| LOW⚡ | pokemon_v2/tests.py | 1216 | def setup_pokemon_habitat_name_data(cls, pokemon_habitat, name="pkm hbtt nm"): | CODE |
| LOW | pokemon_v2/tests.py | 80 | def setup_generation_name_data(cls, generation, name="gen nm"): | CODE |
| LOW | pokemon_v2/tests.py | 99 | def setup_version_group_region_data(cls, version_group=None, region=None): | CODE |
| LOW | pokemon_v2/tests.py | 144 | def setup_ability_effect_text_data(cls, ability, short_effect="ablty shrt efct", effect="ablty efct"): | CODE |
| LOW | pokemon_v2/tests.py | 155 | def setup_ability_change_data(cls, ability): | CODE |
| LOW | pokemon_v2/tests.py | 164 | def setup_ability_change_effect_text_data(cls, ability_change, effect="ablty change efct"): | CODE |
| LOW | pokemon_v2/tests.py | 175 | def setup_ability_flavor_text_data(cls, ability, flavor_text="ablty flvr txt"): | CODE |
| LOW | pokemon_v2/tests.py | 192 | def setup_item_attribute_data(cls, name="itm attr"): | CODE |
| LOW | pokemon_v2/tests.py | 201 | def setup_item_attribute_name_data(cls, item_attribute, name="itm attr nm"): | CODE |
| LOW | pokemon_v2/tests.py | 212 | def setup_item_attribute_description_data(cls, item_attribute, description="itm attr desc"): | CODE |
| LOW | pokemon_v2/tests.py | 259 | def setup_item_pocket_name_data(cls, item_pocket, name="itm pkt nm"): | CODE |
| LOW | pokemon_v2/tests.py | 277 | def setup_item_category_name_data(cls, item_category, name="itm ctgry nm"): | CODE |
| LOW | pokemon_v2/tests.py | 326 | def setup_item_effect_text_data(cls, item, short_effect="ablty shrt efct", effect="ablty efct"): | CODE |
| LOW | pokemon_v2/tests.py | 337 | def setup_item_flavor_text_data(cls, item, flavor_text="itm flvr txt"): | CODE |
| LOW | pokemon_v2/tests.py | 353 | def setup_item_game_index_data(cls, item, game_index=0): | CODE |
| LOW | pokemon_v2/tests.py | 399 | def setup_contest_effect_effect_text_data(cls, contest_effect, effect="cntst efct efct txt"): | CODE |
| LOW | pokemon_v2/tests.py | 410 | def setup_super_contest_effect_data(cls, appeal=2): | CODE |
| LOW | pokemon_v2/tests.py | 419 | def setup_super_contest_effect_flavor_text_data(cls, super_contest_effect, flavor_text="spr cntst efct flvr txt"): | CODE |
| LOW | pokemon_v2/tests.py | 471 | def setup_berry_flavor_map_data(cls, berry, berry_flavor, potency=20): | CODE |
| LOW | pokemon_v2/tests.py | 522 | def setup_egg_group_name_data(cls, egg_group, name="ntr nm"): | CODE |
| LOW | pokemon_v2/tests.py | 539 | def setup_growth_rate_description_data(cls, growth_rate, description="grth rt desc"): | CODE |
| 77 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | config/docker_compose.py | 6 | CODE | |
| LOW | config/local.py | 3 | CODE | |
| LOW | config/docker.py | 4 | CODE | |
| LOW | …ces/scripts/data/new_language/validate_new_language.py | 4 | CODE | |
| LOW | …ources/scripts/data/new_language/apply_new_language.py | 7 | CODE | |
| LOW | Resources/scripts/data/gen8/read_swsh.py | 4 | CODE | |
| LOW | pokemon_v2/models.py | 3 | CODE | |
| LOW | pokemon_v2/serializers.py | 3 | CODE | |
| LOW | pokemon_v2/serializers.py | 15 | CODE | |
| LOW | pokemon_v2/api.py | 2 | CODE | |
| LOW | pokemon_v2/api.py | 24 | CODE | |
| LOW | pokemon_v2/api.py | 25 | CODE | |
| LOW | pokemon_v2/api.py | 29 | CODE | |
| LOW | pokemon_v2/api.py | 29 | CODE | |
| LOW | pokemon_v2/test_models.py | 12 | CODE | |
| LOW | pokemon_v2/tests.py | 10 | CODE | |
| LOW | pokemon_v2/urls.py | 8 | CODE | |
| LOW | pokemon_v2/urls.py | 17 | CODE | |
| LOW | data/v2/build.py | 31 | CODE | |
| LOW | data/v2/__init__.py | 1 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| CRITICAL | pokemon_v2/api.py | 9 | from django.core.exceptions import FieldError | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | Resources/scripts/check_csv.py | 8 | CODE | |
| LOW | Resources/scripts/scraping_pokeball_price.py | 113 | CODE | |
| LOW | Resources/scripts/scraping_pokeball_price.py | 136 | CODE | |
| LOW | Resources/scripts/data/check_encounters.py | 51 | CODE | |
| LOW | Resources/scripts/data/gen8/read_swsh.py | 134 | CODE | |
| LOW | Resources/scripts/data/gen8/read_swsh.py | 188 | CODE | |
| LOW | pokemon_v2/serializers.py | 2689 | CODE | |
| LOW | pokemon_v2/test_models.py | 111 | CODE | |
| LOW | data/v2/build.py | 68 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | Resources/scripts/scraping_pokeball_price.py | 199 | except Exception as e: | CODE |
| MEDIUM | Resources/scripts/scraping_pokeball_price.py | 200 | print(f"Error on {b['name']}: {e}") | CODE |
| LOW | Resources/scripts/data/gen8/to_csv.py | 35 | except Exception as error: | CODE |
| LOW | Resources/scripts/data/gen8/to_csv.py | 74 | except Exception as error: | CODE |
| LOW | pokemon_v2/test_models.py | 160 | except Exception as e: # noqa: BLE001 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | data/v2/build.py | 80 | except (OSError, urllib.error.URLError, ValueError): | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | ruff.toml | 14 | "DJ", # flake8-django: django best practices | CODE |
| MEDIUM | ruff.toml | 22 | "PYI", # flake8-pyi: stub file best practices | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pokemon_v2/tests.py | 478 | CODE | |
| LOW | pokemon_v2/tests.py | 882 | CODE | |
| LOW | pokemon_v2/tests.py | 943 | CODE | |
| LOW | pokemon_v2/tests.py | 983 | CODE | |
| LOW | pokemon_v2/tests.py | 1295 | CODE | |
| LOW | pokemon_v2/tests.py | 1598 | CODE | |
| LOW | pokemon_v2/tests.py | 1685 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | Resources/scripts/updater.sh | 192 | # Check if the updater script has pushed the data to a new branch | COMMENT |
| LOW | pokemon_v2/test_models.py | 149 | # Check if identifier matches the pattern | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | Resources/gcp/create_gql_vm.sh | 61 | # set -a && source .env && set +a | COMMENT |
| LOW | data/v2/build.py | 1 | # To build out the data you'll need to jump into the Django shell | COMMENT |