diff --git a/Cargo.lock b/Cargo.lock index ae99ecd59..c634be0f5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2716,7 +2716,7 @@ dependencies = [ ] [[package]] -name = "py-limbo" +name = "py-turso" version = "0.0.22" dependencies = [ "anyhow", diff --git a/README.md b/README.md index 39c79780a..41ab633a0 100644 --- a/README.md +++ b/README.md @@ -125,9 +125,9 @@ pip install pylimbo Example usage: ```python -import limbo +import turso -con = limbo.connect("sqlite.db") +con = turso.connect("sqlite.db") cur = con.cursor() res = cur.execute("SELECT * FROM users") print(res.fetchone()) diff --git a/antithesis-tests/bank-test/anytime_validate.py b/antithesis-tests/bank-test/anytime_validate.py index de3835003..004305974 100755 --- a/antithesis-tests/bank-test/anytime_validate.py +++ b/antithesis-tests/bank-test/anytime_validate.py @@ -1,10 +1,10 @@ #!/usr/bin/env -S python3 -u -import limbo +import turso from antithesis.assertions import always try: - con = limbo.connect("bank_test.db") + con = turso.connect("bank_test.db") except Exception as e: print(f"Error connecting to database: {e}") exit(0) diff --git a/antithesis-tests/bank-test/eventually_validate.py b/antithesis-tests/bank-test/eventually_validate.py index 21a6c9a81..9099b3ff3 100755 --- a/antithesis-tests/bank-test/eventually_validate.py +++ b/antithesis-tests/bank-test/eventually_validate.py @@ -1,10 +1,10 @@ #!/usr/bin/env -S python3 -u -import limbo +import turso from antithesis.assertions import always try: - con = limbo.connect("bank_test.db") + con = turso.connect("bank_test.db") except Exception as e: print(f"Error connecting to database: {e}") exit(0) diff --git a/antithesis-tests/bank-test/finally_validate.py b/antithesis-tests/bank-test/finally_validate.py index 1d9cc0e7b..104ffbe73 100755 --- a/antithesis-tests/bank-test/finally_validate.py +++ b/antithesis-tests/bank-test/finally_validate.py @@ -1,10 +1,10 @@ #!/usr/bin/env -S python3 -u -import limbo +import turso from antithesis.assertions import always try: - con = limbo.connect("bank_test.db") + con = turso.connect("bank_test.db") except Exception as e: print(f"Error connecting to database: {e}") exit(0) diff --git a/antithesis-tests/bank-test/first_setup.py b/antithesis-tests/bank-test/first_setup.py index b99791d7e..fcbc33530 100755 --- a/antithesis-tests/bank-test/first_setup.py +++ b/antithesis-tests/bank-test/first_setup.py @@ -1,10 +1,10 @@ #!/usr/bin/env -S python3 -u -import limbo +import turso from antithesis.random import get_random try: - con = limbo.connect("bank_test.db") + con = turso.connect("bank_test.db") except Exception as e: print(f"Error connecting to database: {e}") exit(0) diff --git a/antithesis-tests/bank-test/parallel_driver_generate_transaction.py b/antithesis-tests/bank-test/parallel_driver_generate_transaction.py index 6378dc855..3689e964c 100755 --- a/antithesis-tests/bank-test/parallel_driver_generate_transaction.py +++ b/antithesis-tests/bank-test/parallel_driver_generate_transaction.py @@ -3,7 +3,7 @@ import logging from logging.handlers import RotatingFileHandler -import limbo +import turso from antithesis.random import get_random handler = RotatingFileHandler( @@ -17,7 +17,7 @@ logger.setLevel(logging.INFO) logger.addHandler(handler) try: - con = limbo.connect("bank_test.db") + con = turso.connect("bank_test.db") except Exception as e: print(f"Error connecting to database: {e}") exit(0) diff --git a/antithesis-tests/pyproject.toml b/antithesis-tests/pyproject.toml index be471123d..e239b9f29 100644 --- a/antithesis-tests/pyproject.toml +++ b/antithesis-tests/pyproject.toml @@ -1,7 +1,7 @@ [project] dependencies = [ "antithesis>=0.1.17", - "pylimbo" + "pyturso" ] description = "Add your description here" name = "antithesis-tests" @@ -9,4 +9,4 @@ requires-python = ">=3.13" version = "0.1.0" [tool.uv.sources] -pylimbo = { workspace = true } +pyturso = { workspace = true } diff --git a/antithesis-tests/stress-composer/first_setup.py b/antithesis-tests/stress-composer/first_setup.py index 84a18f73a..9d755a071 100755 --- a/antithesis-tests/stress-composer/first_setup.py +++ b/antithesis-tests/stress-composer/first_setup.py @@ -4,7 +4,7 @@ import glob import json import os -import limbo +import turso from antithesis.random import get_random, random_choice constraints = ["NOT NULL", ""] @@ -25,7 +25,7 @@ for f in glob.glob("*.db-wal"): # store initial states in a separate db try: - con_init = limbo.connect("init_state.db") + con_init = turso.connect("init_state.db") except Exception as e: print(f"Error connecting to database: {e}") exit(0) @@ -35,7 +35,7 @@ cur_init.execute("CREATE TABLE schemas (schema TEXT, tbl INT)") cur_init.execute("CREATE TABLE tables (count INT)") try: - con = limbo.connect("stress_composer.db") + con = turso.connect("stress_composer.db") except Exception as e: print(f"Error connecting to database: {e}") exit(0) diff --git a/antithesis-tests/stress-composer/parallel_driver_delete.py b/antithesis-tests/stress-composer/parallel_driver_delete.py index 52e6645c5..4ec62079b 100755 --- a/antithesis-tests/stress-composer/parallel_driver_delete.py +++ b/antithesis-tests/stress-composer/parallel_driver_delete.py @@ -2,13 +2,13 @@ import json -import limbo +import turso from antithesis.random import get_random from utils import generate_random_value # Get initial state try: - con_init = limbo.connect("init_state.db") + con_init = turso.connect("init_state.db") except Exception as e: print(f"Error connecting to database: {e}") exit(0) @@ -25,7 +25,7 @@ pk = tbl_schema["pk"] cols = [f"col_{col}" for col in range(tbl_schema["colCount"]) if col != pk] try: - con = limbo.connect("stress_composer.db") + con = turso.connect("stress_composer.db") except Exception as e: print(f"Failed to open stress_composer.db. Exiting... {e}") exit(0) diff --git a/antithesis-tests/stress-composer/parallel_driver_insert.py b/antithesis-tests/stress-composer/parallel_driver_insert.py index 7e7f2cccd..8e4f73e1f 100755 --- a/antithesis-tests/stress-composer/parallel_driver_insert.py +++ b/antithesis-tests/stress-composer/parallel_driver_insert.py @@ -2,13 +2,13 @@ import json -import limbo +import turso from antithesis.random import get_random from utils import generate_random_value # Get initial state try: - con_init = limbo.connect("init_state.db") + con_init = turso.connect("init_state.db") except Exception as e: print(f"Error connecting to database: {e}") exit(0) @@ -21,7 +21,7 @@ tbl_schema = json.loads(cur_init.execute(f"SELECT schema FROM schemas WHERE tbl cols = ", ".join([f"col_{col}" for col in range(tbl_schema["colCount"])]) try: - con = limbo.connect("stress_composer.db") + con = turso.connect("stress_composer.db") except Exception as e: print(f"Failed to open stress_composer.db. Exiting... {e}") exit(0) @@ -39,7 +39,7 @@ for i in range(insertions): INSERT INTO tbl_{selected_tbl} ({cols}) VALUES ({", ".join(values)}) """) - except limbo.OperationalError as e: + except turso.OperationalError as e: if "UNIQUE constraint failed" in str(e): # Ignore UNIQUE constraint violations pass diff --git a/antithesis-tests/stress-composer/parallel_driver_integritycheck.py b/antithesis-tests/stress-composer/parallel_driver_integritycheck.py index e375fea29..f19226b56 100755 --- a/antithesis-tests/stress-composer/parallel_driver_integritycheck.py +++ b/antithesis-tests/stress-composer/parallel_driver_integritycheck.py @@ -2,13 +2,13 @@ import json -import limbo +import turso from antithesis.assertions import always from antithesis.random import get_random # Get initial state try: - con_init = limbo.connect("init_state.db") + con_init = turso.connect("init_state.db") except Exception as e: print(f"Error connecting to database: {e}") exit(0) @@ -21,7 +21,7 @@ tbl_schema = json.loads(cur_init.execute(f"SELECT schema FROM schemas WHERE tbl cols = ", ".join([f"col_{col}" for col in range(tbl_schema["colCount"])]) try: - con = limbo.connect("stress_composer.db") + con = turso.connect("stress_composer.db") except Exception as e: print(f"Failed to open stress_composer.db. Exiting... {e}") exit(0) diff --git a/antithesis-tests/stress-composer/parallel_driver_rollback.py b/antithesis-tests/stress-composer/parallel_driver_rollback.py index eb3d65a83..9dc3f284e 100755 --- a/antithesis-tests/stress-composer/parallel_driver_rollback.py +++ b/antithesis-tests/stress-composer/parallel_driver_rollback.py @@ -2,13 +2,13 @@ import json -import limbo +import turso from antithesis.random import get_random from utils import generate_random_value # Get initial state try: - con_init = limbo.connect("init_state.db") + con_init = turso.connect("init_state.db") except Exception as e: print(f"Error connecting to database: {e}") exit(0) @@ -21,7 +21,7 @@ tbl_schema = json.loads(cur_init.execute(f"SELECT schema FROM schemas WHERE tbl cols = ", ".join([f"col_{col}" for col in range(tbl_schema["colCount"])]) try: - con = limbo.connect("stress_composer.db") + con = turso.connect("stress_composer.db") except Exception as e: print(f"Failed to open stress_composer.db. Exiting... {e}") exit(0) @@ -39,7 +39,7 @@ for i in range(insertions): INSERT INTO tbl_{selected_tbl} ({cols}) VALUES ({", ".join(values)}) """) - except limbo.OperationalError as e: + except turso.OperationalError as e: if "UNIQUE constraint failed" in str(e): # Ignore UNIQUE constraint violations pass diff --git a/antithesis-tests/stress-composer/parallel_driver_update.py b/antithesis-tests/stress-composer/parallel_driver_update.py index 200333147..e30d53acd 100755 --- a/antithesis-tests/stress-composer/parallel_driver_update.py +++ b/antithesis-tests/stress-composer/parallel_driver_update.py @@ -2,13 +2,13 @@ import json -import limbo +import turso from antithesis.random import get_random from utils import generate_random_value # Get initial state try: - con_init = limbo.connect("init_state.db") + con_init = turso.connect("init_state.db") except Exception as e: print(f"Error connecting to database: {e}") exit(0) @@ -25,7 +25,7 @@ pk = tbl_schema["pk"] cols = [f"col_{col}" for col in range(tbl_schema["colCount"]) if col != pk] # print(cols) try: - con = limbo.connect("stress_composer.db") + con = turso.connect("stress_composer.db") except Exception as e: print(f"Failed to open stress_composer.db. Exiting... {e}") exit(0) @@ -53,7 +53,7 @@ for i in range(updates): cur.execute(f""" UPDATE tbl_{selected_tbl} SET {set_clause} WHERE {where_clause} """) - except limbo.OperationalError as e: + except turso.OperationalError as e: if "UNIQUE constraint failed" in str(e): # Ignore UNIQUE constraint violations pass diff --git a/bindings/python/Cargo.toml b/bindings/python/Cargo.toml index 4a8eaef59..4670aa9d4 100644 --- a/bindings/python/Cargo.toml +++ b/bindings/python/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "py-limbo" +name = "py-turso" version.workspace = true authors.workspace = true edition.workspace = true @@ -8,7 +8,7 @@ repository.workspace = true publish = false [lib] -name = "_limbo" +name = "_turso" crate-type = ["cdylib"] [features] diff --git a/bindings/python/example.py b/bindings/python/example.py index 870766e8f..f63b02737 100644 --- a/bindings/python/example.py +++ b/bindings/python/example.py @@ -1,7 +1,7 @@ -import limbo +import turso # Use the context manager to automatically close the connection -with limbo.connect("sqlite.db") as con: +with turso.connect("sqlite.db") as con: cur = con.cursor() cur.execute(""" CREATE TABLE IF NOT EXISTS users ( diff --git a/bindings/python/limbo/_limbo.pyi b/bindings/python/limbo/_limbo.pyi deleted file mode 100644 index 7d9966c62..000000000 --- a/bindings/python/limbo/_limbo.pyi +++ /dev/null @@ -1,183 +0,0 @@ -from typing import Any, List, Optional, Tuple - -__version__: str - -class Connection: - def cursor(self) -> "Cursor": - """ - Creates a new cursor object using this connection. - - :return: A new Cursor object. - :raises InterfaceError: If the cursor cannot be created. - """ - ... - - def close(self) -> None: - """ - Closes the connection to the database. - - :raises OperationalError: If there is an error closing the connection. - """ - ... - - def commit(self) -> None: - """ - Commits the current transaction. - - :raises OperationalError: If there is an error during commit. - """ - ... - - def rollback(self) -> None: - """ - Rolls back the current transaction. - - :raises OperationalError: If there is an error during rollback. - """ - ... - -class Cursor: - arraysize: int - description: Optional[ - Tuple[ - str, - str, - Optional[str], - Optional[str], - Optional[str], - Optional[str], - Optional[str], - ] - ] - rowcount: int - - def execute(self, sql: str, parameters: Optional[Tuple[Any, ...]] = None) -> "Cursor": - """ - Prepares and executes a SQL statement using the connection. - - :param sql: The SQL query to execute. - :param parameters: The parameters to substitute into the SQL query. - :raises ProgrammingError: If there is an error in the SQL query. - :raises OperationalError: If there is an error executing the query. - :return: The cursor object. - """ - ... - - def executemany(self, sql: str, parameters: Optional[List[Tuple[Any, ...]]] = None) -> None: - """ - Executes a SQL command against all parameter sequences or mappings found in the sequence `parameters`. - - :param sql: The SQL command to execute. - :param parameters: A list of parameter sequences or mappings. - :raises ProgrammingError: If there is an error in the SQL query. - :raises OperationalError: If there is an error executing the query. - """ - ... - - def fetchone(self) -> Optional[Tuple[Any, ...]]: - """ - Fetches the next row from the result set. - - :return: A tuple representing the next row, or None if no more rows are available. - :raises OperationalError: If there is an error fetching the row. - """ - ... - - def fetchall(self) -> List[Tuple[Any, ...]]: - """ - Fetches all remaining rows from the result set. - - :return: A list of tuples, each representing a row in the result set. - :raises OperationalError: If there is an error fetching the rows. - """ - ... - - def fetchmany(self, size: Optional[int] = None) -> List[Tuple[Any, ...]]: - """ - Fetches the next set of rows of a size specified by the `arraysize` property. - - :param size: Optional integer to specify the number of rows to fetch. - :return: A list of tuples, each representing a row in the result set. - :raises OperationalError: If there is an error fetching the rows. - """ - ... - - def close(self) -> None: - """ - Closes the cursor. - - :raises OperationalError: If there is an error closing the cursor. - """ - ... - -# Exception classes -class Warning(Exception): - """Exception raised for important warnings like data truncations while inserting.""" - - ... - -class Error(Exception): - """Base class for all other error exceptions. Catch all database-related errors using this class.""" - - ... - -class InterfaceError(Error): - """Exception raised for errors related to the database interface rather than the database itself.""" - - ... - -class DatabaseError(Error): - """Exception raised for errors that are related to the database.""" - - ... - -class DataError(DatabaseError): - """ - Exception raised for errors due to problems with the processed data like division by zero, numeric value out of - range, etc. - """ - - ... - -class OperationalError(DatabaseError): - """ - Exception raised for errors related to the database’s operation, not necessarily under the programmer's control. - """ - - ... - -class IntegrityError(DatabaseError): - """Exception raised when the relational integrity of the database is affected, e.g., a foreign key check fails.""" - - ... - -class InternalError(DatabaseError): - """ - Exception raised when the database encounters an internal error, e.g., cursor is not valid anymore, transaction out - of sync. - """ - - ... - -class ProgrammingError(DatabaseError): - """ - Exception raised for programming errors, e.g., table not found, syntax error in SQL, wrong number of parameters - specified. - """ - - ... - -class NotSupportedError(DatabaseError): - """Exception raised when a method or database API is used which is not supported by the database.""" - - ... - -def connect(path: str) -> Connection: - """ - Connects to a database at the specified path. - - :param path: The path to the database file. - :return: A Connection object to the database. - :raises InterfaceError: If the database cannot be connected. - """ - ... diff --git a/bindings/python/pyproject.toml b/bindings/python/pyproject.toml index 4b6509391..179bfdf3c 100644 --- a/bindings/python/pyproject.toml +++ b/bindings/python/pyproject.toml @@ -3,7 +3,7 @@ requires = ['maturin>=1,<2', 'typing_extensions'] build-backend = 'maturin' [project] -name = 'pylimbo' +name = 'pyturso' description = "Limbo is a work-in-progress, in-process OLTP database management system, compatible with SQLite." requires-python = '>=3.9' classifiers = [ @@ -45,7 +45,7 @@ Source = "https://github.com/tursodatabase/limbo" [tool.maturin] bindings = 'pyo3' -module-name = "limbo._limbo" +module-name = "turso._turso" features = ["pyo3/extension-module"] [tool.pip-tools] @@ -58,7 +58,7 @@ testpaths = 'tests' log_format = '%(name)s %(levelname)s: %(message)s' [tool.coverage.run] -source = ['limbo'] +source = ['turso'] branch = true [tool.coverage.report] diff --git a/bindings/python/requirements-dev.txt b/bindings/python/requirements-dev.txt index 5ec1981cc..1b64e50e5 100644 --- a/bindings/python/requirements-dev.txt +++ b/bindings/python/requirements-dev.txt @@ -1,13 +1,13 @@ coverage==7.6.1 # via - # pylimbo (pyproject.toml) + # pyturso (pyproject.toml) # pytest-cov iniconfig==2.0.0 # via pytest maturin==1.7.8 - # via pylimbo (pyproject.toml) + # via pyturso (pyproject.toml) mypy==1.11.0 - # via pylimbo (pyproject.toml) + # via pyturso (pyproject.toml) mypy-extensions==1.0.0 # via mypy packaging==24.2 @@ -16,13 +16,13 @@ pluggy==1.5.0 # via pytest pytest==8.3.1 # via - # pylimbo (pyproject.toml) + # pyturso (pyproject.toml) # pytest-cov pytest-cov==5.0.0 - # via pylimbo (pyproject.toml) + # via pyturso (pyproject.toml) ruff==0.5.4 - # via pylimbo (pyproject.toml) + # via pyturso (pyproject.toml) typing-extensions==4.12.2 # via # mypy - # pylimbo (pyproject.toml) + # pyturso (pyproject.toml) diff --git a/bindings/python/requirements.txt b/bindings/python/requirements.txt index c1348444d..826bba2a4 100644 --- a/bindings/python/requirements.txt +++ b/bindings/python/requirements.txt @@ -1,2 +1,2 @@ typing-extensions==4.12.2 - # via pylimbo (pyproject.toml) + # via pyturso (pyproject.toml) diff --git a/bindings/python/src/lib.rs b/bindings/python/src/lib.rs index c745d51ca..08c5201d3 100644 --- a/bindings/python/src/lib.rs +++ b/bindings/python/src/lib.rs @@ -365,7 +365,7 @@ fn py_to_owned_value(obj: &Bound) -> Result { } #[pymodule] -fn _limbo(m: &Bound) -> PyResult<()> { +fn _turso(m: &Bound) -> PyResult<()> { m.add("__version__", env!("CARGO_PKG_VERSION"))?; m.add_class::()?; m.add_class::()?; diff --git a/bindings/python/tests/test_database.py b/bindings/python/tests/test_database.py index 07e8508cc..c9e1209dd 100644 --- a/bindings/python/tests/test_database.py +++ b/bindings/python/tests/test_database.py @@ -1,8 +1,8 @@ import os import sqlite3 -import limbo import pytest +import turso @pytest.fixture(autouse=True) @@ -48,7 +48,7 @@ def setup_database(): print(f"Failed to clean up: {e}") -@pytest.mark.parametrize("provider", ["sqlite3", "limbo"]) +@pytest.mark.parametrize("provider", ["sqlite3", "turso"]) def test_fetchall_select_all_users(provider, setup_database): conn = connect(provider, setup_database) cursor = conn.cursor() @@ -61,7 +61,7 @@ def test_fetchall_select_all_users(provider, setup_database): assert users == [(1, "alice"), (2, "bob")] -@pytest.mark.parametrize("provider", ["sqlite3", "limbo"]) +@pytest.mark.parametrize("provider", ["sqlite3", "turso"]) def test_fetchall_select_user_ids(provider): conn = connect(provider, "tests/database.db") cursor = conn.cursor() @@ -74,7 +74,7 @@ def test_fetchall_select_user_ids(provider): assert user_ids == [(1,), (2,)] -@pytest.mark.parametrize("provider", ["sqlite3", "limbo"]) +@pytest.mark.parametrize("provider", ["sqlite3", "turso"]) def test_in_memory_fetchone_select_all_users(provider): conn = connect(provider, ":memory:") cursor = conn.cursor() @@ -90,7 +90,7 @@ def test_in_memory_fetchone_select_all_users(provider): assert alice == (1, "alice") -@pytest.mark.parametrize("provider", ["sqlite3", "limbo"]) +@pytest.mark.parametrize("provider", ["sqlite3", "turso"]) def test_fetchone_select_all_users(provider): conn = connect(provider, "tests/database.db") cursor = conn.cursor() @@ -107,7 +107,7 @@ def test_fetchone_select_all_users(provider): assert bob == (2, "bob") -@pytest.mark.parametrize("provider", ["sqlite3", "limbo"]) +@pytest.mark.parametrize("provider", ["sqlite3", "turso"]) def test_fetchone_select_max_user_id(provider): conn = connect(provider, "tests/database.db") cursor = conn.cursor() @@ -120,8 +120,8 @@ def test_fetchone_select_max_user_id(provider): assert max_id == (2,) -# Test case for: https://github.com/tursodatabase/limbo/issues/494 -@pytest.mark.parametrize("provider", ["sqlite3", "limbo"]) +# Test case for: https://github.com/tursodatabase/turso/issues/494 +@pytest.mark.parametrize("provider", ["sqlite3", "turso"]) def test_commit(provider): conn = connect(provider, "tests/database.db") cur = conn.cursor() @@ -158,7 +158,7 @@ def test_commit(provider): assert record -@pytest.mark.parametrize("provider", ["sqlite3", "limbo"]) +@pytest.mark.parametrize("provider", ["sqlite3", "turso"]) def test_with_statement(provider): with connect(provider, "tests/database.db") as conn: cursor = conn.cursor() @@ -171,8 +171,8 @@ def test_with_statement(provider): def connect(provider, database): - if provider == "limbo": - return limbo.connect(database) + if provider == "turso": + return turso.connect(database) if provider == "sqlite3": return sqlite3.connect(database) raise Exception(f"Provider `{provider}` is not supported") diff --git a/bindings/python/limbo/__init__.py b/bindings/python/turso/__init__.py similarity index 95% rename from bindings/python/limbo/__init__.py rename to bindings/python/turso/__init__.py index 7898dce9f..94cbbae0b 100644 --- a/bindings/python/limbo/__init__.py +++ b/bindings/python/turso/__init__.py @@ -1,4 +1,4 @@ -from ._limbo import ( +from ._turso import ( Connection, Cursor, DatabaseError, diff --git a/bindings/python/limbo/py.typed b/bindings/python/turso/py.typed similarity index 100% rename from bindings/python/limbo/py.typed rename to bindings/python/turso/py.typed