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

Recursive Item Data: New boots reference a reference. #104

Open
tsworc opened this issue Jan 11, 2025 · 1 comment
Open

Recursive Item Data: New boots reference a reference. #104

tsworc opened this issue Jan 11, 2025 · 1 comment

Comments

@tsworc
Copy link

tsworc commented Jan 11, 2025

I found this issue running py -m lolstaticdata.items upon reaching the new boot upgrade "Forever Forward".
This item is the boots upgrade to Synchronized Souls which is a transformation of the tier 2 boots Symbiotic Soles.
They all share the passive "Voidborn" which gives empowered recall.
In the wiki data, a value containing "=>" followed by an item name indicates a reference to some shared value.
So these boots "Forever Forward" have as their first passive "=>Synchronized Souls", which in turn have as their first passive "=>Symbiotic Soles".
lolstaticdata already handles 1 reference but it does not handle when that result is another reference, atleast not for passives.
The error I found occurs in the file "pull_items_wiki.py" in the function "_parse_passive_info" in the code:
return unique, mythic, name, passive["description"], item_range, cd
The passive["description"] part is meant to be a dictionary with a "description" key but it crashes on "Forever Forward" because the passive is a string "=>Symbiotic Soles" (the value taken from Synchronized Souls) and thus it expects an integer index for a string instead of a string index for a dictionary and crashes.
To be clear the original value of this passive was "=>Synchronized Souls" which then was replaced with "=>Symbiotic Soles" and it just needs one more step to get to the actual voidborn passive object inside Symbiotic Soles.
I fixed this by defining a recursive function that will keep following the "=>" references until it reaches a non-string non-reference then return that, while also trying to track the failed keys to pop them later. This item might be a special case but heres the recursive method I wrote (I don't normally use python so not sure about pull requesting it).

    @classmethod
    def _parse_item_data(cls, item_data: dict, item_name:str,wiki_data:dict) -> Item:
        not_unique = re.compile("[A-z]")
        clear_keys = []
        builds_from = []
        nicknames = []
        clear_keys_2 = []
        def resolve_entry(current_item_name:str, key1: str, key2: Optional[str])->Optional[str]:
            candidate_entry = wiki_data[current_item_name][key1]
            if key2:
                candidate_entry = candidate_entry[key2]
            if type(candidate_entry) == str:
                if "=>" in candidate_entry:
                    try:
                        resolve_item_name = candidate_entry.replace("=>", "")
                        if key2:
                            print(F"Replace value of ['{key1}']['{key2}'] in item '{item_name}' with item '{resolve_item_name}'.")
                        else:
                            print(F"Replace value of ['{key1}'] in item '{item_name}' with item '{resolve_item_name}'.")
                        return resolve_entry(resolve_item_name, key1, key2)
                    except KeyError as e:
                        print(F"Replacement failed... {e}")
                        if key2:
                            clear_keys_2.append(key1,key2)
                            return item_data[key1][key2]
                        clear_keys.append(key1)
                        return item_data[key1]
            return candidate_entry
        for x in item_data:
            item_data[x] = resolve_entry(item_name, x, None)
            if x in "effects":
                for l in item_data[x]:
                    item_data[x][l] = resolve_entry(item_name, x, l)
            if x in "stats":
                for l in item_data[x]:
                    item_data[x][l] = resolve_entry(item_name, x, l)
        for key in clear_keys:
            item_data.pop(key)
        index2 = 0
        stored_clear_key = None
        for key in clear_keys_2:
            if index2 == 0:
                stored_clear_key = key
                index2 = 1
            else:
                item_data[stored_clear_key].pop(key)
                index2 = 0
@tsworc tsworc changed the title Recursive Item Data: New item references a reference. Recursive Item Data: New boots reference a reference. Jan 11, 2025
@Galvantua
Copy link
Contributor

I created a PR that should fix this #108
It's not recursive like this solution, but it handles 2 redirects fine (essentially manually checking for a second redirect)

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

No branches or pull requests

2 participants