Skip to content

fix: resolve ignored individual NUTS level configurations - #2210

Open
stan-buren wants to merge 3 commits into
PyPSA:masterfrom
stan-buren:fix/nuts-admin-countries-config
Open

fix: resolve ignored individual NUTS level configurations#2210
stan-buren wants to merge 3 commits into
PyPSA:masterfrom
stan-buren:fix/nuts-admin-countries-config

Conversation

@stan-buren

Copy link
Copy Markdown
Contributor

Fixes #2207. Individual country overrides in clustering.administrative.countries were silently ignored because the script filtered admin_levels at the root level instead of parsing the nested 'countries' dictionary.

  • Update dict comprehension in base_network.py and cluster_network.py to extract country levels from nested 'countries' config
  • Add unit and regression tests covering overrides extraction, key leaks, and edge cases
  • Update release notes

Closes #2207.

Changes proposed in this Pull Request

Problem & Root Cause

PyPSA-Eur allows users to define custom NUTS levels for specific countries (e.g. countries: {'DE': 2}) in their configuration file under clustering.administrative.countries. During configuration loading and validation, this config is parsed into a dict (admin_levels) containing the keys "level" and "countries", where "countries" holds the nested dictionary with per-country levels.

Previously, scripts/base_network.py and scripts/cluster_network.py parsed this using:

country_level = {
    k: v for k, v in admin_levels.items() if (k != "level") and (k in countries)
}

When iterating over admin_levels.items(), the key k is either "level" or "countries". The condition (k in countries) evaluates whether the string "countries" matches any of the active country codes (e.g., ["DE", "FR"]), which always returns False. As a result, the country_level dict was silently created as an empty dict {} and all user-defined per-country overrides were silently ignored.

Solution

  1. Config parsing fix: Updated the dictionary comprehension in both scripts/base_network.py and scripts/cluster_network.py to:
    country_level = {
        k: v for k, v in admin_levels.get("countries", {}).items() if k in countries
    }
    This targets the nested "countries" dictionary and filters keys based on the active countries list.
  2. Added 6 unit and regression tests in test/test_build_admin_shapes.py, including a regression test that explicitly demonstrates the old code's silent failure.

All 6 unit tests pass successfully locally.

Checklist

Required:

  • Changes are tested locally and behave as expected.
  • Code and workflow changes are documented.
  • A release note entry is added to doc/release_notes.md.

If applicable:

  • Changes in configuration options are reflected in scripts/lib/validation.
  • For new data sources or versions, these instructions have been followed.
  • New rules are documented in the appropriate doc/*.md files.

stan-buren and others added 2 commits June 18, 2026 17:21
Fixes PyPSA#2207. Individual country overrides in clustering.administrative.countries
were silently ignored because the script filtered admin_levels at the root
level instead of parsing the nested 'countries' dictionary.

- Update dict comprehension in base_network.py and cluster_network.py
  to extract country levels from nested 'countries' config
- Add unit and regression tests covering overrides extraction, key leaks, and edge cases
- Update release notes
@fneum
fneum requested a review from bobbyxng June 23, 2026 10:51
@stan-buren

Copy link
Copy Markdown
Contributor Author

I've extracted the country NUTS level extraction logic into a shared helper function extract_country_level in _helpers.py, and refactored both base_network.py and cluster_network.py to use it.

I also updated the tests to import this helper directly, removed the local duplicate definition, and cleaned up the redundant regression test that contained a copy of the old buggy comprehension.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Individual NUTS level definition not working in clustering.administrative.countries config setting

1 participant