1616# limitations under the License.
1717
1818
19+ from __future__ import annotations
20+
1921import asyncio
2022import tracemalloc
2123import typing as t
2224from functools import wraps
25+ from inspect import isclass
2326from warnings import warn
2427
2528
@@ -67,23 +70,7 @@ def foo(x):
6770 pass
6871
6972 """
70- def decorator (f ):
71- if asyncio .iscoroutinefunction (f ):
72- @wraps (f )
73- async def inner (* args , ** kwargs ):
74- deprecation_warn (message , stack_level = 2 )
75- return await f (* args , ** kwargs )
76-
77- return inner
78- else :
79- @wraps (f )
80- def inner (* args , ** kwargs ):
81- deprecation_warn (message , stack_level = 2 )
82- return f (* args , ** kwargs )
83-
84- return inner
85-
86- return decorator
73+ return _make_warning_decorator (message , deprecation_warn )
8774
8875
8976def deprecated_property (message : str ):
@@ -104,20 +91,6 @@ def experimental_warn(message, stack_level=1):
10491 warn (message , category = ExperimentalWarning , stacklevel = stack_level + 1 )
10592
10693
107- class PreviewWarning (Warning ):
108- """ Base class for warnings about experimental features.
109- """
110-
111-
112- def preview_warn (message , stack_level = 1 ):
113- message += (
114- " It might be changed without following the deprecation policy. "
115- "See also "
116- "https://github.com/neo4j/neo4j-python-driver/wiki/preview-features."
117- )
118- warn (message , category = PreviewWarning , stacklevel = stack_level + 1 )
119-
120-
12194def experimental (message ) -> t .Callable [[_FuncT ], _FuncT ]:
12295 """ Decorator for tagging experimental functions and methods.
12396
@@ -147,7 +120,21 @@ def inner(*args, **kwargs):
147120
148121 return inner
149122
150- return decorator
123+ return _make_warning_decorator (message , experimental_warn )
124+
125+
126+ class PreviewWarning (Warning ):
127+ """ Base class for warnings about experimental features.
128+ """
129+
130+
131+ def preview_warn (message , stack_level = 1 ):
132+ message += (
133+ " It might be changed without following the deprecation policy. "
134+ "See also "
135+ "https://github.com/neo4j/neo4j-python-driver/wiki/preview-features."
136+ )
137+ warn (message , category = PreviewWarning , stacklevel = stack_level + 1 )
151138
152139
153140def preview (message ) -> t .Callable [[_FuncT ], _FuncT ]:
@@ -158,18 +145,47 @@ def preview(message) -> t.Callable[[_FuncT], _FuncT]:
158145 def foo(x):
159146 pass
160147 """
148+
149+ return _make_warning_decorator (message , preview_warn )
150+
151+
152+ if t .TYPE_CHECKING :
153+ class _WarningFunc (t .Protocol ):
154+ def __call__ (self , message : str , stack_level : int = 1 ) -> None :
155+ ...
156+ else :
157+ _WarningFunc = object
158+
159+
160+ def _make_warning_decorator (
161+ message : str ,
162+ warning_func : _WarningFunc ,
163+ ) -> t .Callable [[_FuncT ], _FuncT ]:
161164 def decorator (f ):
162165 if asyncio .iscoroutinefunction (f ):
163166 @wraps (f )
164167 async def inner (* args , ** kwargs ):
165- preview_warn (message , stack_level = 2 )
168+ warning_func (message , stack_level = 2 )
166169 return await f (* args , ** kwargs )
167170
168171 return inner
172+ if isclass (f ):
173+ if hasattr (f , "__init__" ):
174+ original_init = f .__init__
175+ @wraps (original_init )
176+ def inner (* args , ** kwargs ):
177+ warning_func (message , stack_level = 2 )
178+ return original_init (* args , ** kwargs )
179+
180+ f .__init__ = inner
181+ return f
182+ raise TypeError (
183+ "Cannot decorate class without __init__"
184+ )
169185 else :
170186 @wraps (f )
171187 def inner (* args , ** kwargs ):
172- preview_warn (message , stack_level = 2 )
188+ warning_func (message , stack_level = 2 )
173189 return f (* args , ** kwargs )
174190
175191 return inner
0 commit comments