Coverage for tests / conftest.py: 97%

70 statements  

« 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

10 

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

18 

19top_level_path = Path(__file__).resolve().parent.parent 1abcdefghi

20docs_src_path = top_level_path / "docs_src" 1abcdefghi

21 

22 

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

32 

33 

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

51 

52 

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) 

59 

60 

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

76 

77 

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

95 

96 return new_print 1abcdefghi

97 

98 

99@dataclass 1abcdefghi

100class PrintMock: 1abcdefghi

101 calls: list[Any] = field(default_factory=list) 1abcdefghi

102 

103 

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

110 

111 

112needs_py311 = pytest.mark.skipif( 1abcdefghi

113 sys.version_info < (3, 11), reason="requires Python 3.11+" 

114)