isoladb 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
isoladb-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,312 @@
1
+ Metadata-Version: 2.4
2
+ Name: isoladb
3
+ Version: 0.1.0
4
+ Summary: Ephemeral PostgreSQL instances for unit testing
5
+ License: MIT
6
+ Keywords: testing,postgresql,database,unit-testing,ephemeral
7
+ Author: Yegor Stepanov
8
+ Requires-Python: >=3.8
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Database
21
+ Classifier: Topic :: Software Development :: Testing
22
+ Provides-Extra: psycopg
23
+ Provides-Extra: pytest
24
+ Provides-Extra: sqlalchemy
25
+ Requires-Dist: psycopg[binary] (>=3.1) ; extra == "psycopg"
26
+ Requires-Dist: pytest (>=7.0) ; extra == "pytest"
27
+ Requires-Dist: sqlalchemy (>=2.0) ; extra == "sqlalchemy"
28
+ Description-Content-Type: text/markdown
29
+
30
+ # isoladb
31
+
32
+ Ephemeral PostgreSQL instances for unit testing. No pre-installed PostgreSQL required — just Python 3.8+.
33
+
34
+ isoladb downloads pre-built PostgreSQL binaries (or uses your system installation), starts an isolated server, creates per-test databases, and cleans up automatically.
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ pip install isoladb
40
+ ```
41
+
42
+ With pytest support:
43
+
44
+ ```bash
45
+ pip install isoladb[pytest]
46
+ ```
47
+
48
+ With psycopg (PostgreSQL client):
49
+
50
+ ```bash
51
+ pip install isoladb[psycopg]
52
+ ```
53
+
54
+ ## Quick Start
55
+
56
+ ```python
57
+ import psycopg
58
+ from isoladb import IsolaDB
59
+
60
+ with IsolaDB() as db:
61
+ with psycopg.connect(db.url) as conn:
62
+ conn.execute("CREATE TABLE users (id serial PRIMARY KEY, name text)")
63
+ conn.execute("INSERT INTO users (name) VALUES ('Alice')")
64
+ conn.commit()
65
+ result = conn.execute("SELECT name FROM users").fetchone()
66
+ assert result[0] == "Alice"
67
+ # Server and database are cleaned up automatically
68
+ ```
69
+
70
+ Each `IsolaDB()` context manager creates a fresh, isolated database. The underlying PostgreSQL server is shared and reused across invocations with the same configuration.
71
+
72
+ ## Connection Properties
73
+
74
+ The context manager yields an object with these properties:
75
+
76
+ | Property | Description | Example |
77
+ |---|---|---|
78
+ | `db.url` | Full connection URL | `postgresql://postgres@localhost/isoladb_test_a1b2c3?host=/tmp/pg_xyz&port=54321` |
79
+ | `db.host` | Unix socket directory | `/tmp/pg_xyz` |
80
+ | `db.port` | Server port | `54321` |
81
+ | `db.dbname` | Database name | `isoladb_test_a1b2c3` |
82
+ | `db.user` | Superuser name | `postgres` |
83
+
84
+ Works with any PostgreSQL client library:
85
+
86
+ ```python
87
+ # psycopg v3
88
+ conn = psycopg.connect(db.url)
89
+
90
+ # psycopg2
91
+ conn = psycopg2.connect(host=db.host, port=db.port, dbname=db.dbname, user=db.user)
92
+
93
+ # asyncpg
94
+ conn = await asyncpg.connect(host=db.host, port=db.port, database=db.dbname, user=db.user)
95
+
96
+ # SQLAlchemy
97
+ engine = create_engine(db.url)
98
+ ```
99
+
100
+ ## PostgreSQL Binary Resolution
101
+
102
+ By default, isoladb looks for PostgreSQL in this order:
103
+
104
+ 1. **System PostgreSQL** — detected via `pg_ctl` on `PATH` (e.g., Homebrew, apt)
105
+ 2. **Cached download** — previously downloaded binaries in `~/.cache/isoladb`
106
+ 3. **Fresh download** — fetched from Maven Central (~50MB, cached for future use)
107
+
108
+ To always use downloaded binaries instead of a system installation:
109
+
110
+ ```python
111
+ with IsolaDB(use_system_pg=False) as db:
112
+ ...
113
+ ```
114
+
115
+ ## Schema and Setup
116
+
117
+ Apply a SQL schema file automatically after each database is created:
118
+
119
+ ```python
120
+ with IsolaDB(schema="schema.sql") as db:
121
+ # Tables from schema.sql are already created
122
+ with psycopg.connect(db.url) as conn:
123
+ conn.execute("INSERT INTO users (name) VALUES ('Alice')")
124
+ ```
125
+
126
+ Or point to a directory of `.sql` files — they are sorted by filename and applied in order:
127
+
128
+ ```
129
+ migrations/
130
+ 001_create_users.sql
131
+ 002_create_posts.sql
132
+ 003_seed_data.sql
133
+ ```
134
+
135
+ ```python
136
+ with IsolaDB(schema="migrations/") as db:
137
+ # All .sql files applied in sorted order
138
+ ...
139
+ ```
140
+
141
+ Non-`.sql` files in the directory are ignored.
142
+
143
+ For programmatic initialization (e.g., Alembic migrations), use a setup callable:
144
+
145
+ ```python
146
+ def apply_migrations(url):
147
+ from alembic.config import Config
148
+ from alembic import command
149
+ cfg = Config("alembic.ini")
150
+ cfg.set_main_option("sqlalchemy.url", url)
151
+ command.upgrade(cfg, "head")
152
+
153
+ with IsolaDB(setup=apply_migrations) as db:
154
+ ...
155
+ ```
156
+
157
+ Both can be combined — schema is applied first, then setup.
158
+
159
+ ## RAM Disk
160
+
161
+ Run the PostgreSQL data directory on a RAM disk for faster I/O:
162
+
163
+ ```python
164
+ with IsolaDB(ram=True) as db:
165
+ ...
166
+ ```
167
+
168
+ Uses tmpfs on Linux and hdiutil RAM disk on macOS. Falls back to a regular temp directory if RAM disk creation fails.
169
+
170
+ ## Async Support
171
+
172
+ ```python
173
+ from isoladb import AsyncIsolaDB
174
+
175
+ async with AsyncIsolaDB() as db:
176
+ conn = await asyncpg.connect(
177
+ host=db.host, port=db.port, database=db.dbname, user=db.user
178
+ )
179
+ await conn.execute("CREATE TABLE test (id serial PRIMARY KEY)")
180
+ await conn.close()
181
+ ```
182
+
183
+ The async setup callable can be either sync or async:
184
+
185
+ ```python
186
+ async def apply_migrations(url: str) -> None:
187
+ engine = create_async_engine(url)
188
+ async with engine.begin() as conn:
189
+ await conn.run_sync(Base.metadata.create_all)
190
+ await engine.dispose()
191
+
192
+ async with AsyncIsolaDB(setup=apply_migrations) as db:
193
+ ...
194
+ ```
195
+
196
+ ## Configuration
197
+
198
+ All options can be passed to `IsolaDB()` / `AsyncIsolaDB()`:
199
+
200
+ | Option | Default | Description |
201
+ |---|---|---|
202
+ | `pg_version` | `"17.2.0"` | PostgreSQL version (for downloaded binaries) |
203
+ | `ram` | `False` | Use RAM disk for the data directory |
204
+ | `ram_size_mb` | `256` | RAM disk size in megabytes |
205
+ | `use_system_pg` | `True` | Prefer system PostgreSQL over downloading |
206
+ | `schema` | `None` | Path to a SQL file or directory of `.sql` files |
207
+ | `setup` | `None` | Callable receiving the connection URL for custom setup |
208
+ | `cache_dir` | `~/.cache/isoladb` | Directory for cached PostgreSQL binaries |
209
+ | `startup_timeout` | `30.0` | Seconds to wait for the server to start |
210
+ | `pg_conf` | `{}` | Extra postgresql.conf settings as `{"key": "value"}` |
211
+
212
+ ## Pytest Plugin
213
+
214
+ isoladb includes a pytest plugin that provides fixtures automatically when `isoladb[pytest]` is installed.
215
+
216
+ ### Fixtures
217
+
218
+ **`isoladb`** — per-test fixture yielding an `IsolaDBConnection` with `.url`, `.host`, `.port`, `.dbname`:
219
+
220
+ ```python
221
+ def test_users(isoladb):
222
+ with psycopg.connect(isoladb.url) as conn:
223
+ conn.execute("CREATE TABLE users (id serial PRIMARY KEY, name text)")
224
+ conn.execute("INSERT INTO users (name) VALUES ('Alice')")
225
+ conn.commit()
226
+ result = conn.execute("SELECT count(*) FROM users").fetchone()
227
+ assert result[0] == 1
228
+ ```
229
+
230
+ **`isoladb_engine`** — per-test fixture yielding a SQLAlchemy engine (requires `sqlalchemy`):
231
+
232
+ ```python
233
+ def test_with_engine(isoladb_engine):
234
+ with isoladb_engine.connect() as conn:
235
+ conn.execute(text("SELECT 1"))
236
+ ```
237
+
238
+ **`isoladb_async`** — per-test async fixture (requires `pytest-asyncio`):
239
+
240
+ ```python
241
+ async def test_async(isoladb_async):
242
+ conn = await asyncpg.connect(
243
+ host=isoladb_async.host, port=isoladb_async.port,
244
+ database=isoladb_async.dbname, user="postgres",
245
+ )
246
+ await conn.execute("SELECT 1")
247
+ await conn.close()
248
+ ```
249
+
250
+ **`isoladb_async_engine`** — per-test async SQLAlchemy engine (requires `sqlalchemy[asyncio]`, `asyncpg`):
251
+
252
+ ```python
253
+ async def test_async_engine(isoladb_async_engine):
254
+ async with isoladb_async_engine.connect() as conn:
255
+ await conn.execute(text("SELECT 1"))
256
+ ```
257
+
258
+ **`isoladb_server`** — session-scoped fixture exposing the underlying `IsolaDBServer`. Useful for custom fixture composition.
259
+
260
+ **`isoladb_setup`** — session-scoped fixture to override with a custom setup callable:
261
+
262
+ ```python
263
+ # conftest.py
264
+ @pytest.fixture(scope="session")
265
+ def isoladb_setup():
266
+ def apply_migrations(url):
267
+ from alembic.config import Config
268
+ from alembic import command
269
+ cfg = Config("alembic.ini")
270
+ cfg.set_main_option("sqlalchemy.url", url)
271
+ command.upgrade(cfg, "head")
272
+ return apply_migrations
273
+ ```
274
+
275
+ ### Ini Options
276
+
277
+ Configure in `pyproject.toml`, `pytest.ini`, or `setup.cfg`:
278
+
279
+ ```toml
280
+ # pyproject.toml
281
+ [tool.pytest.ini_options]
282
+ isoladb_pg_version = "16.1.0"
283
+ isoladb_ram = true
284
+ isoladb_use_system_pg = false
285
+ isoladb_schema = "tests/schema.sql"
286
+ ```
287
+
288
+ | Option | Default | Description |
289
+ |---|---|---|
290
+ | `isoladb_pg_version` | latest stable | PostgreSQL version |
291
+ | `isoladb_ram` | `false` | Use RAM disk |
292
+ | `isoladb_use_system_pg` | `true` | Prefer system PostgreSQL |
293
+ | `isoladb_schema` | none | SQL schema file path |
294
+
295
+ The pytest header shows which PostgreSQL binary is being used:
296
+
297
+ ```
298
+ ============================= test session starts ==============================
299
+ platform darwin -- Python 3.13.6
300
+ isoladb: PostgreSQL at /opt/homebrew/Cellar/postgresql@14/14.19
301
+ ```
302
+
303
+ ## Requirements
304
+
305
+ - Python 3.8+
306
+ - No pre-installed PostgreSQL needed (downloads automatically if not found)
307
+ - Linux (x86_64, arm64) or macOS (x86_64, arm64)
308
+
309
+ ## License
310
+
311
+ MIT
312
+
@@ -0,0 +1,282 @@
1
+ # isoladb
2
+
3
+ Ephemeral PostgreSQL instances for unit testing. No pre-installed PostgreSQL required — just Python 3.8+.
4
+
5
+ isoladb downloads pre-built PostgreSQL binaries (or uses your system installation), starts an isolated server, creates per-test databases, and cleans up automatically.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install isoladb
11
+ ```
12
+
13
+ With pytest support:
14
+
15
+ ```bash
16
+ pip install isoladb[pytest]
17
+ ```
18
+
19
+ With psycopg (PostgreSQL client):
20
+
21
+ ```bash
22
+ pip install isoladb[psycopg]
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ```python
28
+ import psycopg
29
+ from isoladb import IsolaDB
30
+
31
+ with IsolaDB() as db:
32
+ with psycopg.connect(db.url) as conn:
33
+ conn.execute("CREATE TABLE users (id serial PRIMARY KEY, name text)")
34
+ conn.execute("INSERT INTO users (name) VALUES ('Alice')")
35
+ conn.commit()
36
+ result = conn.execute("SELECT name FROM users").fetchone()
37
+ assert result[0] == "Alice"
38
+ # Server and database are cleaned up automatically
39
+ ```
40
+
41
+ Each `IsolaDB()` context manager creates a fresh, isolated database. The underlying PostgreSQL server is shared and reused across invocations with the same configuration.
42
+
43
+ ## Connection Properties
44
+
45
+ The context manager yields an object with these properties:
46
+
47
+ | Property | Description | Example |
48
+ |---|---|---|
49
+ | `db.url` | Full connection URL | `postgresql://postgres@localhost/isoladb_test_a1b2c3?host=/tmp/pg_xyz&port=54321` |
50
+ | `db.host` | Unix socket directory | `/tmp/pg_xyz` |
51
+ | `db.port` | Server port | `54321` |
52
+ | `db.dbname` | Database name | `isoladb_test_a1b2c3` |
53
+ | `db.user` | Superuser name | `postgres` |
54
+
55
+ Works with any PostgreSQL client library:
56
+
57
+ ```python
58
+ # psycopg v3
59
+ conn = psycopg.connect(db.url)
60
+
61
+ # psycopg2
62
+ conn = psycopg2.connect(host=db.host, port=db.port, dbname=db.dbname, user=db.user)
63
+
64
+ # asyncpg
65
+ conn = await asyncpg.connect(host=db.host, port=db.port, database=db.dbname, user=db.user)
66
+
67
+ # SQLAlchemy
68
+ engine = create_engine(db.url)
69
+ ```
70
+
71
+ ## PostgreSQL Binary Resolution
72
+
73
+ By default, isoladb looks for PostgreSQL in this order:
74
+
75
+ 1. **System PostgreSQL** — detected via `pg_ctl` on `PATH` (e.g., Homebrew, apt)
76
+ 2. **Cached download** — previously downloaded binaries in `~/.cache/isoladb`
77
+ 3. **Fresh download** — fetched from Maven Central (~50MB, cached for future use)
78
+
79
+ To always use downloaded binaries instead of a system installation:
80
+
81
+ ```python
82
+ with IsolaDB(use_system_pg=False) as db:
83
+ ...
84
+ ```
85
+
86
+ ## Schema and Setup
87
+
88
+ Apply a SQL schema file automatically after each database is created:
89
+
90
+ ```python
91
+ with IsolaDB(schema="schema.sql") as db:
92
+ # Tables from schema.sql are already created
93
+ with psycopg.connect(db.url) as conn:
94
+ conn.execute("INSERT INTO users (name) VALUES ('Alice')")
95
+ ```
96
+
97
+ Or point to a directory of `.sql` files — they are sorted by filename and applied in order:
98
+
99
+ ```
100
+ migrations/
101
+ 001_create_users.sql
102
+ 002_create_posts.sql
103
+ 003_seed_data.sql
104
+ ```
105
+
106
+ ```python
107
+ with IsolaDB(schema="migrations/") as db:
108
+ # All .sql files applied in sorted order
109
+ ...
110
+ ```
111
+
112
+ Non-`.sql` files in the directory are ignored.
113
+
114
+ For programmatic initialization (e.g., Alembic migrations), use a setup callable:
115
+
116
+ ```python
117
+ def apply_migrations(url):
118
+ from alembic.config import Config
119
+ from alembic import command
120
+ cfg = Config("alembic.ini")
121
+ cfg.set_main_option("sqlalchemy.url", url)
122
+ command.upgrade(cfg, "head")
123
+
124
+ with IsolaDB(setup=apply_migrations) as db:
125
+ ...
126
+ ```
127
+
128
+ Both can be combined — schema is applied first, then setup.
129
+
130
+ ## RAM Disk
131
+
132
+ Run the PostgreSQL data directory on a RAM disk for faster I/O:
133
+
134
+ ```python
135
+ with IsolaDB(ram=True) as db:
136
+ ...
137
+ ```
138
+
139
+ Uses tmpfs on Linux and hdiutil RAM disk on macOS. Falls back to a regular temp directory if RAM disk creation fails.
140
+
141
+ ## Async Support
142
+
143
+ ```python
144
+ from isoladb import AsyncIsolaDB
145
+
146
+ async with AsyncIsolaDB() as db:
147
+ conn = await asyncpg.connect(
148
+ host=db.host, port=db.port, database=db.dbname, user=db.user
149
+ )
150
+ await conn.execute("CREATE TABLE test (id serial PRIMARY KEY)")
151
+ await conn.close()
152
+ ```
153
+
154
+ The async setup callable can be either sync or async:
155
+
156
+ ```python
157
+ async def apply_migrations(url: str) -> None:
158
+ engine = create_async_engine(url)
159
+ async with engine.begin() as conn:
160
+ await conn.run_sync(Base.metadata.create_all)
161
+ await engine.dispose()
162
+
163
+ async with AsyncIsolaDB(setup=apply_migrations) as db:
164
+ ...
165
+ ```
166
+
167
+ ## Configuration
168
+
169
+ All options can be passed to `IsolaDB()` / `AsyncIsolaDB()`:
170
+
171
+ | Option | Default | Description |
172
+ |---|---|---|
173
+ | `pg_version` | `"17.2.0"` | PostgreSQL version (for downloaded binaries) |
174
+ | `ram` | `False` | Use RAM disk for the data directory |
175
+ | `ram_size_mb` | `256` | RAM disk size in megabytes |
176
+ | `use_system_pg` | `True` | Prefer system PostgreSQL over downloading |
177
+ | `schema` | `None` | Path to a SQL file or directory of `.sql` files |
178
+ | `setup` | `None` | Callable receiving the connection URL for custom setup |
179
+ | `cache_dir` | `~/.cache/isoladb` | Directory for cached PostgreSQL binaries |
180
+ | `startup_timeout` | `30.0` | Seconds to wait for the server to start |
181
+ | `pg_conf` | `{}` | Extra postgresql.conf settings as `{"key": "value"}` |
182
+
183
+ ## Pytest Plugin
184
+
185
+ isoladb includes a pytest plugin that provides fixtures automatically when `isoladb[pytest]` is installed.
186
+
187
+ ### Fixtures
188
+
189
+ **`isoladb`** — per-test fixture yielding an `IsolaDBConnection` with `.url`, `.host`, `.port`, `.dbname`:
190
+
191
+ ```python
192
+ def test_users(isoladb):
193
+ with psycopg.connect(isoladb.url) as conn:
194
+ conn.execute("CREATE TABLE users (id serial PRIMARY KEY, name text)")
195
+ conn.execute("INSERT INTO users (name) VALUES ('Alice')")
196
+ conn.commit()
197
+ result = conn.execute("SELECT count(*) FROM users").fetchone()
198
+ assert result[0] == 1
199
+ ```
200
+
201
+ **`isoladb_engine`** — per-test fixture yielding a SQLAlchemy engine (requires `sqlalchemy`):
202
+
203
+ ```python
204
+ def test_with_engine(isoladb_engine):
205
+ with isoladb_engine.connect() as conn:
206
+ conn.execute(text("SELECT 1"))
207
+ ```
208
+
209
+ **`isoladb_async`** — per-test async fixture (requires `pytest-asyncio`):
210
+
211
+ ```python
212
+ async def test_async(isoladb_async):
213
+ conn = await asyncpg.connect(
214
+ host=isoladb_async.host, port=isoladb_async.port,
215
+ database=isoladb_async.dbname, user="postgres",
216
+ )
217
+ await conn.execute("SELECT 1")
218
+ await conn.close()
219
+ ```
220
+
221
+ **`isoladb_async_engine`** — per-test async SQLAlchemy engine (requires `sqlalchemy[asyncio]`, `asyncpg`):
222
+
223
+ ```python
224
+ async def test_async_engine(isoladb_async_engine):
225
+ async with isoladb_async_engine.connect() as conn:
226
+ await conn.execute(text("SELECT 1"))
227
+ ```
228
+
229
+ **`isoladb_server`** — session-scoped fixture exposing the underlying `IsolaDBServer`. Useful for custom fixture composition.
230
+
231
+ **`isoladb_setup`** — session-scoped fixture to override with a custom setup callable:
232
+
233
+ ```python
234
+ # conftest.py
235
+ @pytest.fixture(scope="session")
236
+ def isoladb_setup():
237
+ def apply_migrations(url):
238
+ from alembic.config import Config
239
+ from alembic import command
240
+ cfg = Config("alembic.ini")
241
+ cfg.set_main_option("sqlalchemy.url", url)
242
+ command.upgrade(cfg, "head")
243
+ return apply_migrations
244
+ ```
245
+
246
+ ### Ini Options
247
+
248
+ Configure in `pyproject.toml`, `pytest.ini`, or `setup.cfg`:
249
+
250
+ ```toml
251
+ # pyproject.toml
252
+ [tool.pytest.ini_options]
253
+ isoladb_pg_version = "16.1.0"
254
+ isoladb_ram = true
255
+ isoladb_use_system_pg = false
256
+ isoladb_schema = "tests/schema.sql"
257
+ ```
258
+
259
+ | Option | Default | Description |
260
+ |---|---|---|
261
+ | `isoladb_pg_version` | latest stable | PostgreSQL version |
262
+ | `isoladb_ram` | `false` | Use RAM disk |
263
+ | `isoladb_use_system_pg` | `true` | Prefer system PostgreSQL |
264
+ | `isoladb_schema` | none | SQL schema file path |
265
+
266
+ The pytest header shows which PostgreSQL binary is being used:
267
+
268
+ ```
269
+ ============================= test session starts ==============================
270
+ platform darwin -- Python 3.13.6
271
+ isoladb: PostgreSQL at /opt/homebrew/Cellar/postgresql@14/14.19
272
+ ```
273
+
274
+ ## Requirements
275
+
276
+ - Python 3.8+
277
+ - No pre-installed PostgreSQL needed (downloads automatically if not found)
278
+ - Linux (x86_64, arm64) or macOS (x86_64, arm64)
279
+
280
+ ## License
281
+
282
+ MIT
@@ -0,0 +1,63 @@
1
+ [tool.poetry]
2
+ name = "isoladb"
3
+ version = "0.1.0"
4
+ description = "Ephemeral PostgreSQL instances for unit testing"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ authors = ["Yegor Stepanov"]
8
+ keywords = ["testing", "postgresql", "database", "unit-testing", "ephemeral"]
9
+ packages = [{ include = "isoladb", from = "src" }]
10
+ classifiers = [
11
+ "Development Status :: 3 - Alpha",
12
+ "Intended Audience :: Developers",
13
+ "License :: OSI Approved :: MIT License",
14
+ "Programming Language :: Python :: 3",
15
+ "Programming Language :: Python :: 3.8",
16
+ "Programming Language :: Python :: 3.9",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Topic :: Software Development :: Testing",
22
+ "Topic :: Database",
23
+ ]
24
+
25
+ [tool.poetry.dependencies]
26
+ python = ">=3.8"
27
+ psycopg = {version = ">=3.1", extras = ["binary"], optional = true}
28
+ pytest = {version = ">=7.0", optional = true}
29
+ sqlalchemy = {version = ">=2.0", optional = true}
30
+
31
+ [tool.poetry.extras]
32
+ psycopg = ["psycopg"]
33
+ pytest = ["pytest"]
34
+ sqlalchemy = ["sqlalchemy"]
35
+
36
+ [tool.poetry.group.dev.dependencies]
37
+ pytest = ">=7.0"
38
+ sqlalchemy = ">=2.0"
39
+ ruff = "*"
40
+ mypy = "*"
41
+
42
+ [tool.poetry.plugins.pytest11]
43
+ isoladb = "isoladb.pytest_plugin"
44
+
45
+ [build-system]
46
+ requires = ["poetry-core"]
47
+ build-backend = "poetry.core.masonry.api"
48
+
49
+ [tool.ruff]
50
+ target-version = "py38"
51
+ line-length = 99
52
+
53
+ [tool.ruff.lint]
54
+ select = ["E", "F", "I", "N", "W", "UP"]
55
+
56
+ [tool.pytest.ini_options]
57
+ markers = [
58
+ "integration: tests that download PG binaries and start a real server",
59
+ ]
60
+
61
+ [tool.mypy]
62
+ python_version = "3.8"
63
+ strict = true
@@ -0,0 +1,35 @@
1
+ """isoladb — Ephemeral PostgreSQL instances for unit testing."""
2
+
3
+ from isoladb.async_database import AsyncIsolaDB
4
+ from isoladb.config import IsolaDBConfig
5
+ from isoladb.database import IsolaDB, shutdown
6
+ from isoladb.exceptions import (
7
+ BinaryDownloadError,
8
+ BinaryNotFoundError,
9
+ DatabaseError,
10
+ IsolaDBError,
11
+ RamDiskError,
12
+ ServerStartError,
13
+ ServerStopError,
14
+ UnsupportedPlatformError,
15
+ )
16
+ from isoladb.server import IsolaDBServer
17
+
18
+ __version__ = "0.1.0"
19
+
20
+ __all__ = [
21
+ "IsolaDB",
22
+ "AsyncIsolaDB",
23
+ "IsolaDBConfig",
24
+ "IsolaDBServer",
25
+ "shutdown",
26
+ # Exceptions
27
+ "BinaryDownloadError",
28
+ "BinaryNotFoundError",
29
+ "DatabaseError",
30
+ "IsolaDBError",
31
+ "RamDiskError",
32
+ "ServerStartError",
33
+ "ServerStopError",
34
+ "UnsupportedPlatformError",
35
+ ]