From 776f4ffa635a42ffdecd7a5c46b85ed6b536734c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 21 Nov 2025 01:00:38 +0000 Subject: [PATCH 1/3] Initial plan From eb6978e1d93c7bbb2cb2192da39f57b07cadb979 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 21 Nov 2025 01:06:39 +0000 Subject: [PATCH 2/3] Add warning suppression documentation and comprehensive tests - Improved warning message to explicitly mention how to suppress it - Added comprehensive test suite for warning suppression (5 new tests) - Updated README with clear documentation on suppressing warnings - All tests pass successfully Co-authored-by: nomeguy <85475922+nomeguy@users.noreply.github.com> --- README.md | 22 ++++++ casbin_async_sqlalchemy_adapter/adapter.py | 3 +- tests/test_adapter.py | 79 ++++++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2c89798..e9e830a 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,28 @@ else: > Note that AsyncAdaper must be used for AynscEnforcer. +### Suppressing the Default Table Warning + +By default, when using the default `CasbinRule` table, the adapter will show a warning to remind you to call `create_table()`. If you want to suppress this warning, you have two options: + +**Option 1: Use the `warning` parameter** +```python +adapter = casbin_async_sqlalchemy_adapter.Adapter( + 'sqlite+aiosqlite:///test.db', + warning=False # Suppress the warning +) +``` + +**Option 2: Explicitly pass the `db_class` parameter** +```python +from casbin_async_sqlalchemy_adapter import CasbinRule + +adapter = casbin_async_sqlalchemy_adapter.Adapter( + 'sqlite+aiosqlite:///test.db', + db_class=CasbinRule # Explicitly use default class +) +``` + ## External Session Support The adapter supports using externally managed SQLAlchemy sessions. This feature is useful for: diff --git a/casbin_async_sqlalchemy_adapter/adapter.py b/casbin_async_sqlalchemy_adapter/adapter.py index e919a97..a518625 100644 --- a/casbin_async_sqlalchemy_adapter/adapter.py +++ b/casbin_async_sqlalchemy_adapter/adapter.py @@ -81,7 +81,8 @@ def __init__( if warning: warnings.warn( "Using default CasbinRule table, please note the use of the 'Adapter().create_table()' method" - " to create the table, and ignore this warning if you are using a custom CasbinRule table.", + " to create the table. To suppress this warning, pass 'warning=False' to the Adapter constructor," + " or pass a custom 'db_class' parameter.", RuntimeWarning, ) else: diff --git a/tests/test_adapter.py b/tests/test_adapter.py index 72e2f09..c885069 100644 --- a/tests/test_adapter.py +++ b/tests/test_adapter.py @@ -418,5 +418,84 @@ async def test_add_policies_bulk_internal_session(self): assert r in tuples +class TestWarningParameter(IsolatedAsyncioTestCase): + """Test warning suppression functionality""" + + async def test_default_warning_shown(self): + """Test that warning is shown by default when using default CasbinRule""" + engine = create_async_engine("sqlite+aiosqlite://", future=True) + + import warnings + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + adapter = Adapter(engine) + + # Should have exactly one warning + self.assertEqual(len(w), 1) + self.assertTrue(issubclass(w[0].category, RuntimeWarning)) + self.assertIn("Using default CasbinRule table", str(w[0].message)) + self.assertIn("warning=False", str(w[0].message)) + + async def test_warning_suppressed_with_parameter(self): + """Test that warning=False suppresses the warning""" + engine = create_async_engine("sqlite+aiosqlite://", future=True) + + import warnings + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + adapter = Adapter(engine, warning=False) + + # Should have no warnings + self.assertEqual(len(w), 0) + + async def test_warning_suppressed_with_custom_db_class(self): + """Test that passing db_class suppresses the warning""" + engine = create_async_engine("sqlite+aiosqlite://", future=True) + + import warnings + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + adapter = Adapter(engine, db_class=CasbinRule) + + # Should have no warnings + self.assertEqual(len(w), 0) + + async def test_warning_suppressed_with_both_parameters(self): + """Test that passing both db_class and warning=False works""" + engine = create_async_engine("sqlite+aiosqlite://", future=True) + + import warnings + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + adapter = Adapter(engine, db_class=CasbinRule, warning=False) + + # Should have no warnings + self.assertEqual(len(w), 0) + + async def test_custom_db_class_no_warning(self): + """Test that custom db_class doesn't show warning regardless of warning parameter""" + class CustomRule(Base): + __tablename__ = "custom_casbin_rule" + id = Column(Integer, primary_key=True) + ptype = Column(String(255)) + v0 = Column(String(255)) + v1 = Column(String(255)) + v2 = Column(String(255)) + v3 = Column(String(255)) + v4 = Column(String(255)) + v5 = Column(String(255)) + + engine = create_async_engine("sqlite+aiosqlite://", future=True) + + import warnings + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + # Even with warning=True, custom db_class should not warn + adapter = Adapter(engine, db_class=CustomRule, warning=True) + + # Should have no warnings + self.assertEqual(len(w), 0) + + if __name__ == "__main__": unittest.main() From 71f3cf1e281a27aa8c25caeb6b0cb916463ba4ae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 21 Nov 2025 01:10:37 +0000 Subject: [PATCH 3/3] Fix redundant warnings imports in tests Co-authored-by: nomeguy <85475922+nomeguy@users.noreply.github.com> --- tests/test_adapter.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/test_adapter.py b/tests/test_adapter.py index c885069..34d5c71 100644 --- a/tests/test_adapter.py +++ b/tests/test_adapter.py @@ -14,6 +14,7 @@ import os import unittest +import warnings from unittest import IsolatedAsyncioTestCase import casbin @@ -425,7 +426,6 @@ async def test_default_warning_shown(self): """Test that warning is shown by default when using default CasbinRule""" engine = create_async_engine("sqlite+aiosqlite://", future=True) - import warnings with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") adapter = Adapter(engine) @@ -440,7 +440,6 @@ async def test_warning_suppressed_with_parameter(self): """Test that warning=False suppresses the warning""" engine = create_async_engine("sqlite+aiosqlite://", future=True) - import warnings with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") adapter = Adapter(engine, warning=False) @@ -452,7 +451,6 @@ async def test_warning_suppressed_with_custom_db_class(self): """Test that passing db_class suppresses the warning""" engine = create_async_engine("sqlite+aiosqlite://", future=True) - import warnings with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") adapter = Adapter(engine, db_class=CasbinRule) @@ -464,7 +462,6 @@ async def test_warning_suppressed_with_both_parameters(self): """Test that passing both db_class and warning=False works""" engine = create_async_engine("sqlite+aiosqlite://", future=True) - import warnings with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") adapter = Adapter(engine, db_class=CasbinRule, warning=False) @@ -487,7 +484,6 @@ class CustomRule(Base): engine = create_async_engine("sqlite+aiosqlite://", future=True) - import warnings with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") # Even with warning=True, custom db_class should not warn