Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions tests/test_cache.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
"""Tests for ``threadpoolctl``'s internal caching layer."""

import os
import subprocess
import sys
from ctypes import CDLL

import pytest
Expand Down Expand Up @@ -57,3 +60,52 @@ def cleanup():
# Only one call should ever happen when using the cached method, however:
assert libs[0].my_extra_method() is initial
assert libs[0].my_extra_method() is initial


@pytest.mark.skipif(
not sys.platform.startswith("linux"), reason="Relies on glibc being loaded"
)
def test_register_after_libraries_were_listed():
"""
A controller registered after a library was already listed (and cached as
unsupported) still finds it.
"""
# Run in a subprocess to keep the registered controller out of the other
# tests:
path = os.path.dirname(os.path.dirname(__file__))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The custom env seems unnecessary (I think it got copied from some other test, which probably doesn't need it either).

env = os.environ.copy()
env["PYTHONPATH"] = path + os.pathsep + env.get("PYTHONPATH", "")
script = """
from threadpoolctl import (
LibController,
ThreadpoolController,
get_cached_controller,
register,
)


class FakeController(LibController):
user_api = "fake"
internal_api = "fake"
filename_prefixes = ("libc.",)
check_symbols = ("printf",)

def get_num_threads(self):
return 1

def set_num_threads(self, num_threads):
pass

def get_version(self):
return None


# Lists glibc, which no controller matches yet:
assert not ThreadpoolController().select(user_api="fake").lib_controllers
assert not get_cached_controller().select(user_api="fake").lib_controllers

register(FakeController)
assert ThreadpoolController().select(user_api="fake").lib_controllers
assert get_cached_controller().select(user_api="fake").lib_controllers
"""
subprocess.check_call([sys.executable, "-c", script], env=env)
3 changes: 3 additions & 0 deletions threadpoolctl.py
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,9 @@ def register(controller):
_ALL_USER_APIS.append(controller.user_api)
_ALL_INTERNAL_APIS.append(controller.internal_api)
_ALL_PREFIXES.extend(controller.filename_prefixes)
# Libraries listed before this call may match the new controller:
_CDLL_CACHE._controller_cache.clear()
reset_cached_controller()


def _format_docstring(*args, **kwargs):
Expand Down
Loading