Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Settings: Handle empty Groups #4576

Merged
merged 4 commits into from
Feb 1, 2025

Conversation

qwint
Copy link
Collaborator

@qwint qwint commented Jan 29, 2025

What is this fixing or adding?

alternative to #4452
issue was an apworld that defined

class mySettings(settings.Group):
    pass

and added it as their world.settings type hint to register it, causing late crashes

while the previous solution tried to crash the world early enough to not affect other worlds' settings, this pr instead aims to accept an empty Group as valid and to handle an empty dict type cache directly
export empty groups as an empty dict instead of crashing

How was this tested?

made emerald null out their settings class
on an empty file exported as

pokemon_emerald_settings:
  {}

get_settings().pokemon_emerald_settings returned the class which did not have attributes as expected
reverting emerald changes and re-saving the file populated the section as expected

pokemon_emerald_settings:
  # File name of your English Pokemon Emerald ROM
  rom_file: "Pokemon - Emerald Version (USA, Europe).gba"

If this makes graphical changes, please attach screenshots.

@github-actions github-actions bot added affects: core Issues/PRs that touch core and may need additional validation. waiting-on: peer-review Issue/PR has not been reviewed by enough people yet. labels Jan 29, 2025
Copy link
Member

@black-sliver black-sliver left a comment

Choose a reason for hiding this comment

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

Not sure yet if we want this solution (or both), but It's less messy than the other solution, so maybe.

settings.py Outdated Show resolved Hide resolved
Co-authored-by: black-sliver <[email protected]>
Copy link
Member

@black-sliver black-sliver left a comment

Choose a reason for hiding this comment

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

Thanks!

While I still believe it is probably a mistake to have an empty group, I can think of one legit reason, so in combination with the cleaner code, this probably the best solution until someone runs into other problems 😅

Copy link
Member

@black-sliver black-sliver left a comment

Choose a reason for hiding this comment

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

Something is failing for me on that branch. Blocking merge for now, will update once I figured out what.

@black-sliver
Copy link
Member

black-sliver commented Jan 30, 2025

Okay, I figured out what the problem is:
when upgrading the host.yaml, e.g. with python Launcher.py --update_settings and you already have a key in the Group and the new Group does not have members, then it'll write both the {} as well as the old key, i.e.

pokemon_emerald_settings:
  {}
  rom_file: "path/to/file"

--
This is expected behaviour:
When loading arbitrary values from the yaml, it'll set them as attributes and you can access them like any yaml dict. When saving that again (after the upgrade), it'll ignore the type hint and just use the object's type, but will still write the attribute.

@qwint
Copy link
Collaborator Author

qwint commented Jan 30, 2025

not sure i understand the codepath in question, but would ideal functionality "notice" that keys are going to be added and skip the empty dict write?

settings.py Outdated
@@ -270,6 +270,9 @@ def dump(self, f: TextIO, level: int = 0) -> None:
# fetch class to avoid going through getattr
cls = self.__class__
type_hints = cls.get_type_hints()
if not type_hints:
# write empty dict for empty Group
cls._dump_value(type_hints, f, indent=" " * level)
Copy link
Member

Choose a reason for hiding this comment

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

This adds {} if the class is empty, but loading a yaml can add values to the instance that will then get dumped in line 289.

@ScipioWright ScipioWright added the is: bug/fix Issues that are reporting bugs or pull requests that are fixing bugs. label Jan 30, 2025
@qwint
Copy link
Collaborator Author

qwint commented Jan 30, 2025

tested with an empty host.yaml with and without emerald's settings object mangled
then attempted to use --update_settings to switch between mangled and unmangled and saw things act as expected and only add the empty dict when there is no other values to print

settings.py Outdated Show resolved Hide resolved
settings.py Outdated Show resolved Hide resolved
@qwint
Copy link
Collaborator Author

qwint commented Feb 1, 2025

some quick testing those updates seem to work well

Copy link
Member

@black-sliver black-sliver left a comment

Choose a reason for hiding this comment

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

Reran the broken case now and works. Thanks!

@black-sliver black-sliver merged commit 445c9b2 into ArchipelagoMW:main Feb 1, 2025
16 checks passed
@qwint qwint deleted the settings_empty_group branch February 1, 2025 01:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects: core Issues/PRs that touch core and may need additional validation. is: bug/fix Issues that are reporting bugs or pull requests that are fixing bugs. waiting-on: peer-review Issue/PR has not been reviewed by enough people yet.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants