mirror of
https://github.com/arsenetar/dupeguru.git
synced 2024-10-29 21:05:57 +00:00
Apply pyupgrade changes
This commit is contained in:
parent
e0061d7bc1
commit
63dd4d4561
4
build.py
4
build.py
@ -61,7 +61,7 @@ def parse_args():
|
||||
|
||||
|
||||
def build_one_help(language):
|
||||
print("Generating Help in {}".format(language))
|
||||
print(f"Generating Help in {language}")
|
||||
current_path = Path(".").absolute()
|
||||
changelog_path = current_path.joinpath("help", "changelog")
|
||||
tixurl = "https://github.com/arsenetar/dupeguru/issues/{}"
|
||||
@ -139,7 +139,7 @@ def build_normal():
|
||||
print("Building localizations")
|
||||
build_localizations()
|
||||
print("Building Qt stuff")
|
||||
print_and_do("pyrcc5 {0} > {1}".format(Path("qt", "dg.qrc"), Path("qt", "dg_rc.py")))
|
||||
print_and_do("pyrcc5 {} > {}".format(Path("qt", "dg.qrc"), Path("qt", "dg_rc.py")))
|
||||
fix_qt_resource_file(Path("qt", "dg_rc.py"))
|
||||
build_help()
|
||||
|
||||
|
@ -264,7 +264,7 @@ class DupeGuru(Broadcaster):
|
||||
try:
|
||||
f._read_all_info(attrnames=self.METADATA_TO_READ)
|
||||
return f
|
||||
except EnvironmentError:
|
||||
except OSError:
|
||||
return None
|
||||
|
||||
def _get_export_data(self):
|
||||
|
@ -120,7 +120,7 @@ class Directories:
|
||||
file.is_ref = state == DirectoryState.REFERENCE
|
||||
count += 1
|
||||
yield file
|
||||
except (EnvironmentError, OSError, fs.InvalidPath):
|
||||
except (OSError, fs.InvalidPath):
|
||||
pass
|
||||
logging.debug(
|
||||
"Collected %d files in folder %s",
|
||||
@ -134,14 +134,13 @@ class Directories:
|
||||
j.check_if_cancelled()
|
||||
try:
|
||||
for subfolder in from_folder.subfolders:
|
||||
for folder in self._get_folders(subfolder, j):
|
||||
yield folder
|
||||
yield from self._get_folders(subfolder, j)
|
||||
state = self.get_state(from_folder.path)
|
||||
if state != DirectoryState.EXCLUDED:
|
||||
from_folder.is_ref = state == DirectoryState.REFERENCE
|
||||
logging.debug("Yielding Folder %r state: %d", from_folder, state)
|
||||
yield from_folder
|
||||
except (EnvironmentError, fs.InvalidPath):
|
||||
except (OSError, fs.InvalidPath):
|
||||
pass
|
||||
|
||||
# ---Public
|
||||
@ -173,7 +172,7 @@ class Directories:
|
||||
subpaths = [p for p in path.glob("*") if p.is_dir()]
|
||||
subpaths.sort(key=lambda x: x.name.lower())
|
||||
return subpaths
|
||||
except EnvironmentError:
|
||||
except OSError:
|
||||
return []
|
||||
|
||||
def get_files(self, fileclasses=None, j=job.nulljob):
|
||||
|
@ -166,7 +166,7 @@ def reduce_common_words(word_dict, threshold):
|
||||
The exception to this removal are the objects where all the words of the object are common.
|
||||
Because if we remove them, we will miss some duplicates!
|
||||
"""
|
||||
uncommon_words = set(word for word, objects in word_dict.items() if len(objects) < threshold)
|
||||
uncommon_words = {word for word, objects in word_dict.items() if len(objects) < threshold}
|
||||
for word, objects in list(word_dict.items()):
|
||||
if len(objects) < threshold:
|
||||
continue
|
||||
@ -409,7 +409,7 @@ class Group:
|
||||
|
||||
You can call this after the duplicate scanning process to free a bit of memory.
|
||||
"""
|
||||
discarded = set(m for m in self.matches if not all(obj in self.unordered for obj in [m.first, m.second]))
|
||||
discarded = {m for m in self.matches if not all(obj in self.unordered for obj in [m.first, m.second])}
|
||||
self.matches -= discarded
|
||||
self.candidates = defaultdict(set)
|
||||
return discarded
|
||||
@ -456,7 +456,7 @@ class Group:
|
||||
self._matches_for_ref = None
|
||||
if (len(self) > 1) and any(not getattr(item, "is_ref", False) for item in self):
|
||||
if discard_matches:
|
||||
self.matches = set(m for m in self.matches if item not in m)
|
||||
self.matches = {m for m in self.matches if item not in m}
|
||||
else:
|
||||
self._clear()
|
||||
except ValueError:
|
||||
@ -529,7 +529,7 @@ def get_groups(matches):
|
||||
del dupe2group
|
||||
del matches
|
||||
# should free enough memory to continue
|
||||
logging.warning("Memory Overflow. Groups: {0}".format(len(groups)))
|
||||
logging.warning(f"Memory Overflow. Groups: {len(groups)}")
|
||||
# Now that we have a group, we have to discard groups' matches and see if there're any "orphan"
|
||||
# matches, that is, matches that were candidate in a group but that none of their 2 files were
|
||||
# accepted in the group. With these orphan groups, it's safe to build additional groups
|
||||
|
@ -197,7 +197,7 @@ class File:
|
||||
self.path = path
|
||||
|
||||
def __repr__(self):
|
||||
return "<{} {}>".format(self.__class__.__name__, str(self.path))
|
||||
return f"<{self.__class__.__name__} {str(self.path)}>"
|
||||
|
||||
def __getattribute__(self, attrname):
|
||||
result = object.__getattribute__(self, attrname)
|
||||
@ -317,7 +317,7 @@ class File:
|
||||
raise AlreadyExistsError(newname, self.path.parent)
|
||||
try:
|
||||
self.path.rename(destpath)
|
||||
except EnvironmentError:
|
||||
except OSError:
|
||||
raise OperationError(self)
|
||||
if not destpath.exists():
|
||||
raise OperationError(self)
|
||||
@ -421,5 +421,5 @@ def get_files(path, fileclasses=[File]):
|
||||
if file is not None:
|
||||
result.append(file)
|
||||
return result
|
||||
except EnvironmentError:
|
||||
except OSError:
|
||||
raise InvalidPath(path)
|
||||
|
@ -13,7 +13,7 @@ def colors_to_string(colors):
|
||||
[(0,100,255)] --> 0064ff
|
||||
[(1,2,3),(4,5,6)] --> 010203040506
|
||||
"""
|
||||
return "".join("%02x%02x%02x" % (r, g, b) for r, g, b in colors)
|
||||
return "".join("{:02x}{:02x}{:02x}".format(r, g, b) for r, g, b in colors)
|
||||
|
||||
|
||||
# This function is an important bottleneck of dupeGuru PE. It has been converted to C.
|
||||
|
@ -14,7 +14,7 @@ from .cache import string_to_colors, colors_to_string
|
||||
|
||||
|
||||
def wrap_path(path):
|
||||
return "path:{}".format(path)
|
||||
return f"path:{path}"
|
||||
|
||||
|
||||
def unwrap_path(key):
|
||||
@ -22,7 +22,7 @@ def unwrap_path(key):
|
||||
|
||||
|
||||
def wrap_id(path):
|
||||
return "id:{}".format(path)
|
||||
return f"id:{path}"
|
||||
|
||||
|
||||
def unwrap_id(key):
|
||||
|
@ -87,7 +87,7 @@ def prepare_pictures(pictures, cache_path, with_dimensions, j=job.nulljob):
|
||||
blocks = picture.get_blocks(BLOCK_COUNT_PER_SIDE)
|
||||
cache[picture.unicode_path] = blocks
|
||||
prepared.append(picture)
|
||||
except (IOError, ValueError) as e:
|
||||
except (OSError, ValueError) as e:
|
||||
logging.warning(str(e))
|
||||
except MemoryError:
|
||||
logging.warning(
|
||||
|
@ -43,7 +43,7 @@ class Criterion:
|
||||
|
||||
@property
|
||||
def display(self):
|
||||
return "{} ({})".format(self.category.NAME, self.display_value)
|
||||
return f"{self.category.NAME} ({self.display_value})"
|
||||
|
||||
|
||||
class ValueListCategory(CriterionCategory):
|
||||
|
@ -191,7 +191,7 @@ class Results(Markable):
|
||||
self.__filters.append(filter_str)
|
||||
if self.__filtered_dupes is None:
|
||||
self.__filtered_dupes = flatten(g[:] for g in self.groups)
|
||||
self.__filtered_dupes = set(dupe for dupe in self.__filtered_dupes if filter_re.search(str(dupe.path)))
|
||||
self.__filtered_dupes = {dupe for dupe in self.__filtered_dupes if filter_re.search(str(dupe.path))}
|
||||
filtered_groups = set()
|
||||
for dupe in self.__filtered_dupes:
|
||||
filtered_groups.add(self.get_group_of_duplicate(dupe))
|
||||
@ -301,7 +301,7 @@ class Results(Markable):
|
||||
try:
|
||||
func(dupe)
|
||||
to_remove.append(dupe)
|
||||
except (EnvironmentError, UnicodeEncodeError) as e:
|
||||
except (OSError, UnicodeEncodeError) as e:
|
||||
self.problems.append((dupe, str(e)))
|
||||
if remove_from_results:
|
||||
self.remove_duplicates(to_remove)
|
||||
@ -374,8 +374,8 @@ class Results(Markable):
|
||||
|
||||
try:
|
||||
do_write(outfile)
|
||||
except IOError as e:
|
||||
# If our IOError is because dest is already a directory, we want to handle that. 21 is
|
||||
except OSError as e:
|
||||
# If our OSError is because dest is already a directory, we want to handle that. 21 is
|
||||
# the code we get on OS X and Linux, 13 is what we get on Windows.
|
||||
if e.errno in {21, 13}:
|
||||
p = str(outfile)
|
||||
|
@ -95,7 +95,7 @@ class TestCaseDupeGuru:
|
||||
|
||||
# At some point, any() was used in a wrong way that made Scan() wrongly return 1
|
||||
app = TestApp().app
|
||||
f1, f2 = [FakeFile("foo") for _ in range(2)]
|
||||
f1, f2 = (FakeFile("foo") for _ in range(2))
|
||||
f1.is_ref, f2.is_ref = (False, False)
|
||||
assert not (bool(f1) and bool(f2))
|
||||
add_fake_files_to_directories(app.directories, [f1, f2])
|
||||
|
@ -271,9 +271,9 @@ class TestCaseBuildWordDict:
|
||||
class TestCaseMergeSimilarWords:
|
||||
def test_some_similar_words(self):
|
||||
d = {
|
||||
"foobar": set([1]),
|
||||
"foobar1": set([2]),
|
||||
"foobar2": set([3]),
|
||||
"foobar": {1},
|
||||
"foobar1": {2},
|
||||
"foobar2": {3},
|
||||
}
|
||||
merge_similar_words(d)
|
||||
eq_(1, len(d))
|
||||
@ -283,8 +283,8 @@ class TestCaseMergeSimilarWords:
|
||||
class TestCaseReduceCommonWords:
|
||||
def test_typical(self):
|
||||
d = {
|
||||
"foo": set([NamedObject("foo bar", True) for _ in range(50)]),
|
||||
"bar": set([NamedObject("foo bar", True) for _ in range(49)]),
|
||||
"foo": {NamedObject("foo bar", True) for _ in range(50)},
|
||||
"bar": {NamedObject("foo bar", True) for _ in range(49)},
|
||||
}
|
||||
reduce_common_words(d, 50)
|
||||
assert "foo" not in d
|
||||
@ -293,7 +293,7 @@ class TestCaseReduceCommonWords:
|
||||
def test_dont_remove_objects_with_only_common_words(self):
|
||||
d = {
|
||||
"common": set([NamedObject("common uncommon", True) for _ in range(50)] + [NamedObject("common", True)]),
|
||||
"uncommon": set([NamedObject("common uncommon", True)]),
|
||||
"uncommon": {NamedObject("common uncommon", True)},
|
||||
}
|
||||
reduce_common_words(d, 50)
|
||||
eq_(1, len(d["common"]))
|
||||
@ -302,7 +302,7 @@ class TestCaseReduceCommonWords:
|
||||
def test_values_still_are_set_instances(self):
|
||||
d = {
|
||||
"common": set([NamedObject("common uncommon", True) for _ in range(50)] + [NamedObject("common", True)]),
|
||||
"uncommon": set([NamedObject("common uncommon", True)]),
|
||||
"uncommon": {NamedObject("common uncommon", True)},
|
||||
}
|
||||
reduce_common_words(d, 50)
|
||||
assert isinstance(d["common"], set)
|
||||
@ -312,9 +312,9 @@ class TestCaseReduceCommonWords:
|
||||
# If a word has been removed by the reduce, an object in a subsequent common word that
|
||||
# contains the word that has been removed would cause a KeyError.
|
||||
d = {
|
||||
"foo": set([NamedObject("foo bar baz", True) for _ in range(50)]),
|
||||
"bar": set([NamedObject("foo bar baz", True) for _ in range(50)]),
|
||||
"baz": set([NamedObject("foo bar baz", True) for _ in range(49)]),
|
||||
"foo": {NamedObject("foo bar baz", True) for _ in range(50)},
|
||||
"bar": {NamedObject("foo bar baz", True) for _ in range(50)},
|
||||
"baz": {NamedObject("foo bar baz", True) for _ in range(49)},
|
||||
}
|
||||
try:
|
||||
reduce_common_words(d, 50)
|
||||
@ -328,7 +328,7 @@ class TestCaseReduceCommonWords:
|
||||
o.words = [["foo", "bar"], ["baz"]]
|
||||
return o
|
||||
|
||||
d = {"foo": set([create_it() for _ in range(50)])}
|
||||
d = {"foo": {create_it() for _ in range(50)}}
|
||||
try:
|
||||
reduce_common_words(d, 50)
|
||||
except TypeError:
|
||||
@ -343,7 +343,7 @@ class TestCaseReduceCommonWords:
|
||||
d = {
|
||||
"foo": set([NamedObject("foo bar baz", True) for _ in range(49)] + [only_common]),
|
||||
"bar": set([NamedObject("foo bar baz", True) for _ in range(49)] + [only_common]),
|
||||
"baz": set([NamedObject("foo bar baz", True) for _ in range(49)]),
|
||||
"baz": {NamedObject("foo bar baz", True) for _ in range(49)},
|
||||
}
|
||||
reduce_common_words(d, 50)
|
||||
eq_(1, len(d["foo"]))
|
||||
@ -884,7 +884,7 @@ class TestCaseGetGroups:
|
||||
# If, with a (A, B, C, D) set, all match with A, but C and D don't match with B and that the
|
||||
# (A, B) match is the highest (thus resulting in an (A, B) group), still match C and D
|
||||
# in a separate group instead of discarding them.
|
||||
A, B, C, D = [NamedObject() for _ in range(4)]
|
||||
A, B, C, D = (NamedObject() for _ in range(4))
|
||||
m1 = Match(A, B, 90) # This is the strongest "A" match
|
||||
m2 = Match(A, C, 80) # Because C doesn't match with B, it won't be in the group
|
||||
m3 = Match(A, D, 80) # Same thing for D
|
||||
|
@ -289,8 +289,8 @@ class TestCaseListEmptyUnion(TestCaseListEmpty):
|
||||
compiled = [x for x in self.exclude_list.compiled]
|
||||
assert regex not in compiled
|
||||
# Need to escape both to get the same strings after compilation
|
||||
compiled_escaped = set([x.encode("unicode-escape").decode() for x in compiled[0].pattern.split("|")])
|
||||
default_escaped = set([x.encode("unicode-escape").decode() for x in default_regexes])
|
||||
compiled_escaped = {x.encode("unicode-escape").decode() for x in compiled[0].pattern.split("|")}
|
||||
default_escaped = {x.encode("unicode-escape").decode() for x in default_regexes}
|
||||
assert compiled_escaped == default_escaped
|
||||
eq_(len(default_regexes), len(compiled[0].pattern.split("|")))
|
||||
|
||||
@ -366,8 +366,8 @@ class TestCaseDictEmptyUnion(TestCaseDictEmpty):
|
||||
compiled = [x for x in self.exclude_list.compiled]
|
||||
assert regex not in compiled
|
||||
# Need to escape both to get the same strings after compilation
|
||||
compiled_escaped = set([x.encode("unicode-escape").decode() for x in compiled[0].pattern.split("|")])
|
||||
default_escaped = set([x.encode("unicode-escape").decode() for x in default_regexes])
|
||||
compiled_escaped = {x.encode("unicode-escape").decode() for x in compiled[0].pattern.split("|")}
|
||||
default_escaped = {x.encode("unicode-escape").decode() for x in default_regexes}
|
||||
assert compiled_escaped == default_escaped
|
||||
eq_(len(default_regexes), len(compiled[0].pattern.split("|")))
|
||||
|
||||
|
@ -337,7 +337,7 @@ class TestCaseResultsMarkings:
|
||||
def log_object(o):
|
||||
log.append(o)
|
||||
if o is self.objects[1]:
|
||||
raise EnvironmentError("foobar")
|
||||
raise OSError("foobar")
|
||||
|
||||
log = []
|
||||
self.results.mark_all()
|
||||
@ -464,7 +464,7 @@ class TestCaseResultsXML:
|
||||
eq_(6, len(g1))
|
||||
eq_(3, len([c for c in g1 if c.tag == "file"]))
|
||||
eq_(3, len([c for c in g1 if c.tag == "match"]))
|
||||
d1, d2, d3 = [c for c in g1 if c.tag == "file"]
|
||||
d1, d2, d3 = (c for c in g1 if c.tag == "file")
|
||||
eq_(op.join("basepath", "foo bar"), d1.get("path"))
|
||||
eq_(op.join("basepath", "bar bleh"), d2.get("path"))
|
||||
eq_(op.join("basepath", "foo bleh"), d3.get("path"))
|
||||
@ -477,7 +477,7 @@ class TestCaseResultsXML:
|
||||
eq_(3, len(g2))
|
||||
eq_(2, len([c for c in g2 if c.tag == "file"]))
|
||||
eq_(1, len([c for c in g2 if c.tag == "match"]))
|
||||
d1, d2 = [c for c in g2 if c.tag == "file"]
|
||||
d1, d2 = (c for c in g2 if c.tag == "file")
|
||||
eq_(op.join("basepath", "ibabtu"), d1.get("path"))
|
||||
eq_(op.join("basepath", "ibabtu"), d2.get("path"))
|
||||
eq_("n", d1.get("is_ref"))
|
||||
|
@ -29,7 +29,7 @@ class NamedObject:
|
||||
self.words = getwords(name)
|
||||
|
||||
def __repr__(self):
|
||||
return "<NamedObject %r %r>" % (self.name, self.path)
|
||||
return "<NamedObject {!r} {!r}>".format(self.name, self.path)
|
||||
|
||||
|
||||
no = NamedObject
|
||||
@ -336,7 +336,7 @@ def test_tag_scan(fake_fileexists):
|
||||
def test_tag_with_album_scan(fake_fileexists):
|
||||
s = Scanner()
|
||||
s.scan_type = ScanType.TAG
|
||||
s.scanned_tags = set(["artist", "album", "title"])
|
||||
s.scanned_tags = {"artist", "album", "title"}
|
||||
o1 = no("foo")
|
||||
o2 = no("bar")
|
||||
o3 = no("bleh")
|
||||
@ -356,7 +356,7 @@ def test_tag_with_album_scan(fake_fileexists):
|
||||
def test_that_dash_in_tags_dont_create_new_fields(fake_fileexists):
|
||||
s = Scanner()
|
||||
s.scan_type = ScanType.TAG
|
||||
s.scanned_tags = set(["artist", "album", "title"])
|
||||
s.scanned_tags = {"artist", "album", "title"}
|
||||
s.min_match_percentage = 50
|
||||
o1 = no("foo")
|
||||
o2 = no("bar")
|
||||
@ -373,7 +373,7 @@ def test_that_dash_in_tags_dont_create_new_fields(fake_fileexists):
|
||||
def test_tag_scan_with_different_scanned(fake_fileexists):
|
||||
s = Scanner()
|
||||
s.scan_type = ScanType.TAG
|
||||
s.scanned_tags = set(["track", "year"])
|
||||
s.scanned_tags = {"track", "year"}
|
||||
o1 = no("foo")
|
||||
o2 = no("bar")
|
||||
o1.artist = "The White Stripes"
|
||||
@ -391,7 +391,7 @@ def test_tag_scan_with_different_scanned(fake_fileexists):
|
||||
def test_tag_scan_only_scans_existing_tags(fake_fileexists):
|
||||
s = Scanner()
|
||||
s.scan_type = ScanType.TAG
|
||||
s.scanned_tags = set(["artist", "foo"])
|
||||
s.scanned_tags = {"artist", "foo"}
|
||||
o1 = no("foo")
|
||||
o2 = no("bar")
|
||||
o1.artist = "The White Stripes"
|
||||
@ -405,7 +405,7 @@ def test_tag_scan_only_scans_existing_tags(fake_fileexists):
|
||||
def test_tag_scan_converts_to_str(fake_fileexists):
|
||||
s = Scanner()
|
||||
s.scan_type = ScanType.TAG
|
||||
s.scanned_tags = set(["track"])
|
||||
s.scanned_tags = {"track"}
|
||||
o1 = no("foo")
|
||||
o2 = no("bar")
|
||||
o1.track = 42
|
||||
@ -420,7 +420,7 @@ def test_tag_scan_converts_to_str(fake_fileexists):
|
||||
def test_tag_scan_non_ascii(fake_fileexists):
|
||||
s = Scanner()
|
||||
s.scan_type = ScanType.TAG
|
||||
s.scanned_tags = set(["title"])
|
||||
s.scanned_tags = {"title"}
|
||||
o1 = no("foo")
|
||||
o2 = no("bar")
|
||||
o1.title = "foobar\u00e9"
|
||||
|
@ -40,7 +40,7 @@ def _perform(src, dst, action, actionname):
|
||||
shutil.rmtree(dst)
|
||||
else:
|
||||
os.remove(dst)
|
||||
print("%s %s --> %s" % (actionname, src, dst))
|
||||
print("{} {} --> {}".format(actionname, src, dst))
|
||||
action(src, dst)
|
||||
|
||||
|
||||
@ -95,12 +95,12 @@ def filereplace(filename, outfilename=None, **kwargs):
|
||||
"""Reads `filename`, replaces all {variables} in kwargs, and writes the result to `outfilename`."""
|
||||
if outfilename is None:
|
||||
outfilename = filename
|
||||
fp = open(filename, "rt", encoding="utf-8")
|
||||
fp = open(filename, encoding="utf-8")
|
||||
contents = fp.read()
|
||||
fp.close()
|
||||
# We can't use str.format() because in some files, there might be {} characters that mess with it.
|
||||
for key, item in kwargs.items():
|
||||
contents = contents.replace("{{{}}}".format(key), item)
|
||||
contents = contents.replace(f"{{{key}}}", item)
|
||||
fp = open(outfilename, "wt", encoding="utf-8")
|
||||
fp.write(contents)
|
||||
fp.close()
|
||||
@ -143,8 +143,8 @@ def package_cocoa_app_in_dmg(app_path, destfolder, args):
|
||||
# phase because running the app before packaging can modify it and we want to be sure to have
|
||||
# a valid signature.
|
||||
if args.sign_identity:
|
||||
sign_identity = "Developer ID Application: {}".format(args.sign_identity)
|
||||
result = print_and_do('codesign --force --deep --sign "{}" "{}"'.format(sign_identity, app_path))
|
||||
sign_identity = f"Developer ID Application: {args.sign_identity}"
|
||||
result = print_and_do(f'codesign --force --deep --sign "{sign_identity}" "{app_path}"')
|
||||
if result != 0:
|
||||
print("ERROR: Signing failed. Aborting packaging.")
|
||||
return
|
||||
@ -164,15 +164,15 @@ def build_dmg(app_path, destfolder):
|
||||
workpath = tempfile.mkdtemp()
|
||||
dmgpath = op.join(workpath, plist["CFBundleName"])
|
||||
os.mkdir(dmgpath)
|
||||
print_and_do('cp -R "%s" "%s"' % (app_path, dmgpath))
|
||||
print_and_do('cp -R "{}" "{}"'.format(app_path, dmgpath))
|
||||
print_and_do('ln -s /Applications "%s"' % op.join(dmgpath, "Applications"))
|
||||
dmgname = "%s_osx_%s.dmg" % (
|
||||
dmgname = "{}_osx_{}.dmg".format(
|
||||
plist["CFBundleName"].lower().replace(" ", "_"),
|
||||
plist["CFBundleVersion"].replace(".", "_"),
|
||||
)
|
||||
print("Building %s" % dmgname)
|
||||
# UDBZ = bzip compression. UDZO (zip compression) was used before, but it compresses much less.
|
||||
print_and_do('hdiutil create "%s" -format UDBZ -nocrossdev -srcdir "%s"' % (op.join(destfolder, dmgname), dmgpath))
|
||||
print_and_do('hdiutil create "{}" -format UDBZ -nocrossdev -srcdir "{}"'.format(op.join(destfolder, dmgname), dmgpath))
|
||||
print("Build Complete")
|
||||
|
||||
|
||||
@ -216,7 +216,7 @@ def copy_packages(packages_names, dest, create_links=False, extra_ignores=None):
|
||||
os.unlink(dest_path)
|
||||
else:
|
||||
shutil.rmtree(dest_path)
|
||||
print("Copying package at {0} to {1}".format(source_path, dest_path))
|
||||
print(f"Copying package at {source_path} to {dest_path}")
|
||||
if create_links:
|
||||
os.symlink(op.abspath(source_path), dest_path)
|
||||
else:
|
||||
@ -297,7 +297,7 @@ def read_changelog_file(filename):
|
||||
return
|
||||
yield version, date, description
|
||||
|
||||
with open(filename, "rt", encoding="utf-8") as fp:
|
||||
with open(filename, encoding="utf-8") as fp:
|
||||
contents = fp.read()
|
||||
splitted = re_changelog_header.split(contents)[1:] # the first item is empty
|
||||
result = []
|
||||
|
@ -18,7 +18,7 @@ def get_parser():
|
||||
|
||||
def main():
|
||||
args = get_parser().parse_args()
|
||||
print("Building {}...".format(args.name[0]))
|
||||
print(f"Building {args.name[0]}...")
|
||||
ext = Extension(args.name[0], args.source_files)
|
||||
setup(
|
||||
script_args=["build_ext", "--inplace"],
|
||||
|
@ -73,7 +73,7 @@ def smart_copy(source_path, dest_path):
|
||||
"""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:
|
||||
except OSError as e:
|
||||
if e.errno in {
|
||||
21,
|
||||
13,
|
||||
|
@ -216,7 +216,7 @@ class Columns(GUIObject):
|
||||
self.view.restore_columns()
|
||||
return
|
||||
for col in self.column_list:
|
||||
pref_name = "{}.Columns.{}".format(self.savename, col.name)
|
||||
pref_name = f"{self.savename}.Columns.{col.name}"
|
||||
coldata = self.prefaccess.get_default(pref_name, fallback_value={})
|
||||
if "index" in coldata:
|
||||
col.ordered_index = coldata["index"]
|
||||
@ -231,7 +231,7 @@ class Columns(GUIObject):
|
||||
if not (self.prefaccess and self.savename and self.coldata):
|
||||
return
|
||||
for col in self.column_list:
|
||||
pref_name = "{}.Columns.{}".format(self.savename, col.name)
|
||||
pref_name = f"{self.savename}.Columns.{col.name}"
|
||||
coldata = {"index": col.ordered_index, "width": col.width}
|
||||
if col.optional:
|
||||
coldata["visible"] = col.visible
|
||||
|
@ -451,7 +451,7 @@ class Row:
|
||||
"""
|
||||
|
||||
def __init__(self, table):
|
||||
super(Row, self).__init__()
|
||||
super().__init__()
|
||||
self.table = table
|
||||
|
||||
def _edit(self):
|
||||
|
@ -77,8 +77,7 @@ class Node(MutableSequence):
|
||||
if include_self and predicate(self):
|
||||
yield self
|
||||
for child in self:
|
||||
for found in child.findall(predicate, include_self=True):
|
||||
yield found
|
||||
yield from child.findall(predicate, include_self=True)
|
||||
|
||||
def get_node(self, index_path):
|
||||
"""Returns the node at ``index_path``.
|
||||
|
@ -47,7 +47,7 @@ def log_io_error(func):
|
||||
def wrapper(path, *args, **kwargs):
|
||||
try:
|
||||
return func(path, *args, **kwargs)
|
||||
except (IOError, OSError) as e:
|
||||
except OSError as e:
|
||||
msg = 'Error "{0}" during operation "{1}" on "{2}": "{3}"'
|
||||
classname = e.__class__.__name__
|
||||
funcname = func.__name__
|
||||
|
@ -374,7 +374,7 @@ def main(source_files, outpath, keywords=None):
|
||||
fp = open(options.excludefilename, encoding="utf-8")
|
||||
options.toexclude = fp.readlines()
|
||||
fp.close()
|
||||
except IOError:
|
||||
except OSError:
|
||||
print(
|
||||
"Can't read --exclude-file: %s" % options.excludefilename,
|
||||
file=sys.stderr,
|
||||
|
@ -24,7 +24,7 @@ def tixgen(tixurl):
|
||||
"""
|
||||
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)
|
||||
repl = f"`#\\1 <{urlpattern}>`__"
|
||||
return lambda text: R.sub(repl, text)
|
||||
|
||||
|
||||
|
@ -113,7 +113,7 @@ def test_repeater_with_repeated_notifications():
|
||||
# If REPEATED_NOTIFICATIONS is not empty, only notifs in this set are repeated (but they're
|
||||
# still dispatched locally).
|
||||
class MyRepeater(HelloRepeater):
|
||||
REPEATED_NOTIFICATIONS = set(["hello"])
|
||||
REPEATED_NOTIFICATIONS = {"hello"}
|
||||
|
||||
def __init__(self, broadcaster):
|
||||
HelloRepeater.__init__(self, broadcaster)
|
||||
|
@ -98,7 +98,7 @@ def test_selection_override():
|
||||
def test_findall():
|
||||
t = tree_with_some_nodes()
|
||||
r = t.findall(lambda n: n.name.startswith("sub"))
|
||||
eq_(set(r), set([t[0][0], t[0][1]]))
|
||||
eq_(set(r), {t[0][0], t[0][1]})
|
||||
|
||||
|
||||
def test_findall_dont_include_self():
|
||||
@ -106,7 +106,7 @@ def test_findall_dont_include_self():
|
||||
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
|
||||
eq_(set(r), set([t[0], t[1], t[2]]))
|
||||
eq_(set(r), {t[0], t[1], t[2]})
|
||||
|
||||
|
||||
def test_find_dont_include_self():
|
||||
|
@ -14,7 +14,7 @@ import py.path
|
||||
|
||||
def eq_(a, b, msg=None):
|
||||
__tracebackhide__ = True
|
||||
assert a == b, msg or "%r != %r" % (a, b)
|
||||
assert a == b, msg or "{!r} != {!r}".format(a, b)
|
||||
|
||||
|
||||
def eq_sorted(a, b, msg=None):
|
||||
@ -97,17 +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, f"These calls haven't been made: {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(f"The call {call} hasn't been made in the correct order")
|
||||
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, f"These calls shouldn't have been made: {called}"
|
||||
self.clear_calls()
|
||||
|
||||
|
||||
@ -133,7 +133,7 @@ class TestApp:
|
||||
parent = self.default_parent
|
||||
if holder is None:
|
||||
holder = self
|
||||
setattr(holder, "{0}_gui".format(name), view)
|
||||
setattr(holder, f"{name}_gui", view)
|
||||
gui = class_(parent)
|
||||
gui.view = view
|
||||
setattr(holder, name, gui)
|
||||
|
@ -112,7 +112,7 @@ def install_gettext_trans(base_folder, lang):
|
||||
return lambda s: s
|
||||
try:
|
||||
return gettext.translation(domain, localedir=base_folder, languages=[lang]).gettext
|
||||
except IOError:
|
||||
except OSError:
|
||||
return lambda s: s
|
||||
|
||||
default_gettext = gettext_trget("core")
|
||||
|
@ -270,7 +270,7 @@ def format_size(size, decimal=0, forcepower=-1, showdesc=True):
|
||||
|
||||
_valid_xml_range = "\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD"
|
||||
if sys.maxunicode > 0x10000:
|
||||
_valid_xml_range += "%s-%s" % (chr(0x10000), chr(min(sys.maxunicode, 0x10FFFF)))
|
||||
_valid_xml_range += "{}-{}".format(chr(0x10000), chr(min(sys.maxunicode, 0x10FFFF)))
|
||||
RE_INVALID_XML_SUB = re.compile("[^%s]" % _valid_xml_range, re.U).sub
|
||||
|
||||
|
||||
@ -328,11 +328,11 @@ def modified_after(first_path: Path, second_path: Path):
|
||||
"""
|
||||
try:
|
||||
first_mtime = first_path.stat().st_mtime
|
||||
except (EnvironmentError, AttributeError):
|
||||
except (OSError, AttributeError):
|
||||
return False
|
||||
try:
|
||||
second_mtime = second_path.stat().st_mtime
|
||||
except (EnvironmentError, AttributeError):
|
||||
except (OSError, AttributeError):
|
||||
return True
|
||||
return first_mtime > second_mtime
|
||||
|
||||
|
@ -442,6 +442,6 @@ class DupeGuru(QObject):
|
||||
def select_dest_file(self, prompt, extension):
|
||||
files = tr("{} file (*.{})").format(extension.upper(), extension)
|
||||
destination, chosen_filter = QFileDialog.getSaveFileName(self.resultWindow, prompt, "", files)
|
||||
if not destination.endswith(".{}".format(extension)):
|
||||
destination = "{}.{}".format(destination, extension)
|
||||
if not destination.endswith(f".{extension}"):
|
||||
destination = f"{destination}.{extension}"
|
||||
return destination
|
||||
|
@ -347,7 +347,7 @@ class DirectoriesDialog(QMainWindow):
|
||||
destination, chosen_filter = QFileDialog.getSaveFileName(self, title, "", files)
|
||||
if destination:
|
||||
if not destination.endswith(".dupegurudirs"):
|
||||
destination = "{}.dupegurudirs".format(destination)
|
||||
destination = f"{destination}.dupegurudirs"
|
||||
self.app.model.save_directories_as(destination)
|
||||
|
||||
def scanButtonClicked(self):
|
||||
|
@ -22,7 +22,7 @@ class File(PhotoBase):
|
||||
return (size.width(), size.height())
|
||||
else:
|
||||
return (0, 0)
|
||||
except EnvironmentError:
|
||||
except OSError:
|
||||
logging.warning("Could not read image '%s'", str(self.path))
|
||||
return (0, 0)
|
||||
|
||||
|
@ -470,7 +470,7 @@ class ResultWindow(QMainWindow):
|
||||
destination, chosen_filter = QFileDialog.getSaveFileName(self, title, "", files)
|
||||
if destination:
|
||||
if not destination.endswith(".dupeguru"):
|
||||
destination = "{}.dupeguru".format(destination)
|
||||
destination = f"{destination}.dupeguru"
|
||||
self.app.model.save_as(destination)
|
||||
self.app.recentResults.insertItem(destination)
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Created By: Virgil Dupras
|
||||
# Created On: 2009-10-16
|
||||
# Copyright 2015 Hardcoded Software (http://www.hardcoded.net)
|
||||
|
@ -38,7 +38,7 @@ class ClearableEdit(QLineEdit):
|
||||
self._clearButton = LineEditButton(self)
|
||||
frame_width = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth)
|
||||
padding_right = self._clearButton.sizeHint().width() + frame_width + 1
|
||||
stylesheet = "QLineEdit {{ padding-right:{0}px; }}".format(padding_right)
|
||||
stylesheet = f"QLineEdit {{ padding-right:{padding_right}px; }}"
|
||||
self.setStyleSheet(stylesheet)
|
||||
self._updateClearButton()
|
||||
|
||||
|
2
run.py
2
run.py
@ -71,7 +71,7 @@ def main():
|
||||
# has been installed
|
||||
from qt.app import DupeGuru
|
||||
|
||||
app.setWindowIcon(QIcon(QPixmap(":/{0}".format(DupeGuru.LOGO_NAME))))
|
||||
app.setWindowIcon(QIcon(QPixmap(f":/{DupeGuru.LOGO_NAME}")))
|
||||
global dgapp
|
||||
dgapp = DupeGuru()
|
||||
install_excepthook("https://github.com/hsoft/dupeguru/issues")
|
||||
|
Loading…
Reference in New Issue
Block a user