mirror of
https://github.com/arsenetar/dupeguru.git
synced 2026-01-22 06:37:17 +00:00
Format all files with black correcting line length
This commit is contained in:
@@ -11,9 +11,7 @@ from setuptools import setup, Extension
|
||||
|
||||
def get_parser():
|
||||
parser = argparse.ArgumentParser(description="Build an arbitrary Python extension.")
|
||||
parser.add_argument(
|
||||
"source_files", nargs="+", help="List of source files to compile"
|
||||
)
|
||||
parser.add_argument("source_files", nargs="+", help="List of source files to compile")
|
||||
parser.add_argument("name", nargs=1, help="Name of the resulting extension")
|
||||
return parser
|
||||
|
||||
@@ -23,7 +21,8 @@ def main():
|
||||
print("Building {}...".format(args.name[0]))
|
||||
ext = Extension(args.name[0], args.source_files)
|
||||
setup(
|
||||
script_args=["build_ext", "--inplace"], ext_modules=[ext],
|
||||
script_args=["build_ext", "--inplace"],
|
||||
ext_modules=[ext],
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -48,15 +48,13 @@ def get_unconflicted_name(name):
|
||||
|
||||
|
||||
def is_conflicted(name):
|
||||
"""Returns whether ``name`` is prepended with a bracketed number.
|
||||
"""
|
||||
"""Returns whether ``name`` is prepended with a bracketed number."""
|
||||
return re_conflict.match(name) is not None
|
||||
|
||||
|
||||
@pathify
|
||||
def _smart_move_or_copy(operation, source_path: Path, dest_path: Path):
|
||||
"""Use move() or copy() to move and copy file with the conflict management.
|
||||
"""
|
||||
"""Use move() or copy() to move and copy file with the conflict management."""
|
||||
if dest_path.isdir() and not source_path.isdir():
|
||||
dest_path = dest_path[source_path.name]
|
||||
if dest_path.exists():
|
||||
@@ -68,14 +66,12 @@ def _smart_move_or_copy(operation, source_path: Path, dest_path: Path):
|
||||
|
||||
|
||||
def smart_move(source_path, dest_path):
|
||||
"""Same as :func:`smart_copy`, but it moves files instead.
|
||||
"""
|
||||
"""Same as :func:`smart_copy`, but it moves files instead."""
|
||||
_smart_move_or_copy(shutil.move, source_path, dest_path)
|
||||
|
||||
|
||||
def smart_copy(source_path, dest_path):
|
||||
"""Copies ``source_path`` to ``dest_path``, recursively and with conflict resolution.
|
||||
"""
|
||||
"""Copies ``source_path`` to ``dest_path``, recursively and with conflict resolution."""
|
||||
try:
|
||||
_smart_move_or_copy(shutil.copy, source_path, dest_path)
|
||||
except IOError as e:
|
||||
|
||||
@@ -16,20 +16,17 @@ class SpecialFolder:
|
||||
|
||||
|
||||
def open_url(url):
|
||||
"""Open ``url`` with the default browser.
|
||||
"""
|
||||
"""Open ``url`` with the default browser."""
|
||||
_open_url(url)
|
||||
|
||||
|
||||
def open_path(path):
|
||||
"""Open ``path`` with its associated application.
|
||||
"""
|
||||
"""Open ``path`` with its associated application."""
|
||||
_open_path(str(path))
|
||||
|
||||
|
||||
def reveal_path(path):
|
||||
"""Open the folder containing ``path`` with the default file browser.
|
||||
"""
|
||||
"""Open the folder containing ``path`` with the default file browser."""
|
||||
_reveal_path(str(path))
|
||||
|
||||
|
||||
|
||||
@@ -149,8 +149,7 @@ class Rect:
|
||||
return l1, l2, l3, l4
|
||||
|
||||
def scaled_rect(self, dx, dy):
|
||||
"""Returns a rect that has the same borders at self, but grown/shrunk by dx/dy on each side.
|
||||
"""
|
||||
"""Returns a rect that has the same borders at self, but grown/shrunk by dx/dy on each side."""
|
||||
x, y, w, h = self
|
||||
x -= dx
|
||||
y -= dy
|
||||
@@ -159,8 +158,7 @@ class Rect:
|
||||
return Rect(x, y, w, h)
|
||||
|
||||
def united(self, other):
|
||||
"""Returns the bounding rectangle of this rectangle and `other`.
|
||||
"""
|
||||
"""Returns the bounding rectangle of this rectangle and `other`."""
|
||||
# ul=upper left lr=lower right
|
||||
ulcorner1, lrcorner1 = self.corners()
|
||||
ulcorner2, lrcorner2 = other.corners()
|
||||
|
||||
@@ -80,8 +80,7 @@ class PrefAccessInterface:
|
||||
"""
|
||||
|
||||
def set_default(self, key, value):
|
||||
"""Set the value ``value`` for ``key`` in the currently running app's preference store.
|
||||
"""
|
||||
"""Set the value ``value`` for ``key`` in the currently running app's preference store."""
|
||||
|
||||
|
||||
class Columns(GUIObject):
|
||||
@@ -140,33 +139,27 @@ class Columns(GUIObject):
|
||||
|
||||
# --- Public
|
||||
def column_by_index(self, index):
|
||||
"""Return the :class:`Column` having the :attr:`~Column.logical_index` ``index``.
|
||||
"""
|
||||
"""Return the :class:`Column` having the :attr:`~Column.logical_index` ``index``."""
|
||||
return self.column_list[index]
|
||||
|
||||
def column_by_name(self, name):
|
||||
"""Return the :class:`Column` having the :attr:`~Column.name` ``name``.
|
||||
"""
|
||||
"""Return the :class:`Column` having the :attr:`~Column.name` ``name``."""
|
||||
return self.coldata[name]
|
||||
|
||||
def columns_count(self):
|
||||
"""Returns the number of columns in our set.
|
||||
"""
|
||||
"""Returns the number of columns in our set."""
|
||||
return len(self.column_list)
|
||||
|
||||
def column_display(self, colname):
|
||||
"""Returns display name for column named ``colname``, or ``''`` if there's none.
|
||||
"""
|
||||
"""Returns display name for column named ``colname``, or ``''`` if there's none."""
|
||||
return self._get_colname_attr(colname, "display", "")
|
||||
|
||||
def column_is_visible(self, colname):
|
||||
"""Returns visibility for column named ``colname``, or ``True`` if there's none.
|
||||
"""
|
||||
"""Returns visibility for column named ``colname``, or ``True`` if there's none."""
|
||||
return self._get_colname_attr(colname, "visible", True)
|
||||
|
||||
def column_width(self, colname):
|
||||
"""Returns width for column named ``colname``, or ``0`` if there's none.
|
||||
"""
|
||||
"""Returns width for column named ``colname``, or ``0`` if there's none."""
|
||||
return self._get_colname_attr(colname, "width", 0)
|
||||
|
||||
def columns_to_right(self, colname):
|
||||
@@ -177,11 +170,7 @@ class Columns(GUIObject):
|
||||
"""
|
||||
column = self.coldata[colname]
|
||||
index = column.ordered_index
|
||||
return [
|
||||
col.name
|
||||
for col in self.column_list
|
||||
if (col.visible and col.ordered_index > index)
|
||||
]
|
||||
return [col.name for col in self.column_list if (col.visible and col.ordered_index > index)]
|
||||
|
||||
def menu_items(self):
|
||||
"""Returns a list of items convenient for quick visibility menu generation.
|
||||
@@ -207,8 +196,7 @@ class Columns(GUIObject):
|
||||
self.set_column_order(colnames)
|
||||
|
||||
def reset_to_defaults(self):
|
||||
"""Reset all columns' width and visibility to their default values.
|
||||
"""
|
||||
"""Reset all columns' width and visibility to their default values."""
|
||||
self.set_column_order([col.name for col in self.column_list])
|
||||
for col in self._optional_columns():
|
||||
col.visible = col.default_visible
|
||||
@@ -216,13 +204,11 @@ class Columns(GUIObject):
|
||||
self.view.restore_columns()
|
||||
|
||||
def resize_column(self, colname, newwidth):
|
||||
"""Set column ``colname``'s width to ``newwidth``.
|
||||
"""
|
||||
"""Set column ``colname``'s width to ``newwidth``."""
|
||||
self._set_colname_attr(colname, "width", newwidth)
|
||||
|
||||
def restore_columns(self):
|
||||
"""Restore's column persistent attributes from the last :meth:`save_columns`.
|
||||
"""
|
||||
"""Restore's column persistent attributes from the last :meth:`save_columns`."""
|
||||
if not (self.prefaccess and self.savename and self.coldata):
|
||||
if (not self.savename) and (self.coldata):
|
||||
# This is a table that will not have its coldata saved/restored. we should
|
||||
@@ -241,8 +227,7 @@ class Columns(GUIObject):
|
||||
self.view.restore_columns()
|
||||
|
||||
def save_columns(self):
|
||||
"""Save column attributes in persistent storage for restoration in :meth:`restore_columns`.
|
||||
"""
|
||||
"""Save column attributes in persistent storage for restoration in :meth:`restore_columns`."""
|
||||
if not (self.prefaccess and self.savename and self.coldata):
|
||||
return
|
||||
for col in self.column_list:
|
||||
@@ -263,15 +248,13 @@ class Columns(GUIObject):
|
||||
col.ordered_index = i
|
||||
|
||||
def set_column_visible(self, colname, visible):
|
||||
"""Set the visibility of column ``colname``.
|
||||
"""
|
||||
"""Set the visibility of column ``colname``."""
|
||||
self.table.save_edits() # the table on the GUI side will stop editing when the columns change
|
||||
self._set_colname_attr(colname, "visible", visible)
|
||||
self.view.set_column_visible(colname, visible)
|
||||
|
||||
def set_default_width(self, colname, width):
|
||||
"""Set the default width or column ``colname``.
|
||||
"""
|
||||
"""Set the default width or column ``colname``."""
|
||||
self._set_colname_attr(colname, "default_width", width)
|
||||
|
||||
def toggle_menu_item(self, index):
|
||||
@@ -289,14 +272,10 @@ class Columns(GUIObject):
|
||||
# --- Properties
|
||||
@property
|
||||
def ordered_columns(self):
|
||||
"""List of :class:`Column` in visible order.
|
||||
"""
|
||||
return [
|
||||
col for col in sorted(self.column_list, key=lambda col: col.ordered_index)
|
||||
]
|
||||
"""List of :class:`Column` in visible order."""
|
||||
return [col for col in sorted(self.column_list, key=lambda col: col.ordered_index)]
|
||||
|
||||
@property
|
||||
def colnames(self):
|
||||
"""List of column names in visible order.
|
||||
"""
|
||||
"""List of column names in visible order."""
|
||||
return [col.name for col in self.ordered_columns]
|
||||
|
||||
@@ -21,12 +21,10 @@ class ProgressWindowView:
|
||||
"""
|
||||
|
||||
def show(self):
|
||||
"""Show the dialog.
|
||||
"""
|
||||
"""Show the dialog."""
|
||||
|
||||
def close(self):
|
||||
"""Close the dialog.
|
||||
"""
|
||||
"""Close the dialog."""
|
||||
|
||||
def set_progress(self, progress):
|
||||
"""Set the progress of the progress bar to ``progress``.
|
||||
@@ -76,8 +74,7 @@ class ProgressWindow(GUIObject, ThreadedJobPerformer):
|
||||
self.jobid = None
|
||||
|
||||
def cancel(self):
|
||||
"""Call for a user-initiated job cancellation.
|
||||
"""
|
||||
"""Call for a user-initiated job cancellation."""
|
||||
# The UI is sometimes a bit buggy and calls cancel() on self.view.close(). We just want to
|
||||
# make sure that this doesn't lead us to think that the user acually cancelled the task, so
|
||||
# we verify that the job is still running.
|
||||
|
||||
@@ -27,9 +27,7 @@ class Selectable(Sequence):
|
||||
self._selected_indexes = []
|
||||
if not self._selected_indexes:
|
||||
return
|
||||
self._selected_indexes = [
|
||||
index for index in self._selected_indexes if index < len(self)
|
||||
]
|
||||
self._selected_indexes = [index for index in self._selected_indexes if index < len(self)]
|
||||
if not self._selected_indexes:
|
||||
self._selected_indexes = [len(self) - 1]
|
||||
|
||||
|
||||
@@ -71,8 +71,7 @@ class TextField(GUIObject):
|
||||
|
||||
# --- Public
|
||||
def refresh(self):
|
||||
"""Triggers a view :meth:`~TextFieldView.refresh`.
|
||||
"""
|
||||
"""Triggers a view :meth:`~TextFieldView.refresh`."""
|
||||
self.view.refresh()
|
||||
|
||||
@property
|
||||
|
||||
@@ -55,8 +55,7 @@ class Node(MutableSequence):
|
||||
|
||||
# --- Public
|
||||
def clear(self):
|
||||
"""Clears the node of all its children.
|
||||
"""
|
||||
"""Clears the node of all its children."""
|
||||
del self[:]
|
||||
|
||||
def find(self, predicate, include_self=True):
|
||||
@@ -103,14 +102,12 @@ class Node(MutableSequence):
|
||||
|
||||
@property
|
||||
def children_count(self):
|
||||
"""Same as ``len(self)``.
|
||||
"""
|
||||
"""Same as ``len(self)``."""
|
||||
return len(self)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Name for the node, supplied on init.
|
||||
"""
|
||||
"""Name for the node, supplied on init."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
|
||||
@@ -56,8 +56,7 @@ class Job:
|
||||
|
||||
# ---Private
|
||||
def _subjob_callback(self, progress, desc=""):
|
||||
"""This is the callback passed to children jobs.
|
||||
"""
|
||||
"""This is the callback passed to children jobs."""
|
||||
self.set_progress(progress, desc)
|
||||
return True # if JobCancelled has to be raised, it will be at the highest level
|
||||
|
||||
|
||||
@@ -154,9 +154,7 @@ def strings2pot(target, dest):
|
||||
def allstrings2pot(lprojpath, dest, excludes=None):
|
||||
allstrings = files_with_ext(lprojpath, ".strings")
|
||||
if excludes:
|
||||
allstrings = [
|
||||
p for p in allstrings if op.splitext(op.basename(p))[0] not in excludes
|
||||
]
|
||||
allstrings = [p for p in allstrings if op.splitext(op.basename(p))[0] not in excludes]
|
||||
for strings_path in allstrings:
|
||||
strings2pot(strings_path, dest)
|
||||
|
||||
@@ -195,11 +193,7 @@ def generate_cocoa_strings_from_code(code_folder, dest_folder):
|
||||
# genstrings produces utf-16 files with comments. After having generated the files, we convert
|
||||
# them to utf-8 and remove the comments.
|
||||
ensure_empty_folder(dest_folder)
|
||||
print_and_do(
|
||||
'genstrings -o "{}" `find "{}" -name *.m | xargs`'.format(
|
||||
dest_folder, code_folder
|
||||
)
|
||||
)
|
||||
print_and_do('genstrings -o "{}" `find "{}" -name *.m | xargs`'.format(dest_folder, code_folder))
|
||||
for stringsfile in os.listdir(dest_folder):
|
||||
stringspath = op.join(dest_folder, stringsfile)
|
||||
with open(stringspath, "rt", encoding="utf-16") as fp:
|
||||
@@ -214,9 +208,7 @@ def generate_cocoa_strings_from_code(code_folder, dest_folder):
|
||||
|
||||
|
||||
def generate_cocoa_strings_from_xib(xib_folder):
|
||||
xibs = [
|
||||
op.join(xib_folder, fn) for fn in os.listdir(xib_folder) if fn.endswith(".xib")
|
||||
]
|
||||
xibs = [op.join(xib_folder, fn) for fn in os.listdir(xib_folder) if fn.endswith(".xib")]
|
||||
for xib in xibs:
|
||||
dest = xib.replace(".xib", ".strings")
|
||||
print_and_do("ibtool {} --generate-strings-file {}".format(xib, dest))
|
||||
@@ -234,10 +226,6 @@ def localize_stringsfile(stringsfile, dest_root_folder):
|
||||
|
||||
|
||||
def localize_all_stringsfiles(src_folder, dest_root_folder):
|
||||
stringsfiles = [
|
||||
op.join(src_folder, fn)
|
||||
for fn in os.listdir(src_folder)
|
||||
if fn.endswith(".strings")
|
||||
]
|
||||
stringsfiles = [op.join(src_folder, fn) for fn in os.listdir(src_folder) if fn.endswith(".strings")]
|
||||
for path in stringsfiles:
|
||||
localize_stringsfile(path, dest_root_folder)
|
||||
|
||||
@@ -16,8 +16,7 @@ from collections import defaultdict
|
||||
|
||||
|
||||
class Broadcaster:
|
||||
"""Broadcasts messages that are received by all listeners.
|
||||
"""
|
||||
"""Broadcasts messages that are received by all listeners."""
|
||||
|
||||
def __init__(self):
|
||||
self.listeners = set()
|
||||
@@ -39,8 +38,7 @@ class Broadcaster:
|
||||
|
||||
|
||||
class Listener:
|
||||
"""A listener is initialized with the broadcaster it's going to listen to. Initially, it is not connected.
|
||||
"""
|
||||
"""A listener is initialized with the broadcaster it's going to listen to. Initially, it is not connected."""
|
||||
|
||||
def __init__(self, broadcaster):
|
||||
self.broadcaster = broadcaster
|
||||
@@ -57,13 +55,11 @@ class Listener:
|
||||
self._bound_notifications[message].append(func)
|
||||
|
||||
def connect(self):
|
||||
"""Connects the listener to its broadcaster.
|
||||
"""
|
||||
"""Connects the listener to its broadcaster."""
|
||||
self.broadcaster.add_listener(self)
|
||||
|
||||
def disconnect(self):
|
||||
"""Disconnects the listener from its broadcaster.
|
||||
"""
|
||||
"""Disconnects the listener from its broadcaster."""
|
||||
self.broadcaster.remove_listener(self)
|
||||
|
||||
def dispatch(self, msg):
|
||||
|
||||
@@ -85,9 +85,7 @@ class Path(tuple):
|
||||
def __getitem__(self, key):
|
||||
if isinstance(key, slice):
|
||||
if isinstance(key.start, Path):
|
||||
equal_elems = list(
|
||||
takewhile(lambda pair: pair[0] == pair[1], zip(self, key.start))
|
||||
)
|
||||
equal_elems = list(takewhile(lambda pair: pair[0] == pair[1], zip(self, key.start)))
|
||||
key = slice(len(equal_elems), key.stop, key.step)
|
||||
if isinstance(key.stop, Path):
|
||||
equal_elems = list(
|
||||
@@ -226,9 +224,7 @@ def pathify(f):
|
||||
Calling ``foo('/bar', 0)`` will convert ``'/bar'`` to ``Path('/bar')``.
|
||||
"""
|
||||
sig = signature(f)
|
||||
pindexes = {
|
||||
i for i, p in enumerate(sig.parameters.values()) if p.annotation is Path
|
||||
}
|
||||
pindexes = {i for i, p in enumerate(sig.parameters.values()) if p.annotation is Path}
|
||||
pkeys = {k: v for k, v in sig.parameters.items() if v.annotation is Path}
|
||||
|
||||
def path_or_none(p):
|
||||
@@ -236,9 +232,7 @@ def pathify(f):
|
||||
|
||||
@wraps(f)
|
||||
def wrapped(*args, **kwargs):
|
||||
args = tuple(
|
||||
(path_or_none(a) if i in pindexes else a) for i, a in enumerate(args)
|
||||
)
|
||||
args = tuple((path_or_none(a) if i in pindexes else a) for i, a in enumerate(args))
|
||||
kwargs = {k: (path_or_none(v) if k in pkeys else v) for k, v in kwargs.items()}
|
||||
return f(*args, **kwargs)
|
||||
|
||||
@@ -246,8 +240,7 @@ def pathify(f):
|
||||
|
||||
|
||||
def log_io_error(func):
|
||||
""" Catches OSError, IOError and WindowsError and log them
|
||||
"""
|
||||
"""Catches OSError, IOError and WindowsError and log them"""
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(path, *args, **kwargs):
|
||||
|
||||
@@ -110,22 +110,14 @@ def _visit_pyfiles(list, dirname, names):
|
||||
# get extension for python source files
|
||||
if "_py_ext" not in globals():
|
||||
global _py_ext
|
||||
_py_ext = [
|
||||
triple[0] for triple in imp.get_suffixes() if triple[2] == imp.PY_SOURCE
|
||||
][0]
|
||||
_py_ext = [triple[0] for triple in imp.get_suffixes() if triple[2] == imp.PY_SOURCE][0]
|
||||
|
||||
# don't recurse into CVS directories
|
||||
if "CVS" in names:
|
||||
names.remove("CVS")
|
||||
|
||||
# add all *.py files to list
|
||||
list.extend(
|
||||
[
|
||||
os.path.join(dirname, file)
|
||||
for file in names
|
||||
if os.path.splitext(file)[1] == _py_ext
|
||||
]
|
||||
)
|
||||
list.extend([os.path.join(dirname, file) for file in names if os.path.splitext(file)[1] == _py_ext])
|
||||
|
||||
|
||||
def _get_modpkg_path(dotted_name, pathlist=None):
|
||||
@@ -406,8 +398,7 @@ def main(source_files, outpath, keywords=None):
|
||||
eater(*_token)
|
||||
except tokenize.TokenError as e:
|
||||
print(
|
||||
"%s: %s, line %d, column %d"
|
||||
% (e.args[0], filename, e.args[1][0], e.args[1][1]),
|
||||
"%s: %s, line %d, column %d" % (e.args[0], filename, e.args[1][0], e.args[1][1]),
|
||||
file=sys.stderr,
|
||||
)
|
||||
finally:
|
||||
|
||||
@@ -22,9 +22,7 @@ def tixgen(tixurl):
|
||||
"""This is a filter *generator*. tixurl is a url pattern for the tix with a {0} placeholder
|
||||
for the tix #
|
||||
"""
|
||||
urlpattern = tixurl.format(
|
||||
"\\1"
|
||||
) # will be replaced buy the content of the first group in re
|
||||
urlpattern = tixurl.format("\\1") # will be replaced buy the content of the first group in re
|
||||
R = re.compile(r"#(\d+)")
|
||||
repl = "`#\\1 <{}>`__".format(urlpattern)
|
||||
return lambda text: R.sub(repl, text)
|
||||
@@ -61,9 +59,7 @@ def gen(
|
||||
# The format of the changelog descriptions is in markdown, but since we only use bulled list
|
||||
# and links, it's not worth depending on the markdown package. A simple regexp suffice.
|
||||
description = re.sub(r"\[(.*?)\]\((.*?)\)", "`\\1 <\\2>`__", description)
|
||||
rendered = CHANGELOG_FORMAT.format(
|
||||
version=log["version"], date=log["date_str"], description=description
|
||||
)
|
||||
rendered = CHANGELOG_FORMAT.format(version=log["version"], date=log["date_str"], description=description)
|
||||
rendered_logs.append(rendered)
|
||||
confrepl["version"] = changelog[0]["version"]
|
||||
changelog_out = op.join(basepath, "changelog.rst")
|
||||
@@ -75,6 +71,4 @@ def gen(
|
||||
try:
|
||||
sphinx_build([basepath, destpath])
|
||||
except SystemExit:
|
||||
print(
|
||||
"Sphinx called sys.exit(), but we're cancelling it because we don't actually want to exit"
|
||||
)
|
||||
print("Sphinx called sys.exit(), but we're cancelling it because we don't actually want to exit")
|
||||
|
||||
@@ -31,8 +31,8 @@ class FakeCursor(list):
|
||||
|
||||
|
||||
class _ActualThread(threading.Thread):
|
||||
""" We can't use this class directly because thread object are not automatically freed when
|
||||
nothing refers to it, making it hang the application if not explicitely closed.
|
||||
"""We can't use this class directly because thread object are not automatically freed when
|
||||
nothing refers to it, making it hang the application if not explicitely closed.
|
||||
"""
|
||||
|
||||
def __init__(self, dbname, autocommit):
|
||||
|
||||
@@ -80,9 +80,7 @@ class TestCase_move_copy:
|
||||
assert self.path["baz"].exists()
|
||||
assert not self.path["foo"].exists()
|
||||
|
||||
def test_copy_no_conflict(
|
||||
self, do_setup
|
||||
): # No need to duplicate the rest of the tests... Let's just test on move
|
||||
def test_copy_no_conflict(self, do_setup): # No need to duplicate the rest of the tests... Let's just test on move
|
||||
smart_copy(self.path + "foo", self.path + "baz")
|
||||
assert self.path["baz"].exists()
|
||||
assert self.path["foo"].exists()
|
||||
|
||||
@@ -128,9 +128,7 @@ def test_repeater_with_repeated_notifications():
|
||||
r.connect()
|
||||
listener.connect()
|
||||
b.notify("hello")
|
||||
b.notify(
|
||||
"foo"
|
||||
) # if the repeater repeated this notif, we'd get a crash on HelloListener
|
||||
b.notify("foo") # if the repeater repeated this notif, we'd get a crash on HelloListener
|
||||
eq_(r.hello_count, 1)
|
||||
eq_(listener.hello_count, 1)
|
||||
eq_(r.foo_count, 1)
|
||||
|
||||
@@ -87,8 +87,7 @@ def test_filename(force_ossep):
|
||||
|
||||
|
||||
def test_deal_with_empty_components(force_ossep):
|
||||
"""Keep ONLY a leading space, which means we want a leading slash.
|
||||
"""
|
||||
"""Keep ONLY a leading space, which means we want a leading slash."""
|
||||
eq_("foo//bar", str(Path(("foo", "", "bar"))))
|
||||
eq_("/foo/bar", str(Path(("", "foo", "bar"))))
|
||||
eq_("foo/bar", str(Path("foo/bar/")))
|
||||
@@ -154,8 +153,7 @@ def test_path_slice(force_ossep):
|
||||
|
||||
|
||||
def test_add_with_root_path(force_ossep):
|
||||
"""if I perform /a/b/c + /d/e/f, I want /a/b/c/d/e/f, not /a/b/c//d/e/f
|
||||
"""
|
||||
"""if I perform /a/b/c + /d/e/f, I want /a/b/c/d/e/f, not /a/b/c//d/e/f"""
|
||||
eq_("/foo/bar", str(Path("/foo") + Path("/bar")))
|
||||
|
||||
|
||||
@@ -166,8 +164,7 @@ def test_create_with_tuple_that_have_slash_inside(force_ossep, monkeypatch):
|
||||
|
||||
|
||||
def test_auto_decode_os_sep(force_ossep, monkeypatch):
|
||||
"""Path should decode any either / or os.sep, but always encode in os.sep.
|
||||
"""
|
||||
"""Path should decode any either / or os.sep, but always encode in os.sep."""
|
||||
eq_(("foo\\bar", "bleh"), Path("foo\\bar/bleh"))
|
||||
monkeypatch.setattr(os, "sep", "\\")
|
||||
eq_(("foo", "bar/bleh"), Path("foo\\bar/bleh"))
|
||||
|
||||
@@ -44,9 +44,7 @@ def test_guicalls():
|
||||
# A GUISelectableList appropriately calls its view.
|
||||
sl = GUISelectableList(["foo", "bar"])
|
||||
sl.view = CallLogger()
|
||||
sl.view.check_gui_calls(
|
||||
["refresh"]
|
||||
) # Upon setting the view, we get a call to refresh()
|
||||
sl.view.check_gui_calls(["refresh"]) # Upon setting the view, we get a call to refresh()
|
||||
sl[1] = "baz"
|
||||
sl.view.check_gui_calls(["refresh"])
|
||||
sl.append("foo")
|
||||
|
||||
@@ -105,9 +105,7 @@ def test_findall_dont_include_self():
|
||||
# When calling findall with include_self=False, the node itself is never evaluated.
|
||||
t = tree_with_some_nodes()
|
||||
del t._name # so that if the predicate is called on `t`, we crash
|
||||
r = t.findall(
|
||||
lambda n: not n.name.startswith("sub"), include_self=False
|
||||
) # no crash
|
||||
r = t.findall(lambda n: not n.name.startswith("sub"), include_self=False) # no crash
|
||||
eq_(set(r), set([t[0], t[1], t[2]]))
|
||||
|
||||
|
||||
|
||||
@@ -105,9 +105,7 @@ def test_iterconsume():
|
||||
# We just want to make sure that we return *all* items and that we're not mistakenly skipping
|
||||
# one.
|
||||
eq_(list(range(2500)), list(iterconsume(list(range(2500)))))
|
||||
eq_(
|
||||
list(reversed(range(2500))), list(iterconsume(list(range(2500)), reverse=False))
|
||||
)
|
||||
eq_(list(reversed(range(2500))), list(iterconsume(list(range(2500)), reverse=False)))
|
||||
|
||||
|
||||
# --- String
|
||||
|
||||
@@ -86,9 +86,7 @@ class CallLogger:
|
||||
eq_(set(self.calls), set(expected))
|
||||
self.clear_calls()
|
||||
|
||||
def check_gui_calls_partial(
|
||||
self, expected=None, not_expected=None, verify_order=False
|
||||
):
|
||||
def check_gui_calls_partial(self, expected=None, not_expected=None, verify_order=False):
|
||||
"""Checks that the expected calls have been made to 'self', then clears the log.
|
||||
|
||||
`expected` is an iterable of strings representing method names. Order doesn't matter.
|
||||
@@ -99,25 +97,17 @@ class CallLogger:
|
||||
__tracebackhide__ = True
|
||||
if expected is not None:
|
||||
not_called = set(expected) - set(self.calls)
|
||||
assert not not_called, "These calls haven't been made: {0}".format(
|
||||
not_called
|
||||
)
|
||||
assert not not_called, "These calls haven't been made: {0}".format(not_called)
|
||||
if verify_order:
|
||||
max_index = 0
|
||||
for call in expected:
|
||||
index = self.calls.index(call)
|
||||
if index < max_index:
|
||||
raise AssertionError(
|
||||
"The call {0} hasn't been made in the correct order".format(
|
||||
call
|
||||
)
|
||||
)
|
||||
raise AssertionError("The call {0} hasn't been made in the correct order".format(call))
|
||||
max_index = index
|
||||
if not_expected is not None:
|
||||
called = set(not_expected) & set(self.calls)
|
||||
assert not called, "These calls shouldn't have been made: {0}".format(
|
||||
called
|
||||
)
|
||||
assert not called, "These calls shouldn't have been made: {0}".format(called)
|
||||
self.clear_calls()
|
||||
|
||||
|
||||
@@ -193,27 +183,25 @@ def jointhreads():
|
||||
|
||||
|
||||
def _unify_args(func, args, kwargs, args_to_ignore=None):
|
||||
""" Unify args and kwargs in the same dictionary.
|
||||
"""Unify args and kwargs in the same dictionary.
|
||||
|
||||
The result is kwargs with args added to it. func.func_code.co_varnames is used to determine
|
||||
under what key each elements of arg will be mapped in kwargs.
|
||||
The result is kwargs with args added to it. func.func_code.co_varnames is used to determine
|
||||
under what key each elements of arg will be mapped in kwargs.
|
||||
|
||||
if you want some arguments not to be in the results, supply a list of arg names in
|
||||
args_to_ignore.
|
||||
if you want some arguments not to be in the results, supply a list of arg names in
|
||||
args_to_ignore.
|
||||
|
||||
if f is a function that takes *args, func_code.co_varnames is empty, so args will be put
|
||||
under 'args' in kwargs.
|
||||
if f is a function that takes *args, func_code.co_varnames is empty, so args will be put
|
||||
under 'args' in kwargs.
|
||||
|
||||
def foo(bar, baz)
|
||||
_unifyArgs(foo, (42,), {'baz': 23}) --> {'bar': 42, 'baz': 23}
|
||||
_unifyArgs(foo, (42,), {'baz': 23}, ['bar']) --> {'baz': 23}
|
||||
def foo(bar, baz)
|
||||
_unifyArgs(foo, (42,), {'baz': 23}) --> {'bar': 42, 'baz': 23}
|
||||
_unifyArgs(foo, (42,), {'baz': 23}, ['bar']) --> {'baz': 23}
|
||||
"""
|
||||
result = kwargs.copy()
|
||||
if hasattr(func, "__code__"): # built-in functions don't have func_code
|
||||
args = list(args)
|
||||
if (
|
||||
getattr(func, "__self__", None) is not None
|
||||
): # bound method, we have to add self to args list
|
||||
if getattr(func, "__self__", None) is not None: # bound method, we have to add self to args list
|
||||
args = [func.__self__] + args
|
||||
defaults = list(func.__defaults__) if func.__defaults__ is not None else []
|
||||
arg_count = func.__code__.co_argcount
|
||||
@@ -234,11 +222,11 @@ def _unify_args(func, args, kwargs, args_to_ignore=None):
|
||||
|
||||
|
||||
def log_calls(func):
|
||||
""" Logs all func calls' arguments under func.calls.
|
||||
"""Logs all func calls' arguments under func.calls.
|
||||
|
||||
func.calls is a list of _unify_args() result (dict).
|
||||
func.calls is a list of _unify_args() result (dict).
|
||||
|
||||
Mostly used for unit testing.
|
||||
Mostly used for unit testing.
|
||||
"""
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
|
||||
@@ -110,9 +110,7 @@ def install_gettext_trans(base_folder, lang):
|
||||
if not lang:
|
||||
return lambda s: s
|
||||
try:
|
||||
return gettext.translation(
|
||||
domain, localedir=base_folder, languages=[lang]
|
||||
).gettext
|
||||
return gettext.translation(domain, localedir=base_folder, languages=[lang]).gettext
|
||||
except IOError:
|
||||
return lambda s: s
|
||||
|
||||
|
||||
@@ -19,8 +19,7 @@ from .path import Path, pathify, log_io_error
|
||||
|
||||
|
||||
def nonone(value, replace_value):
|
||||
"""Returns ``value`` if ``value`` is not ``None``. Returns ``replace_value`` otherwise.
|
||||
"""
|
||||
"""Returns ``value`` if ``value`` is not ``None``. Returns ``replace_value`` otherwise."""
|
||||
if value is None:
|
||||
return replace_value
|
||||
else:
|
||||
@@ -28,8 +27,7 @@ def nonone(value, replace_value):
|
||||
|
||||
|
||||
def tryint(value, default=0):
|
||||
"""Tries to convert ``value`` to in ``int`` and returns ``default`` if it fails.
|
||||
"""
|
||||
"""Tries to convert ``value`` to in ``int`` and returns ``default`` if it fails."""
|
||||
try:
|
||||
return int(value)
|
||||
except (TypeError, ValueError):
|
||||
@@ -37,8 +35,7 @@ def tryint(value, default=0):
|
||||
|
||||
|
||||
def minmax(value, min_value, max_value):
|
||||
"""Returns `value` or one of the min/max bounds if `value` is not between them.
|
||||
"""
|
||||
"""Returns `value` or one of the min/max bounds if `value` is not between them."""
|
||||
return min(max(value, min_value), max_value)
|
||||
|
||||
|
||||
@@ -75,8 +72,7 @@ def flatten(iterables, start_with=None):
|
||||
|
||||
|
||||
def first(iterable):
|
||||
"""Returns the first item of ``iterable``.
|
||||
"""
|
||||
"""Returns the first item of ``iterable``."""
|
||||
try:
|
||||
return next(iter(iterable))
|
||||
except StopIteration:
|
||||
@@ -84,14 +80,12 @@ def first(iterable):
|
||||
|
||||
|
||||
def stripfalse(seq):
|
||||
"""Returns a sequence with all false elements stripped out of seq.
|
||||
"""
|
||||
"""Returns a sequence with all false elements stripped out of seq."""
|
||||
return [x for x in seq if x]
|
||||
|
||||
|
||||
def extract(predicate, iterable):
|
||||
"""Separates the wheat from the shaft (`predicate` defines what's the wheat), and returns both.
|
||||
"""
|
||||
"""Separates the wheat from the shaft (`predicate` defines what's the wheat), and returns both."""
|
||||
wheat = []
|
||||
shaft = []
|
||||
for item in iterable:
|
||||
@@ -103,8 +97,7 @@ def extract(predicate, iterable):
|
||||
|
||||
|
||||
def allsame(iterable):
|
||||
"""Returns whether all elements of 'iterable' are the same.
|
||||
"""
|
||||
"""Returns whether all elements of 'iterable' are the same."""
|
||||
it = iter(iterable)
|
||||
try:
|
||||
first_item = next(it)
|
||||
@@ -152,14 +145,12 @@ def iterconsume(seq, reverse=True):
|
||||
|
||||
|
||||
def escape(s, to_escape, escape_with="\\"):
|
||||
"""Returns ``s`` with characters in ``to_escape`` all prepended with ``escape_with``.
|
||||
"""
|
||||
"""Returns ``s`` with characters in ``to_escape`` all prepended with ``escape_with``."""
|
||||
return "".join((escape_with + c if c in to_escape else c) for c in s)
|
||||
|
||||
|
||||
def get_file_ext(filename):
|
||||
"""Returns the lowercase extension part of filename, without the dot.
|
||||
"""
|
||||
"""Returns the lowercase extension part of filename, without the dot."""
|
||||
pos = filename.rfind(".")
|
||||
if pos > -1:
|
||||
return filename[pos + 1 :].lower()
|
||||
@@ -168,8 +159,7 @@ def get_file_ext(filename):
|
||||
|
||||
|
||||
def rem_file_ext(filename):
|
||||
"""Returns the filename without extension.
|
||||
"""
|
||||
"""Returns the filename without extension."""
|
||||
pos = filename.rfind(".")
|
||||
if pos > -1:
|
||||
return filename[:pos]
|
||||
@@ -217,8 +207,7 @@ def format_time(seconds, with_hours=True):
|
||||
|
||||
|
||||
def format_time_decimal(seconds):
|
||||
"""Transforms seconds in a strings like '3.4 minutes'.
|
||||
"""
|
||||
"""Transforms seconds in a strings like '3.4 minutes'."""
|
||||
minus = seconds < 0
|
||||
if minus:
|
||||
seconds *= -1
|
||||
@@ -320,8 +309,7 @@ ONE_DAY = timedelta(1)
|
||||
|
||||
|
||||
def iterdaterange(start, end):
|
||||
"""Yields every day between ``start`` and ``end``.
|
||||
"""
|
||||
"""Yields every day between ``start`` and ``end``."""
|
||||
date = start
|
||||
while date <= end:
|
||||
yield date
|
||||
@@ -365,8 +353,7 @@ def find_in_path(name, paths=None):
|
||||
@log_io_error
|
||||
@pathify
|
||||
def delete_if_empty(path: Path, files_to_delete=[]):
|
||||
"""Deletes the directory at 'path' if it is empty or if it only contains files_to_delete.
|
||||
"""
|
||||
"""Deletes the directory at 'path' if it is empty or if it only contains files_to_delete."""
|
||||
if not path.exists() or not path.isdir():
|
||||
return
|
||||
contents = path.listdir()
|
||||
@@ -411,8 +398,7 @@ def ensure_file(path):
|
||||
|
||||
|
||||
def delete_files_with_pattern(folder_path, pattern, recursive=True):
|
||||
"""Delete all files (or folders) in `folder_path` that match the glob `pattern`.
|
||||
"""
|
||||
"""Delete all files (or folders) in `folder_path` that match the glob `pattern`."""
|
||||
to_delete = glob.glob(op.join(folder_path, pattern))
|
||||
for fn in to_delete:
|
||||
if op.isdir(fn):
|
||||
|
||||
Reference in New Issue
Block a user