Skip to content

Commit bca8e9c

Browse files
authored
Fix session/workspace life-cycle (#680)
* don't emit deprecation warning of workspace.__del__ if it was closed already * don't import things while executing a destructor (in deprecation warning) * unasync _AsyncClassNames as well
1 parent f0c8c1e commit bca8e9c

File tree

7 files changed

+27
-14
lines changed

7 files changed

+27
-14
lines changed

bin/make-unasync

+3
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,9 @@ class CustomRule(unasync.Rule):
172172
# Convert class names from 'AsyncXyz' to 'Xyz'
173173
if len(name) > 5 and name.startswith("Async") and name[5].isupper():
174174
return name[5:]
175+
# Convert class names from '_AsyncXyz' to '_Xyz'
176+
elif len(name) > 6 and name.startswith("_Async") and name[6].isupper():
177+
return "_" + name[6:]
175178
# Convert variable/method/function names from 'async_xyz' to 'xyz'
176179
elif len(name) > 6 and name.startswith("async_"):
177180
return name[6:]

neo4j/_async/work/session.py

+2
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ async def close(self):
147147
This will release any borrowed resources, such as connections, and will
148148
roll back any outstanding transactions.
149149
"""
150+
if self._closed:
151+
return
150152
if self._connection:
151153
if self._auto_result:
152154
if self._state_failed is False:

neo4j/_async/work/workspace.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ def __init__(self, pool, config):
4545
self._closed = False
4646

4747
def __del__(self):
48-
if not self._closed:
49-
unclosed_resource_warn(self)
48+
if self._closed:
49+
return
50+
unclosed_resource_warn(self)
5051
# TODO: 6.0 - remove this
5152
if asyncio.iscoroutinefunction(self.close):
5253
return
@@ -120,5 +121,7 @@ async def _disconnect(self, sync=False):
120121
self._connection_access_mode = None
121122

122123
async def close(self):
124+
if self._closed:
125+
return
123126
await self._disconnect(sync=True)
124127
self._closed = True

neo4j/_sync/work/session.py

+2
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ def close(self):
147147
This will release any borrowed resources, such as connections, and will
148148
roll back any outstanding transactions.
149149
"""
150+
if self._closed:
151+
return
150152
if self._connection:
151153
if self._auto_result:
152154
if self._state_failed is False:

neo4j/_sync/work/transaction.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
__all__ = ("Transaction", "ManagedTransaction")
3030

3131

32-
class _AsyncTransactionBase:
32+
class _TransactionBase:
3333
def __init__(self, connection, fetch_size, on_closed, on_error):
3434
self._connection = connection
3535
self._error_handling_connection = ConnectionErrorHandler(
@@ -196,7 +196,7 @@ def _closed(self):
196196
return self._closed_flag
197197

198198

199-
class Transaction(_AsyncTransactionBase):
199+
class Transaction(_TransactionBase):
200200
""" Container for multiple Cypher queries to be executed within a single
201201
context. :class:`Transaction` objects can be used as a context
202202
managers (:py:const:`with` block) where the transaction is committed
@@ -207,32 +207,32 @@ class Transaction(_AsyncTransactionBase):
207207
208208
"""
209209

210-
@wraps(_AsyncTransactionBase._enter)
210+
@wraps(_TransactionBase._enter)
211211
def __enter__(self):
212212
return self._enter()
213213

214-
@wraps(_AsyncTransactionBase._exit)
214+
@wraps(_TransactionBase._exit)
215215
def __exit__(self, exception_type, exception_value, traceback):
216216
self._exit(exception_type, exception_value, traceback)
217217

218-
@wraps(_AsyncTransactionBase._commit)
218+
@wraps(_TransactionBase._commit)
219219
def commit(self):
220220
return self._commit()
221221

222-
@wraps(_AsyncTransactionBase._rollback)
222+
@wraps(_TransactionBase._rollback)
223223
def rollback(self):
224224
return self._rollback()
225225

226-
@wraps(_AsyncTransactionBase._close)
226+
@wraps(_TransactionBase._close)
227227
def close(self):
228228
return self._close()
229229

230-
@wraps(_AsyncTransactionBase._closed)
230+
@wraps(_TransactionBase._closed)
231231
def closed(self):
232232
return self._closed()
233233

234234

235-
class ManagedTransaction(_AsyncTransactionBase):
235+
class ManagedTransaction(_TransactionBase):
236236
"""Transaction object provided to transaction functions.
237237
238238
Inside a transaction function, the driver is responsible for managing

neo4j/_sync/work/workspace.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ def __init__(self, pool, config):
4545
self._closed = False
4646

4747
def __del__(self):
48-
if not self._closed:
49-
unclosed_resource_warn(self)
48+
if self._closed:
49+
return
50+
unclosed_resource_warn(self)
5051
# TODO: 6.0 - remove this
5152
if asyncio.iscoroutinefunction(self.close):
5253
return
@@ -120,5 +121,7 @@ def _disconnect(self, sync=False):
120121
self._connection_access_mode = None
121122

122123
def close(self):
124+
if self._closed:
125+
return
123126
self._disconnect(sync=True)
124127
self._closed = True

neo4j/meta.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import asyncio
2020
from functools import wraps
21+
from warnings import warn
2122

2223

2324
# Can be automatically overridden in builds
@@ -39,7 +40,6 @@ def get_user_agent():
3940

4041

4142
def deprecation_warn(message, stack_level=2):
42-
from warnings import warn
4343
warn(message, category=DeprecationWarning, stacklevel=stack_level)
4444

4545

0 commit comments

Comments
 (0)