10
10
from __future__ import annotations
11
11
12
12
import os
13
+ from pickle import PickleBuffer
13
14
import platform
14
15
import sys
15
- from typing import TYPE_CHECKING
16
+
17
+ try :
18
+ import lzma
19
+
20
+ has_lzma = True
21
+ except ImportError :
22
+ has_lzma = False
16
23
17
24
from pandas ._typing import F
18
25
from pandas .compat .numpy import (
31
38
pa_version_under9p0 ,
32
39
)
33
40
34
- if TYPE_CHECKING :
35
- import lzma
36
-
37
41
PY39 = sys .version_info >= (3 , 9 )
38
42
PY310 = sys .version_info >= (3 , 10 )
39
43
PY311 = sys .version_info >= (3 , 11 )
40
44
PYPY = platform .python_implementation () == "PyPy"
41
45
IS64 = sys .maxsize > 2 ** 32
42
46
43
47
48
+ if has_lzma :
49
+
50
+ class _LZMAFile (lzma .LZMAFile ):
51
+ def write (self , b ) -> None :
52
+ if isinstance (b , PickleBuffer ):
53
+ # Workaround issue where `lzma.LZMAFile` expects `len`
54
+ # to return the number of bytes in `b` by converting
55
+ # `b` into something that meets that constraint with
56
+ # minimal copying.
57
+ try :
58
+ # coerce to 1-D `uint8` C-contiguous `memoryview` zero-copy
59
+ b = b .raw ()
60
+ except BufferError :
61
+ # perform in-memory copy if buffer is not contiguous
62
+ b = bytes (b )
63
+ return super ().write (b )
64
+
65
+
44
66
def set_function_name (f : F , name : str , cls ) -> F :
45
67
"""
46
68
Bind the name/qualname attributes of the function.
@@ -126,7 +148,7 @@ def is_ci_environment() -> bool:
126
148
return os .environ .get ("PANDAS_CI" , "0" ) == "1"
127
149
128
150
129
- def get_lzma_file () -> type [lzma . LZMAFile ]:
151
+ def get_lzma_file () -> type [_LZMAFile ]:
130
152
"""
131
153
Importing the `LZMAFile` class from the `lzma` module.
132
154
@@ -140,15 +162,13 @@ def get_lzma_file() -> type[lzma.LZMAFile]:
140
162
RuntimeError
141
163
If the `lzma` module was not imported correctly, or didn't exist.
142
164
"""
143
- try :
144
- import lzma
145
- except ImportError :
165
+ if not has_lzma :
146
166
raise RuntimeError (
147
167
"lzma module not available. "
148
168
"A Python re-install with the proper dependencies, "
149
169
"might be required to solve this issue."
150
170
)
151
- return lzma . LZMAFile
171
+ return _LZMAFile
152
172
153
173
154
174
__all__ = [
0 commit comments