@@ -1176,24 +1176,6 @@ def __getattr__(self, name: str) -> Any:
1176
1176
raise AttributeError ("GridIn object has no attribute '%s'" % name )
1177
1177
1178
1178
def __setattr__ (self , name : str , value : Any ) -> None :
1179
- # For properties of this instance like _buffer, or descriptors set on
1180
- # the class like filename, use regular __setattr__
1181
- if name in self .__dict__ or name in self .__class__ .__dict__ :
1182
- object .__setattr__ (self , name , value )
1183
- else :
1184
- if _IS_SYNC :
1185
- # All other attributes are part of the document in db.fs.files.
1186
- # Store them to be sent to server on close() or if closed, send
1187
- # them now.
1188
- self ._file [name ] = value
1189
- if self ._closed :
1190
- self ._coll .files .update_one ({"_id" : self ._file ["_id" ]}, {"$set" : {name : value }})
1191
- else :
1192
- raise AttributeError (
1193
- "AsyncGridIn does not support __setattr__. Use AsyncGridIn.set() instead"
1194
- )
1195
-
1196
- async def set (self , name : str , value : Any ) -> None :
1197
1179
# For properties of this instance like _buffer, or descriptors set on
1198
1180
# the class like filename, use regular __setattr__
1199
1181
if name in self .__dict__ or name in self .__class__ .__dict__ :
@@ -1204,9 +1186,17 @@ async def set(self, name: str, value: Any) -> None:
1204
1186
# them now.
1205
1187
self ._file [name ] = value
1206
1188
if self ._closed :
1207
- await self ._coll .files .update_one (
1208
- {"_id" : self ._file ["_id" ]}, {"$set" : {name : value }}
1209
- )
1189
+ if _IS_SYNC :
1190
+ self ._coll .files .update_one ({"_id" : self ._file ["_id" ]}, {"$set" : {name : value }})
1191
+ else :
1192
+ raise AttributeError (
1193
+ "AsyncGridIn does not support __setattr__ after being closed(). Set the attribute before closing the file or use AsyncGridIn.set() instead"
1194
+ )
1195
+
1196
+ async def set (self , name : str , value : Any ) -> None :
1197
+ self ._file [name ] = value
1198
+ if self ._closed :
1199
+ await self ._coll .files .update_one ({"_id" : self ._file ["_id" ]}, {"$set" : {name : value }})
1210
1200
1211
1201
async def _flush_data (self , data : Any , force : bool = False ) -> None :
1212
1202
"""Flush `data` to a chunk."""
@@ -1400,7 +1390,11 @@ async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> Any:
1400
1390
return False
1401
1391
1402
1392
1403
- class AsyncGridOut (io .IOBase ):
1393
+ GRIDOUT_BASE_CLASS = io .IOBase if _IS_SYNC else object # type: Any
1394
+
1395
+
1396
+ class AsyncGridOut (GRIDOUT_BASE_CLASS ): # type: ignore
1397
+
1404
1398
"""Class to read data out of GridFS."""
1405
1399
1406
1400
def __init__ (
@@ -1460,6 +1454,8 @@ def __init__(
1460
1454
self ._position = 0
1461
1455
self ._file = file_document
1462
1456
self ._session = session
1457
+ if not _IS_SYNC :
1458
+ self .closed = False
1463
1459
1464
1460
_id : Any = _a_grid_out_property ("_id" , "The ``'_id'`` value for this file." )
1465
1461
filename : str = _a_grid_out_property ("filename" , "Name of this file." )
@@ -1486,16 +1482,43 @@ def __init__(
1486
1482
_file : Any
1487
1483
_chunk_iter : Any
1488
1484
1489
- async def __anext__ ( self ) -> bytes :
1490
- return super (). __next__ ()
1485
+ if not _IS_SYNC :
1486
+ closed : bool
1491
1487
1492
- def __next__ (self ) -> bytes : # noqa: F811, RUF100
1493
- if _IS_SYNC :
1494
- return super ().__next__ ()
1495
- else :
1496
- raise TypeError (
1497
- "AsyncGridOut does not support synchronous iteration. Use `async for` instead"
1498
- )
1488
+ async def __anext__ (self ) -> bytes :
1489
+ line = await self .readline ()
1490
+ if line :
1491
+ return line
1492
+ raise StopAsyncIteration ()
1493
+
1494
+ async def to_list (self ) -> list [bytes ]:
1495
+ return [x async for x in self ] # noqa: C416, RUF100
1496
+
1497
+ async def readline (self , size : int = - 1 ) -> bytes :
1498
+ """Read one line or up to `size` bytes from the file.
1499
+
1500
+ :param size: the maximum number of bytes to read
1501
+ """
1502
+ return await self ._read_size_or_line (size = size , line = True )
1503
+
1504
+ async def readlines (self , size : int = - 1 ) -> list [bytes ]:
1505
+ """Read one line or up to `size` bytes from the file.
1506
+
1507
+ :param size: the maximum number of bytes to read
1508
+ """
1509
+ await self .open ()
1510
+ lines = []
1511
+ remainder = int (self .length ) - self ._position
1512
+ bytes_read = 0
1513
+ while remainder > 0 :
1514
+ line = await self ._read_size_or_line (line = True )
1515
+ bytes_read += len (line )
1516
+ lines .append (line )
1517
+ remainder = int (self .length ) - self ._position
1518
+ if 0 < size < bytes_read :
1519
+ break
1520
+
1521
+ return lines
1499
1522
1500
1523
async def open (self ) -> None :
1501
1524
if not self ._file :
@@ -1616,18 +1639,11 @@ async def read(self, size: int = -1) -> bytes:
1616
1639
"""
1617
1640
return await self ._read_size_or_line (size = size )
1618
1641
1619
- async def readline (self , size : int = - 1 ) -> bytes : # type: ignore[override]
1620
- """Read one line or up to `size` bytes from the file.
1621
-
1622
- :param size: the maximum number of bytes to read
1623
- """
1624
- return await self ._read_size_or_line (size = size , line = True )
1625
-
1626
1642
def tell (self ) -> int :
1627
1643
"""Return the current position of this file."""
1628
1644
return self ._position
1629
1645
1630
- async def seek (self , pos : int , whence : int = _SEEK_SET ) -> int : # type: ignore[override]
1646
+ async def seek (self , pos : int , whence : int = _SEEK_SET ) -> int :
1631
1647
"""Set the current position of this file.
1632
1648
1633
1649
:param pos: the position (or offset if using relative
@@ -1690,12 +1706,15 @@ def __aiter__(self) -> AsyncGridOut:
1690
1706
"""
1691
1707
return self
1692
1708
1693
- async def close (self ) -> None : # type: ignore[override]
1709
+ async def close (self ) -> None :
1694
1710
"""Make GridOut more generically file-like."""
1695
1711
if self ._chunk_iter :
1696
1712
await self ._chunk_iter .close ()
1697
1713
self ._chunk_iter = None
1698
- super ().close ()
1714
+ if _IS_SYNC :
1715
+ super ().close ()
1716
+ else :
1717
+ self .closed = True
1699
1718
1700
1719
def write (self , value : Any ) -> NoReturn :
1701
1720
raise io .UnsupportedOperation ("write" )
0 commit comments