Skip to content

Commit 94fc55c

Browse files
committed
Restore progress reporting to extractcode #1996
Do not consume extract events generators in a list. This prohinited the progressive dispatch of "events" being generated to provide progress display in the CLI. Instead we now yield events again as they are created and accumulate events for leter reprocessing if the option to replace originals has been selected. Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>
1 parent e53c819 commit 94fc55c

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

src/extractcode/extract.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def extract(location, kinds=extractcode.default_kinds, recurse=False, replace_or
113113
is True.
114114
115115
If `recurse` is True, extract recursively archives nested inside other
116-
archives If `recurse` is false, then do not extract further an already
116+
archives. If `recurse` is false, then do not extract further an already
117117
extracted archive identified by the corresponding extract suffix location.
118118
119119
If `replace_originals` is True, the extracted archives are replaced by the
@@ -123,9 +123,16 @@ def extract(location, kinds=extractcode.default_kinds, recurse=False, replace_or
123123
if recurse and a nested archive is found, it is extracted to full depth
124124
first before resuming the file system walk.
125125
"""
126-
events = list(extract_files(location, kinds, recurse))
126+
processed_events = []
127+
processed_events_append = processed_events.append
128+
for event in extract_files(location, kinds, recurse):
129+
yield event
130+
if replace_originals:
131+
processed_events_append(event)
132+
133+
# move files around
127134
if replace_originals:
128-
for xevent in reversed(events):
135+
for xevent in reversed(processed_events):
129136
if xevent.done:
130137
source = xevent.source
131138
target = xevent.target
@@ -134,12 +141,22 @@ def extract(location, kinds=extractcode.default_kinds, recurse=False, replace_or
134141
fileutils.delete(source)
135142
fileutils.copytree(target, source)
136143
fileutils.delete(target)
137-
return events
144+
138145

139146
def extract_files(location, kinds=extractcode.default_kinds, recurse=False):
147+
"""
148+
Extract the files found at `location`.
149+
150+
Extract only archives of a kind listed in the `kinds` kind tuple.
151+
152+
If `recurse` is True, extract recursively archives nested inside other
153+
archives. If `recurse` is false, then do not extract further an already
154+
extracted archive identified by the corresponding extract suffix location.
155+
"""
140156
ignored = partial(ignore.is_ignored, ignores=ignore.default_ignores, unignores={})
141157
if TRACE:
142158
logger.debug('extract:start: %(location)r recurse: %(recurse)r\n' % locals())
159+
143160
abs_location = abspath(expanduser(location))
144161
for top, dirs, files in fileutils.walk(abs_location, ignored):
145162
if TRACE:
@@ -192,8 +209,8 @@ def extract_file(location, target, kinds=extractcode.default_kinds, verbose=Fals
192209
extractor = archive.get_extractor(location, kinds)
193210
if TRACE:
194211
logger.debug('extract_file: extractor: for: %(location)r with kinds: %(kinds)r : ' % locals()
195-
+ getattr(extractor, '__module__', '')
196-
+ '.' + getattr(extractor, '__name__', ''))
212+
+getattr(extractor, '__module__', '')
213+
+'.' + getattr(extractor, '__name__', ''))
197214
if extractor:
198215
yield ExtractEvent(location, target, done=False, warnings=[], errors=[])
199216
try:
890 Bytes
Binary file not shown.

tests/extractcode/test_extract.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
from commoncode.system import on_linux
4242
from commoncode.system import on_windows
4343
from commoncode.system import py3
44+
from types import GeneratorType
4445

4546

4647
class TestExtract(FileBasedTesting):
@@ -1111,3 +1112,9 @@ def test_extract_zipslip_tar_posix(self):
11111112

11121113
warns = [r.warnings for r in result if r.warnings]
11131114
assert [] == warns
1115+
1116+
def test_extract_always_returns_a_generator_and_not_a_list(self):
1117+
# a test for #1996 to ensure that progress is displayed "progressively"
1118+
test_dir = self.get_test_loc('extract/generator', copy=True)
1119+
result = extract.extract(test_dir)
1120+
assert isinstance(result, GeneratorType)

0 commit comments

Comments
 (0)