python-httpfile 0.0.4__py3-none-any.whl → 0.0.4.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
httpfile/__init__.py CHANGED
@@ -215,6 +215,8 @@ class HTTPFileReader(RawIOBase, BinaryIO):
215
215
  return self.file.fileno()
216
216
 
217
217
  def flush(self, /):
218
+ if self.closed:
219
+ raise ValueError("I/O operation on closed file.")
218
220
  return self.file.flush()
219
221
 
220
222
  def isatty(self, /) -> bool:
@@ -253,7 +255,16 @@ class HTTPFileReader(RawIOBase, BinaryIO):
253
255
  return 0
254
256
  if self.file_closed:
255
257
  self.reconnect()
256
- size = self.file.readinto(buffer)
258
+ try:
259
+ readinto = self.file.readinto
260
+ except AttributeError:
261
+ read = self.file.read
262
+ def readinto(buffer, /):
263
+ data = read(len(buffer))
264
+ size = len(data)
265
+ buffer[:size] = data
266
+ return data
267
+ size = readinto(buffer)
257
268
  if size:
258
269
  self._add_start(size)
259
270
  return size
@@ -265,6 +276,7 @@ class HTTPFileReader(RawIOBase, BinaryIO):
265
276
  return b""
266
277
  if self.file_closed:
267
278
  self.reconnect()
279
+ # TODO: if no readline method, give a default impl
268
280
  if size is None or size < 0:
269
281
  data = self.file.readline()
270
282
  else:
@@ -280,6 +292,7 @@ class HTTPFileReader(RawIOBase, BinaryIO):
280
292
  return []
281
293
  if self.file_closed:
282
294
  self.reconnect()
295
+ # TODO: if no readlines method, give a default impl
283
296
  ls = self.file.readlines(hint)
284
297
  if ls:
285
298
  self._add_start(sum(map(len, ls)))
@@ -520,9 +533,9 @@ class AsyncHTTPFileReader(HTTPFileReader):
520
533
  headers: None | Mapping = None,
521
534
  start: int = 0,
522
535
  seek_threshold: int = 1 << 20,
523
- urlopen = urlopen,
536
+ urlopen = None,
524
537
  ):
525
- run_async(self.__ainit__(
538
+ self.__dict__["_initing"] = run_async(self.__ainit__(
526
539
  url=url,
527
540
  headers=headers,
528
541
  start=start,
@@ -531,6 +544,9 @@ class AsyncHTTPFileReader(HTTPFileReader):
531
544
  ))
532
545
 
533
546
  async def __aenter__(self, /) -> Self:
547
+ if _initing := self.__dict__.get("_initing"):
548
+ await _initing
549
+ self.__dict__.pop("_initing", None)
534
550
  return self
535
551
 
536
552
  async def __aexit__(self, /, *exc_info):
@@ -597,6 +613,7 @@ class AsyncHTTPFileReader(HTTPFileReader):
597
613
  seek_threshold = max(seek_threshold, 0),
598
614
  _seekable = is_range_request(response),
599
615
  )
616
+ self.__dict__.pop("_initing", None)
600
617
 
601
618
  async def aclose(self, /):
602
619
  if not self.closed:
@@ -609,7 +626,10 @@ class AsyncHTTPFileReader(HTTPFileReader):
609
626
  try:
610
627
  ret = self.response.aclose()
611
628
  except (AttributeError, TypeError):
612
- ret = self.response.close()
629
+ try:
630
+ ret = self.response.close()
631
+ except (AttributeError, TypeError):
632
+ return
613
633
  if isawaitable(ret):
614
634
  run_async(ret)
615
635
 
@@ -617,24 +637,36 @@ class AsyncHTTPFileReader(HTTPFileReader):
617
637
  try:
618
638
  ret = self.response.aclose()
619
639
  except (AttributeError, TypeError):
620
- ret = self.response.close()
640
+ try:
641
+ ret = self.response.close()
642
+ except (AttributeError, TypeError):
643
+ return
621
644
  if isawaitable(ret):
622
645
  await ret
623
646
 
624
647
  async def flush(self, /):
648
+ if self.closed:
649
+ raise ValueError("I/O operation on closed file.")
650
+ if _initing := self.__dict__.get("_initing"):
651
+ await _initing
652
+ self.__dict__.pop("_initing", None)
625
653
  return await ensure_async(self.file.flush, threaded=True)()
626
654
 
627
655
  async def read(self, size: int = -1, /) -> bytes: # type: ignore
628
656
  if self.closed:
629
657
  raise ValueError("I/O operation on closed file.")
658
+ if _initing := self.__dict__.get("_initing"):
659
+ await _initing
660
+ self.__dict__.pop("_initing", None)
630
661
  if size == 0 or not self.chunked and self.tell() >= self.length:
631
662
  return b""
632
663
  if self.file_closed:
633
664
  await self.reconnect()
665
+ read = ensure_async(self.file.read, threaded=True)
634
666
  if size is None or size < 0:
635
- data = await ensure_async(self.file.read, threaded=True)()
667
+ data = await read(-1)
636
668
  else:
637
- data = await ensure_async(self.file.read, threaded=True)(size)
669
+ data = await read(size)
638
670
  if data:
639
671
  self._add_start(len(data))
640
672
  return data
@@ -642,11 +674,23 @@ class AsyncHTTPFileReader(HTTPFileReader):
642
674
  async def readinto(self, buffer, /) -> int: # type: ignore
643
675
  if self.closed:
644
676
  raise ValueError("I/O operation on closed file.")
677
+ if _initing := self.__dict__.get("_initing"):
678
+ await _initing
679
+ self.__dict__.pop("_initing", None)
645
680
  if not buffer or not self.chunked and self.tell() >= self.length:
646
681
  return 0
647
682
  if self.file_closed:
648
683
  await self.reconnect()
649
- size = await ensure_async(self.file.readinto, threaded=True)(buffer)
684
+ try:
685
+ readinto = ensure_async(self.file.readinto, threaded=True)
686
+ except AttributeError:
687
+ read = ensure_async(self.file.read, threaded=True)
688
+ async def readinto(buffer, /):
689
+ data = await read(len(buffer))
690
+ size = len(data)
691
+ buffer[:size] = data
692
+ return size
693
+ size = await readinto(buffer)
650
694
  if size:
651
695
  self._add_start(size)
652
696
  return size
@@ -654,10 +698,14 @@ class AsyncHTTPFileReader(HTTPFileReader):
654
698
  async def readline(self, size: None | int = -1, /) -> bytes: # type: ignore
655
699
  if self.closed:
656
700
  raise ValueError("I/O operation on closed file.")
701
+ if _initing := self.__dict__.get("_initing"):
702
+ await _initing
703
+ self.__dict__.pop("_initing", None)
657
704
  if size == 0 or not self.chunked and self.tell() >= self.length:
658
705
  return b""
659
706
  if self.file_closed:
660
707
  await self.reconnect()
708
+ # TODO: if no readline method, give a default impl
661
709
  if size is None or size < 0:
662
710
  data = await ensure_async(self.file.readline, threaded=True)()
663
711
  else:
@@ -669,16 +717,23 @@ class AsyncHTTPFileReader(HTTPFileReader):
669
717
  async def readlines(self, hint: int = -1, /) -> list[bytes]: # type: ignore
670
718
  if self.closed:
671
719
  raise ValueError("I/O operation on closed file.")
720
+ if _initing := self.__dict__.get("_initing"):
721
+ await _initing
722
+ self.__dict__.pop("_initing", None)
672
723
  if not self.chunked and self.tell() >= self.length:
673
724
  return []
674
725
  if self.file_closed:
675
726
  await self.reconnect()
727
+ # TODO: if no readlines method, give a default impl
676
728
  ls = await ensure_async(self.file.readlines, threaded=True)(hint)
677
729
  if ls:
678
730
  self._add_start(sum(map(len, ls)))
679
731
  return ls
680
732
 
681
733
  async def reconnect(self, /, start: None | int = None) -> int: # type: ignore
734
+ if _initing := self.__dict__.get("_initing"):
735
+ await _initing
736
+ self.__dict__.pop("_initing", None)
682
737
  if not self._seekable:
683
738
  if start is None and self.tell() or start:
684
739
  raise OSError(errno.EOPNOTSUPP, "Unsupport for reconnection of non-seekable streams.")
@@ -711,6 +766,9 @@ class AsyncHTTPFileReader(HTTPFileReader):
711
766
  async def seek(self, pos: int, whence: int = 0, /) -> int: # type: ignore
712
767
  if self.closed:
713
768
  raise ValueError("I/O operation on closed file.")
769
+ if _initing := self.__dict__.get("_initing"):
770
+ await _initing
771
+ self.__dict__.pop("_initing", None)
714
772
  if not self._seekable:
715
773
  raise OSError(errno.EINVAL, "not a seekable stream")
716
774
  if whence == 0:
@@ -1128,7 +1186,7 @@ if find_spec("httpx"):
1128
1186
  elif urlopen is None:
1129
1187
  if _httpx_urlopen_async is None:
1130
1188
  if "__del__" not in AsyncClient.__dict__:
1131
- setattr(AsyncClient, "__del__", lambda self: run_async(self.aclose()))
1189
+ setattr(AsyncClient, "__del__", lambda self: run_async(self.aclose()))
1132
1190
  def async_stream(
1133
1191
  method,
1134
1192
  url,
@@ -1197,4 +1255,5 @@ if find_spec("httpx"):
1197
1255
  __all__.append("HttpxFileReader")
1198
1256
  __all__.append("AsyncHttpxFileReader")
1199
1257
 
1258
+ # TODO: 增加 blacksheep 的 HTTPFileReader
1200
1259
  # TODO: 设计实现一个 HTTPFileWriter,用于实现上传,关闭后视为上传完成
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-httpfile
3
- Version: 0.0.4
3
+ Version: 0.0.4.2
4
4
  Summary: Python httpfile.
5
5
  Home-page: https://github.com/ChenyangGao/web-mount-packs/tree/main/python-module/python-httpfile
6
6
  License: MIT
@@ -0,0 +1,7 @@
1
+ LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
2
+ httpfile/__init__.py,sha256=aU9cp4nBpCxPT49UWb1VFukYJMlo38AESouioBk3uYk,41004
3
+ httpfile/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ python_httpfile-0.0.4.2.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
5
+ python_httpfile-0.0.4.2.dist-info/METADATA,sha256=St2htsaH5qwPmBF6EGhlnVfyIx1KsusYCkgeQ6DTq1Y,1522
6
+ python_httpfile-0.0.4.2.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
7
+ python_httpfile-0.0.4.2.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
2
- httpfile/__init__.py,sha256=PAqvhrEAfTEzVSZ7wbLrPplYX-8G1epkW7MZt2sWWaw,38657
3
- httpfile/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- python_httpfile-0.0.4.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
5
- python_httpfile-0.0.4.dist-info/METADATA,sha256=1CtTQ_EoeIP9eVYlevzlEBdA9D26S9pHfZmdTOnXB0Q,1520
6
- python_httpfile-0.0.4.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
7
- python_httpfile-0.0.4.dist-info/RECORD,,