3
3
import types
4
4
import warnings
5
5
from unittest import mock
6
+ import pyarrow as pa
6
7
7
8
# The module where the version check code resides
8
9
MODULE_PATH = "db_dtypes"
9
10
HELPER_MODULE_PATH = f"{ MODULE_PATH } ._versions_helpers"
10
11
11
- @pytest .fixture ( autouse = True )
12
+ @pytest .fixture
12
13
def cleanup_imports ():
13
14
"""Ensures the target module and its helper are removed from sys.modules
14
15
before each test, allowing for clean imports with patching.
@@ -48,7 +49,7 @@ def cleanup_imports():
48
49
((3 , 12 , 0 ), "3.12.0" , False ),
49
50
]
50
51
)
51
- def test_python_version_warning_on_import (mock_version_tuple , version_str , expect_warning ):
52
+ def test_python_version_warning_on_import (mock_version_tuple , version_str , expect_warning , cleanup_imports ):
52
53
"""Test that a FutureWarning is raised ONLY for Python 3.7 or 3.8 during import.
53
54
"""
54
55
@@ -71,8 +72,6 @@ def test_python_version_warning_on_import(mock_version_tuple, version_str, expec
71
72
assert len (record ) == 1
72
73
warning_message = str (record [0 ].message )
73
74
assert "longer supports Python 3.7 and Python 3.8" in warning_message
74
- assert f"Your Python version is { version_str } " in warning_message
75
- assert "https://cloud.google.com/python/docs/supported-python-versions" in warning_message
76
75
else :
77
76
with warnings .catch_warnings (record = True ) as record :
78
77
warnings .simplefilter ("always" )
@@ -88,3 +87,65 @@ def test_python_version_warning_on_import(mock_version_tuple, version_str, expec
88
87
assert not found_warning , (
89
88
f"Unexpected FutureWarning raised for Python version { version_str } "
90
89
)
90
+
91
+ # --- Test Case 1: JSON types available ---
92
+
93
+ @pytest .fixture
94
+ def cleanup_imports_for_all (request ):
95
+ """
96
+ Ensures the target module and its dependencies potentially affecting
97
+ __all__ are removed from sys.modules before and after each test,
98
+ allowing for clean imports with patching. Also handles PyArrow extension type registration.
99
+ """
100
+
101
+ # Modules that might be checked or imported in __init__
102
+ modules_to_clear = [
103
+ MODULE_PATH ,
104
+ f"{ MODULE_PATH } .core" ,
105
+ f"{ MODULE_PATH } .json" ,
106
+ f"{ MODULE_PATH } .version" ,
107
+ f"{ MODULE_PATH } ._versions_helpers" ,
108
+ ]
109
+ original_modules = {}
110
+
111
+ # Store original modules and remove them
112
+ for mod_name in modules_to_clear :
113
+ original_modules [mod_name ] = sys .modules .get (mod_name )
114
+ if mod_name in sys .modules :
115
+ del sys .modules [mod_name ]
116
+
117
+ yield # Run the test
118
+
119
+ # Restore original modules after test
120
+ for mod_name , original_mod in original_modules .items ():
121
+ if original_mod :
122
+ sys .modules [mod_name ] = original_mod
123
+ elif mod_name in sys .modules :
124
+ # If it wasn't there before but is now, remove it
125
+ del sys .modules [mod_name ]
126
+
127
+ def test_all_includes_json_when_available (cleanup_imports_for_all ):
128
+ """
129
+ Test that __all__ includes JSON types when JSONArray and JSONDtype are available.
130
+ """
131
+
132
+ # No patching needed for the 'else' block, assume normal import works
133
+ # and JSONArray/JSONDtype are truthy.
134
+ import db_dtypes
135
+
136
+ expected_all = [
137
+ "__version__" ,
138
+ "DateArray" ,
139
+ "DateDtype" ,
140
+ "JSONDtype" ,
141
+ "JSONArray" ,
142
+ "JSONArrowType" ,
143
+ "TimeArray" ,
144
+ "TimeDtype" ,
145
+ ]
146
+ # Use set comparison for order independence, as __all__ order isn't critical
147
+ assert set (db_dtypes .__all__ ) == set (expected_all )
148
+ # Explicitly check presence of JSON types
149
+ assert "JSONDtype" in db_dtypes .__all__
150
+ assert "JSONArray" in db_dtypes .__all__
151
+ assert "JSONArrowType" in db_dtypes .__all__
0 commit comments