Skip to content

Conversation

@kalpana-pardeep-rassani
Copy link

@kalpana-pardeep-rassani kalpana-pardeep-rassani commented Nov 28, 2025

Before submitting a pull request (PR), please read the contributing guide.

Please fill out as much of this template as you can, but if you have any problems or questions, just leave a comment and we will help out :)

Description

What is this PR

  • Bug fix
  • Addition of a new feature
  • Other

Why is this PR needed?
The current implementation crashes with a KeyError: 'atlases' if the local custom_atlases.conf file exists but is empty (contains no sections). This prevents the brainglobe list command from running.

What does this PR do?
This PR modifies the get_all_atlases_lastversions function in brainglobe_atlasapi/list_atlases.py to use a safe .get("atlases", {}) method when reading the custom atlas configuration. This ensures that an empty dictionary is used if the 'atlases' section is missing, thus preventing the crash.

References

Fixes #668

How has this PR been tested?

The fix was tested locally by ensuring that the brainglobe list command runs successfully without crashing when the ~/.brainglobe/custom_atlases.conf file is present but completely empty.

Is this a breaking change?

No. This is a fix for an existing bug and does not change any public API or required functionality.

Does this PR require an update to the documentation?

No.

Checklist:

  • [done] The code has been tested locally
  • [done] Tests have been added to cover all new functionality (unit & integration)
  • The documentation has been updated to reflect any changes
  • [done] The code has been formatted with pre-commit
    Note on Test Failures:

All code changes related to Issue #668 (empty config file) have been verified locally. When running the full test suite, I encountered 2 ConnectionErrors (due to the GIN server being unreachable) and 1 FileNotFoundError (due to missing local test data), which are external to this fix. The patch itself is clean.

Copy link
Member

@alessandrofelder alessandrofelder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @kalpana-pardeep-rassani

I unfortunately haven't had time for an in-depth review (hopefully by the end of this week) - apologies. I have some high-level comments for you though which are hopefully helpful. Let me know what you think.

Comment on lines 80 to 89
# --- FIX APPLIED HERE ---
# Safely get the custom atlases data. If the 'atlases' section does not
# exist (e.g., file is empty), custom_atlases.get("atlases", {}) returns {}
# instead of crashing.
custom_atlas_data = custom_atlases.get("atlases", {})

return {**official_atlases["atlases"], **custom_atlas_data}


# The get_atlases_lastversions function below this should remain unchanged.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# --- FIX APPLIED HERE ---
# Safely get the custom atlases data. If the 'atlases' section does not
# exist (e.g., file is empty), custom_atlases.get("atlases", {}) returns {}
# instead of crashing.
custom_atlas_data = custom_atlases.get("atlases", {})
return {**official_atlases["atlases"], **custom_atlas_data}
# The get_atlases_lastversions function below this should remain unchanged.
# Safely get the custom atlases data. If the 'atlases' section does not
# exist (e.g., file is empty), custom_atlases.get("atlases", {}) returns {}
# instead of crashing.
custom_atlas_data = custom_atlases.get("atlases", {})
return {**official_atlases["atlases"], **custom_atlas_data}

I think some of these comments relate to the PR, and not the code itself - so I don't think they belong in the code. Do you agree (I may have missed something)?

return table


def test_empty_config_file_no_crash(tmp_path):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test looks reasonable at first glance but I think it should go somewhere in the tests folder with the other tests. It will be picked up by pytest there!

"""

import re
import warnings # Adding this line
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
import warnings # Adding this line
import warnings

I don't think this comment is useful - it is very generic and not related to the line of code AFAICT

@kalpana-pardeep-rassani kalpana-pardeep-rassani force-pushed the fix/issue-668-empty-conf branch 2 times, most recently from cc46f34 to 6d53dd6 Compare December 1, 2025 18:16
@kalpana-pardeep-rassani
Copy link
Author

kalpana-pardeep-rassani commented Dec 1, 2025 via email

@alessandrofelder
Copy link
Member

I don't think you've addressed any of my comments with your latest changes @kalpana-pardeep-rassani
Maybe something went wrong during pushing?

Most importantly, AFAICT, the test you wrote is in the wrong place, and will therefore not be run by pytest!

@kalpana-pardeep-rassani
Copy link
Author

those 'windows' and 'mac' (pull requests) are cancelled during test, how do i tackle this issue, please guide.. and also these skipped pull requesets what to do with them?

@adamltyson
Copy link
Member

I've re-run the tests.

Copy link
Member

@alessandrofelder alessandrofelder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @kalpana-pardeep-rassani - there is more work needed on the tests. They could be simpler. I hope my comments are helpful.

return dict(official_atlases["atlases"])
return {**official_atlases["atlases"], **custom_atlases["atlases"]}

# --- FIX APPLIED HERE ---
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# --- FIX APPLIED HERE ---

This will not mean anything after this issue is fixed - it's too generic and makes the code harder to interpret. So I think it should be remove.


def test_get_downloaded_atlases():
@pytest.fixture
def mock_atlas_dir(tmp_path, mocker):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the functionality in this fixture is already implemented in https://github.com/brainglobe/brainglobe-atlasapi/blob/main/tests/conftest.py and ready for you to use here, so I would suggest

  • removing it here
  • refactoring your test to use the existing functionality
    so we don't have to look after duplicate code.

assert expected_print in captured.out


def test_empty_custom_config_no_crash(tmp_path: Path, mocker):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is sufficient to only add this test, and not change any of the other tests - they test things that are unrelated to the issue we are trying to fix.

I also think this test could be a lot simpler. You only need to check that

  • when you have an empty custom_atlases.conf file...
    *... then the function doesn't crash, and possibly returns some existing atlases that are not custom.

It shouldn't need to be this long, or involve so many mocks. You can re-use some existing fixtures from conftest.py as I suggested in a previous comment.

@adamltyson
Copy link
Member

Hi @kalpana-pardeep-rassani are you able to get back to this PR?

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.

[BUG] Empty custom_atlases.conf file leads to crash

4 participants