Skip to content

Fix RuntimeWarning and DeprecationWarning in test suite#62

Open
gkorland with Copilot wants to merge 12 commits into
masterfrom
copilot/fix-warnings-in-tests
Open

Fix RuntimeWarning and DeprecationWarning in test suite#62
gkorland with Copilot wants to merge 12 commits into
masterfrom
copilot/fix-warnings-in-tests

Conversation

Copilot AI commented Feb 4, 2026

Copy link
Copy Markdown

Two warnings were appearing during test execution:

  • RuntimeWarning: coroutine 'AsyncManagementCommands.shutdown' was never awaited in client.py:112
  • DeprecationWarning: Use shutil.which instead of find_executable in debug.py:61

Changes

redislite/client.py: Runtime detection for async/sync shutdown

  • Added import asyncio and import inspect to handle async/sync shutdown methods
  • Implemented runtime check using inspect.iscoroutinefunction(self.shutdown):
    • If shutdown is a coroutine function (async), uses asyncio.run(self.shutdown(save=True, now=True, force=True)) to properly await the coroutine
    • If shutdown is a normal function (sync), calls self.shutdown(save=True, now=True, force=True) as originally intended
  • Gracefully handles both sync and async Redis implementations without hardcoding assumptions
  • Preserves the original method signature and properly executes async methods using asyncio.run()

redislite/debug.py: Replace deprecated find_executable with shutil.which

  • Changed import from distutils.spawn.find_executable to shutil.which
  • distutils.spawn.find_executable deprecated since Python 3.3

Warning

<issue_title>Warnings in tests</issue_title>
<issue_description>```
tests/test_client.py::TestRedisliteClient::test_redis_log_attribute
/home/runner/work/falkordblite/falkordblite/redislite/client.py:112: RuntimeWarning: coroutine 'AsyncManagementCommands.shutdown' was never awaited
self.shutdown(save=True, now=True, force=True)
Enable tracemalloc to get traceback where the object was allocated.
See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.
tests/test_configuration.py::TestRedisliteConfiguration::test_debug
tests/test_debug.py::TestRedisliteDebug::test_debug
/home/runner/work/falkordblite/falkordblite/redislite/debug.py:61: DeprecationWarning: Use shutil.which instead of find_executable
redis_server = find_executable('redis-server')
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html


## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>

<issue_title>Warnings in tests</issue_title>

<issue_description>```
tests/test_client.py::TestRedisliteClient::test_redis_log_attribute
/home/runner/work/falkordblite/falkordblite/redislite/client.py:112: RuntimeWarning: coroutine 'AsyncManagementCommands.shutdown' was never awaited
self.shutdown(save=True, now=True, force=True)
Enable tracemalloc to get traceback where the object was allocated.
See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.
tests/test_configuration.py::TestRedisliteConfiguration::test_debug
tests/test_debug.py::TestRedisliteDebug::test_debug
/home/runner/work/falkordblite/falkordblite/redislite/debug.py:61: DeprecationWarning: Use shutil.which instead of find_executable
redis_server = find_executable('redis-server')
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html


## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>
Original prompt

This section details on the original issue you should resolve

<issue_title>Warnings in tests</issue_title>
<issue_description>```
tests/test_client.py::TestRedisliteClient::test_redis_log_attribute
/home/runner/work/falkordblite/falkordblite/redislite/client.py:112: RuntimeWarning: coroutine 'AsyncManagementCommands.shutdown' was never awaited
self.shutdown(save=True, now=True, force=True)
Enable tracemalloc to get traceback where the object was allocated.
See https://docs.pytest.org/en/stable/how-to/capture-warnings.html#resource-warnings for more info.
tests/test_configuration.py::TestRedisliteConfiguration::test_debug
tests/test_debug.py::TestRedisliteDebug::test_debug
/home/runner/work/falkordblite/falkordblite/redislite/debug.py:61: DeprecationWarning: Use shutil.which instead of find_executable
redis_server = find_executable('redis-server')
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html


## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@gkorland gkorland marked this pull request as ready for review February 4, 2026 20:28
gkorland and others added 2 commits February 4, 2026 22:28
…ad of find_executable

Co-authored-by: gkorland <753206+gkorland@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix warnings in Redis Lite tests Fix RuntimeWarning and DeprecationWarning in test suite Feb 4, 2026
Copilot AI requested a review from gkorland February 4, 2026 20:37
Comment thread redislite/client.py Outdated
return # Let async wrapper handle shutdown
self.shutdown(save=True, now=True, force=True)
# Use execute_command to avoid async/sync confusion
self.execute_command('SHUTDOWN', 'SAVE', 'NOW', 'FORCE')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@copilot why not verify in runtime?

# Check if it's a coroutine function
if inspect.iscoroutinefunction(shutdown):
    await shutdown()
else:
    shutdown()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good suggestion! I've implemented the runtime check approach in commit ced665b.

The code now checks inspect.iscoroutinefunction(self.shutdown) at runtime:

  • If it's a coroutine function (async), uses execute_command (always synchronous)
  • Otherwise, calls self.shutdown() with the original parameters

This preserves the original method signature while handling both sync and async cases gracefully. All tests pass without warnings.

Co-authored-by: gkorland <753206+gkorland@users.noreply.github.com>
Copilot AI requested a review from gkorland February 6, 2026 08:49
Comment thread redislite/client.py Outdated
# Check if shutdown is a coroutine function to avoid async/sync confusion
if hasattr(self, 'shutdown') and inspect.iscoroutinefunction(self.shutdown):
# If it's async, use execute_command which is always synchronous
self.execute_command('SHUTDOWN', 'SAVE', 'NOW', 'FORCE')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@copilot don't you think it's better to use asyncio when calling the async API?

asyncio.run(self.shutdown(save=True, now=True, force=True))

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

You're right! Using asyncio.run() is the proper way to handle the async shutdown. I've updated the code in commit 09bd73c to use asyncio.run(self.shutdown(save=True, now=True, force=True)) instead of falling back to execute_command.

This properly awaits the async method when detected, maintaining the original method signature and behavior. All tests pass without warnings.

Co-authored-by: gkorland <753206+gkorland@users.noreply.github.com>
Copilot AI requested a review from gkorland February 6, 2026 10:53
@gkorland gkorland requested a review from Copilot February 6, 2026 11:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Addresses warnings emitted during test runs by correctly awaiting async shutdown logic and replacing a deprecated executable lookup API.

Changes:

  • Update redislite/client.py cleanup flow to detect async shutdown() and await it via asyncio.
  • Replace deprecated distutils.spawn.find_executable usage with shutil.which in debug info collection.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
redislite/client.py Detects coroutine shutdown and runs/awaits it to prevent “coroutine was never awaited” warnings.
redislite/debug.py Switches to shutil.which to eliminate find_executable deprecation warnings.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread redislite/client.py
Comment on lines +116 to +117
# If it's async, use asyncio.run to properly await it
asyncio.run(self.shutdown(save=True, now=True, force=True))

Copilot AI Feb 6, 2026

Copy link

Choose a reason for hiding this comment

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

asyncio.run(...) will raise RuntimeError if _cleanup() executes while an event loop is already running (e.g., in async test environments). Consider handling the 'running loop' case by using asyncio.get_running_loop() and scheduling the coroutine (e.g., loop.create_task(...)) when a loop is active, and only falling back to asyncio.run(coro) when there is no running loop.

Suggested change
# If it's async, use asyncio.run to properly await it
asyncio.run(self.shutdown(save=True, now=True, force=True))
# If it's async, run it safely depending on whether an event loop is running
coro = self.shutdown(save=True, now=True, force=True)
try:
loop = asyncio.get_running_loop()
except RuntimeError:
# No running event loop; safe to use asyncio.run
asyncio.run(coro)
else:
# Event loop already running; schedule the coroutine on it
loop.create_task(coro)

Copilot uses AI. Check for mistakes.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread redislite/client.py
Comment on lines +114 to +118
# Check if shutdown is a coroutine function to avoid async/sync confusion
if hasattr(self, 'shutdown') and inspect.iscoroutinefunction(self.shutdown):
# If it's async, use asyncio.run to properly await it
asyncio.run(self.shutdown(save=True, now=True, force=True))
else:

Copilot AI Mar 2, 2026

Copy link

Choose a reason for hiding this comment

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

asyncio.run(...) will raise RuntimeError if _cleanup() is invoked while an event loop is already running (common in async applications / notebooks). Since the exception isn’t caught (only redis.RedisError is handled), cleanup can abort before the fallback SIGTERM/SIGKILL logic runs, potentially leaving a redis-server process behind. Consider detecting an active loop (asyncio.get_running_loop()), and either scheduling the coroutine safely or falling back to the existing signal-based shutdown path, and/or catching RuntimeError so cleanup still proceeds.

Copilot uses AI. Check for mistakes.
@codecov

codecov Bot commented May 2, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.85%. Comparing base (ae24b52) to head (d72930c).

Additional details and impacted files
@@            Coverage Diff             @@
##           master      #62      +/-   ##
==========================================
- Coverage   85.13%   83.85%   -1.29%     
==========================================
  Files           8        8              
  Lines         572      576       +4     
  Branches       69       70       +1     
==========================================
- Hits          487      483       -4     
- Misses         67       72       +5     
- Partials       18       21       +3     
Flag Coverage Δ
unittests 83.85% <100.00%> (-1.29%) ⬇️
unittests-macos 83.85% <100.00%> (-1.29%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Successfully merging this pull request may close these issues.

Warnings in tests

3 participants