[GH-ISSUE #621] Garbage collection sets requests.Session to None before __del__ is called (TypeError) #370

Closed
opened 2026-02-27 23:22:16 +03:00 by kerem · 7 comments
Owner

Originally created by @RobinReborn on GitHub (Dec 3, 2020).
Original GitHub issue: https://github.com/spotipy-dev/spotipy/issues/621

Describe the bug
Exception raised after Django migration, ie
python manage.py migrate within a pipenv
Your code
I can share my django models and migrations and Pipfile if necessary
Expected behavior
A clear and concise description of what you expected to happen.

Output
Exception ignored in: <function Spotify.__del__ at 0x7fb96d7d4680> Traceback (most recent call last): File "/home/robin/.virtualenvs/moodstream-django-EtsEGWRm/lib/python3.7/site-packages/spotipy/client.py", line 188, in __del__ TypeError: isinstance() arg 2 must be a type or tuple of types Exception ignored in: <function SpotifyAuthBase.__del__ at 0x7fb96d8088c0> Traceback (most recent call last): File "/home/robin/.virtualenvs/moodstream-django-EtsEGWRm/lib/python3.7/site-packages/spotipy/oauth2.py", line 136, in __del__ TypeError: isinstance() arg 2 must be a type or tuple of types
Environment:

  • Python version [3.7.0]
  • spotipy version [2.15.0]

Additional context
Add any other context about the problem here.

Originally created by @RobinReborn on GitHub (Dec 3, 2020). Original GitHub issue: https://github.com/spotipy-dev/spotipy/issues/621 **Describe the bug** Exception raised after Django migration, ie `python manage.py migrate` within a pipenv **Your code** I can share my django models and migrations and Pipfile if necessary **Expected behavior** A clear and concise description of what you expected to happen. **Output** `Exception ignored in: <function Spotify.__del__ at 0x7fb96d7d4680> Traceback (most recent call last): File "/home/robin/.virtualenvs/moodstream-django-EtsEGWRm/lib/python3.7/site-packages/spotipy/client.py", line 188, in __del__ TypeError: isinstance() arg 2 must be a type or tuple of types Exception ignored in: <function SpotifyAuthBase.__del__ at 0x7fb96d8088c0> Traceback (most recent call last): File "/home/robin/.virtualenvs/moodstream-django-EtsEGWRm/lib/python3.7/site-packages/spotipy/oauth2.py", line 136, in __del__ TypeError: isinstance() arg 2 must be a type or tuple of types ` **Environment:** - Python version [3.7.0] - spotipy version [2.15.0] **Additional context** Add any other context about the problem here.
kerem 2026-02-27 23:22:16 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@stephanebruckert commented on GitHub (Dec 8, 2020):

I cannot think of anything obvious, it would be useful to get a bit more context:

  • what is the migration doing?
  • are you calling __del__ yourself?
  • can it be reproduced outside a django migration?
<!-- gh-comment-id:740673272 --> @stephanebruckert commented on GitHub (Dec 8, 2020): I cannot think of anything obvious, it would be useful to get a bit more context: - what is the migration doing? - are you calling `__del__` yourself? - can it be reproduced outside a django migration?
Author
Owner

@menef0124 commented on GitHub (Jun 30, 2021):

I also get the same exact exceptions raised just from having the line import flask in one of my scripts. I haven't actually written anything using Flask yet and the script works fine but the exceptions still occur.

<!-- gh-comment-id:871016240 --> @menef0124 commented on GitHub (Jun 30, 2021): I also get the same exact exceptions raised just from having the line `import flask` in one of my scripts. I haven't actually written anything using Flask yet and the script works fine but the exceptions still occur.
Author
Owner

@succinct commented on GitHub (Mar 20, 2022):

I'm seeing this same issue when I compile to an executable via nuitka, e.g.:

python -m nuitka --follow-imports --standalone program.py

The exact same program.py throws no errors when I run it normally, but once it's migrated to an executable I get the following errors which essentially mirror the above description:

Exception ignored in: <compiled_function Spotify.__del__ at 0x000002566E6B3F10>
Traceback (most recent call last):
  File "C:\Users\<REDACTED>\AppData\Local\Temp\ONEFIL~1\spotipy\client.py", line 188, in __del__
TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union
Exception ignored in: <compiled_function SpotifyAuthBase.__del__ at 0x000002566E7A8130>   
Traceback (most recent call last):
  File "C:\Users\<REDACTED>\AppData\Local\Temp\ONEFIL~1\spotipy\oauth2.py", line 156, in __del__
TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union

This is with Python 2.10.3 and Spotipy 2.19.0 on Windows 10

<!-- gh-comment-id:1073356369 --> @succinct commented on GitHub (Mar 20, 2022): I'm seeing this same issue when I compile to an executable via nuitka, e.g.: `python -m nuitka --follow-imports --standalone program.py` The exact same program.py throws no errors when I run it normally, but once it's migrated to an executable I get the following errors which essentially mirror the above description: ``` Exception ignored in: <compiled_function Spotify.__del__ at 0x000002566E6B3F10> Traceback (most recent call last): File "C:\Users\<REDACTED>\AppData\Local\Temp\ONEFIL~1\spotipy\client.py", line 188, in __del__ TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union Exception ignored in: <compiled_function SpotifyAuthBase.__del__ at 0x000002566E7A8130> Traceback (most recent call last): File "C:\Users\<REDACTED>\AppData\Local\Temp\ONEFIL~1\spotipy\oauth2.py", line 156, in __del__ TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union ``` This is with Python 2.10.3 and Spotipy 2.19.0 on Windows 10
Author
Owner

@zlonghofer commented on GitHub (Mar 2, 2025):

@stephanebruckert I'm experiencing this in a simple Python script.

from dotenv import load_dotenv
from spotipy import Spotify, SpotifyOAuth

if __name__ == "__main__":
    load_dotenv(override=True)
    sp = Spotify()

Specifically, when I save the above block of code to test.py, I run the following commands in Powershell using Python 3.13.0 and Spotipy 2.25.1:

  • py test.py results in no error message.
  • py -i test.py followed immediately by quit() results in the error message shown above.

This is likely due to the garbage collection mechanism differences in an interactive session. Spotipy.__del__ references the module variable requests.Session after it has been deleted by the Python interpreter during cleanup. It is likely that differences in cleanup order from the compiled executable and the django migration.

def __del__(self):
    """Make sure the connection (pool) gets closed"""
    try:
        if isinstance(self._session, requests.Session):
            self._session.close()
    except AttributeError:
        pass

Since requests.Session has already been deleted, its type is <NoneType>, which throws the error.

Unfortunately, the same cleanup mechanism is also present in SpotifyOAuth.__del__ (and quite probably in other locations throughout the codebase). Comprehensive resolution of this issue would probably require checking the __del__ methods on each object throughout the codebase and adding a check that the requests.Session module-level import hasn't yet been deleted.

<!-- gh-comment-id:2692947245 --> @zlonghofer commented on GitHub (Mar 2, 2025): @stephanebruckert I'm experiencing this in a simple Python script. ``` from dotenv import load_dotenv from spotipy import Spotify, SpotifyOAuth if __name__ == "__main__": load_dotenv(override=True) sp = Spotify() ``` Specifically, when I save the above block of code to test.py, I run the following commands in Powershell using Python 3.13.0 and Spotipy 2.25.1: - `py test.py` results in *no* error message. - `py -i test.py` followed immediately by `quit()` results in the error message shown above. This is likely due to the garbage collection mechanism differences in an interactive session. `Spotipy.__del__` references the module variable `requests.Session` after it has been deleted by the Python interpreter during cleanup. It is likely that differences in cleanup order from the compiled executable and the django migration. ``` def __del__(self): """Make sure the connection (pool) gets closed""" try: if isinstance(self._session, requests.Session): self._session.close() except AttributeError: pass ``` Since `requests.Session` has already been deleted, its `type` is `<NoneType>`, which throws the error. Unfortunately, the same cleanup mechanism is also present in `SpotifyOAuth.__del__` (and quite probably in other locations throughout the codebase). Comprehensive resolution of this issue would probably require checking the `__del__` methods on each object throughout the codebase and adding a check that the `requests.Session` module-level import hasn't yet been deleted.
Author
Owner

@dieser-niko commented on GitHub (Mar 3, 2025):

Finally something to reproduce this bug. But yes, I have to agree, it's probably Python's garbage collector. The easiest fix would be to just catch the TypeError like we're already doing with the AttributeError.

Alternatively, we could just "rescue" the requests.Session object by storing it as a variable or something.

Oddly enough, I had to install Python 3.13.0 to get this error. By default I have 3.12.6 installed, where I didn't get the error.

Also, it's possible to minimize the script even more:

from spotipy import Spotify
sp = Spotify()
<!-- gh-comment-id:2693645871 --> @dieser-niko commented on GitHub (Mar 3, 2025): Finally something to reproduce this bug. But yes, I have to agree, it's probably Python's garbage collector. The easiest fix would be to just catch the `TypeError` like we're already doing with the `AttributeError`. Alternatively, we could just "rescue" the `requests.Session` object by storing it as a variable or something. Oddly enough, I had to install Python 3.13.0 to get this error. By default I have 3.12.6 installed, where I didn't get the error. Also, it's possible to minimize the script even more: ```python from spotipy import Spotify sp = Spotify() ```
Author
Owner

@zlonghofer commented on GitHub (Mar 3, 2025):

Wouldn't "rescuing" the requests.Session object be cleaner?

temp_session = requests.Session
Class Spofity:
    def __del__(self):
        if getattr(self, "_session", None) and isinstance(self._session, temp_session):
            self._session.close()

resolves both the AttributeError and the TypeError relying on Python's short-circuiting. If we're checking that the _session attribute exists, the Pythonic way to do this is with getattr.

<!-- gh-comment-id:2694349166 --> @zlonghofer commented on GitHub (Mar 3, 2025): Wouldn't "rescuing" the `requests.Session` object be cleaner? ``` temp_session = requests.Session Class Spofity: def __del__(self): if getattr(self, "_session", None) and isinstance(self._session, temp_session): self._session.close() ``` resolves both the `AttributeError` and the `TypeError` relying on Python's short-circuiting. If we're checking that the `_session` attribute exists, the Pythonic way to do this is with `getattr`.
Author
Owner

@dieser-niko commented on GitHub (Mar 3, 2025):

I guess that would be one way to do it. Relying on catching errors isn't really a good idea if there are other alternatives IMO.

<!-- gh-comment-id:2694769998 --> @dieser-niko commented on GitHub (Mar 3, 2025): I guess that would be one way to do it. Relying on catching errors isn't really a good idea if there are other alternatives IMO.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/spotipy#370
No description provided.