fondberg / spotcast

Home assistant custom component to start Spotify playback on an idle chromecast device as well as control spotify connect devices
Apache License 2.0
640 stars 94 forks source link

HA 2024.2 with Python 3.12 raise an TypeError #432

Open difrost opened 4 months ago

difrost commented 4 months ago

Bug Ticket

Describe the bug

Due to the randrange() changes introduced in Python 3.12 Spotcast raise an TypeError:

 File "/config/custom_components/spotcast/__init__.py", line 285, in start_casting
    spotcast_controller.play(
  File "/config/custom_components/spotcast/spotcast_controller.py", line 370, in play
    position = random.randint(0, results["total"] - 1)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/random.py", line 336, in randint
    return self.randrange(a, b+1)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/random.py", line 312, in randrange
    istop = _index(stop)
            ^^^^^^^^^^^^
TypeError: 'float' object cannot be interpreted as an integer

See following note:

Remove randrange() functionality deprecated since Python 3.10. Formerly, randrange(10.0) losslessly converted to randrange(10). Now, it raises a [TypeError](https://docs.python.org/3/library/exceptions.html#TypeError). Also, the exception raised for non-integer values such as randrange(10.5) or randrange('10') has been changed from [ValueError](https://docs.python.org/3/library/exceptions.html#ValueError) to [TypeError](https://docs.python.org/3/library/exceptions.html#TypeError). This also prevents bugs where randrange(1e25) would silently select from a larger range than randrange(10**25).

Troubleshooting

Make sure to validate all the elements before submitting the ticket (Exception to the steps marked as optional)

Environment

difrost commented 4 months ago

As a quick check I've done a cast to int and that "fixes" the issue:

           if random_song:
                if uri.find("album") > 0:
                    results = client.album_tracks(uri, market=country_code)
                    position = random.randint(0, int(results["total"]) - 1)
                elif uri.find("playlist") > 0:
                    results = client.playlist_tracks(uri)
                    position = random.randint(0, int(results["total"]) - 1)
                elif uri.find("collection") > 0:
                    results = client.current_user_saved_tracks()
                    position = random.randint(0, int(results["total"]) - 1)
                _LOGGER.debug(
                    "Start playback at random position: %s", position)

I'm not sure if that's correct tho can't find a reason why direct cast might cause some future errors. I can make a PR for review.

NOTE: I'm not a Python dev :smile:

fcusson commented 4 months ago

Thanks for the info. If you submit a pr can you just add a comment saying

# TODO: review random position algo

I want to revisit it later, but at least we could fix the dependency issue quick.