diff --git a/docs/python-api.rst b/docs/python-api.rst index 9f69b34..b008cb5 100644 --- a/docs/python-api.rst +++ b/docs/python-api.rst @@ -1719,3 +1719,13 @@ Python 3.8 added the ability to register `deterministic SQLite functions ".format(self.conn) - def register_function(self, fn=None, deterministic=None): + def register_function(self, fn=None, deterministic=None, replace=False): def register(fn): name = fn.__name__ arity = len(inspect.signature(fn).parameters) + if not replace and (name, arity) in self._registered_functions: + return fn kwargs = {} if deterministic and sys.version_info >= (3, 8): kwargs["deterministic"] = True self.conn.create_function(name, arity, fn, **kwargs) + self._registered_functions.add((name, arity)) return fn if fn is None: diff --git a/tests/test_register_function.py b/tests/test_register_function.py index dab0a8d..e6d977a 100644 --- a/tests/test_register_function.py +++ b/tests/test_register_function.py @@ -44,3 +44,25 @@ def test_register_function_deterministic_registered(fresh_db): fresh_db.conn.create_function.assert_called_with( "to_lower_2", 1, to_lower_2, deterministic=True ) + + +def test_register_function_replace(fresh_db): + @fresh_db.register_function() + def one(): + return "one" + + assert "one" == fresh_db.execute("select one()").fetchone()[0] + + # This will fail to replace the function: + @fresh_db.register_function() + def one(): + return "two" + + assert "one" == fresh_db.execute("select one()").fetchone()[0] + + # This will replace it + @fresh_db.register_function(replace=True) + def one(): + return "two" + + assert "two" == fresh_db.execute("select one()").fetchone()[0]