6 from pathlib
import Path
17 with pytest
.raises(rarfile
.NotRarFile
):
18 rarfile
.RarFile("rarfile.py", "r")
19 with pytest
.raises(rarfile
.NotRarFile
):
20 with
open("rarfile.py", "rb") as f
:
21 rarfile
.RarFile(f
, "r")
24 def test_bad_arc_mode_w():
25 with pytest
.raises(NotImplementedError):
26 rarfile
.RarFile("test/files/rar3-comment-plain.rar", "w")
29 def test_bad_arc_mode_rb():
30 with pytest
.raises(NotImplementedError):
31 rarfile
.RarFile("test/files/rar3-comment-plain.rar", "rb")
35 with pytest
.raises(ValueError):
36 rarfile
.RarFile("test/files/rar3-comment-plain.rar", "r", errors
="foo")
39 def test_errors_param():
40 with
open("test/files/rar3-comment-plain.rar", "rb") as f
:
42 buf
= io
.BytesIO(data
[:17])
43 with rarfile
.RarFile(buf
, "r", errors
="stop") as rf
:
44 assert rf
.namelist() == []
45 with pytest
.raises(rarfile
.BadRarFile
):
46 rarfile
.RarFile(buf
, "r", errors
="strict")
49 def test_bad_open_mode_w():
50 rf
= rarfile
.RarFile("test/files/rar3-comment-plain.rar")
51 with pytest
.raises(NotImplementedError):
55 def test_bad_open_psw():
56 rf
= rarfile
.RarFile("test/files/rar3-comment-psw.rar")
57 with pytest
.raises(rarfile
.PasswordRequired
):
61 def test_bad_filelike():
62 with pytest
.raises(ValueError):
63 rarfile
.is_rarfile(bytearray(10))
66 def test_open_psw_late_rar3():
67 rf
= rarfile
.RarFile("test/files/rar3-comment-psw.rar")
68 d1
= rf
.open("file1.txt", "r", "password").read()
69 d2
= rf
.open("file1.txt", "r", b
"password").read()
73 def test_open_psw_late_rar5():
74 rf
= rarfile
.RarFile("test/files/rar5-psw.rar")
75 rf
.open("stest1.txt", "r", "password").read()
76 rf
.open("stest1.txt", "r", b
"password").read()
79 def test_open_pathlib_path():
80 rf
= rarfile
.RarFile("test/files/rar5-psw.rar")
81 rf
.open(Path("stest1.txt"), "r", "password").read()
84 def test_read_psw_late_rar3():
85 rf
= rarfile
.RarFile("test/files/rar3-comment-psw.rar")
86 rf
.read("file1.txt", "password")
87 rf
.read("file1.txt", b
"password")
90 def test_read_psw_late_rar5():
91 rf
= rarfile
.RarFile("test/files/rar5-psw.rar")
92 rf
.read("stest1.txt", "password")
93 rf
.read("stest1.txt", b
"password")
96 def test_open_psw_late():
97 rf
= rarfile
.RarFile("test/files/rar5-psw.rar")
98 with pytest
.raises(rarfile
.BadRarFile
):
99 rf
.read("stest1.txt", "password222")
102 def test_create_from_pathlib_path():
103 # Make sure we can open both relative and absolute Paths
104 rarfile
.RarFile(Path("test/files/rar5-psw.rar"))
105 rarfile
.RarFile(Path("test/files/rar5-psw.rar").resolve())
108 def test_detection():
109 assert rarfile
.is_rarfile("test/files/ctime4.rar.exp") is False
110 assert rarfile
.is_rarfile("test/files/ctime4.rar") is True
111 assert rarfile
.is_rarfile("test/files/rar5-crc.rar") is True
113 assert rarfile
.is_rarfile(Path("test/files/rar5-crc.rar")) is True
115 assert rarfile
.is_rarfile("test/files/_missing_.rar") is False
119 with rarfile
.RarFile("test/files/rar5-crc.rar") as rf
:
120 inf
= rf
.getinfo("stest1.txt")
121 assert isinstance(inf
, rarfile
.RarInfo
)
122 assert rf
.getinfo(inf
) is inf
123 with pytest
.raises(rarfile
.NoRarEntry
):
124 rf
.getinfo("missing.txt")
126 def test_signature_error():
127 with pytest
.raises(rarfile
.NotRarFile
):
128 rarfile
.RarFile("test/files/ctime4.rar.exp")
131 def test_signature_error_mem():
132 data
= io
.BytesIO(b
"x" * 40)
133 with pytest
.raises(rarfile
.NotRarFile
):
134 rarfile
.RarFile(data
)
138 with rarfile
.RarFile("test/files/rar5-crc.rar") as rf
:
139 data
= rf
.read("stest1.txt")
140 with rf
.open("stest1.txt") as f
:
147 assert dst
.getvalue() == data
151 def load_readline(rf
, fn
):
152 with rf
.open(fn
) as f
:
153 tr
= io
.TextIOWrapper(io
.BufferedReader(f
))
162 rf
= rarfile
.RarFile("test/files/seektest.rar")
163 v1
= load_readline(rf
, "stest1.txt")
164 v2
= load_readline(rf
, "stest2.txt")
165 assert len(v1
) == 512
169 def run_parallel(rfile
, entry
):
171 rf
= rarfile
.RarFile(rfile
)
173 with rf
.open(entry
) as f1
:
174 with rf
.open(entry
) as f2
:
175 for _
in range(10000):
184 if not res1
and not res2
:
191 def test_parallel_file_compressed():
192 run_parallel("test/files/seektest.rar", "stest1.txt")
195 def test_parallel_file_direct():
196 run_parallel("test/files/seektest.rar", "stest2.txt")
199 def test_parallel_fd_compressed():
200 with
open("test/files/seektest.rar", "rb") as f
:
201 memfile
= io
.BytesIO(f
.read())
202 run_parallel(memfile
, "stest1.txt")
205 def test_parallel_fd_direct():
206 with
open("test/files/seektest.rar", "rb") as f
:
207 memfile
= io
.BytesIO(f
.read())
208 run_parallel(memfile
, "stest2.txt")
211 def test_printdir(capsys
):
212 rf
= rarfile
.RarFile("test/files/seektest.rar")
214 res
= capsys
.readouterr()
215 assert res
.out
== "stest1.txt\nstest2.txt\n"
219 rf
= rarfile
.RarFile("test/files/seektest.rar")
224 rf
= rarfile
.RarFile("test/files/seektest.rar")
226 n2
= [m
.filename
for m
in rf
]
230 def test_testrar_mem():
231 with
open("test/files/seektest.rar", "rb") as f
:
233 rf
= rarfile
.RarFile(io
.BytesIO(arc
))
237 def test_extract(tmp_path
):
238 ex1
= tmp_path
/ "extract1"
239 ex2
= tmp_path
/ "extract2"
240 ex3
= tmp_path
/ "extract3"
241 os
.makedirs(str(ex1
))
242 os
.makedirs(str(ex2
))
243 os
.makedirs(str(ex3
))
244 rf
= rarfile
.RarFile("test/files/seektest.rar")
246 rf
.extractall(str(ex1
))
247 assert os
.path
.isfile(str(ex1
/ "stest1.txt")) is True
248 assert os
.path
.isfile(str(ex1
/ "stest2.txt")) is True
250 rf
.extract("stest1.txt", str(ex2
))
251 assert os
.path
.isfile(str(ex2
/ "stest1.txt")) is True
252 assert os
.path
.isfile(str(ex2
/ "stest2.txt")) is False
254 inf
= rf
.getinfo("stest2.txt")
255 rf
.extract(inf
, str(ex3
))
256 assert os
.path
.isfile(str(ex3
/ "stest1.txt")) is False
257 assert os
.path
.isfile(str(ex3
/ "stest2.txt")) is True
259 rf
.extractall(str(ex2
), ["stest1.txt"])
260 assert os
.path
.isfile(str(ex2
/ "stest1.txt")) is True
262 rf
.extractall(str(ex3
), [rf
.getinfo("stest2.txt")])
263 assert os
.path
.isfile(str(ex3
/ "stest2.txt")) is True
265 ex4
= tmp_path
/ "extract4"
266 os
.makedirs(str(ex4
))
268 assert os
.path
.isfile(str(ex4
/ "stest1.txt")) is True
269 assert os
.path
.isfile(str(ex4
/ "stest2.txt")) is True
272 def test_extract_mem(tmp_path
):
273 ex1
= tmp_path
/ "extract11"
274 ex2
= tmp_path
/ "extract22"
275 ex3
= tmp_path
/ "extract33"
276 os
.makedirs(str(ex1
))
277 os
.makedirs(str(ex2
))
278 os
.makedirs(str(ex3
))
280 with
open("test/files/seektest.rar", "rb") as f
:
282 rf
= rarfile
.RarFile(io
.BytesIO(arc
))
284 rf
.extractall(str(ex1
))
285 assert os
.path
.isfile(str(ex1
/ "stest1.txt")) is True
286 assert os
.path
.isfile(str(ex1
/ "stest2.txt")) is True
288 rf
.extract("stest1.txt", str(ex2
))
289 assert os
.path
.isfile(str(ex2
/ "stest1.txt")) is True
290 assert os
.path
.isfile(str(ex2
/ "stest2.txt")) is False
292 inf
= rf
.getinfo("stest2.txt")
293 rf
.extract(inf
, str(ex3
))
294 assert os
.path
.isfile(str(ex3
/ "stest1.txt")) is False
295 assert os
.path
.isfile(str(ex3
/ "stest2.txt")) is True
299 assert h
.is_dir() == h
.isdir()
301 h
.is_file() and "F" or "-",
302 h
.is_dir() and "D" or "-",
303 h
.is_symlink() and "L" or "-",
311 infos
.append((info
.type, info
.needs_password(), get_rftype(info
), info
._must
_disable
_hack
()))
313 rf
= rarfile
.RarFile("test/files/seektest.rar", info_callback
=info_cb
)
315 (rarfile
.RAR_BLOCK_MAIN
, False, "---", False),
316 (rarfile
.RAR_BLOCK_FILE
, False, "F--", False),
317 (rarfile
.RAR_BLOCK_FILE
, False, "F--", False),
318 (rarfile
.RAR_BLOCK_ENDARC
, False, "---", False)]
322 rf
= rarfile
.RarFile("test/files/rar5-solid-qo.rar", info_callback
=info_cb
)
324 (rarfile
.RAR_BLOCK_MAIN
, False, "---", True),
325 (rarfile
.RAR_BLOCK_FILE
, False, "F--", False),
326 (rarfile
.RAR_BLOCK_FILE
, False, "F--", True),
327 (rarfile
.RAR_BLOCK_FILE
, False, "F--", True),
328 (rarfile
.RAR_BLOCK_FILE
, False, "F--", True),
329 (rarfile
.RAR_BLOCK_SUB
, False, "---", False),
330 (rarfile
.RAR_BLOCK_ENDARC
, False, "---", False)]
334 # pylint: disable=singleton-comparison
335 def test_rarextfile():
336 with rarfile
.RarFile("test/files/seektest.rar") as rf
:
337 for fn
in ("stest1.txt", "stest2.txt"):
338 with rf
.open(fn
) as f
:
340 assert f
.writable() == False
341 assert f
.seekable() == True
342 assert f
.readable() == True
343 assert f
.readall() == rf
.read(fn
)
346 def test_is_rarfile():
347 with rarfile
.RarFile("test/files/seektest.rar") as rf
:
348 for fn
in ("stest1.txt", "stest2.txt"):
349 with rf
.open(fn
) as f
:
351 assert f
.writable() == False
352 assert f
.seekable() == True
353 assert f
.readable() == True
354 assert f
.readall() == rf
.read(fn
)
357 def test_part_only():
360 info_list
.append(info
)
362 with pytest
.raises(rarfile
.NeedFirstVolume
):
363 with rarfile
.RarFile("test/files/rar3-vols.part2.rar") as rf
:
365 with rarfile
.RarFile("test/files/rar3-vols.part2.rar", part_only
=True, info_callback
=info_cb
) as rf
:
366 assert len(info_list
) == 3
368 with pytest
.raises(rarfile
.NeedFirstVolume
):
369 with rarfile
.RarFile("test/files/rar5-vols.part2.rar") as rf
:
372 with rarfile
.RarFile("test/files/rar5-vols.part2.rar", part_only
=True, info_callback
=info_cb
) as rf
:
373 assert len(info_list
) == 5
376 def test_volume_info():
379 info_list
.append(info
)
380 with rarfile
.RarFile("test/files/rar3-vols.part1.rar", info_callback
=info_cb
) as rf
:
381 assert len(info_list
) == 10
383 with rarfile
.RarFile("test/files/rar5-vols.part1.rar", info_callback
=info_cb
) as rf
:
384 assert len(info_list
) == 16
388 with rarfile
.RarFile("test/files/rar3-comment-plain.rar") as rf
:
389 assert not rf
.is_solid()
390 with rarfile
.RarFile("test/files/rar3-solid.rar") as rf
:
392 with rarfile
.RarFile("test/files/rar5-crc.rar") as rf
:
393 assert not rf
.is_solid()
394 with rarfile
.RarFile("test/files/rar5-solid.rar") as rf
: