10
10
from collections .abc import Mapping
11
11
12
12
import psycopg2
13
- from psycopg2 import extras
14
- from psycopg2 .extensions import POLL_ERROR , POLL_OK , POLL_READ , POLL_WRITE
13
+ import psycopg2 . extensions
14
+ import psycopg2 .extras
15
15
16
16
from .cursor import Cursor
17
- from .utils import _ContextManager , get_running_loop
17
+ from .utils import _ContextManager , create_completed_future , get_running_loop
18
18
19
19
__all__ = ('connect' ,)
20
20
@@ -71,7 +71,7 @@ def __init__(
71
71
self ._enable_json = enable_json
72
72
self ._enable_hstore = enable_hstore
73
73
self ._enable_uuid = enable_uuid
74
- self ._loop = get_running_loop (kwargs . pop ( 'loop' , None ) is not None )
74
+ self ._loop = get_running_loop ()
75
75
self ._waiter = self ._loop .create_future ()
76
76
77
77
kwargs ['async_' ] = kwargs .pop ('async' , True )
@@ -84,7 +84,6 @@ def __init__(
84
84
self ._last_usage = self ._loop .time ()
85
85
self ._writing = False
86
86
self ._echo = echo
87
- self ._cursor_instance = None
88
87
self ._notifies = asyncio .Queue ()
89
88
self ._weakref = weakref .ref (self )
90
89
self ._loop .add_reader (self ._fileno , self ._ready , self ._weakref )
@@ -136,21 +135,21 @@ def _ready(weak_self):
136
135
if waiter is not None and not waiter .done ():
137
136
waiter .set_exception (
138
137
psycopg2 .OperationalError ("Connection closed" ))
139
- if state == POLL_OK :
138
+ if state == psycopg2 . extensions . POLL_OK :
140
139
if self ._writing :
141
140
self ._loop .remove_writer (self ._fileno )
142
141
self ._writing = False
143
142
if waiter is not None and not waiter .done ():
144
143
waiter .set_result (None )
145
- elif state == POLL_READ :
144
+ elif state == psycopg2 . extensions . POLL_READ :
146
145
if self ._writing :
147
146
self ._loop .remove_writer (self ._fileno )
148
147
self ._writing = False
149
- elif state == POLL_WRITE :
148
+ elif state == psycopg2 . extensions . POLL_WRITE :
150
149
if not self ._writing :
151
150
self ._loop .add_writer (self ._fileno , self ._ready , weak_self )
152
151
self ._writing = True
153
- elif state == POLL_ERROR :
152
+ elif state == psycopg2 . extensions . POLL_ERROR :
154
153
self ._fatal_error ("Fatal error on aiopg connection: "
155
154
"POLL_ERROR from underlying .poll() call" )
156
155
else :
@@ -209,9 +208,8 @@ def cursor(self, name=None, cursor_factory=None,
209
208
*name*, *scrollable* and *withhold* parameters are not supported by
210
209
psycopg in asynchronous mode.
211
210
212
- NOTE: as of [TODO] any previously created created cursor from this
213
- connection will be closed
214
211
"""
212
+
215
213
self ._last_usage = self ._loop .time ()
216
214
coro = self ._cursor (name = name , cursor_factory = cursor_factory ,
217
215
scrollable = scrollable , withhold = withhold ,
@@ -222,24 +220,17 @@ async def _cursor(self, name=None, cursor_factory=None,
222
220
scrollable = None , withhold = False , timeout = None ,
223
221
isolation_level = None ):
224
222
225
- if not self .closed_cursor :
226
- warnings .warn (f'You can only have one cursor per connection. '
227
- f'The cursor for connection will be closed forcibly'
228
- f' { self !r} .' , ResourceWarning )
229
-
230
- self .free_cursor ()
231
-
232
223
if timeout is None :
233
224
timeout = self ._timeout
234
225
235
226
impl = await self ._cursor_impl (name = name ,
236
227
cursor_factory = cursor_factory ,
237
228
scrollable = scrollable ,
238
229
withhold = withhold )
239
- self . _cursor_instance = Cursor (
230
+ cursor = Cursor (
240
231
self , impl , timeout , self ._echo , isolation_level
241
232
)
242
- return self . _cursor_instance
233
+ return cursor
243
234
244
235
async def _cursor_impl (self , name = None , cursor_factory = None ,
245
236
scrollable = None , withhold = False ):
@@ -262,29 +253,14 @@ def _close(self):
262
253
self ._loop .remove_writer (self ._fileno )
263
254
264
255
self ._conn .close ()
265
- self .free_cursor ()
266
256
267
257
if self ._waiter is not None and not self ._waiter .done ():
268
258
self ._waiter .set_exception (
269
259
psycopg2 .OperationalError ("Connection closed" ))
270
260
271
- @property
272
- def closed_cursor (self ):
273
- if not self ._cursor_instance :
274
- return True
275
-
276
- return bool (self ._cursor_instance .closed )
277
-
278
- def free_cursor (self ):
279
- if not self .closed_cursor :
280
- self ._cursor_instance .close ()
281
- self ._cursor_instance = None
282
-
283
261
def close (self ):
284
262
self ._close ()
285
- ret = self ._loop .create_future ()
286
- ret .set_result (None )
287
- return ret
263
+ return create_completed_future (self ._loop )
288
264
289
265
@property
290
266
def closed (self ):
@@ -455,7 +431,6 @@ def __repr__(self):
455
431
f'isexecuting={ self ._isexecuting ()} , '
456
432
f'closed={ self .closed } , '
457
433
f'echo={ self .echo } , '
458
- f'cursor={ self ._cursor_instance } '
459
434
f'>'
460
435
)
461
436
@@ -505,18 +480,18 @@ async def _get_oids(self):
505
480
async def _connect (self ):
506
481
try :
507
482
await self ._poll (self ._waiter , self ._timeout )
508
- except Exception :
509
- self .close ()
483
+ except BaseException :
484
+ await asyncio . shield ( self .close () )
510
485
raise
511
486
if self ._enable_json :
512
- extras .register_default_json (self ._conn )
487
+ psycopg2 . extras .register_default_json (self ._conn )
513
488
if self ._enable_uuid :
514
- extras .register_uuid (conn_or_curs = self ._conn )
489
+ psycopg2 . extras .register_uuid (conn_or_curs = self ._conn )
515
490
if self ._enable_hstore :
516
491
oids = await self ._get_oids ()
517
492
if oids is not None :
518
493
oid , array_oid = oids
519
- extras .register_hstore (
494
+ psycopg2 . extras .register_hstore (
520
495
self ._conn ,
521
496
oid = oid ,
522
497
array_oid = array_oid
@@ -531,4 +506,4 @@ async def __aenter__(self):
531
506
return self
532
507
533
508
async def __aexit__ (self , exc_type , exc_val , exc_tb ):
534
- self .close ()
509
+ await self .close ()
0 commit comments