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

ValueError: not enough values to unpack (expected 2, got 1) #464

Open
R-Rajaie opened this issue Jan 29, 2025 · 2 comments
Open

ValueError: not enough values to unpack (expected 2, got 1) #464

R-Rajaie opened this issue Jan 29, 2025 · 2 comments

Comments

@R-Rajaie
Copy link

Hi,

I have a project in which I am attempting to retrieve match data. This code worked in the latter half of last year, but recently it throws me this error when I try to access a match from match history.

Here is the block I am attempting to run:

me = cass.get_account(name = "KC TARGHAMAS", tagline = "miku", region = "NA").summoner
len(me.match_history)

And here is the traceback:

ValueError                                Traceback (most recent call last)
Cell In[22], line 2
      1 me = cass.get_account(name = "KC TARGHAMAS", tagline = "miku", region = "NA").summoner
----> 2 len(me.match_history)

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\merakicommons\container.py:363, in LazyList.__len__(self)
    361     return super().__len__()
    362 else:
--> 363     self._generate_more()
    364     return super().__len__()

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\merakicommons\container.py:380, in LazyList._generate_more(self, count)
    378         next(self)
    379 else:
--> 380     for _ in self:
    381         pass
    382     assert self._empty

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\merakicommons\container.py:355, in LazyList.__iter__(self)
    353 while not self._empty:
    354     try:
--> 355         yield next(self)
    356     except StopIteration:
    357         return

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\merakicommons\container.py:368, in LazyList.__next__(self)
    366 def __next__(self):
    367     try:
--> 368         value = next(self._generator)
    369         super().append(value)
    370     except StopIteration as error:

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\cassiopeia\datastores\ghost.py:646, in UnloadedGhostStore.get_match_history.<locals>.generate_matchlists(start, count)
    644 pulled_matches += 1
    645 if pulled_matches > 0:
--> 646     match = Match.from_match_reference(matchrefdata)
    647     yield match
    648 if pulled_matches >= count:

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\cassiopeia\core\match.py:1961, in Match.from_match_reference(cls, ref)
   1959 @classmethod
   1960 def from_match_reference(cls, ref: MatchReferenceData):
-> 1961     platform, id = ref.id.split("_")
   1962     id = int(id)
   1963     platform = Platform(platform)

ValueError: not enough values to unpack (expected 2, got 1)

I have attempted trying different users, but I still get this. Not sure if I'm doing something wrong, as I'm not too experienced in dealing with APIs. I'm not 100% sure this is something on Cassiopeia's side that broke it, maybe changes in the API? Again, it's not my area of expertise, so I'd appreciate any guidance or help.
Thank you for your time.

@PeteyPii
Copy link

Seems like the issue is here: https://github.com/meraki-analytics/cassiopeia/blame/48184665b79ecda0197b3a31f75f99ba6d462831/cassiopeia/datastores/common.py#L255

            # Decode to text if a charset is included
            match = re.search("CHARSET=(\S+)", content_type)
            if match:
                # Load JSON if necessary
                if "APPLICATION/JSON" in content_type:
                    body = r.json()
                else:
                    body = r.content.decode("utf-8")
            elif "IMAGE/" in content_type:
                body = r.content
            else:
                body = r.content.decode("utf-8")

I'm guessing the Riot API used to return charset=utf-8 in the Content-Type header, but no longer does so the logic breaks. Maybe it can be simplified to the below.

            if "APPLICATION/JSON" in content_type:
                body = r.json()
            elif "IMAGE/" in content_type:
                body = r.content
            else:
                body = r.content.decode("utf-8")

PeteyPii added a commit to PeteyPii/cassiopeia that referenced this issue Jan 31, 2025
@R-Rajaie
Copy link
Author

R-Rajaie commented Feb 10, 2025

Hey,

This fix works for me. I'm now getting issues when fetching patches but I think that's a whole nother issue concerning how Riot changed their patch naming system.

Edit: After testing some more, it seems there may be a deeper issue at hand. Not sure if it's from your fix or is a separate issue that has arisen, but I get an assortment of errors when I try to fetch a variety of different things.

Here is an example:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\merakicommons\cache.py:15, in lazy.<locals>.wrapper(self)
     14 try:
---> 15     return getattr(self, s)
     16 except AttributeError:

AttributeError: 'ParticipantStats' object has no attribute '_lazy__items'

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\merakicommons\ghost.py:41, in ghost_load_on.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
     40 try:
---> 41     return method(*args, **kwargs)
     42 except errors as error:

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\cassiopeia\core\staticdata\realm.py:63, in Realms.version(self)
     60 @CassiopeiaGhost.property(RealmData)
     61 @ghost_load_on
     62 def version(self) -> str:
---> 63     return self._data[RealmData].version

AttributeError: 'RealmData' object has no attribute 'version'

During handling of the above exception, another exception occurred:

GhostLoadingRequiredError                 Traceback (most recent call last)
File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\merakicommons\ghost.py:87, in Ghost.__property.__get__(self, obj, obj_type)
     86 try:
---> 87     return self.fget(obj)
     88 except GhostLoadingRequiredError:

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\merakicommons\ghost.py:43, in ghost_load_on.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
     42 except errors as error:
---> 43     raise GhostLoadingRequiredError(str(error))

GhostLoadingRequiredError: 'RealmData' object has no attribute 'version'

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\datapipelines\sources.py:69, in DataSource.dispatch.<locals>.wrapper(self, type, query, context)
     68 try:
---> 69     return call(self, query, context=context)
     70 except TypeError:

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\datapipelines\queries.py:326, in validate_query.<locals>.wrapper.<locals>.wrapped(self, query, context)
    325 validator(query)
--> 326 return method(self, query, context)

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\cassiopeia\datastores\ddragon.py:273, in DDragon.get_realms(self, query, context)
    272 try:
--> 273     body = json.loads(self._client.get(url)[0])
    275 except HTTPError as e:

File ~\AppData\Local\Programs\Python\Python312\Lib\json\__init__.py:339, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    338 if not isinstance(s, (bytes, bytearray)):
--> 339     raise TypeError(f'the JSON object must be str, bytes or bytearray, '
    340                     f'not {s.__class__.__name__}')
    341 s = s.decode(detect_encoding(s), 'surrogatepass')

TypeError: the JSON object must be str, bytes or bytearray, not dict

During handling of the above exception, another exception occurred:

UnsupportedError                          Traceback (most recent call last)
Cell In[42], line 4
      2 match = me.match_history[0]
      3 participant = match.teams[0].participants[0]
----> 4 participant.stats.items

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\merakicommons\cache.py:17, in lazy.<locals>.wrapper(self)
     15     return getattr(self, s)
     16 except AttributeError:
---> 17     value = method(self)
     18     setattr(self, s, value)
     19     return value

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\cassiopeia\core\match.py:56, in load_match_on_attributeerror.<locals>.wrapper(self, *args, **kwargs)
     53 @functools.wraps(method)
     54 def wrapper(self, *args, **kwargs):
     55     try:
---> 56         return method(self, *args, **kwargs)
     57     except AttributeError:  # teamId
     58         # The match has only partially loaded this participant and it doesn't have all it's data, so load the full match
     59         match = getattr(self, "_{}__match".format(self.__class__.__name__))

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\cassiopeia\core\match.py:1349, in ParticipantStats.items(self)
   1337 ids = [
   1338     self._data[ParticipantStatsData].item0,
   1339     self._data[ParticipantStatsData].item1,
   (...)
   1344     self._data[ParticipantStatsData].item6,
   1345 ]
   1346 version = _choose_staticdata_version(self.__match)
   1347 return SearchableList(
   1348     [
-> 1349         Item(id=id, version=version, region=self.__match.region) if id else None
   1350         for id in ids
   1351     ]
   1352 )

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\cassiopeia\core\common.py:197, in GetFromPipeline.__call__(cls, *args, **kwargs)
    191 query = cls.__get_query_from_kwargs__(**kwargs)
    192 if (
    193     hasattr(cls, "version")
    194     and query.get("version", None) is None
    195     and cls.__name__ not in ["Realms", "Match"]
    196 ):
--> 197     query["version"] = get_latest_version(region=query["region"], endpoint=None)
    198 return pipeline.get(cls, query=query)

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\cassiopeia\core\common.py:33, in get_latest_version(region, endpoint)
     31     return Realms(region=region).latest_versions[endpoint]
     32 else:
---> 33     return Realms(region=region).version

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\merakicommons\ghost.py:90, in Ghost.__property.__get__(self, obj, obj_type)
     88 except GhostLoadingRequiredError:
     89     load_group = self.fget._Ghost__load_group
---> 90     obj.__load__(load_group)
     91     obj._Ghost__set_loaded(load_group)
     93     return self.fget(obj)

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\cassiopeia\core\common.py:272, in CassiopeiaGhost.__load__(self, load_group, load_groups)
    264 if (
    265     hasattr(self.__class__, "version")
    266     and "version" not in query
    267     and self.__class__.__name__ not in ["Realms", "Match"]
    268 ):
    269     query["version"] = get_latest_version(
    270         region=query["region"], endpoint=None
    271     )
--> 272 data = configuration.settings.pipeline.get(
    273     type=self._load_types[load_group], query=query
    274 )
    275 self.__load_hook__(load_group, data)

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\datapipelines\pipelines.py:459, in DataPipeline.get(self, type, query)
    457 for handler in handlers:
    458     try:
--> 459         return handler.get(query, context)
    460     except NotFoundError:
    461         pass

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\datapipelines\pipelines.py:185, in _SourceHandler.get(self, query, context)
    170 def get(self, query: Mapping[str, Any], context: PipelineContext = None) -> T:
    171     """Gets a query from the data source.
    172 
    173     1) Extracts the query from the data source.
   (...)
    183         The requested object.
    184     """
--> 185     result = self._source.get(self._source_type, deepcopy(query), context)
    186     LOGGER.info("Got result \"{result}\" from query \"{query}\" of source \"{source}\"".format(result=result, query=query, source=self._source))
    188     LOGGER.info("Sending result \"{result}\" to sinks before converting".format(result=result))

File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\datapipelines\sources.py:71, in DataSource.dispatch.<locals>.wrapper(self, type, query, context)
     69     return call(self, query, context=context)
     70 except TypeError:
---> 71     raise DataSource.unsupported(type)

UnsupportedError: The type "RealmDto" is not supported by this DataSource!

I got these sorts of errors when also fetching match.patch, team.bans, participant.champion, participant.runes, and participant.summoner_spell_d (and f). Sometimes I didn't get the AttributeError: <x> object has no attribute '_lazy__<y>' or AttributeError: 'RealmData' object has no attribute 'version'.

The only common link is that each command that doesn't work is one that calls https://ddragon.leagueoflegends.com/realms/na.json, so I feel as if it has something to do with how it now interacts with datadragon/dto objects. I decided to install the cassiopeia-diskstore plugin to see if it would change anything as per this article but it didn't seem to really affect anything. Again, not sure if this is from your fix or in general.

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