Coverage for tests / conftest.py: 97%
70 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-11-09 00:02 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-11-09 00:02 +0000
1import os 1abcdefghi
2import shutil 1abcdefghi
3import subprocess 1abcdefghi
4import sys 1abcdefghi
5from collections.abc import Callable, Generator 1abcdefghi
6from dataclasses import dataclass, field 1abcdefghi
7from pathlib import Path 1abcdefghi
8from typing import Any 1abcdefghi
9from unittest.mock import patch 1abcdefghi
11import pytest 1abcdefghi
12from pydantic import BaseModel 1abcdefghi
13from sqlalchemy import Engine 1abcdefghi
14from sqlalchemy.engine import make_url 1abcdefghi
15from sqlalchemy.pool import StaticPool 1abcdefghi
16from sqlmodel import SQLModel, create_engine 1abcdefghi
17from sqlmodel.main import default_registry 1abcdefghi
19top_level_path = Path(__file__).resolve().parent.parent 1abcdefghi
20docs_src_path = top_level_path / "docs_src" 1abcdefghi
23@pytest.fixture(autouse=True) 1abcdefghi
24def clear_sqlmodel() -> Any: 1abcdefghi
25 # Clear the tables in the metadata for the default base model
26 SQLModel.metadata.clear() 1abcdefghi
27 # Clear the Models associated with the registry, to avoid warnings
28 default_registry.dispose() 1abcdefghi
29 yield 1abcdefghi
30 SQLModel.metadata.clear() 1abcdefghi
31 default_registry.dispose() 1abcdefghi
34@pytest.fixture() 1abcdefghi
35def database_engine(clear_sqlmodel: Any) -> Generator[Engine, None, None]: 1abcdefghi
36 url = make_url(os.environ.get("DATABASE_URL", "sqlite://")) 1abcdefghi
37 if url.get_backend_name() == "sqlite": 1abcdefghi
38 engine = create_engine( 1befghi
39 url, connect_args={"check_same_thread": False}, poolclass=StaticPool
40 )
41 else:
42 engine = create_engine(url) 1acd
43 try: 1abcdefghi
44 yield engine 1abcdefghi
45 finally:
46 # Drop tables before clear_sqlmodel removes their metadata.
47 try: 1abcdefghi
48 SQLModel.metadata.drop_all(engine) 1abcdefghi
49 finally:
50 engine.dispose() 1abcdefghi
53@pytest.fixture() 1abcdefghi
54def cov_tmp_path(tmp_path: Path) -> Generator[Path, None, None]: 1abcdefghi
55 yield tmp_path 1abcdefghi
56 for coverage_path in tmp_path.glob(".coverage*"): 1abcdefghi
57 coverage_destiny_path = top_level_path / "coverage" / coverage_path.name
58 shutil.copy(coverage_path, coverage_destiny_path)
61def coverage_run(*, module: str, cwd: str | Path) -> subprocess.CompletedProcess: 1abcdefghi
62 result = subprocess.run( 2}g~gahbhchdhehfhgh
63 [
64 "coverage",
65 "run",
66 "--parallel-mode",
67 "--source=docs_src,tests,sqlmodel",
68 "-m",
69 module,
70 ],
71 cwd=str(cwd),
72 capture_output=True,
73 encoding="utf-8",
74 )
75 return result 2}g~gahbhchdhehfhgh
78def get_testing_print_function( 1abcdefghi
79 calls: list[list[str | dict[str, Any]]],
80) -> Callable[..., Any]:
81 def new_print(*args: Any) -> None: 1abcdefghi
82 data: list[Any] = [] 2CbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbPfQf# $ % ' j k l WbxfXbYbZb0b1b2byfm n 3b4b5b6b7b8b9b!bo RfSf( ) #b$b%b'bTfUfVfWfXfYfZf0f1f2f3f(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b4f5f* + , - p q r }bzf~bacbcccdcecAfs t fcgchcicjckclcmcu 6f7f. / ncocpcqc8f9f!f#f$f%f'f(f)f*f+frcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc,f-f: ; = ? v w x LcBfMcNcOcPcQcRcCfy z ScTcUcVcWcXcYcZcA .f/f@ [ 0c1c2c3c:f;f=f?f@f[f]f^f_f`f{f4c5c6c7c8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c|f}f] ^ _ ` B C D ;cDf=c?c@c[c]c^cEfE F _c`c{c|c}c~cadbdG ~fag{ | cdddedfdbgcgdgegfggghgigjgkglggdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdmgng} ~ abbbH I J AdFfBdCdDdEdFdGdGfK L HdIdJdKdLdMdNdOdM ogpgcbdbPdQdRdSdqgrgsgtgugvgwgxgygzgAgTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8d9d!d#d$dBgCgebfbgbhbN O P %dHf'd(d)d*d+d,dIfQ R -d.d/d:d;d=d?d@dS DgEgibjb[d]d^d_dFgGgHgIgJgKgLgMgNgOgPg`d{d|d}d~daebecedeeefegeheiejekelemeneoeQgRgkblbmbnbT U V peJfqereseteueveKfW X wexeyezeAeBeCeDeY SgTgobpbEeFeGeHeUgVgWgXgYgZg0g1g2g3g4gIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e5g6gqbrbsbtbZ 0 1 2eLf3e4e5e6e7e8eMf2 3 9e!e#e$e%e'e(e)e4 7g8gubvb*e+e,e-e9g!g#g$g%g'g(g)g*g+g,g.e/e:e;e=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdf-g.gwbxbybzb5 6 7 efNfffgfhfifjfkfOf8 9 lfmfnfofpfqfrfsf! /g:gAbBbtfufvfwf;g=g?g@g[g]g^g_g`g{g|g
83 for arg in args: 2CbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbPfQf# $ % ' j k l WbxfXbYbZb0b1b2byfm n 3b4b5b6b7b8b9b!bo RfSf( ) #b$b%b'bTfUfVfWfXfYfZf0f1f2f3f(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b4f5f* + , - p q r }bzf~bacbcccdcecAfs t fcgchcicjckclcmcu 6f7f. / ncocpcqc8f9f!f#f$f%f'f(f)f*f+frcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc,f-f: ; = ? v w x LcBfMcNcOcPcQcRcCfy z ScTcUcVcWcXcYcZcA .f/f@ [ 0c1c2c3c:f;f=f?f@f[f]f^f_f`f{f4c5c6c7c8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c|f}f] ^ _ ` B C D ;cDf=c?c@c[c]c^cEfE F _c`c{c|c}c~cadbdG ~fag{ | cdddedfdbgcgdgegfggghgigjgkglggdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdmgng} ~ abbbH I J AdFfBdCdDdEdFdGdGfK L HdIdJdKdLdMdNdOdM ogpgcbdbPdQdRdSdqgrgsgtgugvgwgxgygzgAgTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8d9d!d#d$dBgCgebfbgbhbN O P %dHf'd(d)d*d+d,dIfQ R -d.d/d:d;d=d?d@dS DgEgibjb[d]d^d_dFgGgHgIgJgKgLgMgNgOgPg`d{d|d}d~daebecedeeefegeheiejekelemeneoeQgRgkblbmbnbT U V peJfqereseteueveKfW X wexeyezeAeBeCeDeY SgTgobpbEeFeGeHeUgVgWgXgYgZg0g1g2g3g4gIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e5g6gqbrbsbtbZ 0 1 2eLf3e4e5e6e7e8eMf2 3 9e!e#e$e%e'e(e)e4 7g8gubvb*e+e,e-e9g!g#g$g%g'g(g)g*g+g,g.e/e:e;e=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdf-g.gwbxbybzb5 6 7 efNfffgfhfifjfkfOf8 9 lfmfnfofpfqfrfsf! /g:gAbBbtfufvfwf;g=g?g@g[g]g^g_g`g{g|g
84 if isinstance(arg, BaseModel): 2CbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbPfQf# $ % ' j k l WbxfXbYbZb0b1b2byfm n 3b4b5b6b7b8b9b!bo RfSf( ) #b$b%b'bTfUfVfWfXfYfZf0f1f2f3f(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b4f5f* + , - p q r }bzf~bacbcccdcecAfs t fcgchcicjckclcmcu 6f7f. / ncocpcqc8f9f!f#f$f%f'f(f)f*f+frcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc,f-f: ; = ? v w x LcBfMcNcOcPcQcRcCfy z ScTcUcVcWcXcYcZcA .f/f@ [ 0c1c2c3c:f;f=f?f@f[f]f^f_f`f{f4c5c6c7c8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c|f}f] ^ _ ` B C D ;cDf=c?c@c[c]c^cEfE F _c`c{c|c}c~cadbdG ~fag{ | cdddedfdbgcgdgegfggghgigjgkglggdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdmgng} ~ abbbH I J AdFfBdCdDdEdFdGdGfK L HdIdJdKdLdMdNdOdM ogpgcbdbPdQdRdSdqgrgsgtgugvgwgxgygzgAgTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8d9d!d#d$dBgCgebfbgbhbN O P %dHf'd(d)d*d+d,dIfQ R -d.d/d:d;d=d?d@dS DgEgibjb[d]d^d_dFgGgHgIgJgKgLgMgNgOgPg`d{d|d}d~daebecedeeefegeheiejekelemeneoeQgRgkblbmbnbT U V peJfqereseteueveKfW X wexeyezeAeBeCeDeY SgTgobpbEeFeGeHeUgVgWgXgYgZg0g1g2g3g4gIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e5g6gqbrbsbtbZ 0 1 2eLf3e4e5e6e7e8eMf2 3 9e!e#e$e%e'e(e)e4 7g8gubvb*e+e,e-e9g!g#g$g%g'g(g)g*g+g,g.e/e:e;e=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdf-g.gwbxbybzb5 6 7 efNfffgfhfifjfkfOf8 9 lfmfnfofpfqfrfsf! /g:gAbBbtfufvfwf;g=g?g@g[g]g^g_g`g{g|g
85 data.append(arg.model_dump()) 2CbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbPfQfj k l WbXbYbZb0b1b2bm n 3b4b5b6b7b8b9b!bo RfSf#b$b%b'bTfUfVfWfXfYfZf0f1f2f3f(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b4f5fp q r }b~bacbcccdcecs t fcgchcicjckclcmcu 6f7fncocpcqc8f9f!f#f$f%f'f(f)f*f+frcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc,f-fv w x LcMcNcOcPcQcRcy z ScTcUcVcWcXcYcZcA .f/f0c1c2c3c:f;f=f?f@f[f]f^f_f`f{f4c5c6c7c8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c|f}fB C D ;c=c?c@c[c]c^cE F _c`c{c|c}c~cadbdG ~fagcdddedfdbgcgdgegfggghgigjgkglggdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdmgngH I J AdBdCdDdEdFdGdK L HdIdJdKdLdMdNdOdM ogpgPdQdRdSdqgrgsgtgugvgwgxgygzgAgTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8d9d!d#d$dBgCgN O P %d'd(d)d*d+d,dQ R -d.d/d:d;d=d?d@dS DgEg[d]d^d_dFgGgHgIgJgKgLgMgNgOgPg`d{d|d}d~daebecedeeefegeheiejekelemeneoeQgRgT U V peqereseteueveW X wexeyezeAeBeCeDeY SgTgEeFeGeHeUgVgWgXgYgZg0g1g2g3g4gIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e5g6gZ 0 1 2e3e4e5e6e7e8e2 3 9e!e#e$e%e'e(e)e4 7g8g*e+e,e-e9g!g#g$g%g'g(g)g*g+g,g.e/e:e;e=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdf-g.g5 6 7 efffgfhfifjfkf8 9 lfmfnfofpfqfrfsf! /g:gtfufvfwf;g=g?g@g[g]g^g_g`g{g|g
86 elif isinstance(arg, list): 2CbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVb# $ % ' j k l WbxfXbYbZb0b1b2byfm n 3b4b5b6b7b8b9b!bo ( ) #b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b* + , - p q r }bzf~bacbcccdcecAfs t fcgchcicjckclcmcu . / ncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc: ; = ? v w x LcBfMcNcOcPcQcRcCfy z ScTcUcVcWcXcYcZcA @ [ 0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c] ^ _ ` B C D ;cDf=c?c@c[c]c^cEfE F _c`c{c|c}c~cadbdG { | cdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzd} ~ abbbH I J AdFfBdCdDdEdFdGdGfK L HdIdJdKdLdMdNdOdM cbdbPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8d9d!d#d$debfbgbhbN O P %dHf'd(d)d*d+d,dIfQ R -d.d/d:d;d=d?d@dS ibjb[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemeneoekblbmbnbT U V peJfqereseteueveKfW X wexeyezeAeBeCeDeY obpbEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eqbrbsbtbZ 0 1 2eLf3e4e5e6e7e8eMf2 3 9e!e#e$e%e'e(e)e4 ubvb*e+e,e-e.e/e:e;e=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfwbxbybzb5 6 7 efNfffgfhfifjfkfOf8 9 lfmfnfofpfqfrfsf! AbBbtfufvfwf
87 new_list = [] 2# $ % ' j k l m n o ( ) * + , - p q r s t u . / : ; = ? v w x y z A @ [ ] ^ _ ` B C D E F G { | } ~ abbbH I J K L M cbdbebfbgbhbN O P Q R S ibjbkblbmbnbT U V W X Y obpbqbrbsbtbZ 0 1 2 3 4 ubvbwbxbybzb5 6 7 8 9 ! AbBb
88 for item in arg: 2# $ % ' j k l m n o ( ) * + , - p q r s t u . / : ; = ? v w x y z A @ [ ] ^ _ ` B C D E F G { | } ~ abbbH I J K L M cbdbebfbgbhbN O P Q R S ibjbkblbmbnbT U V W X Y obpbqbrbsbtbZ 0 1 2 3 4 ubvbwbxbybzb5 6 7 8 9 ! AbBb
89 if isinstance(item, BaseModel): 2# $ % ' j k l m n o ( ) * + , - p q r s t u . / : ; = ? v w x y z A @ [ ] ^ _ ` B C D E F G { | } ~ abbbH I J K L M cbdbebfbgbhbN O P Q R S ibjbkblbmbnbT U V W X Y obpbqbrbsbtbZ 0 1 2 3 4 ubvbwbxbybzb5 6 7 8 9 ! AbBb
90 new_list.append(item.model_dump()) 2# $ % ' j k l m n o ( ) * + , - p q r s t u . / : ; = ? v w x y z A @ [ ] ^ _ ` B C D E F G { | } ~ abbbH I J K L M cbdbebfbgbhbN O P Q R S ibjbkblbmbnbT U V W X Y obpbqbrbsbtbZ 0 1 2 3 4 ubvbwbxbybzb5 6 7 8 9 ! AbBb
91 data.append(new_list) 2# $ % ' j k l m n o ( ) * + , - p q r s t u . / : ; = ? v w x y z A @ [ ] ^ _ ` B C D E F G { | } ~ abbbH I J K L M cbdbebfbgbhbN O P Q R S ibjbkblbmbnbT U V W X Y obpbqbrbsbtbZ 0 1 2 3 4 ubvbwbxbybzb5 6 7 8 9 ! AbBb
92 else:
93 data.append(arg) 2CbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbj k l WbxfXbYbZb0b1b2byfm n 3b4b5b6b7b8b9b!bo #b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|bp q r }bzf~bacbcccdcecAfs t fcgchcicjckclcmcu ncocpcqcrcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKcv w x LcBfMcNcOcPcQcRcCfy z ScTcUcVcWcXcYcZcA 0c1c2c3c4c5c6c7c8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:cB C D ;cDf=c?c@c[c]c^cEfE F _c`c{c|c}c~cadbdG cdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdH I J AdFfBdCdDdEdFdGdGfK L HdIdJdKdLdMdNdOdM PdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8d9d!d#d$dN O P %dHf'd(d)d*d+d,dIfQ R -d.d/d:d;d=d?d@dS [d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemeneoeT U V peJfqereseteueveKfW X wexeyezeAeBeCeDeY EeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eZ 0 1 2eLf3e4e5e6e7e8eMf2 3 9e!e#e$e%e'e(e)e4 *e+e,e-e.e/e:e;e=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdf5 6 7 efNfffgfhfifjfkfOf8 9 lfmfnfofpfqfrfsf! tfufvfwf
94 calls.append(data) 2CbDbEbFbGbHbIbJbKbLbMbNbObPbQbRbSbTbUbVbPfQf# $ % ' j k l WbxfXbYbZb0b1b2byfm n 3b4b5b6b7b8b9b!bo RfSf( ) #b$b%b'bTfUfVfWfXfYfZf0f1f2f3f(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b4f5f* + , - p q r }bzf~bacbcccdcecAfs t fcgchcicjckclcmcu 6f7f. / ncocpcqc8f9f!f#f$f%f'f(f)f*f+frcsctcucvcwcxcyczcAcBcCcDcEcFcGcHcIcJcKc,f-f: ; = ? v w x LcBfMcNcOcPcQcRcCfy z ScTcUcVcWcXcYcZcA .f/f@ [ 0c1c2c3c:f;f=f?f@f[f]f^f_f`f{f4c5c6c7c8c9c!c#c$c%c'c(c)c*c+c,c-c.c/c:c|f}f] ^ _ ` B C D ;cDf=c?c@c[c]c^cEfE F _c`c{c|c}c~cadbdG ~fag{ | cdddedfdbgcgdgegfggghgigjgkglggdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdmgng} ~ abbbH I J AdFfBdCdDdEdFdGdGfK L HdIdJdKdLdMdNdOdM ogpgcbdbPdQdRdSdqgrgsgtgugvgwgxgygzgAgTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8d9d!d#d$dBgCgebfbgbhbN O P %dHf'd(d)d*d+d,dIfQ R -d.d/d:d;d=d?d@dS DgEgibjb[d]d^d_dFgGgHgIgJgKgLgMgNgOgPg`d{d|d}d~daebecedeeefegeheiejekelemeneoeQgRgkblbmbnbT U V peJfqereseteueveKfW X wexeyezeAeBeCeDeY SgTgobpbEeFeGeHeUgVgWgXgYgZg0g1g2g3g4gIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e5g6gqbrbsbtbZ 0 1 2eLf3e4e5e6e7e8eMf2 3 9e!e#e$e%e'e(e)e4 7g8gubvb*e+e,e-e9g!g#g$g%g'g(g)g*g+g,g.e/e:e;e=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdf-g.gwbxbybzb5 6 7 efNfffgfhfifjfkfOf8 9 lfmfnfofpfqfrfsf! /g:gAbBbtfufvfwf;g=g?g@g[g]g^g_g`g{g|g
96 return new_print 1abcdefghi
99@dataclass 1abcdefghi
100class PrintMock: 1abcdefghi
101 calls: list[Any] = field(default_factory=list) 1abcdefghi
104@pytest.fixture(name="print_mock") 1abcdefghi
105def print_mock_fixture() -> Generator[PrintMock, None, None]: 1abcdefghi
106 print_mock = PrintMock() 1abcdefghi
107 new_print = get_testing_print_function(print_mock.calls) 1abcdefghi
108 with patch("builtins.print", new=new_print): 1abcdefghi
109 yield print_mock 1abcdefghi
112needs_py311 = pytest.mark.skipif( 1abcdefghi
113 sys.version_info < (3, 11), reason="requires Python 3.11+"
114)