Changeset View
Standalone View
swh/core/utils.py
Show All 19 Lines | def cwd(path): | ||||
prev_cwd = os.getcwd() | prev_cwd = os.getcwd() | ||||
os.chdir(path) | os.chdir(path) | ||||
try: | try: | ||||
yield | yield | ||||
finally: | finally: | ||||
os.chdir(prev_cwd) | os.chdir(prev_cwd) | ||||
def grouper(iterable, n): | def grouper(iterable, n, fillvalue=None): | ||||
"""Collect data into fixed-length chunks or blocks. | """Collect data into fixed-length chunks or blocks. | ||||
Args: | Args: | ||||
iterable: an iterable | iterable (Iterable): an iterable | ||||
n: size of block | n (int): size of block to slice the iterable into | ||||
fillvalue: value to use for the last block | fillvalue (Optional[Something]): value to use as fill-in | ||||
values (typically for the last loop, the iterable might be | |||||
less than n elements). None by default but could be anything | |||||
relevant for the caller (e.g tuple of (None, None)) | |||||
Returns: | Returns: | ||||
fixed-length chunks of blocks as iterables | fixed-length chunks of blocks as iterables | ||||
""" | """ | ||||
args = [iter(iterable)] * n | args = [iter(iterable)] * n | ||||
for _data in itertools.zip_longest(*args, fillvalue=None): | for _data in itertools.zip_longest(*args, fillvalue=fillvalue): | ||||
yield (d for d in _data if d is not None) | yield (d for d in _data if d is not fillvalue) | ||||
vlorentz: Replace the for loop with what the grouper from the tarloader does:
```
return itertools. | |||||
Done Inline ActionsI hear you but yes we do. Also, fillvalue is both a fillvalue and a stop value that we don't want involved in the last block. What i need to do:
ardumont: I hear you but yes we do.
I realize the docstring is wrong again and the prototype must be… | |||||
Not Done Inline ActionsThen you can drop the fillvalue/stopvalue argument and always set it with stopvalue=object(). This is guaranteed to be unique. vlorentz: Then you can drop the `fillvalue`/`stopvalue` argument and always set it with `stopvalue=object… | |||||
Done Inline Actions
Nice, that would address (particularly if one of the items in the iterator happens to be equal to the fill value). better. Thanks! ardumont: > Then you can drop the fillvalue/stopvalue argument and always set it with stopvalue=object(). | |||||
def backslashescape_errors(exception): | def backslashescape_errors(exception): | ||||
if isinstance(exception, UnicodeDecodeError): | if isinstance(exception, UnicodeDecodeError): | ||||
bad_data = exception.object[exception.start:exception.end] | bad_data = exception.object[exception.start:exception.end] | ||||
escaped = ''.join(r'\x%02x' % x for x in bad_data) | escaped = ''.join(r'\x%02x' % x for x in bad_data) | ||||
return escaped, exception.end | return escaped, exception.end | ||||
return codecs.backslashreplace_errors(exception) | return codecs.backslashreplace_errors(exception) | ||||
▲ Show 20 Lines • Show All 66 Lines • Show Last 20 Lines |
Replace the for loop with what the grouper from the tarloader does:
You don't want to drop the fill values (particularly if one of the items in the iterator happens to be equal to the fill value).