[PATCH 01 of 13] py3: convert to new style classes

2 views
Skip to first unread message

Matt Harbison

unread,
Feb 28, 2025, 5:14:22 PMFeb 28
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1736203889 18000
# Mon Jan 06 17:51:29 2025 -0500
# Branch stable
# Node ID 34fea09137806ea96b8b6c598d86c501d149d50a
# Parent b9b153e52d1f9cd707dff64e3e5a6cd7fee8046a
# EXP-Topic pyupgrade
py3: convert to new style classes

These were rewritten using a hacked version of `pyupgrade` 3.19.1
that enabled only the `new_style_classes` fixer. See hg 9bd6854aab86 for
details.

$ hg files -0 'relglob:**.py' | xargs -0 pyupgrade --py38-plus \
--keep-percent-format --keep-mock --keep-runtime-typing

diff --git a/tests/colormap_test.py b/tests/colormap_test.py
--- a/tests/colormap_test.py
+++ b/tests/colormap_test.py
@@ -12,10 +12,10 @@

def fakectx(userhash, date, tz=0):
# AnnotateColorSaturation uses hash() for mapping user to hue
- class user(object):
+ class user:
def __hash__(self):
return userhash
- class ctx(object):
+ class ctx:
def user(self):
return user()
def date(self):
diff --git a/tests/familyline_test.py b/tests/familyline_test.py
--- a/tests/familyline_test.py
+++ b/tests/familyline_test.py
@@ -24,7 +24,7 @@
assert pending == rev.pending
assert set(dests) == set(rev.destinations)

-class TestPendingAfterFixingItself(object):
+class TestPendingAfterFixingItself:
"""
Test value of _FamilyLineRev.pending after proceed() called
"""
@@ -67,7 +67,7 @@
assert_rev(r9, pending=1, dests=[(7, P, False)])


-class TestPendingAfterFixingParent(object):
+class TestPendingAfterFixingParent:
"""
Test value of _FamilyLineRev.pending after proceed() called against its
parent
@@ -129,7 +129,7 @@
x7.proceed([x6, x4])
assert_rev(r9, pending=3, dests=[]) # 6, 5, 4 / don't count 6 twice

-class TestIgnoredNVAs(object):
+class TestIgnoredNVAs:
"""
Test behaviour about omitting duplicated edge
"""
@@ -183,7 +183,7 @@
# and 4 is excluded because it is parent of 5
assert_rev(r9, pending=0, dests=[(6, F, True)])

-class TestP1OrNot(object):
+class TestP1OrNot:
"""
Test is_p1 value of each NVAs
"""
diff --git a/tests/helpers.py b/tests/helpers.py
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -55,7 +55,7 @@
os.close(fd)
os.unlink(path)

-class EncodingPatcher(object):
+class EncodingPatcher:
"""Temporarily change locale encoding"""

def __init__(self, encoding, fallbackencoding=None):
@@ -115,7 +115,7 @@
return wrapper
return deco

-class HgClient(object):
+class HgClient:
"""Mercurial client to set up fixture repository

>>> hg = HgClient(b'/tmp/foo')
@@ -233,7 +233,7 @@
pass


-class GraphBuilder(object):
+class GraphBuilder:
_re_graphline = re.compile(r"""^
(?P<graph>[ o0-9|/\\+\-]*) #graph
(\s*\[(?P<params>[^#]+)\]\s*)? #params
diff --git a/tests/pytestcaptureexc.py b/tests/pytestcaptureexc.py
--- a/tests/pytestcaptureexc.py
+++ b/tests/pytestcaptureexc.py
@@ -13,7 +13,7 @@

import pytest

-class CaptureExcPlugin(object):
+class CaptureExcPlugin:
"""Capture unhandled exception (probably raised inside event loop)"""

def pytest_addoption(self, parser):
diff --git a/tests/pytesthgenv.py b/tests/pytesthgenv.py
--- a/tests/pytesthgenv.py
+++ b/tests/pytesthgenv.py
@@ -12,7 +12,7 @@

# don't import mercurial or tortoisehg before setting up test environment

-class HgEnvPlugin(object):
+class HgEnvPlugin:
"""Set up temporary environment"""

def pytest_addoption(self, parser):
diff --git a/tests/qt_cmdagent_test.py b/tests/qt_cmdagent_test.py
--- a/tests/qt_cmdagent_test.py
+++ b/tests/qt_cmdagent_test.py
@@ -63,7 +63,7 @@
loop.exec()


-class _CmdAgentTestBase(object):
+class _CmdAgentTestBase:
@classmethod
def setUpClass(cls):
tmpdir = helpers.mktmpdir(cls.__name__)
diff --git a/tests/qt_repoagent_test.py b/tests/qt_repoagent_test.py
--- a/tests/qt_repoagent_test.py
+++ b/tests/qt_repoagent_test.py
@@ -51,7 +51,7 @@
self.assertFalse(self.agent.hiddenRevsIncluded())


-class _RepoAgentChangedSignalTestBase(object):
+class _RepoAgentChangedSignalTestBase:
@classmethod
def setUpClass(cls):
tmpdir = helpers.mktmpdir(cls.__name__)
diff --git a/tortoisehg/hgqt/bugreport.py b/tortoisehg/hgqt/bugreport.py
--- a/tortoisehg/hgqt/bugreport.py
+++ b/tortoisehg/hgqt/bugreport.py
@@ -260,7 +260,7 @@
try:
# A chicken-egg problem here, we need a ui to get your
# editor in order to repair your ui config file.
- class FakeRepo(object):
+ class FakeRepo:
def __init__(self):
self.root = encoding.getcwd()
self.ui = hglib.loadui()
diff --git a/tortoisehg/hgqt/cmdcore.py b/tortoisehg/hgqt/cmdcore.py
--- a/tortoisehg/hgqt/cmdcore.py
+++ b/tortoisehg/hgqt/cmdcore.py
@@ -103,7 +103,7 @@
return '%s(%s)' % (self.__class__.__name__, ', '.join(fields))


-class UiHandler(object):
+class UiHandler:
"""Interface to handle user interaction of Mercurial commands"""

NoInput = 0
diff --git a/tortoisehg/hgqt/csinfo.py b/tortoisehg/hgqt/csinfo.py
--- a/tortoisehg/hgqt/csinfo.py
+++ b/tortoisehg/hgqt/csinfo.py
@@ -54,7 +54,7 @@
def custom(**kargs):
return kargs

-class Factory(object):
+class Factory:

def __init__(self, repo, custom=None, style=None, target=None,
withupdate=False):
@@ -114,7 +114,7 @@
pass


-class SummaryInfo(object):
+class SummaryInfo:

LABELS = {'rev': _('Revision:'), 'revnum': _('Revision:'),
'gitcommit': _('Git Commit:'),
@@ -373,7 +373,7 @@
pass
return default_func(widget, item, markups)

-class SummaryBase(object):
+class SummaryBase:

def __init__(self, target, custom, repo, info):
self.target = target
diff --git a/tortoisehg/hgqt/filedata.py b/tortoisehg/hgqt/filedata.py
--- a/tortoisehg/hgqt/filedata.py
+++ b/tortoisehg/hgqt/filedata.py
@@ -91,7 +91,7 @@
return diff


-class _AbstractFileData(object):
+class _AbstractFileData:

def __init__(
self,
diff --git a/tortoisehg/hgqt/filedialogs.py b/tortoisehg/hgqt/filedialogs.py
--- a/tortoisehg/hgqt/filedialogs.py
+++ b/tortoisehg/hgqt/filedialogs.py
@@ -146,7 +146,7 @@
#
# TODO: this should be removed if filelog_grapher (and FileRevModel) are
# superseded by revset-based implementation.
-class _UnfilteredRepoAgentProxy(object):
+class _UnfilteredRepoAgentProxy:
def __init__(self, repoagent):
self._repoagent = repoagent

diff --git a/tortoisehg/hgqt/graph.py b/tortoisehg/hgqt/graph.py
--- a/tortoisehg/hgqt/graph.py
+++ b/tortoisehg/hgqt/graph.py
@@ -284,7 +284,7 @@
return idx


-class StandardDag(object):
+class StandardDag:
"""Generate DAG for grapher

Public fields:
@@ -388,7 +388,7 @@
yield ctx, parents


-class _FamilyLineRev(object):
+class _FamilyLineRev:
r"""Revision information for building family line relations

Public fields:
@@ -672,7 +672,7 @@
return _iter_graphnodes(dag, GraphNode.fromfilectx)


-class FileDag(object):
+class FileDag:
def __init__(self, repo, path):
self.repo = repo
self.path = path
@@ -766,7 +766,7 @@
return flogheads


-class RevColorPalette(object):
+class RevColorPalette:
"""Assign node and line colors for each revision"""

def __init__(self):
@@ -813,7 +813,7 @@


@attr.s(slots=True, repr=False)
-class GraphEdge(object):
+class GraphEdge:
startrev = attr.ib() # int or None (for working rev)
endrev = attr.ib() # int
color = attr.ib() # int
@@ -833,7 +833,7 @@
# prefer parent-child relation and younger (i.e. longer) edge
return -self.linktype, -self.color

-class GraphNode(object):
+class GraphNode:
"""Graph node for all actual changesets, as well as the working copy

Simple class to encapsulate a hg node in the revision graph. Does
@@ -897,7 +897,7 @@
return max([self.x] + [max(p) for p, _e in self.bottomlines]) + 1


-class PatchGraphNode(object):
+class PatchGraphNode:
"""Node for un-applied patch queue items.

This node is always displayed unfaded and only occupy one column.
@@ -925,7 +925,7 @@
return 1


-class Graph(object):
+class Graph:
"""
Graph object to ease hg repo navigation. The Graph object
instantiate a `revision_grapher` generator, and provide a `fill`
@@ -1042,7 +1042,7 @@
return self.nodesdict[rev].extra[0]


-class GraphWithMq(object):
+class GraphWithMq:
"""Graph layouter that also shows un-applied mq changes"""

def __init__(self, graph, patchnames):
diff --git a/tortoisehg/hgqt/graphopt.py b/tortoisehg/hgqt/graphopt.py
--- a/tortoisehg/hgqt/graphopt.py
+++ b/tortoisehg/hgqt/graphopt.py
@@ -73,7 +73,7 @@
return graphmod.GraphNode.fromchangectx(repo, ctx, xposition, lines)


-class GraphEdge(object):
+class GraphEdge:
"""Edge from startrev to endrev"""

def __init__(self, graph, startrev, endrev, linktype):
@@ -114,7 +114,7 @@
return repo.revs(b'branch(%s)', branch)


-class Graph(object):
+class Graph:
"""Efficient graph layouter for repositories.

The grapher pre-computes the overall layout of the graph in a memory
diff --git a/tortoisehg/hgqt/grep.py b/tortoisehg/hgqt/grep.py
--- a/tortoisehg/hgqt/grep.py
+++ b/tortoisehg/hgqt/grep.py
@@ -411,7 +411,7 @@
else:
self.showMessage.emit(_('No matches found'))

-class DataWrapper(object):
+class DataWrapper:
def __init__(self, data):
self.data = data

diff --git a/tortoisehg/hgqt/hgconfig.py b/tortoisehg/hgqt/hgconfig.py
--- a/tortoisehg/hgqt/hgconfig.py
+++ b/tortoisehg/hgqt/hgconfig.py
@@ -25,7 +25,7 @@

UNSET_DEFAULT = uimod._unset

-class HgConfig(object):
+class HgConfig:
"""Unicode wrapper for Mercurial's ui object

This provides Qt-like API on top of the ui object. Almost all methods
diff --git a/tortoisehg/hgqt/lexers.py b/tortoisehg/hgqt/lexers.py
--- a/tortoisehg/hgqt/lexers.py
+++ b/tortoisehg/hgqt/lexers.py
@@ -42,7 +42,7 @@
def _fixdarkcolors(lexer):
pass

-class _LexerSelector(object):
+class _LexerSelector:
_lexer = None
def match(self, filename, filedata):
return False
diff --git a/tortoisehg/hgqt/manifestmodel.py b/tortoisehg/hgqt/manifestmodel.py
--- a/tortoisehg/hgqt/manifestmodel.py
+++ b/tortoisehg/hgqt/manifestmodel.py
@@ -483,7 +483,7 @@
roote.sort()


-class _Entry(object):
+class _Entry:
"""Each file or directory"""

__slots__ = ('_name', '_parent', 'status', 'ctx', 'pctx', 'subkind',
@@ -621,7 +621,7 @@
return scmutil.matchfiles(repo, []) # TODO: use matchmod.never()


-class _listnodeop(object):
+class _listnodeop:
subreporecursive = False

@staticmethod
@@ -636,7 +636,7 @@
def putpath(e: _Entry, path: Text, c: _Entry) -> None:
e.putchild(path, c)

-class _treenodeop(object):
+class _treenodeop:
subreporecursive = True

@staticmethod
diff --git a/tortoisehg/hgqt/qscilib.py b/tortoisehg/hgqt/qscilib.py
--- a/tortoisehg/hgqt/qscilib.py
+++ b/tortoisehg/hgqt/qscilib.py
@@ -57,7 +57,7 @@
STYLE_FILEVIEW_MARGIN = QsciScintilla.STYLE_LASTPREDEFINED + 1


-class _SciImSupport(object):
+class _SciImSupport:
"""Patch for QsciScintilla to implement improved input method support

See https://doc.qt.io/qt-4.8/qinputmethodevent.html
diff --git a/tortoisehg/hgqt/qtlib.py b/tortoisehg/hgqt/qtlib.py
--- a/tortoisehg/hgqt/qtlib.py
+++ b/tortoisehg/hgqt/qtlib.py
@@ -1269,7 +1269,7 @@

self.setLayout(box)

-class WidgetGroups(object):
+class WidgetGroups:
""" Support for bulk-updating properties of Qt widgets """

def __init__(self) -> None:
@@ -1446,7 +1446,7 @@
def _defaultgenkey(_parent, *args, **_kwargs):
return args

-class TaskWidget(object):
+class TaskWidget:
def canswitch(self) -> bool:
"""Return True if the widget allows to switch away from it"""
return True
@@ -1597,7 +1597,7 @@
return [QShortcut(keyseq, *args, **kwargs)
for keyseq in QKeySequence.keyBindings(key)]

-class PaletteSwitcher(object):
+class PaletteSwitcher:
"""
Class that can be used to enable a predefined, alterantive background color
for a widget
diff --git a/tortoisehg/hgqt/repotreeitem.py b/tortoisehg/hgqt/repotreeitem.py
--- a/tortoisehg/hgqt/repotreeitem.py
+++ b/tortoisehg/hgqt/repotreeitem.py
@@ -193,7 +193,7 @@
return item


-class RepoTreeItem(object):
+class RepoTreeItem:
xmltagname = 'treeitem'

def __init__(self, parent: Optional["RepoTreeItem"] = None) -> None:
diff --git a/tortoisehg/hgqt/repoview.py b/tortoisehg/hgqt/repoview.py
--- a/tortoisehg/hgqt/repoview.py
+++ b/tortoisehg/hgqt/repoview.py
@@ -723,7 +723,7 @@
return size


-class _LabelsLayout(object):
+class _LabelsLayout:
"""Lay out and render text labels"""

def __init__(self, labels, font, margin=2):
diff --git a/tortoisehg/hgqt/settings.py b/tortoisehg/hgqt/settings.py
--- a/tortoisehg/hgqt/settings.py
+++ b/tortoisehg/hgqt/settings.py
@@ -619,7 +619,7 @@
opts['nohist'] = True
return SettingsCheckBox(**opts)

-class _fi(object):
+class _fi:
"""Information of each field"""
__slots__ = ('label', 'cpath', 'values', 'tooltip',
'restartneeded', 'globalonly', 'noglobal',
diff --git a/tortoisehg/hgqt/shortcutregistry.py b/tortoisehg/hgqt/shortcutregistry.py
--- a/tortoisehg/hgqt/shortcutregistry.py
+++ b/tortoisehg/hgqt/shortcutregistry.py
@@ -238,7 +238,7 @@
_TOOLTIP_SHORTCUT_END_TAG)


-class ShortcutRegistry(object):
+class ShortcutRegistry:
"""Dictionary of user-configurable shortcuts

This is pure data object. Use ActionRegistry to manage both shortcuts
diff --git a/tortoisehg/hgqt/status.py b/tortoisehg/hgqt/status.py
--- a/tortoisehg/hgqt/status.py
+++ b/tortoisehg/hgqt/status.py
@@ -1143,7 +1143,7 @@
tip += _(', unresolved merge')
return tip

-class StatusType(object):
+class StatusType:
preferredOrder = 'MAR!?ICS'
def __init__(
self, name: str, icon: str, desc: str, uilabel: str, trname: str
diff --git a/tortoisehg/util/colormap.py b/tortoisehg/util/colormap.py
--- a/tortoisehg/util/colormap.py
+++ b/tortoisehg/util/colormap.py
@@ -18,7 +18,7 @@
def _rescaleceil(val, step):
return float(step) * math.ceil(float(val) / step)

-class AnnotateColorSaturation(object):
+class AnnotateColorSaturation:
def __init__(self, maxhues=None, maxsaturations=None, isdarktheme=False):
self._maxhues = maxhues
self._maxsaturations = maxsaturations
diff --git a/tortoisehg/util/i18n.py b/tortoisehg/util/i18n.py
--- a/tortoisehg/util/i18n.py
+++ b/tortoisehg/util/i18n.py
@@ -95,6 +95,6 @@
except (LookupError, UnicodeEncodeError):
return pycompat.sysbytes(message)

-class keepgettext(object):
+class keepgettext:
def _(self, message: str, context: str = '') -> Dict[str, str]:
return {'id': message, 'str': _(message, context)}
diff --git a/tortoisehg/util/menuthg.py b/tortoisehg/util/menuthg.py
--- a/tortoisehg/util/menuthg.py
+++ b/tortoisehg/util/menuthg.py
@@ -112,7 +112,7 @@

_ALWAYS_DEMOTE_ = ('about', 'userconf', 'repoconf')

-class TortoiseMenu(object):
+class TortoiseMenu:

def __init__(self,
menutext: Text,
@@ -167,7 +167,7 @@
return True


-class TortoiseMenuSep(object):
+class TortoiseMenuSep:

hgcmd = '----'

@@ -178,7 +178,7 @@
return True


-class thg_menu(object):
+class thg_menu:

menus: List[MenuT]

diff --git a/tortoisehg/util/patchctx.py b/tortoisehg/util/patchctx.py
--- a/tortoisehg/util/patchctx.py
+++ b/tortoisehg/util/patchctx.py
@@ -28,7 +28,7 @@

from tortoisehg.util import hglib

-class patchctx(object):
+class patchctx:
_parseErrorFileName = '*ParseError*'

def __init__(self, patchpath, repo, pf=None, rev=None):
diff --git a/tortoisehg/util/wconfig.py b/tortoisehg/util/wconfig.py
--- a/tortoisehg/util/wconfig.py
+++ b/tortoisehg/util/wconfig.py
@@ -60,7 +60,7 @@
value, _source, _level = packed
return value

-class _wsortdict(object):
+class _wsortdict:
"""Wrapper for config.sortdict to record set/del operations"""
def __init__(self, dict: Dict[bytes, Any]) -> None:
self._dict: Dict[bytes, Any] = dict
@@ -136,7 +136,7 @@
for op in self._log:
op(target)

-class _wconfig(object):
+class _wconfig:
"""Wrapper for config.config to replay changes to iniparse on write

This records set/del operations and replays them on write().
diff --git a/tortoisehg/util/win32ill.py b/tortoisehg/util/win32ill.py
--- a/tortoisehg/util/win32ill.py
+++ b/tortoisehg/util/win32ill.py
@@ -175,7 +175,7 @@
_TranslateMessage.restype = _BOOL
_TranslateMessage.argtypes = (ctypes.POINTER(_MSG),)

-class messageserver(object):
+class messageserver:

def __init__(self, logfile: Optional[BinaryIO]) -> None:
self._logfile = logfile

Matt Harbison

unread,
Feb 28, 2025, 5:14:28 PMFeb 28
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1736203971 18000
# Mon Jan 06 17:52:51 2025 -0500
# Branch stable
# Node ID 44196db5303deec1858163ef4e598db098c0b5b5
# Parent 34fea09137806ea96b8b6c598d86c501d149d50a
# EXP-Topic pyupgrade
py3: drop usage of py3 aliases for `OSError`

These were different classes in py2, but now a handful of error classes are just
an alias of `OSError`, like `IOError`, `EnvironmentError`, `WindowsError`, etc.

These were rewritten using a hacked version of `pyupgrade` 3.19.1
that enabled only the `exceptions` fixer. See hg 24ee91ba9aa8 for details.

diff --git a/TortoiseHgOverlayServer.py b/TortoiseHgOverlayServer.py
--- a/TortoiseHgOverlayServer.py
+++ b/TortoiseHgOverlayServer.py
@@ -368,7 +368,7 @@
updated_any = True
shlib.shell_notify([hglib.fromunicode(r)], noassoc=True)
logger.msg('Updated ' + r)
- except (IOError, OSError):
+ except OSError:
print("IOError or OSError on updating %s (check permissions)" % r)
logger.msg('Failed updating %s (check permissions)' % r)
failedroots.add(r)
@@ -480,7 +480,7 @@
f.close()
if not e.startswith(b'@@noicons'):
unlink(fn)
- except (IOError, OSError) as e:
+ except OSError as e:
if e.errno != errno.ENOENT:
logger.msg("Error while trying to remove %s (%s)" % (tfn, e))
if notifypaths:
@@ -635,7 +635,7 @@
logfilename = os.path.join(appdir, 'TortoiseHg', 'OverlayServerLog.txt')
try:
os.makedirs(os.path.dirname(logfilename))
- except EnvironmentError:
+ except OSError:
pass
logger.setfile(logfilename)

diff --git a/tortoisehg/hgqt/about.py b/tortoisehg/hgqt/about.py
--- a/tortoisehg/hgqt/about.py
+++ b/tortoisehg/hgqt/about.py
@@ -195,7 +195,7 @@
with open(paths.get_license_path(), 'r') as fp:
lic = fp.read()
self.lic_txt.setPlainText(lic)
- except IOError:
+ except OSError:
pass

bbox = QDialogButtonBox(self)
diff --git a/tortoisehg/hgqt/bugreport.py b/tortoisehg/hgqt/bugreport.py
--- a/tortoisehg/hgqt/bugreport.py
+++ b/tortoisehg/hgqt/bugreport.py
@@ -182,7 +182,7 @@
if fname:
with open(fname, 'wb') as fp:
fp.write(hglib.fromunicode(self.text))
- except EnvironmentError as e:
+ except OSError as e:
QMessageBox.critical(
self, _('Error writing file'), hglib.exception_str(e)
)
diff --git a/tortoisehg/hgqt/chunks.py b/tortoisehg/hgqt/chunks.py
--- a/tortoisehg/hgqt/chunks.py
+++ b/tortoisehg/hgqt/chunks.py
@@ -199,7 +199,7 @@
if mtime != newmtime:
self.mtime = newmtime
self.refresh()
- except EnvironmentError:
+ except OSError:
pass

def runPatcher(self, fp, wfile, updatestate):
@@ -228,7 +228,7 @@
if ret < 0:
ok = False
self.showMessage.emit(_('Patch failed to apply'))
- except (patch.PatchError, EnvironmentError) as err:
+ except (patch.PatchError, OSError) as err:
ok = False
self.showMessage.emit(hglib.exception_str(err))
rejfilere = re.compile(br'\b%s\.rej\b' % re.escape(wfile))
@@ -434,7 +434,7 @@
no_backup=True)
if wasadded and os.path.exists(fullpath):
os.unlink(fullpath)
- except EnvironmentError:
+ except OSError:
qtlib.InfoMsgBox(_("Unable to remove"),
_("Unable to remove file %s,\n"
"permission denied") %
diff --git a/tortoisehg/hgqt/commit.py b/tortoisehg/hgqt/commit.py
--- a/tortoisehg/hgqt/commit.py
+++ b/tortoisehg/hgqt/commit.py
@@ -975,13 +975,13 @@
try:
curmsg = self.repo.vfs(b'cur-message.txt').read()
self.setMessage(hglib.tounicode(curmsg))
- except EnvironmentError:
+ except OSError:
pass
try:
curmsg = self.repo.vfs(b'last-message.txt').read()
if curmsg:
self.addMessageToHistory(hglib.tounicode(curmsg))
- except EnvironmentError:
+ except OSError:
pass

def saveSettings(self, s: QSettings, prefix: Text) -> None:
@@ -997,7 +997,7 @@
s.setValue(gpref+'userhist', self.userhist)
msg = self.getMessage(True)
self.repo.vfs(b'cur-message.txt', b'w').write(msg)
- except (EnvironmentError, IOError):
+ except OSError:
pass

def addMessageToHistory(self, umsg: Text) -> None:
@@ -1438,7 +1438,7 @@
except KeyError:
pass
wconfig.writefile(cfg, fn)
- except IOError as e:
+ except OSError as e:
qtlib.WarningMsgBox(_('Unable to write configuration file'),
hglib.exception_str(e), parent=self)

@@ -1461,7 +1461,7 @@
except KeyError:
pass
wconfig.writefile(cfg, fn)
- except IOError as e:
+ except OSError as e:
qtlib.WarningMsgBox(_('Unable to write configuration file'),
hglib.exception_str(e), parent=self)

@@ -1484,7 +1484,7 @@
except KeyError:
pass
wconfig.writefile(cfg, fn)
- except IOError as e:
+ except OSError as e:
qtlib.WarningMsgBox(_('Unable to write configuration file'),
hglib.exception_str(e), parent=self)

@@ -1507,7 +1507,7 @@
except KeyError:
pass
wconfig.writefile(cfg, fn)
- except IOError as e:
+ except OSError as e:
qtlib.WarningMsgBox(_('Unable to write configuration file'),
hglib.exception_str(e), parent=self)

diff --git a/tortoisehg/hgqt/filedata.py b/tortoisehg/hgqt/filedata.py
--- a/tortoisehg/hgqt/filedata.py
+++ b/tortoisehg/hgqt/filedata.py
@@ -274,7 +274,7 @@
self._readStatus(ctx, ctx2, wfile, status, changeselect, force)
except _BadContent as e:
self.error = errorprefix + e.args[0] + '\n\n' + forcedisplaymsg
- except (EnvironmentError, error.LookupError, error.Abort) as e:
+ except (OSError, error.LookupError, error.Abort) as e:
self.error = errorprefix + hglib.exception_str(e)

def _checkMaxDiff(
@@ -552,7 +552,7 @@
try:
m = ctx.match([b'path:%s' % self._wfile])
self.diff = b''.join(ctx.diff(pctx, m))
- except (EnvironmentError, error.Abort) as e:
+ except (OSError, error.Abort) as e:
self.error = hglib.exception_str(e)
return

@@ -578,7 +578,7 @@
try:
self.diff = ctx.thgmqpatchdata(wfile)
flags = ctx.flags(wfile)
- except EnvironmentError as e:
+ except OSError as e:
self.error = hglib.exception_str(e)
return

@@ -619,7 +619,7 @@
try:
self.diff = b''.join([ctx.thgmqpatchdata(f) for f in ctx.files()
if f.startswith(self._wfile + b'/')])
- except EnvironmentError as e:
+ except OSError as e:
self.error = hglib.exception_str(e)
return

@@ -881,7 +881,7 @@
if sactual:
lbl = ' <a href="repo:%%s">%s</a>' % _('open...')
self.flabel += lbl % hglib.tounicode(srepo.root)
- except (EnvironmentError, error.RepoError, error.Abort) as e:
+ except (OSError, error.RepoError, error.Abort) as e:
self.error = _('Error previewing subrepo: %s') % \
hglib.exception_str(e)

diff --git a/tortoisehg/hgqt/grep.py b/tortoisehg/hgqt/grep.py
--- a/tortoisehg/hgqt/grep.py
+++ b/tortoisehg/hgqt/grep.py
@@ -549,7 +549,7 @@
continue
try:
data = ctx[wfile].data() # load file data
- except EnvironmentError:
+ except OSError:
self.showMessage.emit(_('Skipping %s, unable to read') %
hglib.tounicode(wfile))
continue
diff --git a/tortoisehg/hgqt/hgignore.py b/tortoisehg/hgqt/hgignore.py
--- a/tortoisehg/hgqt/hgignore.py
+++ b/tortoisehg/hgqt/hgignore.py
@@ -309,7 +309,7 @@
with open(self.ignorefile, 'rb') as fp:
l = fp.readlines()
self.doseoln = l[0].endswith(b'\r\n')
- except (IOError, ValueError, IndexError):
+ except (OSError, ValueError, IndexError):
self.doseoln = os.name == 'nt'
l = []
self.ignorelines = [line.strip() for line in l]
@@ -323,7 +323,7 @@
self.repo.thginvalidate()
with lfutil.lfstatus(self.repo):
self.lclunknowns = self.repo.status(unknown=True).unknown
- except (EnvironmentError, error.RepoError) as e:
+ except (OSError, error.RepoError) as e:
qtlib.WarningMsgBox(_('Unable to read repository status'),
hglib.exception_str(e), parent=self)
except error.Abort as e:
@@ -368,7 +368,7 @@
commands.add(hglib.loadui(), self.repo, self.ignorefile)
shlib.shell_notify([self.ignorefile])
self.ignoreFilterUpdated.emit()
- except EnvironmentError as e:
+ except OSError as e:
qtlib.WarningMsgBox(_('Unable to write .hgignore file'),
hglib.exception_str(e), parent=self)

diff --git a/tortoisehg/hgqt/hgrcutil.py b/tortoisehg/hgqt/hgrcutil.py
--- a/tortoisehg/hgqt/hgrcutil.py
+++ b/tortoisehg/hgqt/hgrcutil.py
@@ -41,7 +41,7 @@
with open(fn, 'w') as f:
f.write('# Generated by TortoiseHg\n')
break
- except EnvironmentError:
+ except OSError:
pass
else:
qtlib.WarningMsgBox(_('Unable to create a config file'),
@@ -70,6 +70,6 @@
cfg.set(cfgFullKey[0], cfgFullKey[1], value)
try:
wconfig.writefile(cfg, fn)
- except EnvironmentError as e:
+ except OSError as e:
return False
return True
diff --git a/tortoisehg/hgqt/manifestmodel.py b/tortoisehg/hgqt/manifestmodel.py
--- a/tortoisehg/hgqt/manifestmodel.py
+++ b/tortoisehg/hgqt/manifestmodel.py
@@ -736,7 +736,7 @@
e.pctx = hglib.revsymbol(srepo, psubstate[1] or b'null')
# pytype: enable=annotation-type-mismatch
_populaterepo(e, srepo, nodeop, statusfilter, smatch)
- except (error.RepoError, EnvironmentError):
+ except (error.RepoError, OSError):
pass

# subrepo is filtered out only if the node and its children do not
diff --git a/tortoisehg/hgqt/purge.py b/tortoisehg/hgqt/purge.py
--- a/tortoisehg/hgqt/purge.py
+++ b/tortoisehg/hgqt/purge.py
@@ -245,7 +245,7 @@
trashcan = repo.vfs.join(b'Trashcan')
try:
shutil.rmtree(trashcan)
- except EnvironmentError:
+ except OSError:
failures.append(trashcan)

self.showMessage.emit('')
@@ -265,7 +265,7 @@
if keephg and name.startswith(b'.hg'):
return
remove_func(repo.wjoin(name))
- except EnvironmentError:
+ except OSError:
failures.append(name)

def removefile(path):
diff --git a/tortoisehg/hgqt/qtlib.py b/tortoisehg/hgqt/qtlib.py
--- a/tortoisehg/hgqt/qtlib.py
+++ b/tortoisehg/hgqt/qtlib.py
@@ -288,7 +288,7 @@
creationflags=openflags,
stderr=None, stdout=None, stdin=None,
cwd=procutil.tonativestr(cwd))
- except (OSError, EnvironmentError) as e:
+ except OSError as e:
QMessageBox.warning(parent,
_('Editor launch failure'),
u'%s : %s' % (hglib.tounicode(cmdline),
diff --git a/tortoisehg/hgqt/quickop.py b/tortoisehg/hgqt/quickop.py
--- a/tortoisehg/hgqt/quickop.py
+++ b/tortoisehg/hgqt/quickop.py
@@ -232,7 +232,7 @@
with lfutil.lfstatus(self.repo):
try:
repostate = self.repo.status()
- except (EnvironmentError, error.Abort) as e:
+ except (OSError, error.Abort) as e:
qtlib.WarningMsgBox(_('Unable to read repository status'),
hglib.exception_str(e), parent=self)
return
@@ -262,7 +262,7 @@
if wfile in repostate.unknown or wfile in repostate.ignored:
try:
util.unlink(wfile)
- except EnvironmentError:
+ except OSError:
pass
files.remove(wfile)
elif self.command == 'add':
diff --git a/tortoisehg/hgqt/rejects.py b/tortoisehg/hgqt/rejects.py
--- a/tortoisehg/hgqt/rejects.py
+++ b/tortoisehg/hgqt/rejects.py
@@ -141,7 +141,7 @@
with open(path + b'.rej', 'rb') as fp:
buf.write(fp.read())
buf.seek(0)
- except IOError as e:
+ except OSError as e:
pass
try:
header = patch.parsepatch(buf)[0]
diff --git a/tortoisehg/hgqt/repofilter.py b/tortoisehg/hgqt/repofilter.py
--- a/tortoisehg/hgqt/repofilter.py
+++ b/tortoisehg/hgqt/repofilter.py
@@ -399,7 +399,7 @@
def saveSettings(self, s: QSettings) -> None:
try:
repoid = hglib.shortrepoid(self._repo)
- except EnvironmentError:
+ except OSError:
return
s.beginGroup('revset/' + repoid)
s.setValue('geom', self.entrydlg.saveGeometry())
diff --git a/tortoisehg/hgqt/reporegistry.py b/tortoisehg/hgqt/reporegistry.py
--- a/tortoisehg/hgqt/reporegistry.py
+++ b/tortoisehg/hgqt/reporegistry.py
@@ -759,7 +759,7 @@
hgsub.append(line)
else:
found = True
- except IOError:
+ except OSError:
qtlib.ErrorMsgBox(_('Could not open .hgsub file'),
_('Cannot read the .hgsub file.<p>'
'Subrepository removal failed.'),
@@ -789,7 +789,7 @@
'Remember that you must commit this .hgsub change in order '
'to complete the removal of the subrepository!'),
parent=self)
- except IOError:
+ except OSError:
qtlib.ErrorMsgBox(_('Could not update .hgsub file'),
_('Cannot update the .hgsub file.<p>'
'Subrepository removal failed.'),
diff --git a/tortoisehg/hgqt/repotreeitem.py b/tortoisehg/hgqt/repotreeitem.py
--- a/tortoisehg/hgqt/repotreeitem.py
+++ b/tortoisehg/hgqt/repotreeitem.py
@@ -457,7 +457,7 @@
self._valid = False
invalidRepoList += invalidSubrepoList

- except (EnvironmentError, error.RepoError, error.Abort) as e:
+ except (OSError, error.RepoError, error.Abort) as e:
# Add the repo to the list of repos/subrepos
# that could not be open
self._valid = False
diff --git a/tortoisehg/hgqt/repoview.py b/tortoisehg/hgqt/repoview.py
--- a/tortoisehg/hgqt/repoview.py
+++ b/tortoisehg/hgqt/repoview.py
@@ -486,7 +486,7 @@
key = '%s/column_widths/%s' % (self.cfgname,
hglib.shortrepoid(self.repo))
s.setValue(key, col_widths)
- except EnvironmentError:
+ except OSError:
pass

self._saveColumnSettings()
diff --git a/tortoisehg/hgqt/repowidget.py b/tortoisehg/hgqt/repowidget.py
--- a/tortoisehg/hgqt/repowidget.py
+++ b/tortoisehg/hgqt/repowidget.py
@@ -780,7 +780,7 @@
with hglib.extractpatch(self.repo.ui, pf) as data:
if data.get('filename'):
filepaths.append(p)
- except EnvironmentError:
+ except OSError:
pass
return filepaths

@@ -1043,7 +1043,7 @@
self.repo.thginvalidate()
self.rebuildGraph()
self.reloadTaskTab()
- except EnvironmentError as e:
+ except OSError as e:
self.showMessage(hglib.exception_str(e))

def rebuildGraph(self):
@@ -1144,7 +1144,7 @@
repoid = hglib.shortrepoid(self.repo)
s.setValue('repoWidget/splitter-' + repoid,
self.repotabs_splitter.saveState())
- except EnvironmentError:
+ except OSError:
pass
self.revDetailsWidget.saveSettings(s)
self.commitDemand.forward('saveSettings', s, 'workbench')
diff --git a/tortoisehg/hgqt/run.py b/tortoisehg/hgqt/run.py
--- a/tortoisehg/hgqt/run.py
+++ b/tortoisehg/hgqt/run.py
@@ -243,7 +243,7 @@
_linesutf8 = lines
else:
_lines = lines
- except IOError:
+ except OSError:
sys.stderr.write('can not read file %r. Ignored.\n' % filename)

def get_files_from_listfile():
@@ -414,7 +414,7 @@
try:
lui = ui.copy()
lui.readconfig(os.path.join(path, b".hg", b"hgrc"))
- except IOError:
+ except OSError:
pass
else:
lui = ui
diff --git a/tortoisehg/hgqt/serve.py b/tortoisehg/hgqt/serve.py
--- a/tortoisehg/hgqt/serve.py
+++ b/tortoisehg/hgqt/serve.py
@@ -275,7 +275,7 @@
base = hglib.shortreponame(lui) or os.path.basename(repopath)
c.set(b'paths', base,
_asconfigliststr(os.path.join(repopath, b'**')))
- except (EnvironmentError, error.Abort, error.RepoError):
+ except (OSError, error.Abort, error.RepoError):
c.set(b'paths', b'/', repopath)
return lui, c
else:
diff --git a/tortoisehg/hgqt/settings.py b/tortoisehg/hgqt/settings.py
--- a/tortoisehg/hgqt/settings.py
+++ b/tortoisehg/hgqt/settings.py
@@ -1780,7 +1780,7 @@
with open(fn, 'w') as f:
f.write('# Generated by TortoiseHg settings dialog\n')
break
- except (IOError, OSError):
+ except OSError:
pass
else:
qtlib.WarningMsgBox(_('Unable to create a Mercurial.ini file'),
@@ -1830,7 +1830,7 @@
try:
wconfig.writefile(self.ini, hglib.fromunicode(self.fn))
return True
- except EnvironmentError as e:
+ except OSError as e:
qtlib.WarningMsgBox(_('Unable to write configuration file'),
hglib.exception_str(e), parent=self)
return False
diff --git a/tortoisehg/hgqt/shelve.py b/tortoisehg/hgqt/shelve.py
--- a/tortoisehg/hgqt/shelve.py
+++ b/tortoisehg/hgqt/shelve.py
@@ -326,7 +326,7 @@
self.refreshCombos()
if shelfpath in self.shelves:
self.combob.setCurrentIndex(self.shelves.index(shelfpath))
- except EnvironmentError as e:
+ except OSError as e:
self.showMessage(hglib.exception_str(e))

@pyqtSlot()
@@ -339,7 +339,7 @@
try:
os.unlink(shelf)
self.showMessage(_('Shelf deleted'))
- except EnvironmentError as e:
+ except OSError as e:
self.showMessage(hglib.exception_str(e))
self.refreshCombos()

@@ -353,7 +353,7 @@
self.repo.ui.quiet = True
commands.revert(self.repo.ui, self.repo, all=True)
self.repo.ui.quiet = False
- except (EnvironmentError, error.Abort) as e:
+ except (OSError, error.Abort) as e:
self.showMessage(hglib.exception_str(e))
self.refreshCombos()
return
@@ -366,7 +366,7 @@
f = open(shelf, "w")
f.close()
self.showMessage(_('Shelf cleared'))
- except EnvironmentError as e:
+ except OSError as e:
self.showMessage(hglib.exception_str(e))
self.refreshCombos()

@@ -380,7 +380,7 @@
try:
os.unlink(shelf)
self.showMessage(_('Shelf deleted'))
- except EnvironmentError as e:
+ except OSError as e:
self.showMessage(hglib.exception_str(e))
self.refreshCombos()

@@ -395,7 +395,7 @@
f = open(shelf, "w")
f.close()
self.showMessage(_('Shelf cleared'))
- except EnvironmentError as e:
+ except OSError as e:
self.showMessage(hglib.exception_str(e))
self.refreshCombos()

diff --git a/tortoisehg/hgqt/status.py b/tortoisehg/hgqt/status.py
--- a/tortoisehg/hgqt/status.py
+++ b/tortoisehg/hgqt/status.py
@@ -769,7 +769,7 @@
for s in wctx.substate:
if wctx.sub(s).dirty():
wctx.dirtySubrepos.append(s)
- except EnvironmentError as e:
+ except OSError as e:
self.showMessage.emit(hglib.exception_str(e))
except (error.LookupError, error.RepoError, error.ConfigError) as e:
self.showMessage.emit(hglib.exception_str(e))
@@ -822,7 +822,7 @@
name, ext = os.path.splitext(fname)
sizebytes = wctx[fname].size()
sizek = (sizebytes + 1023) // 1024
- except EnvironmentError:
+ except OSError:
pass
return [fname, st, mst, hglib.tounicode(fname),
hglib.tounicode(ext[1:]), sizek]
diff --git a/tortoisehg/hgqt/sync.py b/tortoisehg/hgqt/sync.py
--- a/tortoisehg/hgqt/sync.py
+++ b/tortoisehg/hgqt/sync.py
@@ -1108,7 +1108,7 @@
try:
wconfig.writefile(cfg, fn)
self._repoagent.pollStatus()
- except EnvironmentError as e:
+ except OSError as e:
qtlib.WarningMsgBox(_('Unable to write configuration file'),
hglib.exception_str(e), parent=self)
self.reload()
@@ -1211,7 +1211,7 @@
self.autoresolve_chk.isChecked() and b'True' or b'False')
wconfig.writefile(cfg, fn)
self._repoagent.pollStatus()
- except EnvironmentError as e:
+ except OSError as e:
qtlib.WarningMsgBox(_('Unable to write configuration file'),
hglib.exception_str(e), parent=self)
super(PostPullDialog, self).accept()
@@ -1303,7 +1303,7 @@
cfg.remove(b'paths', self.origalias)
try:
wconfig.writefile(cfg, fn)
- except EnvironmentError as e:
+ except OSError as e:
qtlib.WarningMsgBox(_('Unable to write configuration file'),
hglib.exception_str(e), parent=self)
if self.updatesubpaths.isChecked():
@@ -1609,7 +1609,7 @@
try:
wconfig.writefile(cfg, fn)
self._repoagent.pollStatus()
- except EnvironmentError as e:
+ except OSError as e:
qtlib.WarningMsgBox(_('Unable to write configuration file'),
hglib.exception_str(e), parent=self)
super(SecureDialog, self).accept()
diff --git a/tortoisehg/hgqt/thgrepo.py b/tortoisehg/hgqt/thgrepo.py
--- a/tortoisehg/hgqt/thgrepo.py
+++ b/tortoisehg/hgqt/thgrepo.py
@@ -84,7 +84,7 @@
agent = RepoAgent(repo)
_repocache[path] = agent.rawRepo()
return agent.rawRepo()
- except EnvironmentError:
+ except OSError:
raise error.RepoError(b'Cannot open repository at %s' % path)
if not os.path.exists(os.path.join(path, b'.hg/')):
del _repocache[path]
@@ -305,7 +305,7 @@
# are needed an how ambiguity is resolved
st = os.stat(path)
curstats[path] = (st.st_size, st.st_ctime, st.st_mtime)
- except EnvironmentError:
+ except OSError:
pass

curdata = {}
@@ -317,7 +317,7 @@
if last != cur:
try:
curdata[readmeth] = readmeth(self)
- except EnvironmentError:
+ except OSError:
pass
elif cur is not None and readmeth in self._lastdata:
curdata[readmeth] = self._lastdata[readmeth]
@@ -357,7 +357,7 @@
self._ui.debug(b'config change detected\n')
self._uimtime = mtime
self.configChanged.emit()
- except (EnvironmentError, ValueError):
+ except (OSError, ValueError):
pass


@@ -974,7 +974,7 @@
def getModificationTime(x):
try:
return os.path.getmtime(os.path.join(sdir, x))
- except EnvironmentError:
+ except OSError:
return 0
shelves = sorted(os.listdir(sdir),
key=getModificationTime, reverse=True)
@@ -1126,7 +1126,7 @@
try:
patchpath = self._repo.mq.join(self.thgmqpatchname())
mqoriginalparent = mq.patchheader(patchpath).parent
- except EnvironmentError:
+ except OSError:
return ''
return mqoriginalparent

@@ -1171,7 +1171,7 @@
if cachedctx._mtime == os.path.getmtime(patchpath) and \
cachedctx._fsize == os.path.getsize(patchpath):
return cachedctx
- except EnvironmentError:
+ except OSError:
pass
# create a new context object
ctx = patchctx(patchpath, repo, rev=rev)
@@ -1189,7 +1189,7 @@
if isinstance(sub, subrepo.hgsubrepo):
for root, file, status in recursiveMergeStatus(sub._repo):
yield root, file, status
- except (EnvironmentError, error.Abort, error.RepoError):
+ except (OSError, error.Abort, error.RepoError):
pass

def relatedRepositories(repoid):
diff --git a/tortoisehg/hgqt/update.py b/tortoisehg/hgqt/update.py
--- a/tortoisehg/hgqt/update.py
+++ b/tortoisehg/hgqt/update.py
@@ -223,7 +223,7 @@
b'.hgsubstate' in new_ctx
self.path_combo_label.setVisible(showpathcombo)
self.path_combo.setVisible(showpathcombo)
- except (error.LookupError, error.RepoError, EnvironmentError):
+ except (error.LookupError, error.RepoError, OSError):
self.target_info.setText(_('unknown revision!'))
self.commandChanged.emit()

@@ -231,7 +231,7 @@
new_rev = hglib.fromunicode(self.rev_combo.currentText())
try:
new_ctx = hglib.revsymbol(self.repo, new_rev)
- except (error.LookupError, error.RepoError, EnvironmentError):
+ except (error.LookupError, error.RepoError, OSError):
return False

return (self.discard_chk.isChecked()
@@ -329,7 +329,7 @@
try:
node = self.repo.hgchangectx(
hglib.revsymbol(self.repo, hglib.fromunicode(rev)).rev())
- except (error.LookupError, error.RepoError, EnvironmentError):
+ except (error.LookupError, error.RepoError, OSError):
return cmdcore.nullCmdSession()
def isclean() -> bool:
'''whether WD is changed'''
@@ -340,7 +340,7 @@
for s in wc.substate:
if wc.sub(s).dirty():
return False
- except EnvironmentError:
+ except OSError:
return False
return True
def ismergedchange() -> bool:
diff --git a/tortoisehg/hgqt/visdiff.py b/tortoisehg/hgqt/visdiff.py
--- a/tortoisehg/hgqt/visdiff.py
+++ b/tortoisehg/hgqt/visdiff.py
@@ -181,7 +181,7 @@
else:
# Make file read/only, to indicate it's static (archival) nature
os.chmod(dest, stat.S_IREAD)
- except EnvironmentError:
+ except OSError:
pass
return base, fns_and_mtime

@@ -205,7 +205,7 @@
stdin=subprocess.PIPE)
if block:
proc.communicate()
- except (OSError, EnvironmentError) as e:
+ except OSError as e:
QMessageBox.warning(None,
_('Tool launch failure'),
_('%s : %s') % (hglib.tounicode(cmd), hglib.exception_str(e)))
@@ -474,7 +474,7 @@
b'Overwriting: %s (src: %s)\n'
% (working_fn, copy_fn))
util.copyfile(copy_fn, working_fn)
- except EnvironmentError:
+ except OSError:
pass # Ignore I/O errors or missing files

if mainapp:
diff --git a/tortoisehg/hgqt/wctxcleaner.py b/tortoisehg/hgqt/wctxcleaner.py
--- a/tortoisehg/hgqt/wctxcleaner.py
+++ b/tortoisehg/hgqt/wctxcleaner.py
@@ -61,7 +61,7 @@
try:
dirty = _checkchanged(self.repo) or unresolved
self.results = (dirty, len(wctx.parents()))
- except EnvironmentError:
+ except OSError:
self.results = (True, len(wctx.parents()))

def cancel(self):
diff --git a/tortoisehg/util/hglib.py b/tortoisehg/util/hglib.py
--- a/tortoisehg/util/hglib.py
+++ b/tortoisehg/util/hglib.py
@@ -351,7 +351,7 @@
opts = {'list': True}
mqmod.qqueue(ui, repo, None, **opts)
qqueues = tounicode(ui.popbuffer()).splitlines()
- except (error.Abort, EnvironmentError):
+ except (error.Abort, OSError):
qqueues = []
return qqueues

@@ -392,7 +392,7 @@
try:
args = repo.vfs(b'undo.desc', b'r').read().splitlines()
return tounicode(args[1]), int(args[0])
- except (IOError, IndexError, ValueError):
+ except (OSError, IndexError, ValueError):
pass
return '', len(repo)

diff --git a/tortoisehg/util/patchctx.py b/tortoisehg/util/patchctx.py
--- a/tortoisehg/util/patchctx.py
+++ b/tortoisehg/util/patchctx.py
@@ -62,7 +62,7 @@
self._fsize = os.path.getsize(patchpath)
ph = mq.patchheader(self._path)
self._ph = ph
- except EnvironmentError:
+ except OSError:
self._date = dateutil.makedate()
return

diff --git a/tortoisehg/util/shlib.py b/tortoisehg/util/shlib.py
--- a/tortoisehg/util/shlib.py
+++ b/tortoisehg/util/shlib.py
@@ -124,7 +124,7 @@
if f.readline() != b'':
# extra line in f, needs update
update = True
- except IOError:
+ except OSError:
update = True

if update:
@@ -147,7 +147,7 @@
return
try:
f_notify = open(notify, 'wb')
- except IOError:
+ except OSError:
return
try:
abspaths = [os.path.abspath(path) for path in paths if path]
diff --git a/tortoisehg/util/thgstatus.py b/tortoisehg/util/thgstatus.py
--- a/tortoisehg/util/thgstatus.py
+++ b/tortoisehg/util/thgstatus.py
@@ -52,7 +52,7 @@
with open(cachefilepath(repo), 'rb') as f:
for e in f:
_ui.status(b"%s %s\n" % (e[0:1], e[1:-1]))
- except IOError:
+ except OSError:
_ui.status(b"*no status*\n")
return


Matt Harbison

unread,
Feb 28, 2025, 5:14:33 PMFeb 28
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1736204127 18000
# Mon Jan 06 17:55:27 2025 -0500
# Branch stable
# Node ID 733225995a3bec00d946d388b25407866fabc52f
# Parent 44196db5303deec1858163ef4e598db098c0b5b5
# EXP-Topic pyupgrade
pyupgrade: run the `unpack_list_comprehension` fixer

This probably doesn't matter much, but it reduces the noise when running the
tool in the future. See hg 73ab542565e0.

diff --git a/win32/docdiff.py b/win32/docdiff.py
--- a/win32/docdiff.py
+++ b/win32/docdiff.py
@@ -62,10 +62,10 @@
print(sys.argv[0], '[local] [base] [other] [output]')
sys.exit(1)
elif len(args) == 2:
- local, other = [os.path.abspath(f) for f in args]
+ local, other = (os.path.abspath(f) for f in args)
_base, ext = os.path.splitext(local)
else:
- local, base, other, output = [os.path.abspath(f) for f in args]
+ local, base, other, output = (os.path.abspath(f) for f in args)
_base, ext = os.path.splitext(output)

if not ext or ext.lower()[1:] not in scripts.keys():

Matt Harbison

unread,
Feb 28, 2025, 5:14:40 PMFeb 28
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1736204334 18000
# Mon Jan 06 17:58:54 2025 -0500
# Branch stable
# Node ID 0770d6359945463045b2056b7642ed4af5d8b4c8
# Parent 733225995a3bec00d946d388b25407866fabc52f
# EXP-Topic pyupgrade
pyupgrade: modernize calls to superclass methods

This is the `legacy` fixer in `pyupgrade`, with the loop yielding the offset of
`yield` statements commented out. See hg 5cc8deb96b48.

diff --git a/contrib/thgdebugtools/core.py b/contrib/thgdebugtools/core.py
--- a/contrib/thgdebugtools/core.py
+++ b/contrib/thgdebugtools/core.py
@@ -91,7 +91,7 @@
def extsetup(ui):
class dbgqtrun(run.qtrun.__class__):
def _createdialog(self, dlgfunc, args, opts):
- dlg, reporoot = super(dbgqtrun, self)._createdialog(dlgfunc, args,
+ dlg, reporoot = super()._createdialog(dlgfunc, args,
opts)
if isinstance(dlg, QMainWindow):
m = dlg.menuBar().addMenu('&Debug')
diff --git a/contrib/thgdebugtools/dbgutil.py b/contrib/thgdebugtools/dbgutil.py
--- a/contrib/thgdebugtools/dbgutil.py
+++ b/contrib/thgdebugtools/dbgutil.py
@@ -26,7 +26,7 @@
"""Common helper methods for debug menu actions"""

def __init__(self, menu, parent=None):
- super(BaseMenuActions, self).__init__(parent)
+ super().__init__(parent)
self._setupMenu(menu) # must be implemented by sub class

def _findParentWidget(self):
diff --git a/contrib/thgdebugtools/widgets.py b/contrib/thgdebugtools/widgets.py
--- a/contrib/thgdebugtools/widgets.py
+++ b/contrib/thgdebugtools/widgets.py
@@ -105,7 +105,7 @@
triggered = pyqtSignal(object)

def __init__(self, menu, collect, parent=None):
- super(WidgetsFinder, self).__init__(parent)
+ super().__init__(parent)
self._menu = menu
self._menu.aboutToShow.connect(self.rebuild)
self._menu.triggered.connect(self._emitTriggered)
@@ -150,7 +150,7 @@
class GcInfoDialog(QDialog):

def __init__(self, parent=None):
- super(GcInfoDialog, self).__init__(parent)
+ super().__init__(parent)
self.setLayout(QVBoxLayout(self))
self._infoEdit = QTextBrowser(self)
self.layout().addWidget(self._infoEdit)
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -300,7 +300,7 @@
o = indenter.getIndenter()
o.level = 0
o.write('from tortoisehg.util.i18n import _')
- return super(_UICompiler, self).createToplevelWidget(classname,
+ return super().createToplevelWidget(classname,
widgetname)
compiler.UICompiler = _UICompiler

diff --git a/tests/delaylock.py b/tests/delaylock.py
--- a/tests/delaylock.py
+++ b/tests/delaylock.py
@@ -9,5 +9,5 @@
class delaylockrepo(repo.__class__):
def _lock(self, *args, **kwargs):
time.sleep(delay)
- return super(delaylockrepo, self)._lock(*args, **kwargs)
+ return super()._lock(*args, **kwargs)
repo.__class__ = delaylockrepo
diff --git a/tests/qt_cmdagent_test.py b/tests/qt_cmdagent_test.py
--- a/tests/qt_cmdagent_test.py
+++ b/tests/qt_cmdagent_test.py
@@ -32,7 +32,7 @@

class CmdWaiter(QObject):
def __init__(self, session):
- super(CmdWaiter, self).__init__()
+ super().__init__()
self._session = session
self._outputs = []
self._session.outputReceived.connect(self._captureOutput)
@@ -268,7 +268,7 @@

@classmethod
def setUpClass(cls):
- super(CmdAgentServerTest, cls).setUpClass()
+ super().setUpClass()
cls.hg.fwrite(b'testext.py',
b'from binascii import unhexlify\n'
b'from mercurial import registrar\n'
diff --git a/tortoisehg/hgqt/about.py b/tortoisehg/hgqt/about.py
--- a/tortoisehg/hgqt/about.py
+++ b/tortoisehg/hgqt/about.py
@@ -50,7 +50,7 @@
"""Dialog for showing info about TortoiseHg"""

def __init__(self, parent=None):
- super(AboutDialog, self).__init__(parent)
+ super().__init__(parent)

self.setWindowIcon(qtlib.geticon('thg'))
self.setWindowTitle(_('About'))
@@ -166,7 +166,7 @@
def closeEvent(self, event):
self._updatechecker.close()
self._writesettings()
- super(AboutDialog, self).closeEvent(event)
+ super().closeEvent(event)

def _readsettings(self):
s = QSettings()
@@ -180,7 +180,7 @@
class LicenseDialog(QDialog):
"""Dialog for showing the TortoiseHg license"""
def __init__(self, parent=None):
- super(LicenseDialog, self).__init__(parent)
+ super().__init__(parent)

self.setWindowIcon(qtlib.geticon('thg'))
self.setWindowTitle(_('License'))
@@ -212,7 +212,7 @@

def closeEvent(self, event):
self._writesettings()
- super(LicenseDialog, self).closeEvent(event)
+ super().closeEvent(event)

def _readsettings(self):
s = QSettings()
diff --git a/tortoisehg/hgqt/archive.py b/tortoisehg/hgqt/archive.py
--- a/tortoisehg/hgqt/archive.py
+++ b/tortoisehg/hgqt/archive.py
@@ -84,7 +84,7 @@
rev: Optional[Text],
parent: Optional[QWidget] = None,
minrev: Optional[Text] = None) -> None:
- super(ArchiveWidget, self).__init__(parent)
+ super().__init__(parent)
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
self._repoagent = repoagent
if not minrev:
diff --git a/tortoisehg/hgqt/backout.py b/tortoisehg/hgqt/backout.py
--- a/tortoisehg/hgqt/backout.py
+++ b/tortoisehg/hgqt/backout.py
@@ -78,7 +78,7 @@
repoagent: RepoAgent,
rev: int,
parent: Optional[QWidget] = None) -> None:
- super(BackoutDialog, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent
f = self.windowFlags()
self.setWindowFlags(f & ~Qt.WindowType.WindowContextHelpButtonHint)
@@ -138,18 +138,18 @@

def reject(self) -> None:
if self.currentPage().canExit():
- super(BackoutDialog, self).reject()
+ super().reject()

def done(self, r: int) -> None:
self._writeSettings()
- super(BackoutDialog, self).done(r)
+ super().done(r)


class BasePage(QWizardPage):
def __init__(self,
repoagent: RepoAgent,
parent: Optional[QWidget]) -> None:
- super(BasePage, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent

@property
@@ -186,7 +186,7 @@
backoutrev: int,
parentbackout: bool,
parent: Optional[QWidget]) -> None:
- super(SummaryPage, self).__init__(repoagent, parent)
+ super().__init__(repoagent, parent)
self._wctxcleaner = wctxcleaner.WctxCleaner(repoagent, self)
self._wctxcleaner.checkStarted.connect(self._onCheckStarted)
self._wctxcleaner.checkFinished.connect(self._onCheckFinished)
@@ -308,7 +308,7 @@
backoutrev: int,
parentbackout: bool,
parent: Optional[QWidget]) -> None:
- super(BackoutPage, self).__init__(repoagent, parent)
+ super().__init__(repoagent, parent)
self._backoutrev = backoutrev
self._parentbackout = parentbackout
self.backoutcomplete = False
@@ -391,7 +391,7 @@
backoutrev: int,
parentbackout: bool,
parent: Optional[QWidget]) -> None:
- super(CommitPage, self).__init__(repoagent, parent)
+ super().__init__(repoagent, parent)
self._backoutrev = backoutrev
self._parentbackout = parentbackout
self.commitComplete = False
@@ -595,7 +595,7 @@
def __init__(self,
repoagent: RepoAgent,
parent: Optional[QWidget]) -> None:
- super(ResultPage, self).__init__(repoagent, parent)
+ super().__init__(repoagent, parent)
self.setTitle(_('Finished'))
self.setSubTitle(' ')
self.setFinalPage(True)
diff --git a/tortoisehg/hgqt/bisect.py b/tortoisehg/hgqt/bisect.py
--- a/tortoisehg/hgqt/bisect.py
+++ b/tortoisehg/hgqt/bisect.py
@@ -41,7 +41,7 @@
newCandidate = pyqtSignal()

def __init__(self, repoagent, parent=None):
- super(BisectDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowTitle(_('Bisect - %s') % repoagent.displayName())
self.setWindowIcon(qtlib.geticon('hg-bisect'))
self.setWindowFlags(self.windowFlags()
diff --git a/tortoisehg/hgqt/blockmatcher.py b/tortoisehg/hgqt/blockmatcher.py
--- a/tortoisehg/hgqt/blockmatcher.py
+++ b/tortoisehg/hgqt/blockmatcher.py
@@ -152,11 +152,11 @@
self.setValue(value)

def mousePressEvent(self, event):
- super(BlockList, self).mousePressEvent(event)
+ super().mousePressEvent(event)
self.scrollToPos(event.y())

def mouseMoveEvent(self, event):
- super(BlockList, self).mouseMoveEvent(event)
+ super().mouseMoveEvent(event)
self.scrollToPos(event.y())

class BlockMatch(BlockList):
diff --git a/tortoisehg/hgqt/bookmark.py b/tortoisehg/hgqt/bookmark.py
--- a/tortoisehg/hgqt/bookmark.py
+++ b/tortoisehg/hgqt/bookmark.py
@@ -52,7 +52,7 @@
class BookmarkDialog(QDialog):

def __init__(self, repoagent, rev, parent=None):
- super(BookmarkDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowFlags(self.windowFlags() & \
~Qt.WindowType.WindowContextHelpButtonHint)
self._repoagent = repoagent
diff --git a/tortoisehg/hgqt/bugreport.py b/tortoisehg/hgqt/bugreport.py
--- a/tortoisehg/hgqt/bugreport.py
+++ b/tortoisehg/hgqt/bugreport.py
@@ -62,7 +62,7 @@
class BugReport(QDialog):

def __init__(self, opts, parent=None):
- super(BugReport, self).__init__(parent)
+ super().__init__(parent)

layout = QVBoxLayout()
self.setLayout(layout)
@@ -189,15 +189,15 @@

def closeEvent(self, event):
self._updatechecker.close()
- super(BugReport, self).closeEvent(event)
+ super().closeEvent(event)

def accept(self):
self._writesettings()
- super(BugReport, self).accept()
+ super().accept()

def reject(self):
self._writesettings()
- super(BugReport, self).reject()
+ super().reject()

def _readsettings(self):
s = QSettings()
@@ -210,7 +210,7 @@
class ExceptionMsgBox(QDialog):
"""Message box for recoverable exception"""
def __init__(self, main, text, opts, parent=None):
- super(ExceptionMsgBox, self).__init__(parent)
+ super().__init__(parent)
self.setWindowFlags(self.windowFlags() & ~Qt.WindowType.WindowContextHelpButtonHint)
self.setWindowTitle(_('TortoiseHg Error'))

diff --git a/tortoisehg/hgqt/chunks.py b/tortoisehg/hgqt/chunks.py
--- a/tortoisehg/hgqt/chunks.py
+++ b/tortoisehg/hgqt/chunks.py
@@ -525,7 +525,7 @@
QLabel.__init__(self, text, parent)

def sizeHint(self):
- return super(ElideLabel, self).sizeHint()
+ return super().sizeHint()

def paintEvent(self, event):
p = QPainter()
@@ -536,7 +536,7 @@
p.drawText(self.rect(), Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignRight |
Qt.TextFlag.TextSingleLine, elided)
else:
- super(ElideLabel, self).paintEvent(event)
+ super().paintEvent(event)

class DiffBrowser(QFrame):
"""diff browser"""
diff --git a/tortoisehg/hgqt/clone.py b/tortoisehg/hgqt/clone.py
--- a/tortoisehg/hgqt/clone.py
+++ b/tortoisehg/hgqt/clone.py
@@ -93,7 +93,7 @@
config: HgConfig,
cmdagent: cmdcore.CmdAgent,
parent: Optional[QWidget] = None) -> None:
- super(CloneWidget, self).__init__(parent)
+ super().__init__(parent)
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
self._config = config
self._cmdagent = cmdagent
@@ -406,7 +406,7 @@
ui: uimod.ui,
config: HgConfig,
parent: Optional[QWidget] = None) -> None:
- super(CloneDialog, self).__init__(parent)
+ super().__init__(parent)

self.setWindowTitle(_('Clone - %s') % hglib.getcwdu())
self.setWindowIcon(qtlib.geticon('hg-clone'))
@@ -454,4 +454,4 @@
if self._cmdagent.isServiceRunning():
self._cmdagent.stopService()
return # postponed until serviceStopped
- super(CloneDialog, self).done(r)
+ super().done(r)
diff --git a/tortoisehg/hgqt/close_branch.py b/tortoisehg/hgqt/close_branch.py
--- a/tortoisehg/hgqt/close_branch.py
+++ b/tortoisehg/hgqt/close_branch.py
@@ -45,7 +45,7 @@
repoagent: RepoAgent,
rev: int,
parent: Optional[QWidget] = None) -> None:
- super(CloseWidget, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent
self._repo = repoagent.rawRepo()
self._rev = rev
diff --git a/tortoisehg/hgqt/cmdcore.py b/tortoisehg/hgqt/cmdcore.py
--- a/tortoisehg/hgqt/cmdcore.py
+++ b/tortoisehg/hgqt/cmdcore.py
@@ -73,7 +73,7 @@
item: Union[bytes, Text] = b'',
unit: Union[bytes, Text] = b'',
total: Optional[int] = None) -> None:
- super(ProgressMessage, self).__init__((
+ super().__init__((
hglib.tounicode(topic),
pos,
hglib.tounicode(item),
@@ -264,7 +264,7 @@
ui: uimod.ui,
parent: Optional[QObject] = None,
cwd: Optional[Text] = None) -> None:
- super(CmdProc, self).__init__(parent)
+ super().__init__(parent)
self._ui = ui
self._uihandler = None
self._proc = proc = QProcess(self)
@@ -337,7 +337,7 @@
ui: uimod.ui,
parent: Optional[QObject] = None,
cwd: Optional[Text] = None) -> None:
- super(CmdServer, self).__init__(parent)
+ super().__init__(parent)
self._ui = ui
self._uihandler = UiHandler()
self._readchtable = self._idlechtable
@@ -640,7 +640,7 @@
cmdlines: List[List[Text]],
uihandler: UiHandler,
parent: Optional[QObject] = None) -> None:
- super(CmdSession, self).__init__(parent)
+ super().__init__(parent)
self._uihandler = uihandler
self._worker = None
self._queue = list(cmdlines)
@@ -874,7 +874,7 @@
parent: Optional[QObject] = None,
cwd: Optional[Text] = None,
worker: Optional[Text] = None) -> None:
- super(CmdAgent, self).__init__(parent)
+ super().__init__(parent)
self._ui = ui
self._worker = self._createWorker(cwd, worker or 'server')
self._sessqueue = [] # [active, waiting...]
diff --git a/tortoisehg/hgqt/cmdui.py b/tortoisehg/hgqt/cmdui.py
--- a/tortoisehg/hgqt/cmdui.py
+++ b/tortoisehg/hgqt/cmdui.py
@@ -64,7 +64,7 @@
class ProgressMonitor(QWidget):
'Progress bar for use in workbench status bar'
def __init__(self, topic, parent):
- super(ProgressMonitor, self).__init__(parent)
+ super().__init__(parent)

hbox = QHBoxLayout()
hbox.setContentsMargins(*(0,)*4)
@@ -222,7 +222,7 @@
"""Output log viewer"""

def __init__(self, parent=None):
- super(LogWidget, self).__init__(parent)
+ super().__init__(parent)
self.setReadOnly(True)
self.setUtf8(True)
self.setMarginWidth(1, 0)
@@ -286,7 +286,7 @@
if event.key() == Qt.Key.Key_Escape:
event.ignore()
return
- super(LogWidget, self).keyPressEvent(event)
+ super().keyPressEvent(event)


class InteractiveUiHandler(cmdcore.UiHandler):
@@ -294,7 +294,7 @@

# Unlike QObject, "uiparent" does not own this handler
def __init__(self, uiparent: Optional[QWidget] = None) -> None:
- super(InteractiveUiHandler, self).__init__()
+ super().__init__()
self._prompttext = ''
self._promptmode = cmdcore.UiHandler.NoInput
self._promptdefault = ''
@@ -381,7 +381,7 @@
# should know the running session.

def __init__(self, parent=None, logVisible=False):
- super(CmdSessionControlWidget, self).__init__(parent)
+ super().__init__(parent)

vbox = QVBoxLayout()
vbox.setSpacing(4)
@@ -545,7 +545,7 @@
commandFinished = pyqtSignal(int)

def __init__(self, parent=None):
- super(CmdControlDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowFlags(self.windowFlags()
& ~Qt.WindowType.WindowContextHelpButtonHint)

@@ -700,7 +700,7 @@
# should know the running session.

def __init__(self, parent=None):
- super(CmdSessionDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowFlags(self.windowFlags()
& ~Qt.WindowType.WindowContextHelpButtonHint)
self.setWindowTitle(_('TortoiseHg Command Dialog'))
diff --git a/tortoisehg/hgqt/compress.py b/tortoisehg/hgqt/compress.py
--- a/tortoisehg/hgqt/compress.py
+++ b/tortoisehg/hgqt/compress.py
@@ -34,7 +34,7 @@
class CompressDialog(QDialog):

def __init__(self, repoagent, revs, parent):
- super(CompressDialog, self).__init__(parent)
+ super().__init__(parent)
f = self.windowFlags()
self.setWindowFlags(f & ~Qt.WindowType.WindowContextHelpButtonHint)
self._repoagent = repoagent
diff --git a/tortoisehg/hgqt/cslist.py b/tortoisehg/hgqt/cslist.py
--- a/tortoisehg/hgqt/cslist.py
+++ b/tortoisehg/hgqt/cslist.py
@@ -39,7 +39,7 @@
class ChangesetList(QWidget):

def __init__(self, repo=None, parent=None):
- super(ChangesetList, self).__init__(parent)
+ super().__init__(parent)

self.currepo = repo
self.curitems = None
diff --git a/tortoisehg/hgqt/customtools.py b/tortoisehg/hgqt/customtools.py
--- a/tortoisehg/hgqt/customtools.py
+++ b/tortoisehg/hgqt/customtools.py
@@ -337,7 +337,7 @@
def __init__(
self, ini: "IniConfig", parent: Optional[QWidget]=None, **opts
) -> None:
- super(HooksFrame, self).__init__(parent, **opts)
+ super().__init__(parent, **opts)
self.ini = ini
# The frame is created empty, and will be populated on 'refresh',
# which usually happens when the frames is activated
@@ -778,7 +778,7 @@

def done(self, r: int) -> None:
self._writesettings()
- super(CustomConfigDialog, self).done(r)
+ super().done(r)


class CustomToolConfigDialog(CustomConfigDialog):
@@ -800,7 +800,7 @@
toolname: Optional[str] = None,
toolconfig: Optional[Dict[str, Union[str, bool]]] = None,
) -> None:
- super(CustomToolConfigDialog, self).__init__(parent,
+ super().__init__(parent,
dialogname='customtools',
windowTitle=_('Configure Custom Tool'),
windowIcon=qtlib.geticon(DEFAULTICONNAME))
@@ -1039,7 +1039,7 @@
command: str = '',
hookname: str = '',
) -> None:
- super(HookConfigDialog, self).__init__(parent,
+ super().__init__(parent,
dialogname='hookconfigdialog',
windowTitle=_('Configure Hook'),
windowIcon=qtlib.geticon('tools-hooks'))
diff --git a/tortoisehg/hgqt/docklog.py b/tortoisehg/hgqt/docklog.py
--- a/tortoisehg/hgqt/docklog.py
+++ b/tortoisehg/hgqt/docklog.py
@@ -56,7 +56,7 @@
_prompt = '% '

def __init__(self, parent=None):
- super(_LogWidgetForConsole, self).__init__(parent)
+ super().__init__(parent)
self._prompt_marker = self.markerDefine(QsciScintilla.MarkerSymbol.Background)
self.setMarkerBackgroundColor(QColor('#e8f3fe'), self._prompt_marker)
self.cursorPositionChanged.connect(self._updatePrompt)
@@ -88,7 +88,7 @@
# this clears it, if not, this moves the cursor to the prompt
self.setCommandText('')

- super(_LogWidgetForConsole, self).keyPressEvent(event)
+ super().keyPressEvent(event)

def setPrompt(self, text):
if text == self._prompt:
@@ -535,7 +535,7 @@
class LogDockWidget(QDockWidget):

def __init__(self, repomanager, cmdagent, parent=None):
- super(LogDockWidget, self).__init__(parent)
+ super().__init__(parent)

self.setFeatures(QDockWidget.DockWidgetFeature.DockWidgetClosable |
QDockWidget.DockWidgetFeature.DockWidgetMovable |
@@ -586,7 +586,7 @@
w.setParent(None)

def setVisible(self, visible):
- super(LogDockWidget, self).setVisible(visible)
+ super().setVisible(visible)
if visible:
self.raise_()

diff --git a/tortoisehg/hgqt/filectxactions.py b/tortoisehg/hgqt/filectxactions.py
--- a/tortoisehg/hgqt/filectxactions.py
+++ b/tortoisehg/hgqt/filectxactions.py
@@ -185,7 +185,7 @@
repoagent: "RepoAgent",
parent: QWidget,
) -> None:
- super(FilectxActions, self).__init__(parent)
+ super().__init__(parent)
if not isinstance(parent, QWidget):
raise ValueError('parent must be a QWidget')

diff --git a/tortoisehg/hgqt/filedata.py b/tortoisehg/hgqt/filedata.py
--- a/tortoisehg/hgqt/filedata.py
+++ b/tortoisehg/hgqt/filedata.py
@@ -259,7 +259,7 @@
rpath: Optional[bytes] = None,
mstatus: Optional[Text] = None,
) -> None:
- super(FileData, self).__init__(ctx, pctx, path, status, rpath)
+ super().__init__(ctx, pctx, path, status, rpath)
self._mstatus: Optional[Text] = mstatus

def load(self, changeselect: bool = False, force: bool = False) -> None:
@@ -651,7 +651,7 @@
rpath: Optional[bytes],
subkind: Text,
) -> None:
- super(SubrepoData, self).__init__(ctx, pctx, path, status, rpath)
+ super().__init__(ctx, pctx, path, status, rpath)
self._subkind = subkind

def createRebased(
diff --git a/tortoisehg/hgqt/filedialogs.py b/tortoisehg/hgqt/filedialogs.py
--- a/tortoisehg/hgqt/filedialogs.py
+++ b/tortoisehg/hgqt/filedialogs.py
@@ -115,7 +115,7 @@

class _FileDiffScintilla(Scintilla):
def paintEvent(self, event):
- super(_FileDiffScintilla, self).paintEvent(event)
+ super().paintEvent(event)
viewport = self.viewport()

start = self.firstVisibleLine()
@@ -211,13 +211,13 @@
A dialog showing a revision graph for a file.
"""
def __init__(self, repoagent, filename):
- super(FileLogDialog, self).__init__(repoagent, filename)
+ super().__init__(repoagent, filename)
self._readSettings()
self.revdetails = None

def closeEvent(self, event):
self._writeSettings()
- super(FileLogDialog, self).closeEvent(event)
+ super().closeEvent(event)

def _readSettings(self):
s = QSettings()
@@ -435,12 +435,12 @@
filedata: Dict[Text, List[str]]

def __init__(self, repoagent, filename):
- super(FileDiffDialog, self).__init__(repoagent, filename)
+ super().__init__(repoagent, filename)
self._readSettings()

def closeEvent(self, event):
self._writeSettings()
- super(FileDiffDialog, self).closeEvent(event)
+ super().closeEvent(event)

def _readSettings(self):
s = QSettings()
@@ -661,7 +661,7 @@
self._updateFileActionsForSelection(watched.selectionModel())
return False
else:
- return super(FileDiffDialog, self).eventFilter(watched, event)
+ return super().eventFilter(watched, event)

def onRevisionSelected(self, rev):
if rev is None or rev not in self.filerevmodel.graph.nodesdict:
diff --git a/tortoisehg/hgqt/fileview.py b/tortoisehg/hgqt/fileview.py
--- a/tortoisehg/hgqt/fileview.py
+++ b/tortoisehg/hgqt/fileview.py
@@ -736,7 +736,7 @@
chunkMarkersBuilt = pyqtSignal()

def __init__(self, sci, parent=None):
- super(_DiffViewControl, self).__init__(parent)
+ super().__init__(parent)
self._sci = sci
self._buildtimer = QTimer(self)
self._buildtimer.timeout.connect(self._buildMarker)
@@ -794,7 +794,7 @@
chunkMarkersBuilt = pyqtSignal()

def __init__(self, ui, sci, blk, parent=None):
- super(_FileViewControl, self).__init__(parent)
+ super().__init__(parent)
self._ui = ui
self._sci = sci
self._blk = blk
@@ -921,7 +921,7 @@
forceDisplayRequested = pyqtSignal()

def __init__(self, sci, parent=None):
- super(_MessageViewControl, self).__init__(parent)
+ super().__init__(parent)
self._sci = sci
self._forceviewindicator = None

@@ -980,7 +980,7 @@
visualDiffToLocalRequested = pyqtSignal(str, int)

def __init__(self, repoagent, sci, fd, parent=None):
- super(_AnnotateViewControl, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent
self._cmdsession = cmdcore.nullCmdSession()
self._sci = sci
@@ -1020,7 +1020,7 @@
line = self._sci.lineNearPoint(cast(QMouseEvent, event).pos())
self._emitRevisionHintAtLine(line)
return False
- return super(_AnnotateViewControl, self).eventFilter(watched, event)
+ return super().eventFilter(watched, event)

def _loadAnnotateSettings(self):
s = QSettings()
@@ -1312,7 +1312,7 @@
chunkSelectionChanged = pyqtSignal()

def __init__(self, sci, fd, parent=None):
- super(_ChunkSelectionViewControl, self).__init__(parent)
+ super().__init__(parent)
self._sci = sci
p = qtlib.getcheckboxpixmap(QStyle.StateFlag.State_On, QColor('#B0FFA0'), sci)
self._sci.markerDefine(p, _IncludedChunkStartMarker)
diff --git a/tortoisehg/hgqt/graft.py b/tortoisehg/hgqt/graft.py
--- a/tortoisehg/hgqt/graft.py
+++ b/tortoisehg/hgqt/graft.py
@@ -57,7 +57,7 @@
repoagent: RepoAgent,
parent: Optional[QWidget],
**opts) -> None:
- super(GraftDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowIcon(qtlib.geticon('hg-transplant'))
self.setWindowFlags(self.windowFlags()
& ~Qt.WindowType.WindowContextHelpButtonHint)
@@ -317,8 +317,8 @@
if not qtlib.QuestionMsgBox(_('Confirm Exit'), main, text,
labels=labels, parent=self):
return
- super(GraftDialog, self).reject()
+ super().reject()

def done(self, r: int) -> None:
self._writeSettings()
- super(GraftDialog, self).done(r)
+ super().done(r)
diff --git a/tortoisehg/hgqt/grep.py b/tortoisehg/hgqt/grep.py
--- a/tortoisehg/hgqt/grep.py
+++ b/tortoisehg/hgqt/grep.py
@@ -302,7 +302,7 @@
and self.thread and self.thread.isRunning()):
self.stopClicked()
else:
- return super(SearchWidget, self).keyPressEvent(event)
+ return super().keyPressEvent(event)

def canExit(self):
'Repowidget is closing, can we quit?'
@@ -422,7 +422,7 @@
progress = pyqtSignal(str, object, str, str, object)

def __init__(self, repo, pattern, icase, inc, exc, follow):
- super(HistorySearchThread, self).__init__()
+ super().__init__()
self.repo = hg.repository(repo.ui, repo.root)
self.pattern = pattern
self.icase = icase
@@ -499,7 +499,7 @@
progress = pyqtSignal(str, object, str, str, object)

def __init__(self, repo, regexp, ctx, inc, exc, once, recurse):
- super(CtxSearchThread, self).__init__()
+ super().__init__()
self.repo = hg.repository(repo.ui, repo.root)
self.regexp = regexp
self.ctx = ctx
@@ -844,7 +844,7 @@

class SearchDialog(QDialog):
def __init__(self, repoagent, upats, parent=None, **opts):
- super(SearchDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowFlags(Qt.WindowType.Window)
self.setWindowIcon(qtlib.geticon('view-filter'))
self.setWindowTitle(_('TortoiseHg Search'))
@@ -869,7 +869,7 @@
return

self._searchwidget.saveSettings(QSettings())
- super(SearchDialog, self).closeEvent(event)
+ super().closeEvent(event)

def setSearch(self, upattern, **opts):
self._searchwidget.setSearch(upattern, **opts)
diff --git a/tortoisehg/hgqt/guess.py b/tortoisehg/hgqt/guess.py
--- a/tortoisehg/hgqt/guess.py
+++ b/tortoisehg/hgqt/guess.py
@@ -458,7 +458,7 @@
showMessage = pyqtSignal(str)

def __init__(self, repo, ufiles, minpct, copies):
- super(RenameSearchThread, self).__init__()
+ super().__init__()
self.repo = hg.repository(hglib.loadui(), repo.root)
self.ufiles = ufiles
self.minpct = minpct
diff --git a/tortoisehg/hgqt/hgemail.py b/tortoisehg/hgqt/hgemail.py
--- a/tortoisehg/hgqt/hgemail.py
+++ b/tortoisehg/hgqt/hgemail.py
@@ -57,7 +57,7 @@
:outgoingrevs: Target revision of outgoing bundle.
(Passed as `hg email --bundle --rev {rev}`)
"""
- super(EmailDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowFlags(Qt.WindowType.Window)
self._repoagent = repoagent
self._cmdsession = cmdcore.nullCmdSession()
@@ -84,7 +84,7 @@

def closeEvent(self, event):
self._writesettings()
- super(EmailDialog, self).closeEvent(event)
+ super().closeEvent(event)

def _readsettings(self):
s = QSettings()
@@ -387,7 +387,7 @@
('description', lambda ctx: ctx.longsummary())]

def __init__(self, repo, revs, selectedrevs, parent=None):
- super(_ChangesetsModel, self).__init__(parent)
+ super().__init__(parent)
self._repo = repo
self._revs = list(reversed(sorted(revs)))
self._selectedrevs = set(selectedrevs)
@@ -443,7 +443,7 @@
self._readonly = readonly

def flags(self, index):
- v = super(_ChangesetsModel, self).flags(index)
+ v = super().flags(index)
if index.column() == 0 and not self._readonly:
return Qt.ItemFlag.ItemIsUserCheckable | v
else:
diff --git a/tortoisehg/hgqt/hginit.py b/tortoisehg/hgqt/hginit.py
--- a/tortoisehg/hgqt/hginit.py
+++ b/tortoisehg/hgqt/hginit.py
@@ -54,7 +54,7 @@
cmdagent: cmdcore.CmdAgent,
destdir: Text = '.',
parent: Optional[QWidget] = None) -> None:
- super(InitWidget, self).__init__(parent)
+ super().__init__(parent)
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
self._cmdagent = cmdagent

@@ -146,7 +146,7 @@
ui: uimod.ui,
destdir: Text = '.',
parent: Optional[QWidget] = None) -> None:
- super(InitDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowTitle(_('New Repository'))
self.setWindowIcon(qtlib.geticon('hg-init'))
self.setObjectName('init')
@@ -169,4 +169,4 @@
if self._cmdagent.isServiceRunning():
self._cmdagent.stopService()
return # postponed until serviceStopped
- super(InitDialog, self).done(r)
+ super().done(r)
diff --git a/tortoisehg/hgqt/htmlui.py b/tortoisehg/hgqt/htmlui.py
--- a/tortoisehg/hgqt/htmlui.py
+++ b/tortoisehg/hgqt/htmlui.py
@@ -21,20 +21,20 @@

class htmlui(ui_mod.ui):
def __init__(self, src=None):
- super(htmlui, self).__init__(src)
+ super().__init__(src)
self.setconfig(b'ui', b'interactive', b'off')
self.setconfig(b'progress', b'disable', b'True')
self.output, self.error = [], []

def write(self, *args, **opts):
if self._buffers:
- return super(htmlui, self).write(*args, **opts)
+ return super().write(*args, **opts)
label = opts.get('label', b'')
self.output.extend(self.smartlabel(b''.join(args), label))

def write_err(self, *args, **opts):
if self._buffers:
- return super(htmlui, self).write_err(*args, **opts)
+ return super().write_err(*args, **opts)
label = opts.get('label', b'ui.error')
self.error.extend(self.smartlabel(b''.join(args), label))

@@ -45,7 +45,7 @@
find it later when it is passed to smartlabel through ui.write()
'''
if self._buffers:
- return super(htmlui, self).label(msg, label)
+ return super().label(msg, label)
return BEGINTAG + self.style(msg, label) + ENDTAG

def style(self, msg, label):
diff --git a/tortoisehg/hgqt/infobar.py b/tortoisehg/hgqt/infobar.py
--- a/tortoisehg/hgqt/infobar.py
+++ b/tortoisehg/hgqt/infobar.py
@@ -118,7 +118,7 @@
}

def __init__(self, parent=None):
- super(InfoBar, self).__init__(parent, frameShape=QFrame.Shape.StyledPanel,
+ super().__init__(parent, frameShape=QFrame.Shape.StyledPanel,
frameShadow=QFrame.Shadow.Plain)
self.setAutoFillBackground(True)
p = self.palette()
@@ -146,17 +146,17 @@
def closeEvent(self, event):
if self.isVisible():
self.finished.emit(0)
- super(InfoBar, self).closeEvent(event)
+ super().closeEvent(event)

def keyPressEvent(self, event):
if event.key() == Qt.Key.Key_Escape:
self.close()
- super(InfoBar, self).keyPressEvent(event)
+ super().keyPressEvent(event)

def heightForWidth(self, width):
# loosely based on the internal strategy of QBoxLayout
if self.layout().hasHeightForWidth():
- return super(InfoBar, self).heightForWidth(width)
+ return super().heightForWidth(width)
else:
return self.sizeHint().height()

@@ -165,7 +165,7 @@
"""Show status message"""

def __init__(self, message, parent=None):
- super(StatusInfoBar, self).__init__(parent)
+ super().__init__(parent)
self._msglabel = QLabel(message, self,
wordWrap=True,
textInteractionFlags=Qt.TextInteractionFlag.TextSelectableByMouse \
@@ -180,7 +180,7 @@
infobartype = ERROR

def __init__(self, message, parent=None):
- super(CommandErrorInfoBar, self).__init__(parent)
+ super().__init__(parent)

self._msglabel = QLabel(message, self,
wordWrap=True,
@@ -202,7 +202,7 @@
infobartype = CONFIRM

def __init__(self, message, parent=None):
- super(ConfirmInfoBar, self).__init__(parent)
+ super().__init__(parent)

# no wordWrap=True and stretch=1, which inserts unwanted space
# between _msglabel and _buttons.
@@ -228,7 +228,7 @@
self.finished.emit(1)
self.rejected.emit()
self.hide() # avoid double emission of finished signal
- super(ConfirmInfoBar, self).closeEvent(event)
+ super().closeEvent(event)

@pyqtSlot()
def _accept(self):
@@ -251,7 +251,7 @@
linkActivated = pyqtSignal(str)

def __init__(self, repoagent, parent=None):
- super(InfoBarPlaceholder, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent
lay = QVBoxLayout()
lay.setSpacing(0)
@@ -361,7 +361,7 @@
self.layout().setContentsMargins(0, max(cmy, 0), 0, 0)

def resizeEvent(self, event):
- super(InfoBarPlaceholder, self).resizeEvent(event)
+ super().resizeEvent(event)
self._updateInfoBarGeometry()

@pyqtSlot(str)
diff --git a/tortoisehg/hgqt/lexers.py b/tortoisehg/hgqt/lexers.py
--- a/tortoisehg/hgqt/lexers.py
+++ b/tortoisehg/hgqt/lexers.py
@@ -78,7 +78,7 @@
regex = None
headersize = 3
def match(self, filename, filedata):
- if super(_ScriptLexerSelector, self).match(filename, filedata):
+ if super().match(filename, filedata):
return True
if self.regex and filedata:
for line in filedata.splitlines()[:self.headersize]:
@@ -113,7 +113,7 @@

class _LexerCPP(Qsci.QsciLexerCPP):
def refreshProperties(self):
- super(_LexerCPP, self).refreshProperties()
+ super().refreshProperties()
# disable grey-out of inactive block, which is hard to read.
# as of QScintilla 2.7.2, this property isn't mapped to wrapper.
self.propertyChanged.emit(b'lexer.cpp.track.preprocessor', b'0')
diff --git a/tortoisehg/hgqt/locktool.py b/tortoisehg/hgqt/locktool.py
--- a/tortoisehg/hgqt/locktool.py
+++ b/tortoisehg/hgqt/locktool.py
@@ -264,4 +264,4 @@
elif event.key() == Qt.Key.Key_Escape and not sess.isFinished():
sess.abort()
else:
- return super(LockDialog, self).keyPressEvent(event)
+ return super().keyPressEvent(event)
diff --git a/tortoisehg/hgqt/manifestmodel.py b/tortoisehg/hgqt/manifestmodel.py
--- a/tortoisehg/hgqt/manifestmodel.py
+++ b/tortoisehg/hgqt/manifestmodel.py
@@ -249,7 +249,7 @@
return ['text/uri-list']

def flags(self, index: QModelIndex) -> Qt_ItemFlags:
- f = super(ManifestModel, self).flags(index)
+ f = super().flags(index)
if not index.isValid():
return f
if not (self.isDir(index) or self.fileStatus(index) == 'R'
diff --git a/tortoisehg/hgqt/matching.py b/tortoisehg/hgqt/matching.py
--- a/tortoisehg/hgqt/matching.py
+++ b/tortoisehg/hgqt/matching.py
@@ -40,7 +40,7 @@
class MatchDialog(QDialog):

def __init__(self, repoagent, rev=None, parent=None):
- super(MatchDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowFlags(self.windowFlags() & \
~Qt.WindowType.WindowContextHelpButtonHint)

diff --git a/tortoisehg/hgqt/merge.py b/tortoisehg/hgqt/merge.py
--- a/tortoisehg/hgqt/merge.py
+++ b/tortoisehg/hgqt/merge.py
@@ -54,7 +54,7 @@
class MergeDialog(QWizard):

def __init__(self, repoagent, otherrev, parent=None):
- super(MergeDialog, self).__init__(parent)
+ super().__init__(parent)
assert isinstance(otherrev, int), repr(otherrev)
self._repoagent = repoagent
f = self.windowFlags()
@@ -119,16 +119,16 @@

def reject(self):
if self.currentPage().canExit():
- super(MergeDialog, self).reject()
+ super().reject()

def done(self, r):
self._writeSettings()
- super(MergeDialog, self).done(r)
+ super().done(r)


class BasePage(QWizardPage):
def __init__(self, repoagent, parent):
- super(BasePage, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent

@property
@@ -172,7 +172,7 @@
refreshFinished = pyqtSignal()

def __init__(self, repoagent, otherrev, parent):
- super(SummaryPage, self).__init__(repoagent, parent)
+ super().__init__(repoagent, parent)
self._wctxcleaner = wctxcleaner.WctxCleaner(repoagent, self)
self._wctxcleaner.checkStarted.connect(self._onCheckStarted)
self._wctxcleaner.checkFinished.connect(self._onCheckFinished)
@@ -286,7 +286,7 @@
% (self.otherCsInfo.get_data('revid')),
labels=labels, parent=self):
return False
- return super(SummaryPage, self).validatePage()
+ return super().validatePage()

## custom methods ##

@@ -302,7 +302,7 @@
return True

def currentPage(self):
- super(SummaryPage, self).currentPage()
+ super().currentPage()
self.refresh()

def refresh(self):
@@ -339,7 +339,7 @@

class MergePage(BasePage):
def __init__(self, repoagent, otherrev, parent):
- super(MergePage, self).__init__(repoagent, parent)
+ super().__init__(repoagent, parent)
self._otherrev = otherrev
self.mergecomplete = False

@@ -363,7 +363,7 @@
self.layout().addWidget(autonext)

def currentPage(self):
- super(MergePage, self).currentPage()
+ super().currentPage()
if len(self.repo[None].parents()) > 1:
self.mergecomplete = True
self.completeChanged.emit()
@@ -452,7 +452,7 @@
class CommitPage(BasePage):

def __init__(self, repoagent, parent):
- super(CommitPage, self).__init__(repoagent, parent)
+ super().__init__(repoagent, parent)

self.setTitle(_('Commit merge results'))
self.setSubTitle(' ')
@@ -580,7 +580,7 @@
self.msgEntry.saveSettings(s, 'merge/message')

def currentPage(self):
- super(CommitPage, self).currentPage()
+ super().currentPage()
self.wizard().setOption(QWizard.WizardOption.NoDefaultButton, True)
self.mergeCsInfo.updateItems() # show post-merge state

@@ -672,7 +672,7 @@

class ResultPage(BasePage):
def __init__(self, repoagent, parent):
- super(ResultPage, self).__init__(repoagent, parent)
+ super().__init__(repoagent, parent)
self.setTitle(_('Finished'))
self.setSubTitle(' ')
self.setFinalPage(True)
@@ -686,6 +686,6 @@
self.layout().addStretch(1)

def currentPage(self):
- super(ResultPage, self).currentPage()
+ super().currentPage()
self.mergeCsInfo.updateItems(self.repo[b'tip'])
self.wizard().setOption(QWizard.WizardOption.NoCancelButton, True)
diff --git a/tortoisehg/hgqt/messageentry.py b/tortoisehg/hgqt/messageentry.py
--- a/tortoisehg/hgqt/messageentry.py
+++ b/tortoisehg/hgqt/messageentry.py
@@ -40,7 +40,7 @@
class MessageEntry(qscilib.Scintilla):

def __init__(self, parent, getCheckedFunc=None):
- super(MessageEntry, self).__init__(parent)
+ super().__init__(parent)
self.setEdgeColor(QColor('LightSalmon'))
self.setEdgeMode(QsciScintilla.EdgeMode.EdgeLine)
self.setReadOnly(False)
@@ -69,7 +69,7 @@
self._re_boundary = re.compile(r'[0-9i#]+\.|\(?[0-9i#]+\)|\(@\)')

def setText(self, text):
- result = super(MessageEntry, self).setText(text)
+ result = super().setText(text)
self.setDefaultEolMode()
return result

@@ -270,13 +270,13 @@
line, col = self.getCursorPosition()
self.reflowBlock(line)
else:
- super(MessageEntry, self).keyPressEvent(event)
+ super().keyPressEvent(event)

def resizeEvent(self, event):
- super(MessageEntry, self).resizeEvent(event)
+ super().resizeEvent(event)
self.showHScrollBar(self.frameGeometry().height() > self.fontHeight * 3)

def minimumSizeHint(self):
- size = super(MessageEntry, self).minimumSizeHint()
+ size = super().minimumSizeHint()
size.setHeight(self.fontHeight * 3 // 2)
return size
diff --git a/tortoisehg/hgqt/mq.py b/tortoisehg/hgqt/mq.py
--- a/tortoisehg/hgqt/mq.py
+++ b/tortoisehg/hgqt/mq.py
@@ -94,7 +94,7 @@
"""Container for patch queue management actions"""

def __init__(self, parent=None):
- super(QueueManagementActions, self).__init__(parent)
+ super().__init__(parent)
assert parent is None or isinstance(parent, QWidget), repr(parent)
self._repoagent = None
self._cmdsession = cmdcore.nullCmdSession()
@@ -279,7 +279,7 @@
"""Container for MQ patch actions except for queue management"""

def __init__(self, parent=None):
- super(PatchQueueActions, self).__init__(parent)
+ super().__init__(parent)
assert parent is None or isinstance(parent, QWidget), repr(parent)
self._repoagent = None
self._cmdsession = cmdcore.nullCmdSession()
@@ -414,7 +414,7 @@
"""List of all patches in active queue"""

def __init__(self, repoagent, parent=None):
- super(PatchQueueModel, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent
self._repoagent.repositoryChanged.connect(self._updateCache)
self._series = []
@@ -489,7 +489,7 @@
return self._toolTip(index)

def flags(self, index):
- flags = super(PatchQueueModel, self).flags(index)
+ flags = super().flags(index)
if not index.isValid():
return flags | Qt.ItemFlag.ItemIsDropEnabled # insertion point
patch = self._series[index.row()]
@@ -955,7 +955,7 @@
self._patchActions.abort()
self._qqueueActions.abort()
else:
- return super(MQPatchesWidget, self).keyPressEvent(event)
+ return super().keyPressEvent(event)


class OptionsDialog(QDialog):
diff --git a/tortoisehg/hgqt/p4pending.py b/tortoisehg/hgqt/p4pending.py
--- a/tortoisehg/hgqt/p4pending.py
+++ b/tortoisehg/hgqt/p4pending.py
@@ -133,4 +133,4 @@
else:
self.reject()
else:
- return super(PerforcePending, self).keyPressEvent(event)
+ return super().keyPressEvent(event)
diff --git a/tortoisehg/hgqt/phabreview.py b/tortoisehg/hgqt/phabreview.py
--- a/tortoisehg/hgqt/phabreview.py
+++ b/tortoisehg/hgqt/phabreview.py
@@ -102,7 +102,7 @@

:revs: List of revisions to be sent.
"""
- super(PhabReviewDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowFlags(Qt.WindowType.Window)
self._repoagent = repoagent
self._cmdsession = cmdcore.nullCmdSession()
@@ -157,7 +157,7 @@

def closeEvent(self, event):
self._writesettings()
- super(PhabReviewDialog, self).closeEvent(event)
+ super().closeEvent(event)

def _readsettings(self) -> None:
s = QSettings()
diff --git a/tortoisehg/hgqt/pick.py b/tortoisehg/hgqt/pick.py
--- a/tortoisehg/hgqt/pick.py
+++ b/tortoisehg/hgqt/pick.py
@@ -54,7 +54,7 @@
repoagent: RepoAgent,
parent: Optional[QWidget],
**opts) -> None:
- super(PickDialog, self).__init__(parent)
+ super().__init__(parent)

# TODO: self.setWindowIcon(qtlib.geticon('hg-pick'))
self.setWindowFlags(self.windowFlags()
@@ -269,8 +269,8 @@
if not qtlib.QuestionMsgBox(_('Confirm Exit'), main, text,
labels=labels, parent=self):
return
- super(PickDialog, self).reject()
+ super().reject()

def done(self, r: int) -> None:
self._writeSettings()
- super(PickDialog, self).done(r)
+ super().done(r)
diff --git a/tortoisehg/hgqt/postreview.py b/tortoisehg/hgqt/postreview.py
--- a/tortoisehg/hgqt/postreview.py
+++ b/tortoisehg/hgqt/postreview.py
@@ -72,7 +72,7 @@

class LoadReviewDataThread(QThread):
def __init__ (self, dialog: "PostReviewDialog") -> None:
- super(LoadReviewDataThread, self).__init__(dialog)
+ super().__init__(dialog)
self.dialog = dialog

def run(self) -> None:
@@ -136,7 +136,7 @@
repoagent: RepoAgent,
revs: Sequence[Union[bytes, int]],
parent: Optional[QWidget] = None) -> None:
- super(PostReviewDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowFlags(self.windowFlags() & ~Qt.WindowType.WindowContextHelpButtonHint)
self.ui = ui
self._repoagent = repoagent
@@ -196,7 +196,7 @@
self.review_thread.wait()

self.writeSettings()
- super(PostReviewDialog, self).closeEvent(event)
+ super().closeEvent(event)

def readSettings(self) -> None:
s = QSettings()
@@ -362,7 +362,7 @@
self.qui.changesets_view.setEnabled(True)

def close(self) -> None:
- super(PostReviewDialog, self).close()
+ super().close()

def accept(self) -> None:
if not self.isValid():
@@ -435,7 +435,7 @@
_('Error'), hglib.tounicode(error))

self.writeSettings()
- super(PostReviewDialog, self).accept()
+ super().accept()

@pyqtSlot(str, str)
def _captureOutput(self, msg: Text, label: Text) -> None:
diff --git a/tortoisehg/hgqt/prune.py b/tortoisehg/hgqt/prune.py
--- a/tortoisehg/hgqt/prune.py
+++ b/tortoisehg/hgqt/prune.py
@@ -50,7 +50,7 @@
def __init__(self,
repoagent: RepoAgent,
parent: Optional[QWidget] = None) -> None:
- super(PruneWidget, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent

self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
diff --git a/tortoisehg/hgqt/purge.py b/tortoisehg/hgqt/purge.py
--- a/tortoisehg/hgqt/purge.py
+++ b/tortoisehg/hgqt/purge.py
@@ -179,7 +179,7 @@
return
s = QSettings()
s.setValue('purge/geom', self.saveGeometry())
- super(PurgeDialog, self).reject()
+ super().reject()

def accept(self):
unknown = self.ucb.isChecked()
@@ -222,7 +222,7 @@
showMessage = pyqtSignal(str)

def __init__(self, repo, opts, parent):
- super(PurgeThread, self).__init__(parent)
+ super().__init__(parent)
self.failures = 0
self.root = repo.root
self.opts = opts
diff --git a/tortoisehg/hgqt/qdelete.py b/tortoisehg/hgqt/qdelete.py
--- a/tortoisehg/hgqt/qdelete.py
+++ b/tortoisehg/hgqt/qdelete.py
@@ -25,7 +25,7 @@
class QDeleteDialog(QDialog):

def __init__(self, patches, parent):
- super(QDeleteDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowTitle(_('Delete Patches'))
self.setWindowIcon(qtlib.geticon('hg-qdelete'))
self.setWindowFlags(self.windowFlags()
@@ -61,7 +61,7 @@

def accept(self):
self._writeSettings()
- super(QDeleteDialog, self).accept()
+ super().accept()

def options(self):
return {'keep': self._keepchk.isChecked()}
diff --git a/tortoisehg/hgqt/qfold.py b/tortoisehg/hgqt/qfold.py
--- a/tortoisehg/hgqt/qfold.py
+++ b/tortoisehg/hgqt/qfold.py
@@ -47,7 +47,7 @@
class QFoldDialog(QDialog):

def __init__(self, repoagent, patches, parent):
- super(QFoldDialog, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent
self.setWindowTitle(_('Patch fold - %s') % repoagent.displayName())
self.setWindowIcon(qtlib.geticon('hg-qfold'))
@@ -164,7 +164,7 @@

def closeEvent(self, event):
self._writesettings()
- super(QFoldDialog, self).closeEvent(event)
+ super().closeEvent(event)

def _readsettings(self):
s = QSettings()
diff --git a/tortoisehg/hgqt/qscilib.py b/tortoisehg/hgqt/qscilib.py
--- a/tortoisehg/hgqt/qscilib.py
+++ b/tortoisehg/hgqt/qscilib.py
@@ -159,7 +159,7 @@
# editing position goes wrong. So we sticks to our version.
if True:
def __init__(self, parent=None):
- super(ScintillaCompat, self).__init__(parent)
+ super().__init__(parent)
self._imsupport = _SciImSupport(self)

def inputMethodQuery(self, query):
@@ -173,7 +173,7 @@
0, p)
w = self.SendScintilla(QsciScintilla.SCI_GETCARETWIDTH)
return QRect(x, y, w, self.textHeight(l))
- return super(ScintillaCompat, self).inputMethodQuery(query)
+ return super().inputMethodQuery(query)

def inputMethodEvent(self, event):
if self.isReadOnly():
@@ -197,7 +197,7 @@
def keyPressEvent(self, event):
if event.key() == Qt.Key.Key_Backtab:
event = QKeyEvent(event.type(), Qt.Key.Key_Tab, Qt.KeyboardModifier.ShiftModifier)
- super(ScintillaCompat, self).keyPressEvent(event)
+ super().keyPressEvent(event)

if not hasattr(QsciScintilla, 'createStandardContextMenu'):
def createStandardContextMenu(self):
@@ -280,7 +280,7 @@
"""Scintilla widget for rich file view or editor"""

def __init__(self, parent=None):
- super(Scintilla, self).__init__(parent)
+ super().__init__(parent)
self.autoUseTabs = True
self.setUtf8(True)
self.setWrapVisualFlags(QsciScintilla.WrapVisualFlag.WrapFlagByBorder)
@@ -522,7 +522,7 @@
self.autoUseTabs = (tabs == -1)
if self.autoUseTabs and self.lines():
tabs = findTabIndentsInLines(self.text().splitlines())
- super(Scintilla, self).setIndentationsUseTabs(tabs)
+ super().setIndentationsUseTabs(tabs)

@pyqtSlot(bool)
def _setAutoCompletionEnabled(self, enabled):
@@ -547,7 +547,7 @@
"""Emitted (pattern, icase, wrap, forward) when requested"""

def __init__(self, parent=None):
- super(SearchToolBar, self).__init__(_('Search'), parent,
+ super().__init__(_('Search'), parent,
objectName='search')
self.setIconSize(qtlib.smallIconSize())

@@ -597,7 +597,7 @@
def keyPressEvent(self, event):
if event.key() in (Qt.Key.Key_Enter, Qt.Key.Key_Return):
return # handled by returnPressed
- super(SearchToolBar, self).keyPressEvent(event)
+ super().keyPressEvent(event)

def wheelEvent(self, event):
if QT_VERSION >= 0x50000:
@@ -610,10 +610,10 @@
if d < 0:
self._nextact.trigger()
return
- super(SearchToolBar, self).wheelEvent(event)
+ super().wheelEvent(event)

def setVisible(self, visible=True):
- super(SearchToolBar, self).setVisible(visible)
+ super().setVisible(visible)
if visible:
self._le.setFocus()
self._le.selectAll()
@@ -685,7 +685,7 @@
"""

def __init__(self, parent=None, keys=None, keyseqs=None):
- super(KeyPressInterceptor, self).__init__(parent)
+ super().__init__(parent)
self._keys = {Qt.Key.Key_Escape}
self._keyseqs = [QKeySequence.StandardKey.Refresh]
if keys:
@@ -695,7 +695,7 @@

def eventFilter(self, watched, event):
if event.type() != QEvent.Type.KeyPress:
- return super(KeyPressInterceptor, self).eventFilter(
+ return super().eventFilter(
watched, event)
if self._isinterceptable(event):
event.ignore()
diff --git a/tortoisehg/hgqt/qtapp.py b/tortoisehg/hgqt/qtapp.py
--- a/tortoisehg/hgqt/qtapp.py
+++ b/tortoisehg/hgqt/qtapp.py
@@ -140,7 +140,7 @@
_exceptionOccured = pyqtSignal(object, object, object)

def __init__(self, ui, mainapp, parent=None):
- super(ExceptionCatcher, self).__init__(parent)
+ super().__init__(parent)
self._ui = ui
self._mainapp = mainapp
self.errors = []
@@ -478,7 +478,7 @@
"""

def __init__(self):
- super(QtRunner, self).__init__()
+ super().__init__()
self._ui = None
self._config = None
self._mainapp = None
diff --git a/tortoisehg/hgqt/qtlib.py b/tortoisehg/hgqt/qtlib.py
--- a/tortoisehg/hgqt/qtlib.py
+++ b/tortoisehg/hgqt/qtlib.py
@@ -954,7 +954,7 @@
for k, btn in self.hotkeys.items():
if event.text() == k:
btn.clicked.emit(False)
- super(CustomPrompt, self).keyPressEvent(event)
+ super().keyPressEvent(event)

class ChoicePrompt(QDialog):
def __init__(self,
@@ -1052,13 +1052,13 @@
"""

def __init__(self, parent: QComboBox) -> None:
- super(BadCompletionBlocker, self).__init__(parent)
+ super().__init__(parent)
if not isinstance(parent, QComboBox):
raise ValueError('invalid object to watch: %r' % parent)

def eventFilter(self, watched: QObject, event: QEvent) -> bool:
if watched is not self.parent():
- return super(BadCompletionBlocker, self).eventFilter(watched, event)
+ return super().eventFilter(watched, event)
if (event.type() != QEvent.Type.KeyPress
or cast(QKeyEvent, event).key() not in (Qt.Key.Key_Enter, Qt.Key.Key_Return)
or not watched.isEditable()):
@@ -1073,7 +1073,7 @@
"""Button which properties are defined by QAction like QToolButton"""

def __init__(self, action: QAction, parent: Optional[QWidget] = None):
- super(ActionPushButton, self).__init__(parent)
+ super().__init__(parent)
self.setAutoDefault(False) # action won't be used as dialog default
self._defaultAction = action
self.addAction(action)
@@ -1084,7 +1084,7 @@
if (event.type() == QEvent.Type.ActionChanged
and event.action() is self._defaultAction):
self._copyActionProps()
- super(ActionPushButton, self).actionEvent(event)
+ super().actionEvent(event)

def _copyActionProps(self) -> None:
action = self._defaultAction
@@ -1390,7 +1390,7 @@
genkey: Optional[Callable[..., Hashable]] = None,
parent: Optional[QObject] = None
) -> None:
- super(DialogKeeper, self).__init__(parent)
+ super().__init__(parent)
self._createdlg: Callable[..., _W] = createdlg
self._genkey = genkey or DialogKeeper._defaultgenkey
self._keytodlgs = {} # key: [dlg, ...]
@@ -1466,7 +1466,7 @@
createinst: object,
parent: Optional[QWidget] = None,
) -> None:
- super(DemandWidget, self).__init__(parent)
+ super().__init__(parent)
# We store a reference to the create function name to avoid having a
# hard reference to the bound function, which prevents it being
# disposed. Weak references to bound functions don't work.
@@ -1480,7 +1480,7 @@
def showEvent(self, event):
"""create the widget if necessary"""
self.get()
- super(DemandWidget, self).showEvent(event)
+ super().showEvent(event)

def forward(self, funcname: Text, *args, **opts) -> Optional[Any]:
if self._widget:
@@ -1553,7 +1553,7 @@
def accept(self) -> None:
try:
hglib.fromunicode(self.textValue())
- return super(_EncodingSafeInputDialog, self).accept()
+ return super().accept()
except UnicodeEncodeError:
WarningMsgBox(_('Text Translation Failure'),
_('Unable to translate input to local encoding.'),
diff --git a/tortoisehg/hgqt/rebase.py b/tortoisehg/hgqt/rebase.py
--- a/tortoisehg/hgqt/rebase.py
+++ b/tortoisehg/hgqt/rebase.py
@@ -66,7 +66,7 @@
repoagent: RepoAgent,
parent: Optional[QWidget],
**opts) -> None:
- super(RebaseDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowIcon(qtlib.geticon('hg-rebase'))
self.setWindowFlags(self.windowFlags()
& ~Qt.WindowType.WindowContextHelpButtonHint)
@@ -331,8 +331,8 @@
if not qtlib.QuestionMsgBox(_('Confirm Exit'), main, text,
labels=labels, parent=self):
return
- super(RebaseDialog, self).reject()
+ super().reject()

def done(self, r: int) -> None:
self._writeSettings()
- super(RebaseDialog, self).done(r)
+ super().done(r)
diff --git a/tortoisehg/hgqt/rejects.py b/tortoisehg/hgqt/rejects.py
--- a/tortoisehg/hgqt/rejects.py
+++ b/tortoisehg/hgqt/rejects.py
@@ -46,7 +46,7 @@

class RejectsDialog(QDialog):
def __init__(self, ui, path: bytes, parent=None) -> None:
- super(RejectsDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowTitle(_('Merge rejected patch chunks into %s') %
hglib.tounicode(path))
self.setWindowFlags(Qt.WindowType.Window)
@@ -262,16 +262,16 @@
self._textEncoding()):
return
self.saveSettings()
- super(RejectsDialog, self).accept()
+ super().accept()

def reject(self):
self.saveSettings()
- super(RejectsDialog, self).reject()
+ super().reject()

class RejectBrowser(qscilib.Scintilla):
'Display a rejected diff hunk in an easily copy/pasted format'
def __init__(self, parent):
- super(RejectBrowser, self).__init__(parent)
+ super().__init__(parent)

self.setFrameStyle(0)
self.setReadOnly(True)
diff --git a/tortoisehg/hgqt/rename.py b/tortoisehg/hgqt/rename.py
--- a/tortoisehg/hgqt/rename.py
+++ b/tortoisehg/hgqt/rename.py
@@ -52,7 +52,7 @@

def __init__(self, repoagent: RepoAgent, parent: Optional[QWidget] = None, source: Optional[Text] = None, destination: Optional[Text] = None,
iscopy: bool = False) -> None:
- super(RenameWidget, self).__init__(parent)
+ super().__init__(parent)
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
self._repoagent = repoagent

@@ -227,7 +227,7 @@

def __init__(self, repoagent: RepoAgent, parent: Optional[QWidget] = None, source: Optional[Text] = None, destination: Optional[Text] = None,
iscopy: bool = False) -> None:
- super(RenameDialog, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent

self.setWindowIcon(qtlib.geticon('hg-rename'))
diff --git a/tortoisehg/hgqt/repofilter.py b/tortoisehg/hgqt/repofilter.py
--- a/tortoisehg/hgqt/repofilter.py
+++ b/tortoisehg/hgqt/repofilter.py
@@ -124,19 +124,19 @@

class SelectAllLineEdit(QLineEdit):
def __init__(self, parent: Optional[QWidget] = None) -> None:
- super(SelectAllLineEdit, self).__init__(parent)
+ super().__init__(parent)
self.just_got_focus = False

def focusInEvent(self, ev):
if ev.reason() == Qt.FocusReason.MouseFocusReason:
self.just_got_focus = True
- super(SelectAllLineEdit, self).focusInEvent(ev)
+ super().focusInEvent(ev)

def mouseReleaseEvent(self, ev):
if self.just_got_focus:
self.just_got_focus = False
self.selectAll()
- super(SelectAllLineEdit, self).mouseReleaseEvent(ev)
+ super().mouseReleaseEvent(ev)


class RepoFilterBar(QToolBar):
@@ -156,7 +156,7 @@
def __init__(self,
repoagent: thgrepo.RepoAgent,
parent: Optional[QWidget] = None) -> None:
- super(RepoFilterBar, self).__init__(parent)
+ super().__init__(parent)
self.layout().setContentsMargins(0, 0, 0, 0)
self.setIconSize(qtlib.smallIconSize())
self._repoagent = repoagent
@@ -293,7 +293,7 @@
if event.type() == QEvent.Type.Resize:
self._updateQueryTypeGeometry()
return False
- return super(RepoFilterBar, self).eventFilter(watched, event)
+ return super().eventFilter(watched, event)

def openEditor(self):
query = self._prepareQuery()
diff --git a/tortoisehg/hgqt/repomodel.py b/tortoisehg/hgqt/repomodel.py
--- a/tortoisehg/hgqt/repomodel.py
+++ b/tortoisehg/hgqt/repomodel.py
@@ -631,7 +631,7 @@
return None

def flags(self, index: QModelIndex) -> Qt_ItemFlags:
- flags = super(HgRepoListModel, self).flags(index)
+ flags = super().flags(index)
if not index.isValid():
return flags
row = index.row()
diff --git a/tortoisehg/hgqt/reporegistry.py b/tortoisehg/hgqt/reporegistry.py
--- a/tortoisehg/hgqt/reporegistry.py
+++ b/tortoisehg/hgqt/reporegistry.py
@@ -98,7 +98,7 @@
def dragEnterEvent(self, event):
if event.source() is self:
# Use the default event handler for internal dragging
- super(RepoTreeView, self).dragEnterEvent(event)
+ super().dragEnterEvent(event)
return

d = event.mimeData()
@@ -146,7 +146,7 @@
# For instance, suprepo items support Copy actions only
supportedActions = firstItem.getSupportedDragDropActions()

- super(RepoTreeView, self).startDrag(supportedActions)
+ super().startDrag(supportedActions)

def dropEvent(self, event: QDropEvent):
data = event.mimeData()
@@ -191,7 +191,7 @@
if index.isValid():
self.removeRequested.emit(index)
return
- super(RepoTreeView, self).keyPressEvent(event)
+ super().keyPressEvent(event)

def mouseMoveEvent(self, event: QMouseEvent) -> None:
self.msg = ''
@@ -206,7 +206,7 @@
# Bail out early to avoid tripping over this bug:
# https://bugreports.qt.io/browse/QTBUG-10180
return
- super(RepoTreeView, self).mouseMoveEvent(event)
+ super().mouseMoveEvent(event)

def leaveEvent(self, event):
if self.msg != '':
@@ -218,10 +218,10 @@
self.openRequested.emit(index)
else:
# a double-click on non-repo rows opens an editor
- super(RepoTreeView, self).mouseDoubleClickEvent(event)
+ super().mouseDoubleClickEvent(event)

def sizeHint(self):
- size = super(RepoTreeView, self).sizeHint()
+ size = super().sizeHint()
size.setWidth(QFontMetrics(self.font()).horizontalAdvance('M') * 15)
return size

diff --git a/tortoisehg/hgqt/repotab.py b/tortoisehg/hgqt/repotab.py
--- a/tortoisehg/hgqt/repotab.py
+++ b/tortoisehg/hgqt/repotab.py
@@ -50,7 +50,7 @@
def mouseReleaseEvent(self, event: QMouseEvent) -> None:
if event.button() == Qt.MouseButton.MiddleButton:
self.tabCloseRequested.emit(self.tabAt(event.pos()))
- super(_TabBar, self).mouseReleaseEvent(event)
+ super().mouseReleaseEvent(event)


class RepoTabWidget(QWidget):
@@ -74,7 +74,7 @@
# tab-index is the master, so do not use stack.setCurrentIndex().

def __init__(self, config, actionregistry, repomanager, parent=None):
- super(RepoTabWidget, self).__init__(parent)
+ super().__init__(parent)
self._config = config
self._actionregistry = actionregistry
self._repomanager = repomanager
diff --git a/tortoisehg/hgqt/repotreeitem.py b/tortoisehg/hgqt/repotreeitem.py
--- a/tortoisehg/hgqt/repotreeitem.py
+++ b/tortoisehg/hgqt/repotreeitem.py
@@ -533,7 +533,7 @@
if role == Qt.ItemDataRole.DecorationRole and column == 0:
return _newSubrepoIcon('hg', valid=self._valid)
else:
- return super(StandaloneSubrepoItem, self).data(column, role)
+ return super().data(column, role)

class SubrepoItem(RepoItem):
"""Actual Mercurial subrepo"""
@@ -543,7 +543,7 @@
if role == Qt.ItemDataRole.DecorationRole and column == 0:
return _newSubrepoIcon('hg', valid=self._valid)
else:
- return super(SubrepoItem, self).data(column, role)
+ return super().data(column, role)

def menulist(self):
acts = ['open', 'clone', None, 'addsubrepo', 'removesubrepo',
@@ -574,7 +574,7 @@
if role == Qt.ItemDataRole.DecorationRole and column == 0:
return _newSubrepoIcon(self._repotype)
else:
- return super(AlienSubrepoItem, self).data(column, role)
+ return super().data(column, role)

def menulist(self):
return ['explore', 'terminal', 'copypath']
diff --git a/tortoisehg/hgqt/repoview.py b/tortoisehg/hgqt/repoview.py
--- a/tortoisehg/hgqt/repoview.py
+++ b/tortoisehg/hgqt/repoview.py
@@ -305,7 +305,7 @@
elif w is not None:
w = fontm.horizontalAdvance(str(w) + 'w')
else:
- w = super(HgRepoView, self).sizeHintForColumn(c)
+ w = super().sizeHintForColumn(c)
self.setColumnWidth(c, w)

def revFromindex(self, index):
@@ -493,7 +493,7 @@

def showEvent(self, event):
self._adjustRowHeight()
- super(HgRepoView, self).showEvent(event)
+ super().showEvent(event)

def enablefilterpalette(self, enable):
self._paletteswitcher.enablefilterpalette(enable)
@@ -510,7 +510,7 @@
painter.drawRect(vp.x(), option.rect.y(),
vp.width() - 1, 0)
else:
- super(HgRepoViewStyle, self).drawPrimitive(element, option, painter,
+ super().drawPrimitive(element, option, painter,
widget)


@@ -537,7 +537,7 @@
class GraphDelegate(QStyledItemDelegate):

def __init__(self, parent=None):
- super(GraphDelegate, self).__init__(parent)
+ super().__init__(parent)
self._rowheight = 16 # updated to the actual height on paint()

def _col2x(self, col):
@@ -713,7 +713,7 @@
symbol(symbolsize)

def sizeHint(self, option, index):
- size = super(GraphDelegate, self).sizeHint(option, index)
+ size = super().sizeHint(option, index)
gnode = index.data(repomodel.GraphNodeRole)
if gnode:
# return width for current height assuming that row height
@@ -779,14 +779,14 @@
"""Render text labels in place of icon/pixmap decoration"""

def __init__(self, parent=None, margin=2):
- super(LabeledDelegate, self).__init__(parent)
+ super().__init__(parent)
self._margin = margin

def _makeLabelsLayout(self, labels, option):
return _LabelsLayout(labels, option.font, self._margin)

def initStyleOption(self, option, index):
- super(LabeledDelegate, self).initStyleOption(option, index)
+ super().initStyleOption(option, index)
labels = index.data(repomodel.LabelsRole)
if not labels:
return
@@ -796,7 +796,7 @@
option.features |= QStyleOptionViewItem.ViewItemFeature.HasDecoration

def paint(self, painter, option, index):
- super(LabeledDelegate, self).paint(painter, option, index)
+ super().paint(painter, option, index)
labels = index.data(repomodel.LabelsRole)
if not labels:
return
@@ -820,7 +820,7 @@
painter.restore()

def sizeHint(self, option, index):
- size = super(LabeledDelegate, self).sizeHint(option, index)
+ size = super().sizeHint(option, index)
# give additional margins for each row (even if it has no labels
# because all rows must have the same height)
option = QStyleOptionViewItem(option)
diff --git a/tortoisehg/hgqt/repowidget.py b/tortoisehg/hgqt/repowidget.py
--- a/tortoisehg/hgqt/repowidget.py
+++ b/tortoisehg/hgqt/repowidget.py
@@ -2621,7 +2621,7 @@

class LightRepoWindow(QMainWindow):
def __init__(self, actionregistry, repoagent):
- super(LightRepoWindow, self).__init__()
+ super().__init__()
self._repoagent = repoagent
self.setIconSize(qtlib.smallIconSize())

@@ -2659,7 +2659,7 @@
self.setWindowTitle(_('TortoiseHg: %s') % repoagent.displayName())

def createPopupMenu(self):
- menu = super(LightRepoWindow, self).createPopupMenu()
+ menu = super().createPopupMenu()
assert menu # should have toolbar
stbar = self.statusBar()
a = menu.addAction(_('S&tatus Bar'))
diff --git a/tortoisehg/hgqt/resolve.py b/tortoisehg/hgqt/resolve.py
--- a/tortoisehg/hgqt/resolve.py
+++ b/tortoisehg/hgqt/resolve.py
@@ -70,7 +70,7 @@

class ResolveDialog(QDialog):
def __init__(self, repoagent, parent=None):
- super(ResolveDialog, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent
self._cmdsession = cmdcore.nullCmdSession()
self.setWindowFlags(self.windowFlags()
@@ -460,7 +460,7 @@
if not qtlib.QuestionMsgBox(_('Confirm Exit'), main, text,
labels=labels, parent=self):
return
- super(ResolveDialog, self).reject()
+ super().reject()

def _updateActions(self):
self._updateUnresolvedActions()
@@ -533,7 +533,7 @@
return None

def flags(self, index: QModelIndex) -> Qt_ItemFlags:
- flags = super(PathsModel, self).flags(index)
+ flags = super().flags(index)
if not index.isValid():
return flags
flags |= Qt.ItemFlag.ItemIsDragEnabled
diff --git a/tortoisehg/hgqt/revdetails.py b/tortoisehg/hgqt/revdetails.py
--- a/tortoisehg/hgqt/revdetails.py
+++ b/tortoisehg/hgqt/revdetails.py
@@ -304,7 +304,7 @@
return True
return False

- return super(RevDetailsWidget, self).eventFilter(watched, event)
+ return super().eventFilter(watched, event)

def onRevisionSelected(self, rev):
'called by repowidget when repoview changes revisions'
@@ -668,7 +668,7 @@
def done(self, ret):
s = QSettings()
s.setValue('revdetails/geom', self.saveGeometry())
- super(RevDetailsDialog, self).done(ret)
+ super().done(ret)


def createManifestDialog(repoagent, rev=None, parent=None):
diff --git a/tortoisehg/hgqt/revert.py b/tortoisehg/hgqt/revert.py
--- a/tortoisehg/hgqt/revert.py
+++ b/tortoisehg/hgqt/revert.py
@@ -32,7 +32,7 @@

class RevertDialog(QDialog):
def __init__(self, repoagent, wfiles, rev, parent):
- super(RevertDialog, self).__init__(parent)
+ super().__init__(parent)

self._repoagent = repoagent
self._cmdsession = cmdcore.nullCmdSession()
diff --git a/tortoisehg/hgqt/revset.py b/tortoisehg/hgqt/revset.py
--- a/tortoisehg/hgqt/revset.py
+++ b/tortoisehg/hgqt/revset.py
@@ -318,7 +318,7 @@
returnPressed = pyqtSignal()

def __init__(self, parent=None):
- super(RevsetEntry, self).__init__(parent)
+ super().__init__(parent)
self.setMarginWidth(1, 0)
self.setReadOnly(False)
self.setUtf8(True)
@@ -363,7 +363,7 @@
event.ignore()
self.returnPressed.emit()
return
- super(RevsetEntry, self).keyPressEvent(event)
+ super().keyPressEvent(event)

def sizeHint(self):
return QSize(10, self.fontMetrics().height())
diff --git a/tortoisehg/hgqt/serve.py b/tortoisehg/hgqt/serve.py
--- a/tortoisehg/hgqt/serve.py
+++ b/tortoisehg/hgqt/serve.py
@@ -63,7 +63,7 @@
ui: uimod.ui,
webconf: Optional[IniConfig],
parent: Optional[QWidget] = None) -> None:
- super(ServeDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowFlags((self.windowFlags() | Qt.WindowType.WindowMinimizeButtonHint)
& ~Qt.WindowType.WindowContextHelpButtonHint)
self.setWindowIcon(qtlib.geticon('hg-serve'))
@@ -171,7 +171,7 @@

def reject(self) -> None:
self.stop()
- super(ServeDialog, self).reject()
+ super().reject()

def isstarted(self) -> bool:
"""Is the web server running?"""
@@ -196,7 +196,7 @@
self.stop()
return

- return super(ServeDialog, self).keyPressEvent(event)
+ return super().keyPressEvent(event)

def closeEvent(self, event):
if self.isstarted():
@@ -204,7 +204,7 @@
event.ignore()
return

- return super(ServeDialog, self).closeEvent(event)
+ return super().closeEvent(event)

@util.propertycache
def _trayicon(self):
diff --git a/tortoisehg/hgqt/settings.py b/tortoisehg/hgqt/settings.py
--- a/tortoisehg/hgqt/settings.py
+++ b/tortoisehg/hgqt/settings.py
@@ -407,7 +407,7 @@
"""Dummy widget for group separator"""

def __init__(self, parent=None, **opts):
- super(Spacer, self).__init__(parent)
+ super().__init__(parent)
if opts.get('cpath'):
raise ValueError('do not set cpath for spacer')
self.opts = opts
@@ -1471,7 +1471,7 @@
restartRequested = pyqtSignal(str)

def __init__(self, rcpath, focus=None, parent=None, readonly=False):
- super(SettingsForm, self).__init__(parent)
+ super().__init__(parent)

# If forcereadonly is false, the settings form will be readonly
# if the corresponding ini file is readonly
diff --git a/tortoisehg/hgqt/shellconf.py b/tortoisehg/hgqt/shellconf.py
--- a/tortoisehg/hgqt/shellconf.py
+++ b/tortoisehg/hgqt/shellconf.py
@@ -91,7 +91,7 @@
class ShellConfigWindow(QDialog):

def __init__(self, parent=None):
- super(ShellConfigWindow, self).__init__(parent)
+ super().__init__(parent)

self.menu_cmds = {}
self.dirty = False
diff --git a/tortoisehg/hgqt/shelve.py b/tortoisehg/hgqt/shelve.py
--- a/tortoisehg/hgqt/shelve.py
+++ b/tortoisehg/hgqt/shelve.py
@@ -550,4 +550,4 @@

def reject(self):
self.storeSettings()
- super(ShelveDialog, self).reject()
+ super().reject()
diff --git a/tortoisehg/hgqt/shortcutregistry.py b/tortoisehg/hgqt/shortcutregistry.py
--- a/tortoisehg/hgqt/shortcutregistry.py
+++ b/tortoisehg/hgqt/shortcutregistry.py
@@ -333,7 +333,7 @@
_actionsMap: Dict[Text, weakref.WeakSet[QAction]]

def __init__(self):
- super(ActionRegistry, self).__init__()
+ super().__init__()
# QAction instances are owned by QWidget and will be destroyed when
# C++ object is deleted. Since QAction will be instantiated per
# context (e.g. window), more than one instances may be registered
diff --git a/tortoisehg/hgqt/shortcutsettings.py b/tortoisehg/hgqt/shortcutsettings.py
--- a/tortoisehg/hgqt/shortcutsettings.py
+++ b/tortoisehg/hgqt/shortcutsettings.py
@@ -50,7 +50,7 @@
def __init__(self,
registry: shortcutregistry.ShortcutRegistry,
parent: Optional[QWidget] = None) -> None:
- super(ShortcutSettingsWidget, self).__init__(parent)
+ super().__init__(parent)
self._registry = registry

vbox = QVBoxLayout(self)
@@ -201,7 +201,7 @@
def __init__(self,
registry: shortcutregistry.ActionRegistry,
parent: Optional[QWidget] = None) -> None:
- super(ShortcutSettingsDialog, self).__init__(parent)
+ super().__init__(parent)
self._registry = registry

self.setWindowTitle(_('Shortcut Settings'))
@@ -225,4 +225,4 @@
self._registry.updateShortcuts(self._widget.registry())
self._registry.saveSettings()
self._registry.applyChangesToActions()
- super(ShortcutSettingsDialog, self).accept()
+ super().accept()
diff --git a/tortoisehg/hgqt/sign.py b/tortoisehg/hgqt/sign.py
--- a/tortoisehg/hgqt/sign.py
+++ b/tortoisehg/hgqt/sign.py
@@ -36,7 +36,7 @@
class SignDialog(QDialog):

def __init__(self, repoagent, rev='tip', parent=None, opts=None):
- super(SignDialog, self).__init__(parent)
+ super().__init__(parent)
if opts is None:
opts = {}
self.setWindowFlags(self.windowFlags() &
diff --git a/tortoisehg/hgqt/status.py b/tortoisehg/hgqt/status.py
--- a/tortoisehg/hgqt/status.py
+++ b/tortoisehg/hgqt/status.py
@@ -699,7 +699,7 @@
showMessage = pyqtSignal(str)

def __init__(self, repo, pctx, pats, opts, parent=None):
- super(StatusThread, self).__init__()
+ super().__init__()
self.repo = hg.repository(repo.ui, repo.root)
self.pctx = pctx
self.pats = pats
@@ -782,7 +782,7 @@
def scrollTo(self, index, hint=QAbstractItemView.ScrollHint.EnsureVisible):
# don't update horizontal position by selection change
orighoriz = self.horizontalScrollBar().value()
- super(WctxFileTree, self).scrollTo(index, hint)
+ super().scrollTo(index, hint)
self.horizontalScrollBar().setValue(orighoriz)


@@ -1181,7 +1181,7 @@
statusChanged = pyqtSignal(str)

def __init__(self, statustext, types=None, parent=None):
- super(StatusFilterActionGroup, self).__init__(parent)
+ super().__init__(parent)
self._TYPES = 'MARSC'
if types is not None:
self._TYPES = types
diff --git a/tortoisehg/hgqt/sync.py b/tortoisehg/hgqt/sync.py
--- a/tortoisehg/hgqt/sync.py
+++ b/tortoisehg/hgqt/sync.py
@@ -609,7 +609,7 @@
elif event.key() == Qt.Key.Key_Escape and not sess.isFinished():
sess.abort()
else:
- return super(SyncWidget, self).keyPressEvent(event)
+ return super().keyPressEvent(event)

def stopclicked(self):
self._cmdsession.abort()
@@ -1116,7 +1116,7 @@

class PostPullDialog(QDialog):
def __init__(self, repoagent, parent):
- super(PostPullDialog, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent
repo = repoagent.rawRepo()
layout = QVBoxLayout()
@@ -1214,12 +1214,12 @@
except OSError as e:
qtlib.WarningMsgBox(_('Unable to write configuration file'),
hglib.exception_str(e), parent=self)
- super(PostPullDialog, self).accept()
+ super().accept()


class SaveDialog(QDialog):
def __init__(self, repoagent, alias, urlu, parent, edit=False):
- super(SaveDialog, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent

self.setWindowTitle(_('Save Path'))
@@ -1342,7 +1342,7 @@
self._repoagent.pollStatus()
s = QSettings()
s.setValue('sync/updatesubpaths', self.updatesubpaths.isChecked())
- super(SaveDialog, self).accept()
+ super().accept()

@pyqtSlot(bool)
def _removeAuthData(self, showclean):
@@ -1382,7 +1382,7 @@
repoagent: thgrepo.RepoAgent,
urlu: str,
parent: QWidget) -> None:
- super(SecureDialog, self).__init__(parent)
+ super().__init__(parent)
self._repoagent = repoagent
self._querysess = cmdcore.nullCmdSession()
repo = repoagent.rawRepo()
@@ -1612,7 +1612,7 @@
except OSError as e:
qtlib.WarningMsgBox(_('Unable to write configuration file'),
hglib.exception_str(e), parent=self)
- super(SecureDialog, self).accept()
+ super().accept()

@pyqtSlot()
def _updateUi(self):
@@ -1642,7 +1642,7 @@
if self.editable and event.matches(QKeySequence.StandardKey.Delete):
self.deleteSelected()
else:
- return super(PathsTree, self).keyPressEvent(event)
+ return super().keyPressEvent(event)

def deleteSelected(self):
for index in self.selectedRows():
diff --git a/tortoisehg/hgqt/tag.py b/tortoisehg/hgqt/tag.py
--- a/tortoisehg/hgqt/tag.py
+++ b/tortoisehg/hgqt/tag.py
@@ -63,7 +63,7 @@
rev: Text = 'tip',
parent: Optional[QWidget] = None,
opts: Optional[Dict[Text, Union[bool, bytes]]] = None) -> None:
- super(TagDialog, self).__init__(parent)
+ super().__init__(parent)
if opts is None:
opts = {}
self.setWindowFlags(self.windowFlags() &
@@ -341,4 +341,4 @@
self.set_status(_('Repository command still running'), False)
return

- super(TagDialog, self).reject()
+ super().reject()
diff --git a/tortoisehg/hgqt/thgimport.py b/tortoisehg/hgqt/thgimport.py
--- a/tortoisehg/hgqt/thgimport.py
+++ b/tortoisehg/hgqt/thgimport.py
@@ -64,7 +64,7 @@
"""Dialog to import patches"""

def __init__(self, repoagent, parent, **opts):
- super(ImportDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowFlags(self.windowFlags()
& ~Qt.WindowType.WindowContextHelpButtonHint
| Qt.WindowType.WindowMaximizeButtonHint)
@@ -181,7 +181,7 @@
if event.matches(QKeySequence.StandardKey.Refresh):
self.checkStatus()
else:
- return super(ImportDialog, self).keyPressEvent(event)
+ return super().keyPressEvent(event)

def browsefiles(self):
caption = _("Select patches")
diff --git a/tortoisehg/hgqt/thgrepo.py b/tortoisehg/hgqt/thgrepo.py
--- a/tortoisehg/hgqt/thgrepo.py
+++ b/tortoisehg/hgqt/thgrepo.py
@@ -117,7 +117,7 @@
repositoryDestroyed = pyqtSignal()

def __init__(self, repo, parent=None):
- super(RepoWatcher, self).__init__(parent)
+ super().__init__(parent)
self._repo = repo
self._ui = repo.ui
self._fswatcher = None
@@ -699,7 +699,7 @@
]

def __init__(self, ui, parent=None):
- super(RepoManager, self).__init__(parent)
+ super().__init__(parent)
self._ui = ui
self._openagents = {} # path: (agent, refcount)
# refcount=0 means the repo is about to be closed
@@ -830,7 +830,7 @@
# If changeid is a basectx, repo[changeid] returns the same object.
# We assumes changectx is already wrapped in that case; otherwise,
# changectx would be double wrapped by thgchangectx.
- changectx = super(thgrepository, self).__getitem__(changeid)
+ changectx = super().__getitem__(changeid)
if changectx is changeid:
return changectx
changectx.__class__ = _extendchangectx(changectx)
@@ -841,7 +841,7 @@
# This provides temporary workaround for troubles caused by class
# extension: e.g. changectx(n) != thgchangectx(n).
# thgrepository and thgchangectx should be removed in some way.
- return super(thgrepository, self).__getitem__(changeid)
+ return super().__getitem__(changeid)

@localrepo.unfilteredpropertycache
def _thghiddentags(self):
@@ -1085,7 +1085,7 @@
def _createchangectxcls(parentcls):
class thgchangectx(parentcls):
def sub(self, path):
- srepo = super(thgchangectx, self).sub(path)
+ srepo = super().sub(path)
if isinstance(srepo, subrepo.hgsubrepo):
r = srepo._repo
r = r.unfiltered()
diff --git a/tortoisehg/hgqt/thgstrip.py b/tortoisehg/hgqt/thgstrip.py
--- a/tortoisehg/hgqt/thgstrip.py
+++ b/tortoisehg/hgqt/thgstrip.py
@@ -57,7 +57,7 @@
rev: Optional[Text] = None,
parent: Optional[QWidget] = None,
opts: Optional[Dict[Text, Any]] = None) -> None:
- super(StripWidget, self).__init__(parent)
+ super().__init__(parent)
if opts is None:
opts = {}
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
diff --git a/tortoisehg/hgqt/topic.py b/tortoisehg/hgqt/topic.py
--- a/tortoisehg/hgqt/topic.py
+++ b/tortoisehg/hgqt/topic.py
@@ -36,7 +36,7 @@
class TopicDialog(QDialog):

def __init__(self, repoagent, rev, parent=None):
- super(TopicDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowFlags(self.windowFlags() &
~Qt.WindowType.WindowContextHelpButtonHint)
self._repoagent = repoagent
diff --git a/tortoisehg/hgqt/update.py b/tortoisehg/hgqt/update.py
--- a/tortoisehg/hgqt/update.py
+++ b/tortoisehg/hgqt/update.py
@@ -61,7 +61,7 @@
parent: Optional[QWidget] = None,
opts: Optional[UpdateOpts] = None) -> None:
# TODO: unify the `rev` type
- super(UpdateWidget, self).__init__(parent)
+ super().__init__(parent)
if opts is None:
opts = {}
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
@@ -429,7 +429,7 @@
rev: Optional[Union[Text, pycompat.unicode]] = None,
parent: Optional[QWidget] = None,
opts: Optional[UpdateOpts] = None) -> None:
- super(UpdateDialog, self).__init__(parent)
+ super().__init__(parent)
if opts is None:
opts = {}
self._repoagent = repoagent
diff --git a/tortoisehg/hgqt/updatecheck.py b/tortoisehg/hgqt/updatecheck.py
--- a/tortoisehg/hgqt/updatecheck.py
+++ b/tortoisehg/hgqt/updatecheck.py
@@ -44,7 +44,7 @@
updateUnavailable = pyqtSignal()

def __init__(self, parent=None):
- super(Checker, self).__init__(parent)
+ super().__init__(parent)
self._newverreply = None

@pyqtSlot()
diff --git a/tortoisehg/hgqt/wctxcleaner.py b/tortoisehg/hgqt/wctxcleaner.py
--- a/tortoisehg/hgqt/wctxcleaner.py
+++ b/tortoisehg/hgqt/wctxcleaner.py
@@ -74,7 +74,7 @@
checkFinished = pyqtSignal(bool, int) # clean, parents

def __init__(self, repoagent, parent=None):
- super(WctxCleaner, self).__init__(parent)
+ super().__init__(parent)
assert parent is None or isinstance(parent, QWidget), parent
self._repoagent = repoagent
self._cmdsession = cmdcore.nullCmdSession()
diff --git a/tortoisehg/hgqt/webconf.py b/tortoisehg/hgqt/webconf.py
--- a/tortoisehg/hgqt/webconf.py
+++ b/tortoisehg/hgqt/webconf.py
@@ -64,7 +64,7 @@
def __init__(self,
parent: Optional[QWidget] = None,
webconf: Optional[IniConfig] = None) -> None:
- super(WebconfForm, self).__init__(parent, acceptDrops=True)
+ super().__init__(parent, acceptDrops=True)
self._qui = Ui_WebconfForm()
self._qui.setupUi(self)
self._initicons()
@@ -216,7 +216,7 @@
"""Dialog to add/edit path mapping"""
def __init__(self, title: Text, acceptlabel: Text, path: Optional[Text] = None, localpath: Optional[Text] = None,
invalidpaths: Optional[Iterable[Text]] = None, parent: Optional[QWidget] = None) -> None:
- super(_PathDialog, self).__init__(parent)
+ super().__init__(parent)
self.setWindowFlags((self.windowFlags() | Qt.WindowType.WindowMinimizeButtonHint)
& ~Qt.WindowType.WindowContextHelpButtonHint)
self.resize(QFontMetrics(self.font()).horizontalAdvance('M') * 50, self.height())
@@ -329,7 +329,7 @@
def __init__(self,
config: IniConfig,
parent: Optional[QObject] = None) -> None:
- super(WebconfModel, self).__init__(parent)
+ super().__init__(parent)
self._config = config

def data(self, index: QModelIndex, role: int) -> Any:
diff --git a/tortoisehg/hgqt/workbench.py b/tortoisehg/hgqt/workbench.py
--- a/tortoisehg/hgqt/workbench.py
+++ b/tortoisehg/hgqt/workbench.py
@@ -658,7 +658,7 @@

def createPopupMenu(self):
"""Create new popup menu for toolbars and dock widgets"""
- menu = super(Workbench, self).createPopupMenu()
+ menu = super().createPopupMenu()
assert menu # should have toolbar/dock menu
# replace default log dock action by customized one
menu.insertAction(self._console.toggleViewAction(),
diff --git a/tortoisehg/util/pipeui.py b/tortoisehg/util/pipeui.py
--- a/tortoisehg/util/pipeui.py
+++ b/tortoisehg/util/pipeui.py
@@ -209,12 +209,12 @@

def _writenobuf(self, dest, *args, **opts):
label = opts.get('label', b'')
- super(pipeui, self)._writenobuf(dest, *_packmsgs(args, label),
+ super()._writenobuf(dest, *_packmsgs(args, label),
**opts)

def prompt(self, msg, default=b'y'):
fullmsg = _packprompt(msg, default)
- return super(pipeui, self).prompt(fullmsg, default)
+ return super().prompt(fullmsg, default)

# write raw prompt value with choices
def promptchoice(self, prompt, default=0):
@@ -229,7 +229,7 @@

def getpass(self, prompt=None, default=None):
prompt = self.label(prompt or _('password: '), b'ui.getpass')
- return super(pipeui, self).getpass(prompt, default)
+ return super().getpass(prompt, default)

# TODO: progress handler can be extracted to new class, and pass its
# instance to scmutil.progress() per makeprogress() call.

Matt Harbison

unread,
Feb 28, 2025, 5:14:45 PMFeb 28
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1736204651 18000
# Mon Jan 06 18:04:11 2025 -0500
# Branch stable
# Node ID 6f5c994ce20614e45da679d0f103258da5bd847a
# Parent 0770d6359945463045b2056b7642ed4af5d8b4c8
# EXP-Topic pyupgrade
pyupgrade: rewrite `yield` statements in a loop to `yield from`

This is the `legacy` fixer in `pyupgrade`, with the `yield` statement yielding
loop commented back in. This seems to help pytype in some cases, and hurt it in
others. But that can be manually fixed later. See hg e627cc25b6f3.

diff --git a/tortoisehg/hgqt/repotreeitem.py b/tortoisehg/hgqt/repotreeitem.py
--- a/tortoisehg/hgqt/repotreeitem.py
+++ b/tortoisehg/hgqt/repotreeitem.py
@@ -84,8 +84,7 @@
if stopfunc and stopfunc(root):
return
for c in root.childs:
- for e in flatten(c, stopfunc):
- yield e
+ yield from flatten(c, stopfunc)

def find(root: "RepoTreeItem", targetfunc, stopfunc=None) -> "RepoTreeItem":
"""Search recursively for item of which targetfunc evaluates to True"""
diff --git a/tortoisehg/hgqt/status.py b/tortoisehg/hgqt/status.py
--- a/tortoisehg/hgqt/status.py
+++ b/tortoisehg/hgqt/status.py
@@ -1042,8 +1042,7 @@
return self.rows[index.row()]

def getAllRows(self):
- for row in self.rows:
- yield row
+ yield from self.rows

def sort(self, col, order):
self.layoutAboutToBeChanged.emit()
diff --git a/tortoisehg/hgqt/thgrepo.py b/tortoisehg/hgqt/thgrepo.py
--- a/tortoisehg/hgqt/thgrepo.py
+++ b/tortoisehg/hgqt/thgrepo.py
@@ -1187,8 +1187,7 @@
for s in wctx.substate:
sub = wctx.sub(s)
if isinstance(sub, subrepo.hgsubrepo):
- for root, file, status in recursiveMergeStatus(sub._repo):
- yield root, file, status
+ yield from recursiveMergeStatus(sub._repo)

Matt Harbison

unread,
Feb 28, 2025, 5:14:51 PMFeb 28
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1736204930 18000
# Mon Jan 06 18:08:50 2025 -0500
# Branch stable
# Node ID c5c323e7fa299be703df20629dee428be0013493
# Parent 6f5c994ce20614e45da679d0f103258da5bd847a
# EXP-Topic pyupgrade
pyupgrade: drop the quoting around type annotations

This is the `typing_pep563` fixer in `pyupgrade`. Quoting to delay evaluation
hasn't been necessary since adding `from __future__ import annotations` in
1f17abd911a2. See hg 4cb75772818d.

diff --git a/tortoisehg/hgqt/customtools.py b/tortoisehg/hgqt/customtools.py
--- a/tortoisehg/hgqt/customtools.py
+++ b/tortoisehg/hgqt/customtools.py
@@ -74,7 +74,7 @@

class ToolsFrame(QFrame):
def __init__(
- self, ini: "IniConfig", parent: Optional[QWidget]=None, **opts
+ self, ini: IniConfig, parent: Optional[QWidget]=None, **opts
) -> None:
QFrame.__init__(self, parent, **opts)
self.widgets = []
@@ -163,7 +163,7 @@
# Ensure that the first location list is shown
selectlocation(0)

- def getCurrentToolList(self) -> Optional["ToolListBox"]:
+ def getCurrentToolList(self) -> Optional[ToolListBox]:
index = self.locationcombo.currentIndex()
location = self.locationcombo.itemData(index)
for widget in self.widgets:
@@ -252,7 +252,7 @@
except KeyError:
pass

- def applyChanges(self, ini: "IniConfig") -> bool:
+ def applyChanges(self, ini: IniConfig) -> bool:
# widget.value() returns the _NEW_ values
# widget.curvalue returns the _ORIGINAL_ values (yes, this is a bit
# misleading! "cur" means "current" as in currently valid)
@@ -335,7 +335,7 @@

class HooksFrame(QFrame):
def __init__(
- self, ini: "IniConfig", parent: Optional[QWidget]=None, **opts
+ self, ini: IniConfig, parent: Optional[QWidget]=None, **opts
) -> None:
super().__init__(parent, **opts)
self.ini = ini
@@ -476,7 +476,7 @@
self.btnedit.setEnabled(tablehasitems)
self.btndelete.setEnabled(tablehasitems)

- def applyChanges(self, ini: "IniConfig") -> bool:
+ def applyChanges(self, ini: IniConfig) -> bool:
# widget.value() returns the _NEW_ values
# widget.curvalue returns the _ORIGINAL_ values (yes, this is a bit
# misleading! "cur" means "current" as in currently valid)
@@ -570,7 +570,7 @@
SEPARATOR: str = '------'
def __init__(
self,
- ini: "IniConfig",
+ ini: IniConfig,
parent: Optional[QWidget] = None,
location: Optional[str] = None,
minimumwidth: Optional[int] = None,
diff --git a/tortoisehg/hgqt/filectxactions.py b/tortoisehg/hgqt/filectxactions.py
--- a/tortoisehg/hgqt/filectxactions.py
+++ b/tortoisehg/hgqt/filectxactions.py
@@ -86,18 +86,18 @@
_W = TypeVar('_W', bound=QWidget)


-def _lcanonpaths(fds: List["FileData"]) -> List[bytes]:
+def _lcanonpaths(fds: List[FileData]) -> List[bytes]:
return [hglib.fromunicode(e.canonicalFilePath()) for e in fds]

# predicates to filter files
-def _anydeleted(fds: List["FileData"]) -> List["FileData"]:
+def _anydeleted(fds: List[FileData]) -> List[FileData]:
if any(
e.rev() is None and cast(context.workingctx, e.rawContext()).deleted()
for e in fds
):
return fds
return []
-def _committed(fds: List["FileData"]) -> List["FileData"]:
+def _committed(fds: List[FileData]) -> List[FileData]:
# pytype: disable=unsupported-operands
return [e for e in fds if e.rev() is not None and e.rev() >= 0]
# pytype: enable=unsupported-operands
@@ -109,28 +109,28 @@
s = frozenset(s)
# include directory since its status is unknown
return lambda fds: [e for e in fds if e.isDir() or e.fileStatus() in s]
-def _indirectbaserev(fds: List["FileData"]) -> List["FileData"]:
+def _indirectbaserev(fds: List[FileData]) -> List[FileData]:
return [e for e in fds if e.baseRev() not in e.parentRevs()]
-def _isdir(fds: List["FileData"]) -> List["FileData"]:
+def _isdir(fds: List[FileData]) -> List[FileData]:
return [e for e in fds if e.isDir()]
-def _isfile(fds: List["FileData"]) -> List["FileData"]:
+def _isfile(fds: List[FileData]) -> List[FileData]:
return [e for e in fds if not e.isDir()]
-def _merged(fds: List["FileData"]) -> List["FileData"]:
+def _merged(fds: List[FileData]) -> List[FileData]:
return [e for e in fds if len(e.rawContext().parents()) > 1]
def _mergestatus(s: Text) -> _FileDataFilter:
s = frozenset(s)
# include directory since its status is unknown
return lambda fds: [e for e in fds if e.isDir() or e.mergeStatus() in s]
-def _notpatch(fds: List["FileData"]) -> List["FileData"]:
+def _notpatch(fds: List[FileData]) -> List[FileData]:
# pytype: disable=unsupported-operands
return [e for e in fds if e.rev() is None or e.rev() >= 0]
# pytype: enable=unsupported-operands

-def _notsubrepo(fds: List["FileData"]) -> List["FileData"]:
+def _notsubrepo(fds: List[FileData]) -> List[FileData]:
return [e for e in fds if not e.repoRootPath() and not e.subrepoType()]
-def _notsubroot(fds: List["FileData"]) -> List["FileData"]:
+def _notsubroot(fds: List[FileData]) -> List[FileData]:
return [e for e in fds if not e.subrepoType()]
-def _single(fds: List["FileData"]) -> List["FileData"]:
+def _single(fds: List[FileData]) -> List[FileData]:
if len(fds) != 1:
return []
return fds
@@ -139,8 +139,8 @@

def _filterby(
fdfilters: Tuple[_FileDataFilter, ...],
- fds: List["FileData"]
-) -> List["FileData"]:
+ fds: List[FileData]
+) -> List[FileData]:
for f in fdfilters:
if not fds:
return []
@@ -182,7 +182,7 @@

def __init__(
self,
- repoagent: "RepoAgent",
+ repoagent: RepoAgent,
parent: QWidget,
) -> None:
super().__init__(parent)
@@ -190,8 +190,8 @@
raise ValueError('parent must be a QWidget')

self._repoagent = repoagent
- self._cmdsession: "CmdSession" = cmdcore.nullCmdSession()
- self._selfds: List["FileData"] = []
+ self._cmdsession: CmdSession = cmdcore.nullCmdSession()
+ self._selfds: List[FileData] = []

self._nav_dialogs = qtlib.DialogKeeper(FilectxActions._createnavdialog,
FilectxActions._gennavdialogkey,
@@ -227,11 +227,11 @@
return p

@property
- def _ui(self) -> "uimod.ui":
+ def _ui(self) -> uimod.ui:
repo = self._repoagent.rawRepo()
return repo.ui

- def _repoAgentFor(self, fd: "FileData") -> "RepoAgent":
+ def _repoAgentFor(self, fd: FileData) -> RepoAgent:
rpath = fd.repoRootPath()
if not rpath:
return self._repoagent
@@ -245,11 +245,11 @@
for act, fdfilters in allactions:
act.setEnabled(idle and bool(_filterby(fdfilters, selfds)))

- def fileDataListForAction(self, name: Text) -> List["FileData"]:
+ def fileDataListForAction(self, name: Text) -> List[FileData]:
fdfilters = self._actions[name][1]
return _filterby(fdfilters, self._selfds)

- def setFileDataList(self, selfds: List["FileData"]) -> None:
+ def setFileDataList(self, selfds: List[FileData]) -> None:
self._selfds = list(selfds)
self._updateActions()

@@ -268,21 +268,21 @@
assert name not in self._actions, name
self._actions[name] = action, fdfilters

- def _runCommand(self, cmdline: List[Text]) -> "CmdSession":
+ def _runCommand(self, cmdline: List[Text]) -> CmdSession:
if not self._cmdsession.isFinished():
return cmdcore.nullCmdSession()
sess = self._repoagent.runCommand(cmdline, self._parentWidget())
self._handleNewCommand(sess)
return sess

- def _runCommandSequence(self, cmdlines: List[List[Text]]) -> "CmdSession":
+ def _runCommandSequence(self, cmdlines: List[List[Text]]) -> CmdSession:
if not self._cmdsession.isFinished():
return cmdcore.nullCmdSession()
sess = self._repoagent.runCommandSequence(cmdlines, self._parentWidget())
self._handleNewCommand(sess)
return sess

- def _handleNewCommand(self, sess: "CmdSession") -> None:
+ def _handleNewCommand(self, sess: CmdSession) -> None:
assert self._cmdsession.isFinished()
self._cmdsession = sess
sess.commandFinished.connect(self._onCommandFinished)
@@ -297,7 +297,7 @@
@actionSlot(_('File &History / Annotate'), 'hg-log', 'Shift+Return',
_('Show the history of the selected file'),
(_isfile, _notpatch, _filestatus('MARC!')))
- def navigateFileLog(self, fds: List["FileData"]) -> None:
+ def navigateFileLog(self, fds: List[FileData]) -> None:
from tortoisehg.hgqt import filedialogs, fileview
for fd in fds:
dlg = self._navigate(filedialogs.FileLogDialog, fd)
@@ -308,7 +308,7 @@
@actionSlot(_('Co&mpare File Revisions'), 'compare-files', None,
_('Compare revisions of the selected file'),
(_isfile, _notpatch))
- def navigateFileDiff(self, fds: List["FileData"]) -> None:
+ def navigateFileDiff(self, fds: List[FileData]) -> None:
from tortoisehg.hgqt import filedialogs
for fd in fds:
self._navigate(filedialogs.FileDiffDialog, fd)
@@ -316,7 +316,7 @@
def _navigate(
self,
dlgclass: Type[_W],
- fd: "FileData"
+ fd: FileData
) -> Optional[_W]:
repoagent = self._repoAgentFor(fd)
repo = repoagent.rawRepo()
@@ -329,7 +329,7 @@
def _createnavdialog(
self,
dlgclass: Type[_W],
- repoagent: "RepoAgent",
+ repoagent: RepoAgent,
filename: bytes,
) -> _W:
return dlgclass(repoagent, filename)
@@ -337,7 +337,7 @@
def _gennavdialogkey(
self,
dlgclass: Type[_W],
- repoagent: "RepoAgent",
+ repoagent: RepoAgent,
filename: bytes,
) -> Tuple[Type[_W], bytes]:
repo = repoagent.rawRepo()
@@ -346,36 +346,36 @@
@actionSlot(_('Filter Histor&y'), 'hg-log', None,
_('Query about changesets affecting the selected files'),
_notsubrepo)
- def filterFile(self, fds: List["FileData"]) -> None:
+ def filterFile(self, fds: List[FileData]) -> None:
pats = ["file('path:%s')" % e.filePath() for e in fds]
self.filterRequested.emit(' or '.join(pats))

@actionSlot(_('Diff &Changeset to Parent'), 'visualdiff', None, '',
_notpatch)
- def visualDiff(self, fds: List["FileData"]) -> None:
+ def visualDiff(self, fds: List[FileData]) -> None:
self._visualDiffToBase(fds[0], [])

@actionSlot(_('Diff Changeset to Loc&al'), 'ldiff', None, '',
_committed)
- def visualDiffToLocal(self, fds: List["FileData"]) -> None:
+ def visualDiffToLocal(self, fds: List[FileData]) -> None:
self._visualDiff(fds[0], [], rev=['rev(%d)' % fds[0].rev()])

@actionSlot(_('&Diff to Parent'), 'visualdiff', 'Ctrl+D',
_('View file changes in external diff tool'),
(_notpatch, _notsubroot, _filestatus('MAR!')))
- def visualDiffFile(self, fds: List["FileData"]) -> None:
+ def visualDiffFile(self, fds: List[FileData]) -> None:
self._visualDiffToBase(fds[0], fds)

@actionSlot(_('Diff to &Local'), 'ldiff', 'Shift+Ctrl+D',
_('View changes to current in external diff tool'),
_committed)
- def visualDiffFileToLocal(self, fds: List["FileData"]) -> None:
+ def visualDiffFileToLocal(self, fds: List[FileData]) -> None:
self._visualDiff(fds[0], fds, rev=['rev(%d)' % fds[0].rev()])

def _visualDiffToBase(
self,
- an_fd: "FileData",
- fds: List["FileData"],
+ an_fd: FileData,
+ fds: List[FileData],
) -> None:
if an_fd.baseRev() == an_fd.parentRevs()[0]:
self._visualDiff(an_fd, fds, change=an_fd.rev()) # can 3-way
@@ -387,8 +387,8 @@

def _visualDiff(
self,
- an_fd: "FileData",
- fds: List["FileData"],
+ an_fd: FileData,
+ fds: List[FileData],
**opts,
) -> None:
filenames = _lcanonpaths(fds)
@@ -401,10 +401,10 @@
_('View file as it appeared at this revision using the '
'visual editor'),
_committed)
- def editFile(self, fds: List["FileData"]) -> None:
+ def editFile(self, fds: List[FileData]) -> None:
self._editFileAt(fds, fds[0].rawContext())

- def _editFileAt(self, fds: List["FileData"], ctx: "HgContext") -> None:
+ def _editFileAt(self, fds: List[FileData], ctx: HgContext) -> None:
repo = self._repoAgentFor(fds[0]).rawRepo()
filenames = _lcanonpaths(fds)
base, _ = visdiff.snapshot(repo, filenames, ctx)
@@ -416,10 +416,10 @@
_("Open file as it appeared at this revision using the "
"system's default application for this file type"),
_committed)
- def openFile(self, fds: List["FileData"]) -> None:
+ def openFile(self, fds: List[FileData]) -> None:
self._openFileAt(fds, fds[0].rawContext())

- def _openFileAt(self, fds: List["FileData"], ctx: "HgContext") -> None:
+ def _openFileAt(self, fds: List[FileData], ctx: HgContext) -> None:
repo = self._repoAgentFor(fds[0]).rawRepo()
filenames = _lcanonpaths(fds)
base, _ = visdiff.snapshot(repo, filenames, ctx)
@@ -431,7 +431,7 @@
@actionSlot(_('&Save at Revision...'), None, 'Shift+Ctrl+S',
_('Save file as it appeared at this revision'),
_committed)
- def saveFile(self, fds: List["FileData"]) -> None:
+ def saveFile(self, fds: List[FileData]) -> None:
cmdlines = []
for fd in fds:
wfile, ext = os.path.splitext(fd.absoluteFilePath())
@@ -457,7 +457,7 @@
_('Edit current file(s) in working copy with the visual '
'editor'),
(_isfile, _filestatus('MACI?')))
- def editLocalFile(self, fds: List["FileData"]) -> None:
+ def editLocalFile(self, fds: List[FileData]) -> None:
repo = self._repoAgentFor(fds[0]).rawRepo()
filenames = _lcanonpaths(fds)
qtlib.editfiles(repo, filenames, parent=self._parentWidget())
@@ -466,7 +466,7 @@
_("Open current file(s) in working copy with the system's "
"default application for this file type"),
(_isfile, _filestatus('MACI?')))
- def openLocalFile(self, fds: List["FileData"]) -> None:
+ def openLocalFile(self, fds: List[FileData]) -> None:
repo = self._repoAgentFor(fds[0]).rawRepo()
for fd in fds:
qtlib.openlocalurl(fd.absoluteFilePath())
@@ -475,13 +475,13 @@
_('Open parent folder of current file in the system file '
'manager'),
(_isfile, _filestatus('MACI?')))
- def exploreLocalFile(self, fds: List["FileData"]) -> None:
+ def exploreLocalFile(self, fds: List[FileData]) -> None:
for fd in fds:
qtlib.openlocalurl(os.path.dirname(fd.absoluteFilePath()))

@actionSlot(_('&Copy Patch'), 'copy-patch', None, '',
(_notpatch, _notsubroot, _filestatus('MAR!')))
- def copyPatch(self, fds: List["FileData"]) -> None:
+ def copyPatch(self, fds: List[FileData]) -> None:
paths = [hglib.escapepath(fd.filePath()) for fd in fds]
revs = pycompat.maplist(hglib.escaperev,
[fds[0].baseRev(), fds[0].rev()])
@@ -502,20 +502,20 @@

@actionSlot(_('Copy Absolute &Path'), None, 'Shift+Ctrl+C',
_('Copy full path of file(s) to the clipboard'))
- def copyPath(self, fds: List["FileData"]) -> None:
+ def copyPath(self, fds: List[FileData]) -> None:
paths = [e.absoluteFilePath() for e in fds]
QApplication.clipboard().setText(os.linesep.join(paths))

@actionSlot(_('Copy Relative Path'), None, None,
_('Copy repository relative path of file(s) to the clipboard'))
- def copyRelativePath(self, fds: List["FileData"]) -> None:
+ def copyRelativePath(self, fds: List[FileData]) -> None:
paths = [QDir.toNativeSeparators(e.filePath()) for e in fds]
QApplication.clipboard().setText(os.linesep.join(paths))

@actionSlot(_('&Revert to Revision...'), 'hg-revert', 'Shift+Ctrl+R',
_('Revert file(s) to contents at this revision'),
_notpatch)
- def revertFile(self, fds: List["FileData"]) -> None:
+ def revertFile(self, fds: List[FileData]) -> None:
repoagent = self._repoAgentFor(fds[0])
fileSelection = [e.canonicalFilePath() for e in fds]
rev = fds[0].rev()
@@ -529,7 +529,7 @@
@actionSlot(_('Open S&ubrepository'), 'thg-repository-open', None,
_('Open the selected subrepository'),
_subrepotype('hg'))
- def openSubrepo(self, fds: List["FileData"]) -> None:
+ def openSubrepo(self, fds: List[FileData]) -> None:
for fd in fds:
if fd.rev() is None:
link = 'repo:%s' % fd.absoluteFilePath()
@@ -543,14 +543,14 @@
@actionSlot(_('E&xplore Folder'), 'system-file-manager', None,
_('Open the selected folder in the system file manager'),
_isdir)
- def explore(self, fds: List["FileData"]) -> None:
+ def explore(self, fds: List[FileData]) -> None:
for fd in fds:
qtlib.openlocalurl(fd.absoluteFilePath())

@actionSlot(_('Open &Terminal'), 'utilities-terminal', None,
_('Open a shell terminal in the selected folder'),
_isdir)
- def terminal(self, fds: List["FileData"]) -> None:
+ def terminal(self, fds: List[FileData]) -> None:
for fd in fds:
root = hglib.fromunicode(fd.absoluteFilePath())
currentfile = hglib.fromunicode(fd.filePath())
@@ -616,15 +616,15 @@
self._addAction('remergeFileMenu', *self._createRemergeFileMenu())

@property
- def repo(self) -> "localrepo.localrepository":
+ def repo(self) -> localrepo.localrepository:
return self._repoagent.rawRepo()

def _runWorkingFileCommand(
self,
cmdname: Text,
- fds: List["FileData"],
+ fds: List[FileData],
opts: Optional[Dict[Text, Any]]=None,
- ) -> "CmdSession":
+ ) -> CmdSession:
if not opts:
opts = {}
paths = [hglib.escapepath(fd.filePath()) for fd in fds]
@@ -649,31 +649,31 @@
# base revision in amend/qrefresh mode
@actionSlot(_('Diff &Local'), 'ldiff', 'Ctrl+Shift+D', '',
(_indirectbaserev, _notsubroot, _filestatus('MARC!')))
- def visualDiffLocalFile(self, fds: List["FileData"]) -> None:
+ def visualDiffLocalFile(self, fds: List[FileData]) -> None:
self._visualDiff(fds[0], fds)

@actionSlot(_('&View Missing'), None, None, '',
(_isfile, _filestatus('R!')))
- def editMissingFile(self, fds: List["FileData"]) -> None:
+ def editMissingFile(self, fds: List[FileData]) -> None:
wctx = fds[0].rawContext()
self._editFileAt(fds, wctx.p1())

@actionSlot(_('View O&ther'), None, None, '',
(_isfile, _merged, _filestatus('MA')))
- def editOtherFile(self, fds: List["FileData"]) -> None:
+ def editOtherFile(self, fds: List[FileData]) -> None:
wctx = fds[0].rawContext()
self._editFileAt(fds, wctx.p2())

@actionSlot(_('&Add'), 'hg-add', None, '',
(_notsubroot, _filestatus('RI?')))
- def addFile(self, fds: List["FileData"]) -> None:
+ def addFile(self, fds: List[FileData]) -> None:
repo = self._repoAgentFor(fds[0]).rawRepo()
if b'largefiles' in repo.extensions():
self._addFileWithPrompt(fds)
else:
self._runWorkingFileCommand('add', fds)

- def _addFileWithPrompt(self, fds: List["FileData"]) -> None:
+ def _addFileWithPrompt(self, fds: List[FileData]) -> None:
repo = self._repoAgentFor(fds[0]).rawRepo()
result = lfprompt.promptForLfiles(self._parentWidget(), repo.ui, repo,
_lcanonpaths(fds))
@@ -690,17 +690,17 @@

@actionSlot(_('Add &Largefiles...'), None, None, '',
(_notsubroot, _filestatus('I?')))
- def addLargefile(self, fds: List["FileData"]) -> None:
+ def addLargefile(self, fds: List[FileData]) -> None:
self._runWorkingFileCommand('add', fds, {'large': True})

@actionSlot(_('&Forget'), 'hg-remove', None, '',
(_notsubroot, _filestatus('MAC!')))
- def forgetFile(self, fds: List["FileData"]) -> None:
+ def forgetFile(self, fds: List[FileData]) -> None:
self._runWorkingFileCommand('forget', fds)

@actionSlot(_('&Delete Unversioned...'), 'hg-purge', 'Delete', '',
(_notsubroot, _filestatus('?I')))
- def purgeFile(self, fds: List["FileData"]) -> None:
+ def purgeFile(self, fds: List[FileData]) -> None:
parent = self._parentWidget()
files = [hglib.fromunicode(fd.filePath()) for fd in fds]
res = qtlib.CustomPrompt(
@@ -714,12 +714,12 @@

@actionSlot(_('Re&move Versioned'), 'hg-remove', None, '',
(_notsubroot, _filestatus('C')))
- def removeFile(self, fds: List["FileData"]) -> None:
+ def removeFile(self, fds: List[FileData]) -> None:
self._runWorkingFileCommand('remove', fds)

@actionSlot(_('&Revert...'), 'hg-revert', None, '',
_filestatus('MAR!'))
- def revertWorkingFile(self, fds: List["FileData"]) -> None:
+ def revertWorkingFile(self, fds: List[FileData]) -> None:
parent = self._parentWidget()
files = _lcanonpaths(fds)
wctx = cast(context.workingctx, fds[0].rawContext())
@@ -756,15 +756,15 @@

@actionSlot(_('&Copy...'), 'edit-copy', None, '',
(_single, _isfile, _filestatus('MAC')))
- def copyFile(self, fds: List["FileData"]) -> None:
+ def copyFile(self, fds: List[FileData]) -> None:
self._openRenameDialog(fds, iscopy=True)

@actionSlot(_('Re&name...'), 'hg-rename', None, '',
(_single, _isfile, _filestatus('MAC')))
- def renameFile(self, fds: List["FileData"]) -> None:
+ def renameFile(self, fds: List[FileData]) -> None:
self._openRenameDialog(fds, iscopy=False)

- def _openRenameDialog(self, fds: List["FileData"], iscopy: bool) -> None:
+ def _openRenameDialog(self, fds: List[FileData], iscopy: bool) -> None:
from tortoisehg.hgqt.rename import RenameDialog
srcfd, = fds
repoagent = self._repoAgentFor(srcfd)
@@ -775,7 +775,7 @@

@actionSlot(_('&Ignore...'), 'thg-ignore', None, '',
(_notsubroot, _filestatus('?')))
- def editHgignore(self, fds: List["FileData"]) -> None:
+ def editHgignore(self, fds: List[FileData]) -> None:
from tortoisehg.hgqt.hgignore import HgignoreDialog
repoagent = self._repoAgentFor(fds[0])
parent = self._parentWidget()
@@ -788,7 +788,7 @@
@actionSlot(_('Edit Re&jects'), None, None,
_('Manually resolve rejected patch chunks'),
(_single, _isfile, _filestatus('?I'), _filepath(r'\.rej$')))
- def editRejects(self, fds: List["FileData"]) -> None:
+ def editRejects(self, fds: List[FileData]) -> None:
lpath = hglib.fromunicode(fds[0].absoluteFilePath()[:-4]) # drop .rej
dlg = rejects.RejectsDialog(self._ui, lpath, self._parentWidget())
if dlg.exec():
@@ -796,7 +796,7 @@

@actionSlot(_('De&tect Renames...'), 'thg-guess', None, '',
(_isfile, _filestatus('A?!')))
- def guessRename(self, fds: List["FileData"]) -> None:
+ def guessRename(self, fds: List[FileData]) -> None:
from tortoisehg.hgqt.guess import DetectRenameDialog
repoagent = self._repoAgentFor(fds[0])
parent = self._parentWidget()
@@ -813,17 +813,17 @@

@actionSlot(_('&Mark Resolved'), None, None, '',
(_notsubroot, _mergestatus('U')))
- def markFileAsResolved(self, fds: List["FileData"]) -> None:
+ def markFileAsResolved(self, fds: List[FileData]) -> None:
self._runWorkingFileCommand('resolve', fds, {'mark': True})

@actionSlot(_('&Mark Unresolved'), None, None, '',
(_notsubroot, _mergestatus('R')))
- def markFileAsUnresolved(self, fds: List["FileData"]) -> None:
+ def markFileAsUnresolved(self, fds: List[FileData]) -> None:
self._runWorkingFileCommand('resolve', fds, {'unmark': True})

@actionSlot(_('Restart Mer&ge'), None, None, '',
(_notsubroot, _mergestatus('U')))
- def remergeFile(self, fds: List["FileData"]) -> None:
+ def remergeFile(self, fds: List[FileData]) -> None:
self._runWorkingFileCommand('resolve', fds)

def _createRenameFileMenu(self) -> _MenuActionEntry:
diff --git a/tortoisehg/hgqt/filedata.py b/tortoisehg/hgqt/filedata.py
--- a/tortoisehg/hgqt/filedata.py
+++ b/tortoisehg/hgqt/filedata.py
@@ -95,14 +95,14 @@

def __init__(
self,
- ctx: "HgContext",
- ctx2: Optional["HgContext"],
+ ctx: HgContext,
+ ctx2: Optional[HgContext],
wfile: bytes,
status: Optional[Text] = None,
rpath: Optional[bytes] = None,
) -> None:
self._ctx = ctx
- self._pctx: Optional["HgContext"] = ctx2
+ self._pctx: Optional[HgContext] = ctx2
self._wfile = wfile
self._status: Optional[Text] = status
self._rpath: bytes = rpath or b''
@@ -119,7 +119,7 @@

def createRebased(
self: _T_AbstractFileData,
- pctx: "HgContext",
+ pctx: HgContext,
) -> _T_AbstractFileData:
# new status is not known
return self.__class__(self._ctx, pctx, self._wfile, rpath=self._rpath)
@@ -176,10 +176,10 @@
# may contain nullrev, which allows "nullrev in parentRevs()"
return [p.rev() for p in self._ctx.parents()]

- def rawContext(self) -> "HgContext":
+ def rawContext(self) -> HgContext:
return self._ctx

- def rawBaseContext(self) -> Optional["HgContext"]:
+ def rawBaseContext(self) -> Optional[HgContext]:
return self._pctx

# absoluteFilePath : "C:\\Documents\\repo\\foo\\subrepo\\bar\\baz"
@@ -252,8 +252,8 @@

def __init__(
self,
- ctx: "HgContext",
- pctx: Optional["HgContext"],
+ ctx: HgContext,
+ pctx: Optional[HgContext],
path: bytes,
status: Optional[Text] = None,
rpath: Optional[bytes] = None,
@@ -279,11 +279,11 @@

def _checkMaxDiff(
self,
- ctx: "HgContext",
+ ctx: HgContext,
wfile: bytes,
maxdiff: int,
force: bool
- ) -> Tuple["context.basefilectx", bytes]:
+ ) -> Tuple[context.basefilectx, bytes]:
self.error = None
fctx = ctx.filectx(wfile)
size = hglib.getestimatedsize(fctx)
@@ -305,9 +305,9 @@

def _checkRenamed(
self,
- repo: "localrepo.localrepository",
- ctx: "HgContext",
- pctx: Optional["HgContext"],
+ repo: localrepo.localrepository,
+ ctx: HgContext,
+ pctx: Optional[HgContext],
wfile: bytes
) -> Optional[bytes]:
m = scmutil.matchfiles(repo, [wfile])
@@ -325,15 +325,15 @@

def _readStatus(
self,
- ctx: "HgContext",
- ctx2: Optional["HgContext"],
+ ctx: HgContext,
+ ctx2: Optional[HgContext],
wfile: bytes,
status: Text,
changeselect: bool,
force: bool,
) -> None:
def getstatus(
- repo: "localrepo.localrepository",
+ repo: localrepo.localrepository,
n1: Optional[bytes],
n2: Optional[bytes],
wfile: bytes,
@@ -644,8 +644,8 @@

def __init__(
self,
- ctx: "HgContext",
- pctx: Optional["HgContext"],
+ ctx: HgContext,
+ pctx: Optional[HgContext],
path: bytes,
status: Optional[Text],
rpath: Optional[bytes],
@@ -656,7 +656,7 @@

def createRebased(
self: _TSubrepoData,
- pctx: Optional["HgContext"],
+ pctx: Optional[HgContext],
) -> _TSubrepoData:
# new status should be unknown, but currently it is 'S'
# TODO: replace 'S' by subrepo's status
@@ -893,8 +893,8 @@


def createFileData(
- ctx: "ThgContext",
- ctx2: Optional["HgContext"],
+ ctx: ThgContext,
+ ctx2: Optional[HgContext],
wfile: bytes,
status: Optional[Text] = None,
rpath: Optional[bytes] = None,
@@ -916,8 +916,8 @@
return FileData(ctx, ctx2, wfile, status, rpath, mstatus)

def createDirData(
- ctx: "ThgContext",
- pctx: Optional["HgContext"],
+ ctx: ThgContext,
+ pctx: Optional[HgContext],
path: bytes,
rpath: Optional[bytes] = None,
) -> Union[DirData, PatchDirData]:
@@ -935,8 +935,8 @@
return DirData(ctx, pctx, path, rpath=rpath)

def createSubrepoData(
- ctx: "HgContext",
- pctx: Optional["HgContext"],
+ ctx: HgContext,
+ pctx: Optional[HgContext],
path: bytes,
status: Optional[Text] = None,
rpath: Optional[bytes] = None,
@@ -949,7 +949,7 @@
# TODO: replace 'S' by subrepo's status
return SubrepoData(ctx, pctx, path, 'S', rpath, subkind)

-def createNullData(repo: "localrepo.localrepository") -> FileData:
+def createNullData(repo: localrepo.localrepository) -> FileData:
ctx = repo[nullrev]
fd = FileData(ctx, ctx.p1(), b'', 'C')
return fd
diff --git a/tortoisehg/hgqt/fileencoding.py b/tortoisehg/hgqt/fileencoding.py
--- a/tortoisehg/hgqt/fileencoding.py
+++ b/tortoisehg/hgqt/fileencoding.py
@@ -124,7 +124,7 @@
name = codecs.lookup(name).name
return _SUBSTMAP.get(name, name)

-def contentencoding(ui: "uimod.ui", fallbackenc: Optional[Text] = None) -> Text:
+def contentencoding(ui: uimod.ui, fallbackenc: Optional[Text] = None) -> Text:
"""Preferred encoding of file contents in repository"""
# assumes web.encoding is the content encoding, not the filename one
enc = pycompat.sysstr(ui.config(b'web', b'encoding'))
@@ -153,7 +153,7 @@
return localeencs

def guessencoding(
- ui: "uimod.ui",
+ ui: uimod.ui,
data: bytes,
fallbackenc: Optional[Text] = None
) -> Text:
@@ -181,7 +181,7 @@
return prefenc


-def createActionGroup(parent: "QObject") -> QActionGroup:
+def createActionGroup(parent: QObject) -> QActionGroup:
group = QActionGroup(parent)
for enc, region in _ENCODINGNAMES:
a = group.addAction('%s (%s)' % (region, enc))
@@ -189,14 +189,14 @@
a.setData(enc)
return group

-def addCustomAction(group: QActionGroup, name: Text) -> "QAction":
+def addCustomAction(group: QActionGroup, name: Text) -> QAction:
cname = canonname(name) # will raise LookupError for invalid name
a = group.addAction(name)
a.setCheckable(True)
a.setData(cname)
return a

-def addActionsToMenu(menu: "QMenu", group: QActionGroup) -> None:
+def addActionsToMenu(menu: QMenu, group: QActionGroup) -> None:
localeencs = set(_localeencodings())
localeacts = []
otheracts = []
@@ -212,7 +212,7 @@
menu.addSeparator()
menu.addActions(otheracts)

-def findActionByName(group: QActionGroup, name: Text) -> "QAction":
+def findActionByName(group: QActionGroup, name: Text) -> QAction:
cname = canonname(name)
for a in group.actions():
if str(a.data()) == cname:
diff --git a/tortoisehg/hgqt/hgignore.py b/tortoisehg/hgqt/hgignore.py
--- a/tortoisehg/hgqt/hgignore.py
+++ b/tortoisehg/hgqt/hgignore.py
@@ -82,7 +82,7 @@

def __init__(
self,
- repoagent: "RepoAgent",
+ repoagent: RepoAgent,
parent: Optional[QWidget] = None,
*pats: bytes,
) -> None:
diff --git a/tortoisehg/hgqt/manifestmodel.py b/tortoisehg/hgqt/manifestmodel.py
--- a/tortoisehg/hgqt/manifestmodel.py
+++ b/tortoisehg/hgqt/manifestmodel.py
@@ -127,7 +127,7 @@
if role == self.StatusRole:
return self.fileStatus(index)

- e: "_Entry" = index.internalPointer()
+ e: _Entry = index.internalPointer()
if role in (Qt.ItemDataRole.DisplayRole, Qt.ItemDataRole.EditRole):
return e.name

@@ -144,7 +144,7 @@
if not index.isValid():
return filedata.createNullData(repo)

- f: "_Entry" = index.internalPointer()
+ f: _Entry = index.internalPointer()
e = f.parent
while e and e.ctx is None:
e = e.parent
@@ -163,13 +163,13 @@
"""Return the subrepo type the specified index"""
if not index.isValid():
return
- e: "_Entry" = index.internalPointer()
+ e: _Entry = index.internalPointer()
return e.subkind

def fileIcon(self, index: QModelIndex) -> QIcon:
if not index.isValid():
return QIcon()
- e: "_Entry" = index.internalPointer()
+ e: _Entry = index.internalPointer()
k = (e.path, e.status, e.subkind)
try:
return self._iconcache[k]
@@ -177,7 +177,7 @@
self._iconcache[k] = ic = self._makeFileIcon(e)
return ic

- def _makeFileIcon(self, e: "_Entry") -> QIcon:
+ def _makeFileIcon(self, e: _Entry) -> QIcon:
if e.subkind in _subrepoType2IcoMap:
assert e.subkind is not None
ic = qtlib.geticon(_subrepoType2IcoMap[e.subkind])
@@ -207,7 +207,7 @@
"""Return the change status of the specified file"""
if not index.isValid():
return
- e: "_Entry" = index.internalPointer()
+ e: _Entry = index.internalPointer()
# TODO: 'S' should not be a status
if e.subkind:
return 'S'
@@ -218,7 +218,7 @@
"""Return the change status of the specified subrepo"""
if not index.isValid():
return
- e: "_Entry" = index.internalPointer()
+ e: _Entry = index.internalPointer()
if not e.subkind:
return
return e.status
@@ -226,7 +226,7 @@
def isDir(self, index: QModelIndex) -> bool:
if not index.isValid():
return True # root entry must be a directory
- e: "_Entry" = index.internalPointer()
+ e: _Entry = index.internalPointer()
return e.isdir

def mimeData(self, indexes: Iterable[QModelIndex]) -> QMimeData:
@@ -284,13 +284,13 @@
if not index.isValid():
return QModelIndex()

- e: "_Entry" = index.internalPointer()
+ e: _Entry = index.internalPointer()
if e.path:
return self.indexFromPath(e.parent.path, index.column())
else:
return QModelIndex()

- def _parententry(self, parent: QModelIndex) -> "_Entry":
+ def _parententry(self, parent: QModelIndex) -> _Entry:
if parent.isValid():
return parent.internalPointer()
else:
@@ -428,7 +428,7 @@

def _repopulateNodes(self,
newnodeop: Optional[Any] = None,
- newroote: Optional["_Entry"] = None) -> None:
+ newroote: Optional[_Entry] = None) -> None:
"""Recreate populated nodes if any"""
if not self._rootpopulated:
# no stale nodes
@@ -455,7 +455,7 @@

def _newRevNode(self,
rev: Optional[int],
- prev: int = FirstParent) -> "_Entry":
+ prev: int = FirstParent) -> _Entry:
"""Create empty root node for the specified revision"""
if not _isreporev(rev):
raise ValueError('unacceptable revision number: %r' % rev)
@@ -472,7 +472,7 @@
roote.pctx = repo[prev]
return roote

- def _populateNodes(self, roote: "_Entry") -> None:
+ def _populateNodes(self, roote: _Entry) -> None:
repo = self._repoagent.rawRepo()
lpat = hglib.fromunicode(self._namefilter)

@@ -490,17 +490,17 @@
'_child', '_nameindex')

_name: Text
- _parent: Optional["_Entry"]
+ _parent: Optional[_Entry]
status: Optional[Text]
ctx: Optional[ThgContext]
pctx: Optional[ThgContext]
subkind: Optional[Text]
- _child: Dict[Text, "_Entry"]
+ _child: Dict[Text, _Entry]
_nameindex: List[Text]

def __init__(self,
name: Text = '',
- parent: Optional["_Entry"] = None) -> None:
+ parent: Optional[_Entry] = None) -> None:
self._name = name
self._parent = parent
self.status = None
@@ -510,7 +510,7 @@
self._child = {}
self._nameindex = []

- def copyskel(self) -> "_Entry":
+ def copyskel(self) -> _Entry:
"""Create unpopulated copy of this entry"""
e = self.__class__()
e.status = self.status
@@ -520,7 +520,7 @@
return e

@property
- def parent(self) -> Optional["_Entry"]:
+ def parent(self) -> Optional[_Entry]:
return self._parent

@property
@@ -547,16 +547,16 @@

__bool__ = __nonzero__

- def __getitem__(self, name: Text) -> "_Entry":
+ def __getitem__(self, name: Text) -> _Entry:
return self._child[name]

- def makechild(self, name: Text) -> "_Entry":
+ def makechild(self, name: Text) -> _Entry:
if name not in self._child:
self._nameindex.append(name)
self._child[name] = e = self.__class__(name, parent=self)
return e

- def putchild(self, name: Text, e: "_Entry") -> None:
+ def putchild(self, name: Text, e: _Entry) -> None:
assert not e.name and not e.parent, (e.name, e.parent)
e._name = name
e._parent = self
@@ -567,7 +567,7 @@
def __contains__(self, item: Text) -> bool:
return item in self._child

- def at(self, index: int) -> "_Entry":
+ def at(self, index: int) -> _Entry:
return self._child[self._nameindex[index]]

def index(self, name: Text) -> int:
diff --git a/tortoisehg/hgqt/postreview.py b/tortoisehg/hgqt/postreview.py
--- a/tortoisehg/hgqt/postreview.py
+++ b/tortoisehg/hgqt/postreview.py
@@ -71,7 +71,7 @@


class LoadReviewDataThread(QThread):
- def __init__ (self, dialog: "PostReviewDialog") -> None:
+ def __init__ (self, dialog: PostReviewDialog) -> None:
super().__init__(dialog)
self.dialog = dialog

diff --git a/tortoisehg/hgqt/qtlib.py b/tortoisehg/hgqt/qtlib.py
--- a/tortoisehg/hgqt/qtlib.py
+++ b/tortoisehg/hgqt/qtlib.py
@@ -872,7 +872,7 @@
title: Text,
main: Text,
text: Text = '',
- buttons: "Union[QMessageBox.StandardButtons, QMessageBox.StandardButton]" = QMessageBox.StandardButton.Ok,
+ buttons: Union[QMessageBox.StandardButtons, QMessageBox.StandardButton] = QMessageBox.StandardButton.Ok,
labels: Optional[Iterable[Tuple[QMessageBox.StandardButton, Text]]] = None,
parent: Optional[QWidget] = None,
defaultbutton: Optional[Union[QPushButton, QMessageBox.StandardButton]] = None,
@@ -1565,7 +1565,7 @@
label: Text,
mode: QLineEdit.EchoMode = QLineEdit.EchoMode.Normal,
text: Text = '',
- flags: "Union[Qt.WindowType, Qt.WindowFlags]" = Qt.WindowType.Widget,
+ flags: Union[Qt.WindowType, Qt.WindowFlags] = Qt.WindowType.Widget,
) -> Tuple[Text, bool]:
flags |= (Qt.WindowType.CustomizeWindowHint | Qt.WindowType.WindowTitleHint
| Qt.WindowType.WindowCloseButtonHint)
diff --git a/tortoisehg/hgqt/repotreeitem.py b/tortoisehg/hgqt/repotreeitem.py
--- a/tortoisehg/hgqt/repotreeitem.py
+++ b/tortoisehg/hgqt/repotreeitem.py
@@ -56,17 +56,17 @@
_TRepoTreeItem = TypeVar('_TRepoTreeItem', bound='RepoTreeItem')


-def _dumpChild(xw, parent: "RepoTreeItem") -> None:
+def _dumpChild(xw, parent: RepoTreeItem) -> None:
for c in parent.childs:
c.dumpObject(xw)

-def undumpObject(xr) -> "RepoTreeItem":
+def undumpObject(xr) -> RepoTreeItem:
xmltagname = str(xr.name())
obj = _xmlUndumpMap[xmltagname](xr)
assert obj.xmltagname == xmltagname, (obj.xmltagname, xmltagname)
return obj

-def _undumpChild(xr, parent: "RepoTreeItem", undump=undumpObject) -> None:
+def _undumpChild(xr, parent: RepoTreeItem, undump=undumpObject) -> None:
while not xr.atEnd():
xr.readNext()
if xr.isStartElement():
@@ -78,7 +78,7 @@
elif xr.isEndElement():
break

-def flatten(root: "RepoTreeItem", stopfunc=None) -> Iterable["RepoTreeItem"]:
+def flatten(root: RepoTreeItem, stopfunc=None) -> Iterable[RepoTreeItem]:
"""Iterate root and its child items recursively until stop condition"""
yield root
if stopfunc and stopfunc(root):
@@ -86,7 +86,7 @@
for c in root.childs:
yield from flatten(c, stopfunc)

-def find(root: "RepoTreeItem", targetfunc, stopfunc=None) -> "RepoTreeItem":
+def find(root: RepoTreeItem, targetfunc, stopfunc=None) -> RepoTreeItem:
"""Search recursively for item of which targetfunc evaluates to True"""
for e in flatten(root, stopfunc):
if targetfunc(e):
@@ -107,8 +107,8 @@
return _quotenamere.sub(lambda m: '%%%02X' % ord(m.group(0)), s)

def _buildquotenamemap(
- items: Iterable["RepoTreeItem"]
-) -> Dict[str, List["RepoTreeItem"]]:
+ items: Iterable[RepoTreeItem]
+) -> Dict[str, List[RepoTreeItem]]:
namemap = {}
for e in items:
q = _quotename(e.shortname())
@@ -118,7 +118,7 @@
namemap[q].append(e)
return namemap

-def itempath(item: "RepoTreeItem") -> str:
+def itempath(item: RepoTreeItem) -> str:
"""Virtual path to the given item"""
rnames = []
while item.parent():
@@ -132,7 +132,7 @@
item = item.parent()
return '/'.join(reversed(rnames))

-def findbyitempath(root: "RepoTreeItem", path: str) -> "RepoTreeItem":
+def findbyitempath(root: RepoTreeItem, path: str) -> RepoTreeItem:
"""Return the item for the given virtual path

>>> root = RepoTreeItem()
@@ -195,22 +195,22 @@
class RepoTreeItem:
xmltagname = 'treeitem'

- def __init__(self, parent: Optional["RepoTreeItem"] = None) -> None:
- self._parent: Optional["RepoTreeItem"] = parent
- self.childs: List["RepoTreeItem"] = []
+ def __init__(self, parent: Optional[RepoTreeItem] = None) -> None:
+ self._parent: Optional[RepoTreeItem] = parent
+ self.childs: List[RepoTreeItem] = []
self._row = 0

- def appendChild(self, child: "RepoTreeItem") -> None:
+ def appendChild(self, child: RepoTreeItem) -> None:
child._row = len(self.childs)
child._parent = self
self.childs.append(child)

- def insertChild(self, row: int, child: "RepoTreeItem") -> None:
+ def insertChild(self, row: int, child: RepoTreeItem) -> None:
child._row = row
child._parent = self
self.childs.insert(row, child)

- def child(self, row: int) -> "RepoTreeItem":
+ def child(self, row: int) -> RepoTreeItem:
return self.childs[row]

def childCount(self) -> int:
@@ -236,7 +236,7 @@
def row(self) -> int:
return self._row

- def parent(self) -> Optional["RepoTreeItem"]:
+ def parent(self) -> Optional[RepoTreeItem]:
return self._parent

def menulist(self):
diff --git a/tortoisehg/util/hglib.py b/tortoisehg/util/hglib.py
--- a/tortoisehg/util/hglib.py
+++ b/tortoisehg/util/hglib.py
@@ -1432,7 +1432,7 @@
)


-def dirstate_changing_files(repo: "localrepo.localrepository"):
+def dirstate_changing_files(repo: localrepo.localrepository):
try:
changing_files = repo.dirstate.changing_files
except AttributeError:

Matt Harbison

unread,
Feb 28, 2025, 5:14:58 PMFeb 28
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1736205068 18000
# Mon Jan 06 18:11:08 2025 -0500
# Branch stable
# Node ID 8e77415b51c469213c150842146176002ffb00c7
# Parent c5c323e7fa299be703df20629dee428be0013493
# EXP-Topic pyupgrade
pyupgrade: drop the usage of `typing.Text`

This is the `typing_text` fixer in `pyupgrade`. This type was meant to be for
py2/py3 interoperability, being bytes on py2 and str on py3. See hg cb769c0ffe35.

diff --git a/TortoiseHgOverlayServer.py b/TortoiseHgOverlayServer.py
--- a/TortoiseHgOverlayServer.py
+++ b/TortoiseHgOverlayServer.py
@@ -134,7 +134,7 @@
def __init__(self):
self.file = None

- def setfile(self, name: Text) -> None:
+ def setfile(self, name: str) -> None:
oname = name + '.old'
try:
rename(hglib.fromunicode(name), hglib.fromunicode(oname))
@@ -144,7 +144,7 @@
self.msg('%s, Version %s' % (APP_TITLE, version.version()))
self.msg('Logging to file started')

- def msg(self, msg: Text) -> None:
+ def msg(self, msg: str) -> None:
ts = '[%s] ' % time.strftime('%c')
f = self.file
if f:
@@ -159,7 +159,7 @@

iconcache = {}

-def load_icon(name: Text):
+def load_icon(name: str):
from tortoisehg.util.paths import get_tortoise_icon
iconPathName = get_tortoise_icon(name)
if iconPathName and os.path.isfile(iconPathName):
@@ -170,14 +170,14 @@
hicon = LoadIcon(0, win32con.IDI_APPLICATION)
return hicon

-def get_icon(name: Text):
+def get_icon(name: str):
try:
return iconcache[name]
except KeyError:
iconcache[name] = load_icon(name)
return iconcache[name]

-def SetIcon(hwnd, name: Text, add: bool = False) -> None:
+def SetIcon(hwnd, name: str, add: bool = False) -> None:
# Try and find a custom icon
if '--noicon' in sys.argv:
return
@@ -322,7 +322,7 @@

PIPEBUFSIZE = 4096

-def getrepos(batch: Iterable[Text]) -> Tuple[Set[Text], Set[Text]]:
+def getrepos(batch: Iterable[str]) -> Tuple[Set[str], Set[str]]:
roots = set()
notifypaths = set()
for path in batch:
@@ -343,7 +343,7 @@
notifypaths.add(path)
return roots, notifypaths

-def update_batch(batch: Iterable[Text]) -> None:
+def update_batch(batch: Iterable[str]) -> None:
'''updates thgstatus for all paths in batch'''
roots, notifypaths = getrepos(batch)
if roots:
@@ -435,7 +435,7 @@
pass
return show_taskbaricon, hgighlight_taskbaricon

-def update(args: List[Text], hwnd) -> None:
+def update(args: List[str], hwnd) -> None:
batch = []
r = args[0]
print("got update request %s (first in batch)" % r)
@@ -466,7 +466,7 @@
if show and highlight:
SetIcon(hwnd, "hg.ico")

-def remove(args: List[Text]) -> None:
+def remove(args: List[str]) -> None:
path = args[0]
logger.msg('Removing ' + path)
roots, notifypaths = getrepos([path])
@@ -486,7 +486,7 @@
if notifypaths:
shlib.shell_notify([hglib.fromunicode(p) for p in notifypaths])

-def dispatch(req, cmd: Text, args: List[Text], hwnd) -> None:
+def dispatch(req, cmd: str, args: List[str], hwnd) -> None:
print("dispatch(%s)" % req)
if cmd == 'update':
update(args, hwnd)
diff --git a/contrib/nautilus-thg.py b/contrib/nautilus-thg.py
--- a/contrib/nautilus-thg.py
+++ b/contrib/nautilus-thg.py
@@ -82,7 +82,7 @@
nofilecmds = 'about serve synch repoconfig userconfig merge unmerge'.split()

class HgExtensionDefault(GObject.GObject):
- allvfs: Dict[Text, Any]
+ allvfs: Dict[str, Any]

def __init__(self):
self.scanStack = []
@@ -113,12 +113,12 @@
self.gmon = Gio.file_new_for_path(self.notify).monitor(Gio.FileMonitorFlags.NONE, None)
self.gmon.connect('changed', self.notified)

- def icon(self, iname: Text) -> Optional[Text]:
+ def icon(self, iname: str) -> Optional[str]:
return paths.get_tortoise_icon(iname)

def get_path_for_vfs_file(self,
vfs_file,
- store: bool = True) -> Optional[Text]:
+ store: bool = True) -> Optional[str]:
if vfs_file.get_uri_scheme() != 'file':
return None
# TODO: is get_uri returing unicode?
@@ -130,7 +130,7 @@
self.allvfs[path] = vfs_file
return path

- def get_vfs(self, path: Text):
+ def get_vfs(self, path: str):
vfs = self.allvfs.get(path, None)
if vfs and vfs.is_gone():
del self.allvfs[path]
@@ -138,7 +138,7 @@
return vfs

def get_repo_for_path(self,
- path: Text) -> Optional[localrepo.localrepository]:
+ path: str) -> Optional[localrepo.localrepository]:
'''
Find mercurial repository for vfs_file
Returns hg.repo
@@ -156,9 +156,9 @@

def run_dialog(self,
menuitem,
- hgtkcmd: Text,
- cwd: Optional[Text] = None,
- files: Optional[List[Text]] = None) -> None:
+ hgtkcmd: str,
+ cwd: Optional[str] = None,
+ files: Optional[List[str]] = None) -> None:
'''
hgtkcmd - hgtk subcommand
'''
@@ -207,7 +207,7 @@

def _buildMenu(self,
menus: menuthg.thg_menu,
- files: List[Text]) -> List[Nautilus.MenuItem]:
+ files: List[str]) -> List[Nautilus.MenuItem]:
'''Build one level of a menu'''
items = []
if files:
@@ -264,7 +264,7 @@
"Version control status"),

def _get_file_status(self,
- localpath: Text,
+ localpath: str,
repo: Optional[localrepo.localrepository] = None):
cachestate = cachethg.get_state(localpath, repo)
cache2state = {cachethg.UNCHANGED: ('default', 'clean'),
@@ -297,7 +297,7 @@
if root:
self.invalidate(files, root)

- def invalidate(self, paths: List[Text], root: Text = '') -> None:
+ def invalidate(self, paths: List[str], root: str = '') -> None:
started = bool(self.inv_dirs)
if cachethg.cache_pdir == root and root not in self.inv_dirs:
cachethg.overlay_cache.clear()
@@ -325,7 +325,7 @@
self.inv_dirs.clear()

# property page borrowed from http://www.gnome.org/~gpoo/hg/nautilus-hg/
- def __add_row(self, row, label_item: Text, label_value: Text) -> None:
+ def __add_row(self, row, label_item: str, label_value: str) -> None:
label = Gtk.Label(label_item)
label.set_use_markup(True)
label.set_alignment(1, 0)
diff --git a/tortoisehg/hgqt/archive.py b/tortoisehg/hgqt/archive.py
--- a/tortoisehg/hgqt/archive.py
+++ b/tortoisehg/hgqt/archive.py
@@ -81,9 +81,9 @@

def __init__(self,
repoagent: thgrepo.RepoAgent,
- rev: Optional[Text],
+ rev: Optional[str],
parent: Optional[QWidget] = None,
- minrev: Optional[Text] = None) -> None:
+ minrev: Optional[str] = None) -> None:
super().__init__(parent)
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
self._repoagent = repoagent
@@ -254,19 +254,19 @@
rev = self.rootrev_combo.currentText()
return hglib.fromunicode(rev)

- def get_selected_archive_type(self) -> Dict[Text, Text]:
+ def get_selected_archive_type(self) -> Dict[str, str]:
"""Return a dictionary describing the selected archive type"""
return _ARCHIVE_TYPES[self._typesradios.checkedId()]

def update_path(self) -> None:

# pytype: disable=redundant-function-type-comment
- def remove_ext(path: Text) -> Text:
+ def remove_ext(path: str) -> str:
for ext in ('.tar', '.tar.bz2', '.tar.gz', '.zip'):
if path.endswith(ext):
return path.replace(ext, '')
return path
- def remove_rev(path: Text) -> Text:
+ def remove_rev(path: str) -> str:
l = ''
for i in pycompat.xrange(self.rev_combo.count() - 1):
l += self.rev_combo.itemText(i)
@@ -278,9 +278,9 @@
if path.endswith(rev):
return path.replace(rev, '')
return path
- def add_rev(path: Text, rev: Text) -> Text:
+ def add_rev(path: str, rev: str) -> str:
return '%s_%s' % (path, rev)
- def add_ext(path: Text) -> Text:
+ def add_ext(path: str) -> str:
select = self.get_selected_archive_type()
if select['type'] != 'files':
path += select['ext']
@@ -310,7 +310,7 @@
self.compose_command()

@pyqtSlot()
- def compose_command(self) -> List[Text]:
+ def compose_command(self) -> List[str]:
content = self.content_mode.checkedId()
targetrev = hglib.tounicode(self.get_selected_rev())
if content == self._archive_content_all_files:
@@ -376,9 +376,9 @@


def createArchiveDialog(repoagent: thgrepo.RepoAgent,
- rev: Optional[Text] = None,
+ rev: Optional[str] = None,
parent: Optional[QWidget] = None,
- minrev: Optional[Text] = None) -> cmdui.CmdControlDialog:
+ minrev: Optional[str] = None) -> cmdui.CmdControlDialog:
dlg = cmdui.CmdControlDialog(parent)
dlg.setWindowTitle(_('Archive - %s') % repoagent.displayName())
dlg.setWindowIcon(qtlib.geticon('hg-archive'))
diff --git a/tortoisehg/hgqt/backout.py b/tortoisehg/hgqt/backout.py
--- a/tortoisehg/hgqt/backout.py
+++ b/tortoisehg/hgqt/backout.py
@@ -61,7 +61,7 @@
)


-def checkrev(repo: localrepo.localrepository, rev: int) -> Optional[Text]:
+def checkrev(repo: localrepo.localrepository, rev: int) -> Optional[str]:
op1, op2 = repo.dirstate.parents()
if op1 is None:
return _('Backout requires a parent revision')
@@ -375,7 +375,7 @@
self.completeChanged.emit()

@pyqtSlot(str)
- def onLinkActivated(self, cmd: Text) -> None:
+ def onLinkActivated(self, cmd: str) -> None:
if cmd == 'resolve':
dlg = resolve.ResolveDialog(self._repoagent, self)
dlg.exec()
@@ -405,13 +405,13 @@

# pytype: disable=redundant-function-type-comment
# csinfo
- def label_func(widget, item: Text, ctx: HgContext):
+ def label_func(widget, item: str, ctx: HgContext):
if item == 'rev':
return _('Revision:')
elif item == 'parents':
return _('Parents')
raise csinfo.UnknownItem()
- def data_func(widget, item: Text, ctx: HgContext):
+ def data_func(widget, item: str, ctx: HgContext):
if item == 'rev':
return _('Working Directory'), str(ctx)
elif item == 'parents':
@@ -437,7 +437,7 @@
else:
return '<a href="view">%s</a> (%s)' % (text, rev)
elif item == 'parents':
- def branch_markup(branch: Text) -> Text:
+ def branch_markup(branch: str) -> str:
opts = dict(fg='black', bg='#aaffaa')
return qtlib.markup(' %s ' % branch, **opts)
csets = []
@@ -536,7 +536,7 @@
self.msgEntry.moveCursorToEnd()

@pyqtSlot(str)
- def onLinkActivated(self, cmd: Text) -> None:
+ def onLinkActivated(self, cmd: str) -> None:
if cmd == 'view':
dlg = status.StatusDialog(self._repoagent, [], {}, self)
dlg.exec()
diff --git a/tortoisehg/hgqt/clone.py b/tortoisehg/hgqt/clone.py
--- a/tortoisehg/hgqt/clone.py
+++ b/tortoisehg/hgqt/clone.py
@@ -68,7 +68,7 @@
longopts = set(e[1] for e in entry[1])
return b'startrev' in longopts

-def _suggesteddest(src: Text, basedest: Text) -> Text:
+def _suggesteddest(src: str, basedest: str) -> str:
if '://' in basedest:
return basedest
try:
@@ -169,15 +169,15 @@
else:
return chk, text, None

- def chktext2(chklabel: Text,
+ def chktext2(chklabel: str,
stretch: Optional[int] = None) -> Tuple[QCheckBox, QLineEdit]:
# pytype gets confused if the returned tuple is sliced and returned
# without unpacking.
chk, text, _unused = chktext(chklabel, stretch=stretch)
return chk, text

- def chktext3(chklabel: Text,
- btnlabel: Text,
+ def chktext3(chklabel: str,
+ btnlabel: str,
btnslot,
stretch: Optional[int] = None) -> Tuple[QCheckBox, QLineEdit, QPushButton]:
assert btnlabel
@@ -281,17 +281,17 @@
if combo.itemText(i) != combo.currentText())
qs.setValue(key, l[:10])

- def source(self) -> Text:
+ def source(self) -> str:
return self.src_combo.currentText().strip()

- def setSource(self, url: Text) -> None:
+ def setSource(self, url: str) -> None:
self.src_combo.setCurrentIndex(self.src_combo.findText(url))
self.src_combo.setEditText(url)

- def destination(self) -> Text:
+ def destination(self) -> str:
return self.dest_combo.currentText().strip()

- def setDestination(self, url: Text) -> None:
+ def setDestination(self, url: str) -> None:
self.dest_combo.setCurrentIndex(self.dest_combo.findText(url))
self.dest_combo.setEditText(url)

@@ -299,23 +299,23 @@
def _suggestDestination(self) -> None:
self.setDestination(_suggesteddest(self.source(), self.destination()))

- def revSymbol(self) -> Text:
+ def revSymbol(self) -> str:
if not self.rev_chk.isChecked():
return ''
return self.rev_text.text().strip()

- def setRevSymbol(self, rev: Text) -> None:
+ def setRevSymbol(self, rev: str) -> None:
self.rev_chk.setChecked(bool(rev))
self.rev_text.setText(rev)

- def testOption(self, key: Text) -> bool:
+ def testOption(self, key: str) -> bool:
return self._opt_checks[key].isChecked()

- def setOption(self, key: Text, on: bool) -> None:
+ def setOption(self, key: str, on: bool) -> None:
self._opt_checks[key].setChecked(on)

@pyqtSlot()
- def _composeCommand(self) -> List[Text]:
+ def _composeCommand(self) -> List[str]:
opts = {
'verbose': True,
'config': [],
@@ -417,31 +417,31 @@
self.setCommandWidget(CloneWidget(config, cmdagent, self))
self.commandFinished.connect(self._emitCloned)

- def source(self) -> Text:
+ def source(self) -> str:
return self.commandWidget().source()

- def setSource(self, url: Text) -> None:
+ def setSource(self, url: str) -> None:
assert self.isCommandFinished()
self.commandWidget().setSource(url)

- def destination(self) -> Text:
+ def destination(self) -> str:
return self.commandWidget().destination()

- def setDestination(self, url: Text) -> None:
+ def setDestination(self, url: str) -> None:
assert self.isCommandFinished()
self.commandWidget().setDestination(url)

- def revSymbol(self) -> Text:
+ def revSymbol(self) -> str:
return self.commandWidget().revSymbol()

- def setRevSymbol(self, rev: Text) -> None:
+ def setRevSymbol(self, rev: str) -> None:
assert self.isCommandFinished()
self.commandWidget().setRevSymbol(rev)

- def testOption(self, key: Text) -> bool:
+ def testOption(self, key: str) -> bool:
return self.commandWidget().testOption(key)

- def setOption(self, key: Text, on: bool) -> None:
+ def setOption(self, key: str, on: bool) -> None:
assert self.isCommandFinished()
self.commandWidget().setOption(key, on)

diff --git a/tortoisehg/hgqt/close_branch.py b/tortoisehg/hgqt/close_branch.py
--- a/tortoisehg/hgqt/close_branch.py
+++ b/tortoisehg/hgqt/close_branch.py
@@ -65,7 +65,7 @@
hglib.tounicode(self._repo[self._rev].branch()))
form.addRow(_('Commit message:'), self.hg_commit)

- def compose_command(self) -> List[Text]:
+ def compose_command(self) -> List[str]:
rev = '%d' % self._rev
cmdline = hglib.buildcmdargs('close-head', m=self.hg_commit.text(),
r=rev)
diff --git a/tortoisehg/hgqt/cmdcore.py b/tortoisehg/hgqt/cmdcore.py
--- a/tortoisehg/hgqt/cmdcore.py
+++ b/tortoisehg/hgqt/cmdcore.py
@@ -68,10 +68,10 @@
if hglib.TYPE_CHECKING:
# pseudo implementation to help pytype (TODO: replace with attr.s)
def __init__(self,
- topic: Union[bytes, Text],
+ topic: Union[bytes, str],
pos: Optional[int],
- item: Union[bytes, Text] = b'',
- unit: Union[bytes, Text] = b'',
+ item: Union[bytes, str] = b'',
+ unit: Union[bytes, str] = b'',
total: Optional[int] = None) -> None:
super().__init__((
hglib.tounicode(topic),
@@ -116,12 +116,12 @@
self._dataout = None

def setPrompt(self,
- text: Text,
+ text: str,
mode: int,
- default: Optional[Text] = None) -> None:
+ default: Optional[str] = None) -> None:
pass

- def getLineInput(self) -> Optional[Text]:
+ def getLineInput(self) -> Optional[str]:
# '' to use default; None to abort
return ''

@@ -195,7 +195,7 @@
def stopService(self) -> None:
# {Starting,Ready,Restarting}->Stopping; *->*
pass
- def startCommand(self, cmdline: List[Text], uihandler: UiHandler) -> None:
+ def startCommand(self, cmdline: List[str], uihandler: UiHandler) -> None:
raise NotImplementedError
def abortCommand(self) -> None:
raise NotImplementedError
@@ -263,7 +263,7 @@
def __init__(self,
ui: uimod.ui,
parent: Optional[QObject] = None,
- cwd: Optional[Text] = None) -> None:
+ cwd: Optional[str] = None) -> None:
super().__init__(parent)
self._ui = ui
self._uihandler = None
@@ -276,7 +276,7 @@
proc.readyReadStandardError.connect(self._stderr)
proc.errorOccurred.connect(self._handleerror)

- def startCommand(self, cmdline: List[Text], uihandler: UiHandler) -> None:
+ def startCommand(self, cmdline: List[str], uihandler: UiHandler) -> None:
self._uihandler = uihandler
fullcmdline = _proccmdline(self._ui, _localprocexts)
fullcmdline.extend(cmdline)
@@ -336,7 +336,7 @@
def __init__(self,
ui: uimod.ui,
parent: Optional[QObject] = None,
- cwd: Optional[Text] = None) -> None:
+ cwd: Optional[str] = None) -> None:
super().__init__(parent)
self._ui = ui
self._uihandler = UiHandler()
@@ -430,7 +430,7 @@
def isCommandRunning(self) -> bool:
return self._readchtable is self._runcommandchtable

- def startCommand(self, cmdline: List[Text], uihandler: UiHandler) -> None:
+ def startCommand(self, cmdline: List[str], uihandler: UiHandler) -> None:
assert self._servicestate == CmdWorker.Ready, self._servicestate
assert not self.isCommandRunning()
try:
@@ -617,7 +617,7 @@
}


-_workertypes: Dict[Text, Callable[[uimod.ui, Optional[QObject], Optional[Text]], CmdWorker]] = {
+_workertypes: Dict[str, Callable[[uimod.ui, Optional[QObject], Optional[str]], CmdWorker]] = {
'proc': CmdProc,
'server': CmdServer,
}
@@ -637,7 +637,7 @@
readyRead = pyqtSignal()

def __init__(self,
- cmdlines: List[List[Text]],
+ cmdlines: List[List[str]],
uihandler: UiHandler,
parent: Optional[QObject] = None) -> None:
super().__init__(parent)
@@ -685,14 +685,14 @@
"""True if a command is running; False if finished or not started yet"""
return bool(self._worker) and self._qnextp > 0

- def errorString(self) -> Text:
+ def errorString(self) -> str:
"""Error message received in the last command"""
if self._abortbyuser:
return _('Terminated by user')
else:
return ''.join(self._erroroutputs).rstrip()

- def warningString(self) -> Text:
+ def warningString(self) -> str:
"""Warning message received in the last command"""
return ''.join(self._warningoutputs).rstrip()

@@ -872,8 +872,8 @@
def __init__(self,
ui: uimod.ui,
parent: Optional[QObject] = None,
- cwd: Optional[Text] = None,
- worker: Optional[Text] = None) -> None:
+ cwd: Optional[str] = None,
+ worker: Optional[str] = None) -> None:
super().__init__(parent)
self._ui = ui
self._worker = self._createWorker(cwd, worker or 'server')
@@ -922,14 +922,14 @@
sess.setParent(None)

def runCommand(self,
- cmdline: List[Text],
+ cmdline: List[str],
uihandler: Optional[Union[QWidget, UiHandler]] = None) -> CmdSession:
"""Executes a single Mercurial command asynchronously and returns
new CmdSession object"""
return self.runCommandSequence([cmdline], uihandler)

def runCommandSequence(self,
- cmdlines: List[List[Text]],
+ cmdlines: List[List[str]],
uihandler: Optional[Union[QWidget, UiHandler]] = None) -> CmdSession:
"""Executes a series of Mercurial commands asynchronously and returns
new CmdSession object which will provide notification signals.
@@ -963,7 +963,7 @@
for sess in self._sessqueue[:]:
sess.abort()

- def _createWorker(self, cwd: Optional[Text], name: Text) -> CmdWorker:
+ def _createWorker(self, cwd: Optional[str], name: str) -> CmdWorker:
self._ui.debug(b"creating cmdworker '%s'\n" % pycompat.sysbytes(name))
worker = _workertypes[name](self._ui, self, cwd)
worker.serviceStateChanged.connect(self._tryEmitServiceStopped)
diff --git a/tortoisehg/hgqt/commit.py b/tortoisehg/hgqt/commit.py
--- a/tortoisehg/hgqt/commit.py
+++ b/tortoisehg/hgqt/commit.py
@@ -104,10 +104,10 @@

# `opts` arg type internal to this module. Public classes use
# Dict[Text, bytes] to support @command.
- CommitOpts = Dict[Text, Union[bool, Text]]
+ CommitOpts = Dict[str, Union[bool, str]]

# TODO: simplify to just be List[Text]?
- CmdLines = List[List[Union[bytes, Text]]]
+ CmdLines = List[List[Union[bytes, str]]]

if os.name == 'nt':
from ..util import bugtraq
@@ -133,7 +133,7 @@

return opts

-def commitopts2str(opts: CommitOpts, mode: Text = 'commit') -> Text:
+def commitopts2str(opts: CommitOpts, mode: str = 'commit') -> str:
optslist = []
for opt, value in opts.items():
if opt in ['user', 'date', 'pushafter', 'autoinc',
@@ -147,7 +147,7 @@
optslist.append('--%s=%s' % (opt, value))
return ' '.join(optslist)

-def mergecommitmessage(repo: localrepo.localrepository) -> Text:
+def mergecommitmessage(repo: localrepo.localrepository) -> str:
wctx = repo[None]
engmsg = repo.ui.configbool(b'tortoisehg', b'engmsg')
bcustommsg = repo.ui.config(b'tortoisehg', b'mergecommitmessage')
@@ -163,7 +163,7 @@
return text

def _getUserOptions(opts: CommitOpts,
- optionlist: Iterable[Text]) -> List[Text]:
+ optionlist: Iterable[str]) -> List[str]:
out = []
for opt in optionlist:
if opt not in opts:
@@ -185,9 +185,9 @@
isnew: bool,
stwidget: status.StatusWidget,
pnwidget: QLineEdit,
- message: Text,
+ message: str,
opts: CommitOpts,
- olist: Iterable[Text]) -> Optional[CmdLines]:
+ olist: Iterable[str]) -> Optional[CmdLines]:
# TODO: convert all bytes to unicode in the return value
if isnew:
name = pnwidget.text()
@@ -242,9 +242,9 @@
def __init__(self,
repoagent: RepoAgent,
pats: List[bytes],
- opts: Dict[Text, bytes],
+ opts: Dict[str, bytes],
parent: Optional[QObject] = None,
- rev: Optional[Text] = None) -> None:
+ rev: Optional[str] = None) -> None:
# TODO: drop `opts`, since it is immediately overwritten?
# TODO: make `rev` a byte string?
QWidget.__init__(self, parent)
@@ -416,11 +416,11 @@
return self._repoagent.rawRepo()

@property
- def rev(self) -> Text:
+ def rev(self) -> str:
"""Return current revision"""
return self._rev

- def selectRev(self, rev: Text) -> None:
+ def selectRev(self, rev: str) -> None:
"""
Select the revision that must be set when the dialog is shown again
"""
@@ -439,7 +439,7 @@
self.commitSetAction(refresh=True,
actionName=preferredActionName)

- def _getPreferredActionName(self) -> Text:
+ def _getPreferredActionName(self) -> str:
"""Select the preferred action, depending on the selected revision"""
if not self.hasmqbutton:
return 'commit'
@@ -510,7 +510,7 @@
def __init__(self, parent, repo):
self.repo = repo
QMenu.__init__(self, parent)
- def getActionByName(self, act: Text) -> QAction:
+ def getActionByName(self, act: str) -> QAction:
return [a for a in self.actions() if a._name == act][0]
def showEvent(self, event):
for a in self.actions():
@@ -541,7 +541,7 @@
@pyqtSlot(bool)
def commitSetAction(self,
refresh: bool = False,
- actionName: Optional[Text] = None) -> None:
+ actionName: Optional[str] = None) -> None:
# TODO: should this slot also be declared with str arg?
allowcs = False
if actionName:
@@ -690,7 +690,7 @@
self._runCommand(curraction._name, wholecmdlines)

@pyqtSlot(str, str)
- def fileDisplayed(self, wfile: Text, contents: Text) -> None:
+ def fileDisplayed(self, wfile: str, contents: str) -> None:
'Status widget is displaying a new file'
if not (wfile and contents):
return
@@ -900,7 +900,7 @@
self.msgte.setFocus()
self.refresh()

- def canUndo(self) -> Optional[Text]:
+ def canUndo(self) -> Optional[str]:
'Returns undo description or None if not valid'
desc, oldlen = hglib.readundodesc(self.repo)
if desc == 'commit':
@@ -948,7 +948,7 @@
self.setMessage(message)
self.msgte.setFocus()

- def setMessage(self, msg: Text, modified: bool = False) -> None:
+ def setMessage(self, msg: str, modified: bool = False) -> None:
self.msgte.setText(msg)
self.msgte.moveCursorToEnd()
self.msgte.setModified(modified)
@@ -958,7 +958,7 @@
return False
return self._cmdsession.isFinished()

- def loadSettings(self, s: QSettings, prefix: Text) -> None:
+ def loadSettings(self, s: QSettings, prefix: str) -> None:
'Load history, etc, from QSettings instance'
repoid = hglib.shortrepoid(self.repo)
lpref = prefix + '/commit/' # local settings (splitter, etc)
@@ -984,7 +984,7 @@
except OSError:
pass

- def saveSettings(self, s: QSettings, prefix: Text) -> None:
+ def saveSettings(self, s: QSettings, prefix: str) -> None:
'Save history, etc, in QSettings instance'
try:
repoid = hglib.shortrepoid(self.repo)
@@ -1000,14 +1000,14 @@
except OSError:
pass

- def addMessageToHistory(self, umsg: Text) -> None:
+ def addMessageToHistory(self, umsg: str) -> None:
if umsg in self.msghistory:
self.msghistory.remove(umsg)
self.msghistory.insert(0, umsg)
self.msghistory = self.msghistory[:10]
self.updateRecentMessages()

- def addUsernameToHistory(self, user: Text) -> None:
+ def addUsernameToHistory(self, user: str) -> None:
if user in self.userhist:
self.userhist.remove(user)
self.userhist.insert(0, user)
@@ -1215,7 +1215,7 @@
def stop(self):
self._cmdsession.abort()

- def _runCommand(self, action: Text, cmdlines: CmdLines) -> None:
+ def _runCommand(self, action: str, cmdlines: CmdLines) -> None:
self.currentAction = action
self.progress.emit(*cmdui.startProgress(_topicmap[action], ''))
self.commitButtonEnable.emit(False)
@@ -1259,9 +1259,9 @@
def __init__(self,
repoagent: RepoAgent,
opts: CommitOpts,
- userhistory: List[Text],
+ userhistory: List[str],
parent: QWidget,
- mode: Text = 'commit') -> None:
+ mode: str = 'commit') -> None:
QDialog.__init__(self, parent)
self.setWindowTitle(_('%s - commit options') % repoagent.displayName())
self._repoagent = repoagent
@@ -1512,7 +1512,7 @@
hglib.exception_str(e), parent=self)

def accept(self):
- outopts: Dict[Text, Text] = {}
+ outopts: Dict[str, str] = {}
if self.datecb.isChecked():
udate = self.datele.text()
date = hglib.fromunicode(udate)
@@ -1566,7 +1566,7 @@
def __init__(self,
repoagent: RepoAgent,
pats: List[bytes],
- opts: Dict[Text, bytes],
+ opts: Dict[str, bytes],
parent: Optional[QObject] = None) -> None:
QDialog.__init__(self, parent)
self.setWindowFlags(Qt.WindowType.Window)
@@ -1621,11 +1621,11 @@
self.commit.msgte.setFocus()
qtlib.newshortcutsforstdkey(QKeySequence.StandardKey.Refresh, self, self.refresh)

- def linkActivated(self, link: Text) -> None:
+ def linkActivated(self, link: str) -> None:
if link.startswith('repo:'):
self._subdialogs.open(link[len('repo:'):])

- def _createSubDialog(self, uroot: Text) -> CommitDialog:
+ def _createSubDialog(self, uroot: str) -> CommitDialog:
repoagent = self._repoagent.subRepoAgent(uroot)
return CommitDialog(repoagent, [], {}, parent=self)

diff --git a/tortoisehg/hgqt/filectxactions.py b/tortoisehg/hgqt/filectxactions.py
--- a/tortoisehg/hgqt/filectxactions.py
+++ b/tortoisehg/hgqt/filectxactions.py
@@ -74,9 +74,9 @@
from ..util.typelib import HgContext
FileData = _AbstractFileData

-_ActionTableEntry = Tuple[Text, Optional[Text], Optional[Text], Text,
+_ActionTableEntry = Tuple[str, Optional[str], Optional[str], str,
Tuple["_FileDataFilter", ...]]
-_ActionTable = Dict[Text, _ActionTableEntry]
+_ActionTable = Dict[str, _ActionTableEntry]

# The filter function type to reduce the list of input FileData entries.
_FileDataFilter = Callable[[List["FileData"]], List["FileData"]]
@@ -102,10 +102,10 @@
return [e for e in fds if e.rev() is not None and e.rev() >= 0]
# pytype: enable=unsupported-operands

-def _filepath(pat: Text) -> _FileDataFilter:
+def _filepath(pat: str) -> _FileDataFilter:
patre = re.compile(pat)
return lambda fds: [e for e in fds if patre.search(e.filePath())]
-def _filestatus(s: Text) -> _FileDataFilter:
+def _filestatus(s: str) -> _FileDataFilter:
s = frozenset(s)
# include directory since its status is unknown
return lambda fds: [e for e in fds if e.isDir() or e.fileStatus() in s]
@@ -117,7 +117,7 @@
return [e for e in fds if not e.isDir()]
def _merged(fds: List[FileData]) -> List[FileData]:
return [e for e in fds if len(e.rawContext().parents()) > 1]
-def _mergestatus(s: Text) -> _FileDataFilter:
+def _mergestatus(s: str) -> _FileDataFilter:
s = frozenset(s)
# include directory since its status is unknown
return lambda fds: [e for e in fds if e.isDir() or e.mergeStatus() in s]
@@ -134,7 +134,7 @@
if len(fds) != 1:
return []
return fds
-def _subrepotype(t: Text) -> _FileDataFilter:
+def _subrepotype(t: str) -> _FileDataFilter:
return lambda fds: [e for e in fds if e.subrepoType() == t]

def _filterby(
@@ -197,8 +197,8 @@
FilectxActions._gennavdialogkey,
self)

- self._actions: Dict[Text, _MenuActionEntry] = {}
- self._customactions: Dict[Text, _MenuActionEntry] = {}
+ self._actions: Dict[str, _MenuActionEntry] = {}
+ self._customactions: Dict[str, _MenuActionEntry] = {}
for name, d in self._actiontable.items():
desc, icon, key, tip, fdfilters = d
# QAction must be owned by QWidget; otherwise statusTip for context
@@ -245,7 +245,7 @@
for act, fdfilters in allactions:
act.setEnabled(idle and bool(_filterby(fdfilters, selfds)))

- def fileDataListForAction(self, name: Text) -> List[FileData]:
+ def fileDataListForAction(self, name: str) -> List[FileData]:
fdfilters = self._actions[name][1]
return _filterby(fdfilters, self._selfds)

@@ -257,25 +257,25 @@
"""List of the actions; The owner widget should register them"""
return [a for a, _f in self._actions.values()]

- def action(self, name: Text) -> QAction:
+ def action(self, name: str) -> QAction:
return self._actions[name][0]

def _addAction(
- self, name: Text,
+ self, name: str,
action: QAction,
fdfilters: Tuple[_FileDataFilter, ...]
) -> None:
assert name not in self._actions, name
self._actions[name] = action, fdfilters

- def _runCommand(self, cmdline: List[Text]) -> CmdSession:
+ def _runCommand(self, cmdline: List[str]) -> CmdSession:
if not self._cmdsession.isFinished():
return cmdcore.nullCmdSession()
sess = self._repoagent.runCommand(cmdline, self._parentWidget())
self._handleNewCommand(sess)
return sess

- def _runCommandSequence(self, cmdlines: List[List[Text]]) -> CmdSession:
+ def _runCommandSequence(self, cmdlines: List[List[str]]) -> CmdSession:
if not self._cmdsession.isFinished():
return cmdcore.nullCmdSession()
sess = self._repoagent.runCommandSequence(cmdlines, self._parentWidget())
@@ -556,7 +556,7 @@
currentfile = hglib.fromunicode(fd.filePath())
qtlib.openshell(root, currentfile, self._ui)

- def setupCustomToolsMenu(self, location: Text) -> None:
+ def setupCustomToolsMenu(self, location: str) -> None:
tools, toollist = hglib.tortoisehgtools(self._ui, location)
submenu = QMenu(_('Custom Tools'), self._parentWidget())
submenu.triggered.connect(self._runCustomCommandByMenu)
@@ -621,9 +621,9 @@

def _runWorkingFileCommand(
self,
- cmdname: Text,
+ cmdname: str,
fds: List[FileData],
- opts: Optional[Dict[Text, Any]]=None,
+ opts: Optional[Dict[str, Any]]=None,
) -> CmdSession:
if not opts:
opts = {}
diff --git a/tortoisehg/hgqt/filedata.py b/tortoisehg/hgqt/filedata.py
--- a/tortoisehg/hgqt/filedata.py
+++ b/tortoisehg/hgqt/filedata.py
@@ -66,7 +66,7 @@
return True
return False

-def _checkdifferror(data: bytes, maxdiff: int) -> Optional[Text]:
+def _checkdifferror(data: bytes, maxdiff: int) -> Optional[str]:
p = _('Diff not displayed: ')
size = len(data)
if size > maxdiff:
@@ -78,7 +78,7 @@
# it's incredibly slow to render long line by QScintilla
return p + _('File may be binary (maximum line length exceeded)')

-def _trimdiffheader(diff: Text) -> Text:
+def _trimdiffheader(diff: str) -> str:
# trim first three lines, for example:
# diff -r f6bfc41af6d7 -r c1b18806486d tortoisehg/hgqt/mq.py
# --- a/tortoisehg/hgqt/mq.py
@@ -98,21 +98,21 @@
ctx: HgContext,
ctx2: Optional[HgContext],
wfile: bytes,
- status: Optional[Text] = None,
+ status: Optional[str] = None,
rpath: Optional[bytes] = None,
) -> None:
self._ctx = ctx
self._pctx: Optional[HgContext] = ctx2
self._wfile = wfile
- self._status: Optional[Text] = status
+ self._status: Optional[str] = status
self._rpath: bytes = rpath or b''
self.contents: Optional[bytes] = None
- self.ucontents: Optional[Text] = None
- self.error: Optional[Text] = None
+ self.ucontents: Optional[str] = None
+ self.error: Optional[str] = None
self.olddata: Optional[bytes] = None
self.diff: Optional[bytes] = None
- self.flabel: Text = u''
- self.elabel: Text = u''
+ self.flabel: str = u''
+ self.elabel: str = u''
self.changes: Optional[patch.header] = None

self._textencoding = fileencoding.contentencoding(ctx.repo().ui)
@@ -188,46 +188,46 @@
# filePath : "foo/subrepo/bar/baz"
# repoRootPath : "foo/subrepo"

- def absoluteFilePath(self) -> Text:
+ def absoluteFilePath(self) -> str:
"""Absolute file-system path of this file"""
repo = self._ctx.repo()
return hglib.tounicode(os.path.normpath(repo.wjoin(self._wfile)))

- def absoluteRepoRootPath(self) -> Text:
+ def absoluteRepoRootPath(self) -> str:
"""Absolute file-system path to the root of the container repository"""
# repo.root should be normalized
repo = self._ctx.repo()
return hglib.tounicode(repo.root)

- def canonicalFilePath(self) -> Text:
+ def canonicalFilePath(self) -> str:
"""Path relative to the repository root which contains this file"""
return hglib.tounicode(self._wfile)

- def filePath(self) -> Text:
+ def filePath(self) -> str:
"""Path relative to the top repository root in the current context"""
return hglib.tounicode(posixpath.join(self._rpath, self._wfile))

- def repoRootPath(self) -> Text:
+ def repoRootPath(self) -> str:
"""Root path of the container repository relative to the top repository
in the current context; '' for top repository"""
return hglib.tounicode(self._rpath)

- def fileStatus(self) -> Optional[Text]:
+ def fileStatus(self) -> Optional[str]:
return self._status

def isDir(self) -> bool:
return not self._wfile

- def mergeStatus(self) -> Optional[Text]:
+ def mergeStatus(self) -> Optional[str]:
pass

- def subrepoType(self) -> Optional[Text]:
+ def subrepoType(self) -> Optional[str]:
pass

- def textEncoding(self) -> Text:
+ def textEncoding(self) -> str:
return self._textencoding

- def setTextEncoding(self, name: Text) -> None:
+ def setTextEncoding(self, name: str) -> None:
self._textencoding = fileencoding.canonname(name)

def detectTextEncoding(self) -> None:
@@ -238,13 +238,13 @@
fallbackenc = self._textencoding
self._textencoding = fileencoding.guessencoding(ui, data, fallbackenc)

- def _textToUnicode(self, s: bytes) -> Text:
+ def _textToUnicode(self, s: bytes) -> str:
return s.decode(self._textencoding, 'replace')

- def diffText(self) -> Text:
+ def diffText(self) -> str:
return self._textToUnicode(self.diff or b'')

- def fileText(self) -> Text:
+ def fileText(self) -> str:
return self._textToUnicode(self.contents or b'')


@@ -255,12 +255,12 @@
ctx: HgContext,
pctx: Optional[HgContext],
path: bytes,
- status: Optional[Text] = None,
+ status: Optional[str] = None,
rpath: Optional[bytes] = None,
- mstatus: Optional[Text] = None,
+ mstatus: Optional[str] = None,
) -> None:
super().__init__(ctx, pctx, path, status, rpath)
- self._mstatus: Optional[Text] = mstatus
+ self._mstatus: Optional[str] = mstatus

def load(self, changeselect: bool = False, force: bool = False) -> None:
if self.rev() == nullrev:
@@ -328,7 +328,7 @@
ctx: HgContext,
ctx2: Optional[HgContext],
wfile: bytes,
- status: Text,
+ status: str,
changeselect: bool,
force: bool,
) -> None:
@@ -337,7 +337,7 @@
n1: Optional[bytes],
n2: Optional[bytes],
wfile: bytes,
- ) -> Optional[Text]:
+ ) -> Optional[str]:
m = scmutil.matchfiles(repo, [wfile])
st = repo.status(n1, n2, match=m)
if wfile in st.modified:
@@ -514,10 +514,10 @@
else:
self.diff = b''

- def mergeStatus(self) -> Optional[Text]:
+ def mergeStatus(self) -> Optional[str]:
return self._mstatus

- def diffText(self) -> Text:
+ def diffText(self) -> str:
udiff = self._textToUnicode(self.diff or b'')
if self.changes:
return udiff
@@ -605,7 +605,7 @@
# patch has no comparison base
return nullrev

- def diffText(self) -> Text:
+ def diffText(self) -> str:
return _trimdiffheader(self._textToUnicode(self.diff or b''))


@@ -647,9 +647,9 @@
ctx: HgContext,
pctx: Optional[HgContext],
path: bytes,
- status: Optional[Text],
+ status: Optional[str],
rpath: Optional[bytes],
- subkind: Text,
+ subkind: str,
) -> None:
super().__init__(ctx, pctx, path, status, rpath)
self._subkind = subkind
@@ -676,8 +676,8 @@
self.flabel = u'<b>%s</b>' % self.filePath()

try:
- def genSubrepoRevChangedDescription(subrelpath: bytes, sfrom: Text, sto: Text,
- repo: localrepo.localrepository) -> Tuple[List[Text], Text]:
+ def genSubrepoRevChangedDescription(subrelpath: bytes, sfrom: str, sto: str,
+ repo: localrepo.localrepository) -> Tuple[List[str], str]:
"""Generate a subrepository revision change description"""
out = []
def getLog(_ui, srepo, opts):
@@ -888,7 +888,7 @@
def isDir(self) -> bool:
return True

- def subrepoType(self) -> Text:
+ def subrepoType(self) -> str:
return self._subkind


@@ -896,9 +896,9 @@
ctx: ThgContext,
ctx2: Optional[HgContext],
wfile: bytes,
- status: Optional[Text] = None,
+ status: Optional[str] = None,
rpath: Optional[bytes] = None,
- mstatus: Optional[Text] = None,
+ mstatus: Optional[str] = None,
) -> Union[FileData, PatchFileData]:
if isinstance(ctx, patchctx.patchctx):
if mstatus:
@@ -938,9 +938,9 @@
ctx: HgContext,
pctx: Optional[HgContext],
path: bytes,
- status: Optional[Text] = None,
+ status: Optional[str] = None,
rpath: Optional[bytes] = None,
- subkind: Optional[Text] = None,
+ subkind: Optional[str] = None,
) -> SubrepoData:
if not subkind:
subkind = pycompat.sysstr(
diff --git a/tortoisehg/hgqt/filedialogs.py b/tortoisehg/hgqt/filedialogs.py
--- a/tortoisehg/hgqt/filedialogs.py
+++ b/tortoisehg/hgqt/filedialogs.py
@@ -432,7 +432,7 @@
Qt4 dialog to display diffs between different mercurial revisions of a file.
"""

- filedata: Dict[Text, List[str]]
+ filedata: Dict[str, List[str]]

def __init__(self, repoagent, filename):
super().__init__(repoagent, filename)
diff --git a/tortoisehg/hgqt/fileencoding.py b/tortoisehg/hgqt/fileencoding.py
--- a/tortoisehg/hgqt/fileencoding.py
+++ b/tortoisehg/hgqt/fileencoding.py
@@ -47,7 +47,7 @@
#
# - no UTF-16 or -32, which is binary in Mercurial
# - no ASCII because it can be represented in other encodings
-_ENCODINGNAMES: List[Tuple[Text, Text]] = [
+_ENCODINGNAMES: List[Tuple[str, str]] = [
('utf-8', _('Unicode')),
('iso8859-1', _('Western Europe')),
('cp1252', _('Western Europe')),
@@ -85,7 +85,7 @@
]

# map to wider encoding included in the table
-_SUBSTMAP: Dict[Text, Text] = {
+_SUBSTMAP: Dict[str, str] = {
'ascii': 'utf-8',
'shift_jis': 'cp932',
}
@@ -103,10 +103,10 @@
# cp1251, koi8-r, koi8-u, iso8859-7, cp1253, cp1254, cp1256, iso8859-6,
# cp1255, iso8859-8, cp1258, iso8859-4, iso8859-13, cp1257, iso8859-3,
# iso8859-10, iso8859-14, iso8859-16
-_LOCALEENCODINGS: Text = _('$FILE_ENCODINGS').replace('$FILE_ENCODINGS', '')
+_LOCALEENCODINGS: str = _('$FILE_ENCODINGS').replace('$FILE_ENCODINGS', '')


-def canonname(name: Text) -> Text:
+def canonname(name: str) -> str:
"""Resolve aliases and substitutions of the specified encoding

>>> canonname('Shift_JIS')
@@ -124,7 +124,7 @@
name = codecs.lookup(name).name
return _SUBSTMAP.get(name, name)

-def contentencoding(ui: uimod.ui, fallbackenc: Optional[Text] = None) -> Text:
+def contentencoding(ui: uimod.ui, fallbackenc: Optional[str] = None) -> str:
"""Preferred encoding of file contents in repository"""
# assumes web.encoding is the content encoding, not the filename one
enc = pycompat.sysstr(ui.config(b'web', b'encoding'))
@@ -136,11 +136,11 @@
% pycompat.sysbytes(enc))
return canonname(fallbackenc or pycompat.sysstr(encoding.encoding))

-def knownencodings() -> List[Text]:
+def knownencodings() -> List[str]:
"""List of encoding names which are likely used"""
return [enc for enc, _region in _ENCODINGNAMES]

-def _localeencodings() -> List[Text]:
+def _localeencodings() -> List[str]:
localeencs = []
if _LOCALEENCODINGS:
localeencs.extend(canonname(e) for e in _LOCALEENCODINGS.split(','))
@@ -155,8 +155,8 @@
def guessencoding(
ui: uimod.ui,
data: bytes,
- fallbackenc: Optional[Text] = None
-) -> Text:
+ fallbackenc: Optional[str] = None
+) -> str:
"""Guess encoding of the specified data from locale-specific candidates

This is faster than chardet.detect() and works well for structured
@@ -189,7 +189,7 @@
a.setData(enc)
return group

-def addCustomAction(group: QActionGroup, name: Text) -> QAction:
+def addCustomAction(group: QActionGroup, name: str) -> QAction:
cname = canonname(name) # will raise LookupError for invalid name
a = group.addAction(name)
a.setCheckable(True)
@@ -212,20 +212,20 @@
menu.addSeparator()
menu.addActions(otheracts)

-def findActionByName(group: QActionGroup, name: Text) -> QAction:
+def findActionByName(group: QActionGroup, name: str) -> QAction:
cname = canonname(name)
for a in group.actions():
if str(a.data()) == cname:
return a
raise LookupError('no encoding action: %s' % name)

-def checkedActionName(group: QActionGroup) -> Text:
+def checkedActionName(group: QActionGroup) -> str:
a = group.checkedAction()
if not a:
return ''
return str(a.data())

-def checkActionByName(group: QActionGroup, name: Text) -> None:
+def checkActionByName(group: QActionGroup, name: str) -> None:
try:
a = findActionByName(group, name)
except LookupError:
diff --git a/tortoisehg/hgqt/graft.py b/tortoisehg/hgqt/graft.py
--- a/tortoisehg/hgqt/graft.py
+++ b/tortoisehg/hgqt/graft.py
@@ -234,7 +234,7 @@
def graftstate(self) -> Optional[List[bytes]]:
return hglib.readgraftstate(self.repo)

- def _runCommand(self, cmdline: List[Text]) -> cmdcore.CmdSession:
+ def _runCommand(self, cmdline: List[str]) -> cmdcore.CmdSession:
assert self._cmdsession.isFinished()
self._cmdsession = sess = self._repoagent.runCommand(cmdline, self)
sess.commandFinished.connect(self._stbar.clearProgress)
@@ -298,7 +298,7 @@
self.abortbtn.setEnabled(False)
return False

- def linkActivated(self, cmd: Text) -> None:
+ def linkActivated(self, cmd: str) -> None:
if cmd == 'resolve':
dlg = resolve.ResolveDialog(self._repoagent, self)
dlg.exec()
diff --git a/tortoisehg/hgqt/hgconfig.py b/tortoisehg/hgqt/hgconfig.py
--- a/tortoisehg/hgqt/hgconfig.py
+++ b/tortoisehg/hgqt/hgconfig.py
@@ -50,25 +50,25 @@
return self._ui

def configBool(self,
- section: Text,
- name: Text,
+ section: str,
+ name: str,
default: bool = UNSET_DEFAULT) -> bool:
data = self._ui.configbool(hglib.fromunicode(section), hglib.fromunicode(name),
default=default)
return bool(data)

def configInt(self,
- section: Text,
- name: Text,
+ section: str,
+ name: str,
default: int = UNSET_DEFAULT) -> int:
data = self._ui.configint(hglib.fromunicode(section), hglib.fromunicode(name),
default=default)
return int(data)

def configString(self,
- section: Text,
- name: Text,
- default: Text = UNSET_DEFAULT) -> Text:
+ section: str,
+ name: str,
+ default: str = UNSET_DEFAULT) -> str:
if default is not UNSET_DEFAULT:
default = hglib.fromunicode(default)
data = self._ui.config(hglib.fromunicode(section), hglib.fromunicode(name),
@@ -78,20 +78,20 @@
return hglib.tounicode(data)

def configStringList(self,
- section: Text,
- name: Text,
- default: List[Text] = UNSET_DEFAULT) -> List[Text]:
+ section: str,
+ name: str,
+ default: List[str] = UNSET_DEFAULT) -> List[str]:
if default is not UNSET_DEFAULT:
default = pycompat.maplist(hglib.fromunicode, default)
data = self._ui.configlist(hglib.fromunicode(section), hglib.fromunicode(name),
default=default)
return hglib.to_unicode_list(data)

- def configStringItems(self, section: Text) -> List[Tuple[Text, Text]]:
+ def configStringItems(self, section: str) -> List[Tuple[str, str]]:
"""Returns a list of string (key, value) pairs under the specified
section"""
items = self._ui.configitems(hglib.fromunicode(section))
return [(hglib.tounicode(k), hglib.tounicode(v)) for k, v in items]

- def hasConfig(self, section: Text, name: Text) -> bool:
+ def hasConfig(self, section: str, name: str) -> bool:
return self._ui.hasconfig(hglib.fromunicode(section), hglib.fromunicode(name))
diff --git a/tortoisehg/hgqt/hginit.py b/tortoisehg/hgqt/hginit.py
--- a/tortoisehg/hgqt/hginit.py
+++ b/tortoisehg/hgqt/hginit.py
@@ -52,7 +52,7 @@
def __init__(self,
ui: uimod.ui,
cmdagent: cmdcore.CmdAgent,
- destdir: Text = '.',
+ destdir: str = '.',
parent: Optional[QWidget] = None) -> None:
super().__init__(parent)
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
@@ -112,10 +112,10 @@
if path:
self._dest_edit.setText(path)

- def destination(self) -> Text:
+ def destination(self) -> str:
return self._dest_edit.text().strip()

- def _buildCommand(self) -> List[Text]:
+ def _buildCommand(self) -> List[str]:
cfgs = []
if self._add_files_chk.isChecked():
cfgs.append('hooks.post-init.thgskel='
@@ -144,7 +144,7 @@

def __init__(self,
ui: uimod.ui,
- destdir: Text = '.',
+ destdir: str = '.',
parent: Optional[QWidget] = None) -> None:
super().__init__(parent)
self.setWindowTitle(_('New Repository'))
@@ -156,7 +156,7 @@
self.setCommandWidget(InitWidget(ui, cmdagent, destdir, self))
self.commandFinished.connect(self._handleNewRepo)

- def destination(self) -> Text:
+ def destination(self) -> str:
return self.commandWidget().destination()

@pyqtSlot(int)
diff --git a/tortoisehg/hgqt/locktool.py b/tortoisehg/hgqt/locktool.py
--- a/tortoisehg/hgqt/locktool.py
+++ b/tortoisehg/hgqt/locktool.py
@@ -147,7 +147,7 @@
self.refillModel()
self.reload()

- def refillModel(self) -> Dict[Text, List[Text]]:
+ def refillModel(self) -> Dict[str, List[str]]:
# this code is specific to simplelock
locks: Dict[bytes, List[bytes]] = self.sl.parseLocks(self.repo)
lockables: List[bytes] = self.sl.readlockables(self.repo)
@@ -196,11 +196,11 @@
self.showMessage.emit(_('Locking %s') % wfile)
self.lockrun(['lock', wfile])

- def unlock(self, wfile: Text) -> None:
+ def unlock(self, wfile: str) -> None:
self.showMessage.emit(_('Unlocking %s') % wfile)
self.lockrun(['unlock', wfile])

- def lock(self, wfile: Text, user: Text) -> None:
+ def lock(self, wfile: str, user: str) -> None:
self.showMessage.emit(_('Locking %s') % wfile)
self.lockrun(['lock', wfile])

@@ -210,7 +210,7 @@
self.showMessage.emit(_('Refreshing locks...'))
self.lockrun(['locks']) # has side-effect of refreshing locks

- def lockrun(self, ucmdline: List[Text]) -> None:
+ def lockrun(self, ucmdline: List[str]) -> None:
self.operation = ucmdline + [None]
self._cmdsession = sess = self._repoagent.runCommand(ucmdline, self)
sess.commandFinished.connect(self.operationComplete)
diff --git a/tortoisehg/hgqt/manifestmodel.py b/tortoisehg/hgqt/manifestmodel.py
--- a/tortoisehg/hgqt/manifestmodel.py
+++ b/tortoisehg/hgqt/manifestmodel.py
@@ -98,8 +98,8 @@
FirstParent = -2
SecondParent = -3

- def __init__(self, repoagent: RepoAgent, parent: Optional[QObject] = None, rev: Optional[int] = None, namefilter: Optional[Text] = None,
- statusfilter: Text = 'MASC', flat: bool = False) -> None:
+ def __init__(self, repoagent: RepoAgent, parent: Optional[QObject] = None, rev: Optional[int] = None, namefilter: Optional[str] = None,
+ statusfilter: str = 'MASC', flat: bool = False) -> None:
QAbstractItemModel.__init__(self, parent)

self._fileiconprovider = QFileIconProvider()
@@ -131,7 +131,7 @@
if role in (Qt.ItemDataRole.DisplayRole, Qt.ItemDataRole.EditRole):
return e.name

- def filePath(self, index: QModelIndex) -> Text:
+ def filePath(self, index: QModelIndex) -> str:
"""Return path at the given index [unicode]"""
if not index.isValid():
return ''
@@ -159,7 +159,7 @@
return filedata.createDirData(e.ctx, e.pctx, wfile, rpath)
return filedata.createFileData(e.ctx, e.pctx, wfile, f.status, rpath)

- def subrepoType(self, index: QModelIndex) -> Optional[Text]:
+ def subrepoType(self, index: QModelIndex) -> Optional[str]:
"""Return the subrepo type the specified index"""
if not index.isValid():
return
@@ -203,7 +203,7 @@

return ic

- def fileStatus(self, index: QModelIndex) -> Optional[Text]:
+ def fileStatus(self, index: QModelIndex) -> Optional[str]:
"""Return the change status of the specified file"""
if not index.isValid():
return
@@ -214,7 +214,7 @@
return e.status

# TODO: this should be merged to fileStatus()
- def subrepoStatus(self, index: QModelIndex) -> Optional[Text]:
+ def subrepoStatus(self, index: QModelIndex) -> Optional[str]:
"""Return the change status of the specified subrepo"""
if not index.isValid():
return
@@ -245,7 +245,7 @@
m.setUrls([QUrl.fromLocalFile(os.path.join(base, e)) for e in files])
return m

- def mimeTypes(self) -> List[Text]:
+ def mimeTypes(self) -> List[str]:
return ['text/uri-list']

def flags(self, index: QModelIndex) -> Qt_ItemFlags:
@@ -265,7 +265,7 @@
return QModelIndex()
return self.createIndex(row, column, self._parententry(parent).at(row))

- def indexFromPath(self, path: Text, column: int = 0) -> QModelIndex:
+ def indexFromPath(self, path: str, column: int = 0) -> QModelIndex:
"""Return index for the specified path if found [unicode]

If not found, returns invalid index.
@@ -354,25 +354,25 @@
if self._rootpopulated:
self.revLoaded.emit(self.rev())

- def nameFilter(self) -> Text:
+ def nameFilter(self) -> str:
"""Return the current name filter"""
return self._namefilter

@pyqtSlot(str)
- def setNameFilter(self, pattern: Text) -> None:
+ def setNameFilter(self, pattern: str) -> None:
"""Filter file name by partial match of glob pattern"""
if self._namefilter == pattern:
return
self._namefilter = pattern
self._repopulateNodes()

- def statusFilter(self) -> Text:
+ def statusFilter(self) -> str:
"""Return the current status filter"""
return self._statusfilter

# TODO: split or remove 'S' which causes several design flaws
@pyqtSlot(str)
- def setStatusFilter(self, status: Text) -> None:
+ def setStatusFilter(self, status: str) -> None:
"""Filter file tree by change status 'MARSC'"""
assert all(c in 'MARSC' for c in status), repr(status)
if self._statusfilter == status:
@@ -489,17 +489,17 @@
__slots__ = ('_name', '_parent', 'status', 'ctx', 'pctx', 'subkind',
'_child', '_nameindex')

- _name: Text
+ _name: str
_parent: Optional[_Entry]
- status: Optional[Text]
+ status: Optional[str]
ctx: Optional[ThgContext]
pctx: Optional[ThgContext]
- subkind: Optional[Text]
- _child: Dict[Text, _Entry]
- _nameindex: List[Text]
+ subkind: Optional[str]
+ _child: Dict[str, _Entry]
+ _nameindex: List[str]

def __init__(self,
- name: Text = '',
+ name: str = '',
parent: Optional[_Entry] = None) -> None:
self._name = name
self._parent = parent
@@ -524,14 +524,14 @@
return self._parent

@property
- def path(self) -> Text:
+ def path(self) -> str:
if self.parent is None or not self.parent.name:
return self.name
else:
return self.parent.path + '/' + self.name

@property
- def name(self) -> Text:
+ def name(self) -> str:
return self._name

@property
@@ -547,16 +547,16 @@

__bool__ = __nonzero__

- def __getitem__(self, name: Text) -> _Entry:
+ def __getitem__(self, name: str) -> _Entry:
return self._child[name]

- def makechild(self, name: Text) -> _Entry:
+ def makechild(self, name: str) -> _Entry:
if name not in self._child:
self._nameindex.append(name)
self._child[name] = e = self.__class__(name, parent=self)
return e

- def putchild(self, name: Text, e: _Entry) -> None:
+ def putchild(self, name: str, e: _Entry) -> None:
assert not e.name and not e.parent, (e.name, e.parent)
e._name = name
e._parent = self
@@ -564,13 +564,13 @@
self._nameindex.append(name)
self._child[name] = e

- def __contains__(self, item: Text) -> bool:
+ def __contains__(self, item: str) -> bool:
return item in self._child

def at(self, index: int) -> _Entry:
return self._child[self._nameindex[index]]

- def index(self, name: Text) -> int:
+ def index(self, name: str) -> int:
return self._nameindex.index(name)

def sort(self, reverse: bool = False) -> None:
@@ -625,28 +625,28 @@
subreporecursive = False

@staticmethod
- def findpath(e: _Entry, path: Text) -> _Entry:
+ def findpath(e: _Entry, path: str) -> _Entry:
return e[path]

@staticmethod
- def makepath(e: _Entry, path: Text) -> _Entry:
+ def makepath(e: _Entry, path: str) -> _Entry:
return e.makechild(path)

@staticmethod
- def putpath(e: _Entry, path: Text, c: _Entry) -> None:
+ def putpath(e: _Entry, path: str, c: _Entry) -> None:
e.putchild(path, c)

class _treenodeop:
subreporecursive = True

@staticmethod
- def findpath(e: _Entry, path: Text) -> _Entry:
+ def findpath(e: _Entry, path: str) -> _Entry:
for p in path.split('/'):
e = e[p]
return e

@staticmethod
- def makepath(e: _Entry, path: Text) -> _Entry:
+ def makepath(e: _Entry, path: str) -> _Entry:
for p in path.split('/'):
if p not in e:
e.makechild(p)
@@ -654,7 +654,7 @@
return e

@staticmethod
- def putpath(e: _Entry, path: Text, c: _Entry) -> None:
+ def putpath(e: _Entry, path: str, c: _Entry) -> None:
rp = path.rfind('/')
if rp >= 0:
e = _treenodeop.makepath(e, path[:rp])
@@ -669,7 +669,7 @@
def _populaterepo(roote: _Entry,
repo: localrepo.localrepository,
nodeop,
- statusfilter: Text,
+ statusfilter: str,
match: matchmod.basematcher) -> None:
# TODO: replace 'Any' with structural typing for _treenodeop/_listnodeop
if 'S' in statusfilter:
@@ -689,7 +689,7 @@
e.status = st

def _comparesubstate(state1: Tuple[bytes, bytes, bytes],
- state2: Tuple[bytes, bytes, bytes]) -> Text:
+ state2: Tuple[bytes, bytes, bytes]) -> str:
if state1 == state2:
return 'C'
elif state1 == hglib.nullsubrepostate:
@@ -702,7 +702,7 @@
def _populatesubrepos(roote: _Entry,
repo: localrepo.localrepository,
nodeop,
- statusfilter: Text,
+ statusfilter: str,
match: matchmod.basematcher) -> None:
# TODO: replace 'Any' with structural typing for _treenodeop/_listnodeop
ctx = roote.ctx
@@ -747,7 +747,7 @@
def _populatepatch(roote: _Entry,
repo: localrepo.localrepository,
nodeop,
- statusfilter: Text,
+ statusfilter: str,
match: matchmod.basematcher) -> None:
# TODO: replace 'Any' with structural typing for _treenodeop/_listnodeop
ctx = roote.ctx
@@ -765,7 +765,7 @@
class ManifestCompleter(QCompleter):
"""QCompleter for ManifestModel"""

- def splitPath(self, path: Text) -> List[Text]:
+ def splitPath(self, path: str) -> List[str]:
"""
>>> c = ManifestCompleter()
>>> c.splitPath(u'foo/bar')
@@ -778,7 +778,7 @@
"""
return path.split('/')

- def pathFromIndex(self, index: QModelIndex) -> Text:
+ def pathFromIndex(self, index: QModelIndex) -> str:
if not index.isValid():
return ''
m = self.model()
diff --git a/tortoisehg/hgqt/phabreview.py b/tortoisehg/hgqt/phabreview.py
--- a/tortoisehg/hgqt/phabreview.py
+++ b/tortoisehg/hgqt/phabreview.py
@@ -67,27 +67,27 @@
__slots__ = ()

def __new__(cls,
- username: Text,
- realname: Text,
- roles: List[Text]) -> user:
+ username: str,
+ realname: str,
+ roles: List[str]) -> user:
return tuple.__new__(cls, (username, realname, roles))

@property
- def username(self) -> Text:
+ def username(self) -> str:
'''username used by phabsend'''
return self[0]

@property
- def realname(self) -> Text:
+ def realname(self) -> str:
'''friendly name of this user'''
return self[1]

@property
- def roles(self) -> List[Text]:
+ def roles(self) -> List[str]:
'''the roles filled by this user'''
return self[2]

- def __repr__(self) -> Text:
+ def __repr__(self) -> str:
return '%s (%s)' % (self.realname, self.username)


@@ -168,7 +168,7 @@
s.setValue('phabsend/geom', self.saveGeometry())

def _reviewerhistorypath(self,
- withcallsign: bool = False) -> Optional[Text]:
+ withcallsign: bool = False) -> Optional[str]:
'''Fetches the path in the settings used to store reviewer history.

If no reviewers are stored or the configuration isn't present to find
@@ -321,7 +321,7 @@
"""Returns list of revisions to be sent"""
return self._changesets.selectedrevs

- def _phabsendopts(self, **opts) -> Dict[Text, Any]:
+ def _phabsendopts(self, **opts) -> Dict[str, Any]:
"""Generate opts for phabsend by form values"""
opts['rev'] = hglib.compactrevs(self._revs)

diff --git a/tortoisehg/hgqt/pick.py b/tortoisehg/hgqt/pick.py
--- a/tortoisehg/hgqt/pick.py
+++ b/tortoisehg/hgqt/pick.py
@@ -192,7 +192,7 @@
sess = self._runCommand(cmdline)
sess.commandFinished.connect(self._abortFinished)

- def _runCommand(self, cmdline: List[Text]) -> cmdcore.CmdSession:
+ def _runCommand(self, cmdline: List[str]) -> cmdcore.CmdSession:
assert self._cmdsession.isFinished()
self._cmdsession = sess = self._repoagent.runCommand(cmdline, self)
sess.commandFinished.connect(self._stbar.clearProgress)
@@ -247,7 +247,7 @@
self.abortbtn.setEnabled(False)
return False

- def linkActivated(self, cmd: Text) -> None:
+ def linkActivated(self, cmd: str) -> None:
if cmd == 'resolve':
dlg = resolve.ResolveDialog(self._repoagent, self)
dlg.exec()
diff --git a/tortoisehg/hgqt/postreview.py b/tortoisehg/hgqt/postreview.py
--- a/tortoisehg/hgqt/postreview.py
+++ b/tortoisehg/hgqt/postreview.py
@@ -278,19 +278,19 @@
"""Returns list of revisions to be sent"""
return self._changesets.revs

- def getRepoId(self) -> Text:
+ def getRepoId(self) -> str:
comboText = self.qui.repo_id_combo.currentText().split(":")
return comboText[0]

- def getReviewId(self) -> Text:
+ def getReviewId(self) -> str:
comboText = self.qui.review_id_combo.currentText().split(":")
return comboText[0]

- def getSummary(self) -> Text:
+ def getSummary(self) -> str:
comboText = self.qui.review_id_combo.currentText().split(":")
return comboText[1]

- def postReviewOpts(self, **opts) -> Dict[Text, Union[bool, Text]]:
+ def postReviewOpts(self, **opts) -> Dict[str, Union[bool, str]]:
"""Generate opts for reviewboard by form values"""
opts['outgoingchanges'] = self.qui.outgoing_changes_check.isChecked()
opts['branch'] = self.qui.branch_check.isChecked()
@@ -374,7 +374,7 @@
self.qui.progress_label.setText("Posting Review...")
self.qui.progress_label.show()

- def cmdargs(opts: Dict[Text, Union[bool, Text]]) -> List[Text]:
+ def cmdargs(opts: Dict[str, Union[bool, str]]) -> List[str]:
args = []
for k, v in opts.items():
if isinstance(v, bool):
@@ -438,7 +438,7 @@
super().accept()

@pyqtSlot(str, str)
- def _captureOutput(self, msg: Text, label: Text) -> None:
+ def _captureOutput(self, msg: str, label: str) -> None:
if label != 'control':
self._cmdoutputs.append(msg)

diff --git a/tortoisehg/hgqt/prune.py b/tortoisehg/hgqt/prune.py
--- a/tortoisehg/hgqt/prune.py
+++ b/tortoisehg/hgqt/prune.py
@@ -86,10 +86,10 @@

self._revedit.setFocus()

- def revset(self) -> Text:
+ def revset(self) -> str:
return self._revedit.currentText()

- def setRevset(self, revspec: Text) -> None:
+ def setRevset(self, revspec: str) -> None:
if self.revset() == revspec:
return
w = self._revedit
@@ -143,7 +143,7 @@


def createPruneDialog(repoagent: RepoAgent,
- revspec: Text,
+ revspec: str,
parent: Optional[QWidget] = None) -> cmdui.CmdControlDialog:
dlg = cmdui.CmdControlDialog(parent)
dlg.setWindowIcon(qtlib.geticon('edit-cut'))
diff --git a/tortoisehg/hgqt/qtlib.py b/tortoisehg/hgqt/qtlib.py
--- a/tortoisehg/hgqt/qtlib.py
+++ b/tortoisehg/hgqt/qtlib.py
@@ -146,7 +146,7 @@
atexit.register(cleanup)
return tmproot

-def openhelpcontents(url: Text) -> None:
+def openhelpcontents(url: str) -> None:
'Open online help, use local CHM file if available'
if not url.startswith('http'):
fullurl = 'https://tortoisehg.readthedocs.org/en/latest/' + url
@@ -364,7 +364,7 @@
# a) it appears to be broken before PyQt 4.11.x (#4882)
# b) it may raise TypeError if a setting has a value of an unexpected type

-def readBool(qs: QSettings, key: Text, default: bool = False) -> bool:
+def readBool(qs: QSettings, key: str, default: bool = False) -> bool:
"""Read the specified value from QSettings and coerce into bool"""
v = qs.value(key, default)
if hglib.isbasestring(v):
@@ -372,7 +372,7 @@
return not (v == '0' or v == 'false' or v == '')
return bool(v)

-def readByteArray(qs: QSettings, key: Text, default: bytes = b'') -> QByteArray:
+def readByteArray(qs: QSettings, key: str, default: bytes = b'') -> QByteArray:
"""Read the specified value from QSettings and coerce into QByteArray"""
v = qs.value(key, default)
if v is None:
@@ -382,7 +382,7 @@
except TypeError:
return QByteArray(default)

-def readInt(qs: QSettings, key: Text, default: int = 0) -> int:
+def readInt(qs: QSettings, key: str, default: int = 0) -> int:
"""Read the specified value from QSettings and coerce into int"""
v = qs.value(key, default)
if v is None:
@@ -392,7 +392,7 @@
except (TypeError, ValueError):
return int(default)

-def readString(qs: QSettings, key: Text, default: Text = '') -> Text:
+def readString(qs: QSettings, key: str, default: str = '') -> str:
"""Read the specified value from QSettings and coerce into string"""
v = qs.value(key, default)
if v is None:
@@ -404,9 +404,9 @@

def readStringList(
qs: QSettings,
- key: Text,
- default: Iterable[Text] = (),
-) -> List[Text]:
+ key: str,
+ default: Iterable[str] = (),
+) -> List[str]:
"""Read the specified value from QSettings and coerce into string list"""
v = qs.value(key, default)
if v is None:
@@ -491,7 +491,7 @@
# See https://doc.qt.io/qt-4.8/richtext-html-subset.html
# and https://www.w3.org/TR/SVG/types.html#ColorKeywords

-def geteffect(labels: Text) -> Text:
+def geteffect(labels: str) -> str:
'map labels like "log.date" to Qt font styles'
effects = []
# Multiple labels may be requested
@@ -512,7 +512,7 @@
effects.append('color: ' + e)
return ';'.join(effects)

-def gettextcoloreffect(labels: Text) -> QColor:
+def gettextcoloreffect(labels: str) -> QColor:
"""Map labels like "log.date" to foreground color if available"""
for l in labels.split():
if not l:
@@ -522,7 +522,7 @@
return QColor(e)
return QColor()

-def getbgcoloreffect(labels: Text) -> QColor:
+def getbgcoloreffect(labels: str) -> QColor:
"""Map labels like "log.date" to background color if available

Returns QColor object. You may need to check validity by isValid().
@@ -550,7 +550,7 @@
'decoration': 'text-decoration',
}

-def markup(msg: AnyStr, **styles: Text) -> Text:
+def markup(msg: AnyStr, **styles: str) -> str:
style = {'white-space': 'pre'}
for name, value in styles.items():
if not value:
@@ -564,7 +564,7 @@
msg = msg.replace('\n', '<br />')
return u'<span style="%s">%s</span>' % (style, msg)

-def descriptionhtmlizer(ui: uimod.ui) -> Callable[[AnyStr], Text]:
+def descriptionhtmlizer(ui: uimod.ui) -> Callable[[AnyStr], str]:
"""Return a function to mark up ctx.description() as an HTML

>>> from mercurial import ui
@@ -631,7 +631,7 @@
except re.error:
pass

- def htmlize(desc: AnyStr) -> Text:
+ def htmlize(desc: AnyStr) -> str:
"""Mark up ctx.description() [localstr] as an HTML [unicode]"""
desc = hglib.tounicode(desc)

@@ -668,24 +668,24 @@

return htmlize

-_iconcache: Dict[Text, QIcon] = {}
+_iconcache: Dict[str, QIcon] = {}

if getattr(sys, 'frozen', False) and os.name == 'nt':
- def iconpath(f: Text, *insidef: Text) -> Text:
+ def iconpath(f: str, *insidef: str) -> str:
return posixpath.join(':/icons', f, *insidef)
else:
- def iconpath(f: Text, *insidef: Text) -> Text:
+ def iconpath(f: str, *insidef: str) -> str:
return os.path.join(paths.get_icon_path(), f, *insidef)

if hasattr(QIcon, 'hasThemeIcon'): # PyQt>=4.7
- def _findthemeicon(name: Text) -> Optional[QIcon]:
+ def _findthemeicon(name: str) -> Optional[QIcon]:
if QIcon.hasThemeIcon(name):
return QIcon.fromTheme(name)
else:
- def _findthemeicon(name: Text) -> Optional[QIcon]:
+ def _findthemeicon(name: str) -> Optional[QIcon]:
pass

-def _findcustomicon(name: Text) -> Optional[QIcon]:
+def _findcustomicon(name: str) -> Optional[QIcon]:
# let a user set the icon of a custom tool button
if os.path.isabs(name):
path = name
@@ -706,7 +706,7 @@
(QSize(32, 32), '32x32/status', '.png'),
(QSize(24, 24), '24x24/actions', '.png')]

-def getallicons() -> List[Text]:
+def getallicons() -> List[str]:
"""Get a sorted, unique list of all available icons"""
iconset = set()
for size, subdir, sfx in _SCALABLE_ICON_PATHS:
@@ -717,7 +717,7 @@
iconset.add(pycompat.unicode(iconname).rsplit('.', 1)[0])
return sorted(iconset)

-def _findscalableicon(name: Text) -> Optional[QIcon]:
+def _findscalableicon(name: str) -> Optional[QIcon]:
"""Find icon from qrc by using freedesktop-like icon lookup"""
o = QIcon()
for size, subdir, sfx in _SCALABLE_ICON_PATHS:
@@ -728,7 +728,7 @@
if not o.isNull():
return o

-def geticon(name: Text) -> QIcon:
+def geticon(name: str) -> QIcon:
"""
Return a QIcon for the specified name. (the given 'name' parameter
must *not* provide the extension).
@@ -758,9 +758,9 @@
return QIcon(pixmap)


-_pixmapcache: Dict[Text, QPixmap] = {}
+_pixmapcache: Dict[str, QPixmap] = {}

-def getpixmap(name: Text, width: int = 16, height: int = 16) -> QPixmap:
+def getpixmap(name: str, width: int = 16, height: int = 16) -> QPixmap:
key = '%s_%sx%s' % (name, width, height)
try:
return _pixmapcache[key]
@@ -836,7 +836,7 @@

class ThgFont(QObject):
changed = pyqtSignal(QFont)
- def __init__(self, name: Text) -> None:
+ def __init__(self, name: str) -> None:
QObject.__init__(self)
self.myfont = QFont()
self.myfont.fromString(name)
@@ -846,7 +846,7 @@
self.myfont = f
self.changed.emit(f)

-_fontdefaults: Dict[Text, Text] = {
+_fontdefaults: Dict[str, str] = {
'fontcomment': 'monospace,10',
'fontdiff': 'monospace,10',
'fonteditor': 'monospace,10',
@@ -855,7 +855,7 @@
}
if sys.platform == 'darwin':
_fontdefaults['fontoutputlog'] = 'sans,10'
-_fontcache: Dict[Text, ThgFont] = {}
+_fontcache: Dict[str, ThgFont] = {}

def initfontcache(ui: uimod.ui):
for name in _fontdefaults:
@@ -863,17 +863,17 @@
pycompat.sysbytes(_fontdefaults[name]))
_fontcache[name] = ThgFont(hglib.tounicode(fname))

-def getfont(name: Text) -> ThgFont:
+def getfont(name: str) -> ThgFont:
assert name in _fontdefaults, (name, _fontdefaults)
return _fontcache[name]

def CommonMsgBox(
icon: QMessageBox.Icon,
- title: Text,
- main: Text,
- text: Text = '',
+ title: str,
+ main: str,
+ text: str = '',
buttons: Union[QMessageBox.StandardButtons, QMessageBox.StandardButton] = QMessageBox.StandardButton.Ok,
- labels: Optional[Iterable[Tuple[QMessageBox.StandardButton, Text]]] = None,
+ labels: Optional[Iterable[Tuple[QMessageBox.StandardButton, str]]] = None,
parent: Optional[QWidget] = None,
defaultbutton: Optional[Union[QPushButton, QMessageBox.StandardButton]] = None,
) -> int:
@@ -894,16 +894,16 @@
msg.setInformativeText(info)
return msg.exec()

-def InfoMsgBox(*args: Text, **kargs) -> int:
+def InfoMsgBox(*args: str, **kargs) -> int:
return CommonMsgBox(QMessageBox.Icon.Information, *args, **kargs)

-def WarningMsgBox(*args: Text, **kargs) -> int:
+def WarningMsgBox(*args: str, **kargs) -> int:
return CommonMsgBox(QMessageBox.Icon.Warning, *args, **kargs)

-def ErrorMsgBox(*args: Text, **kargs) -> int:
+def ErrorMsgBox(*args: str, **kargs) -> int:
return CommonMsgBox(QMessageBox.Icon.Critical, *args, **kargs)

-def QuestionMsgBox(*args: Text, **kargs) -> bool:
+def QuestionMsgBox(*args: str, **kargs) -> bool:
btn = QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
res = CommonMsgBox(QMessageBox.Icon.Question, buttons=btn, *args, **kargs)
return res == QMessageBox.StandardButton.Yes
@@ -914,10 +914,10 @@
title: AnyStr,
message: AnyStr,
parent: Optional[QWidget],
- choices: Iterable[Text],
+ choices: Iterable[str],
default: Optional[int] = None,
esc: Optional[int] = None,
- files: Optional[Iterable[Union[bytes, Text]]] = None,
+ files: Optional[Iterable[Union[bytes, str]]] = None,
) -> None:
# Note: `files` is typed as `Union[bytes, str]` instead of `AnyStr`
# because the latter is defined with TypeVar, and that would enforce
@@ -958,11 +958,11 @@

class ChoicePrompt(QDialog):
def __init__(self,
- title: Text,
- message: Text,
+ title: str,
+ message: str,
parent: QWidget,
- choices: List[Text],
- default: Optional[Text] = None) -> None:
+ choices: List[str],
+ default: Optional[str] = None) -> None:
QDialog.__init__(self, parent)
self.setWindowTitle(title)
self.setWindowFlags(self.windowFlags() & ~Qt.WindowType.WindowContextHelpButtonHint)
@@ -997,7 +997,7 @@
self.box.addLayout(vbox)
self.setLayout(self.box)

- def run(self) -> Optional[Text]:
+ def run(self) -> Optional[str]:
if self.exec():
return self.choices[self.choice_combo.currentIndex()]
return None
@@ -1140,7 +1140,7 @@

def __init__(
self,
- label: Text,
+ label: str,
parent: Optional[QWidget] = None,
):
QLabel.__init__(self, parent)
@@ -1156,7 +1156,7 @@

def __init__(
self,
- label: Text,
+ label: str,
expanded: bool = True,
stretch: bool = True,
parent: Optional[QWidget] = None,
@@ -1210,8 +1210,8 @@

def set_status(
self,
- text: Text,
- icon: Optional[Union[bool, Text, QIcon]] = None,
+ text: str,
+ icon: Optional[Union[bool, str, QIcon]] = None,
) -> None:
self.set_text(text)
self.set_icon(icon)
@@ -1220,7 +1220,7 @@
self.clear_text()
self.clear_icon()

- def set_text(self, text: Optional[Text] = '') -> None:
+ def set_text(self, text: Optional[str] = '') -> None:
if text is None:
text = ''
self.status_text.setText(text)
@@ -1228,7 +1228,7 @@
def clear_text(self) -> None:
self.set_text()

- def set_icon(self, icon: Optional[Union[bool, Text, QIcon]] = None) -> None:
+ def set_icon(self, icon: Optional[Union[bool, str, QIcon]] = None) -> None:
if icon is None:
self.clear_icon()
else:
@@ -1248,7 +1248,7 @@

def __init__(
self,
- label: Optional[Union[QLabel, Text]] = None,
+ label: Optional[Union[QLabel, str]] = None,
parent: Optional[QWidget] = None,
) -> None:
QWidget.__init__(self, parent)
@@ -1276,27 +1276,27 @@
object.__init__(self)

# help pytype by forward declaring
- self.groups: Dict[Text, List[QWidget]] = {}
+ self.groups: Dict[str, List[QWidget]] = {}

self.clear(all=True)

### Public Methods ###

- def add(self, widget: QWidget, group: Text = 'default') -> None:
+ def add(self, widget: QWidget, group: str = 'default') -> None:
if group not in self.groups:
self.groups[group] = []
widgets = self.groups[group]
if widget not in widgets:
widgets.append(widget)

- def remove(self, widget: QWidget, group: Text = 'default') -> None:
+ def remove(self, widget: QWidget, group: str = 'default') -> None:
if group not in self.groups:
return
widgets = self.groups[group]
if widget in widgets:
widgets.remove(widget)

- def clear(self, group: Text = 'default', all: bool = True) -> None:
+ def clear(self, group: str = 'default', all: bool = True) -> None:
if all:
self.groups = {}
else:
@@ -1304,9 +1304,9 @@

def set_prop(
self,
- prop: Text,
+ prop: str,
value: object,
- group: Text = 'default',
+ group: str = 'default',
cond: Optional[Callable[[QWidget], bool]] = None,
) -> None:
if group not in self.groups:
@@ -1462,7 +1462,7 @@

def __init__(
self,
- createfuncname: Text,
+ createfuncname: str,
createinst: object,
parent: Optional[QWidget] = None,
) -> None:
@@ -1482,7 +1482,7 @@
self.get()
super().showEvent(event)

- def forward(self, funcname: Text, *args, **opts) -> Optional[Any]:
+ def forward(self, funcname: str, *args, **opts) -> Optional[Any]:
if self._widget:
return getattr(self._widget, funcname)(*args, **opts)
return None
@@ -1506,7 +1506,7 @@
return True
return self._widget.canExit()

- def __getattr__(self, name: Text) -> Any:
+ def __getattr__(self, name: str) -> Any:
return getattr(self._widget, name)

class Spacer(QWidget):
@@ -1527,7 +1527,7 @@

def getCurrentUsername(widget: Optional[QWidget],
repo: localrepo.localrepository,
- opts: Optional[Dict[Text, Text]] = None) -> Optional[Text]:
+ opts: Optional[Dict[str, str]] = None) -> Optional[str]:
if opts:
# 1. Override has highest priority
user = opts.get('user')
@@ -1561,12 +1561,12 @@

def getTextInput(
parent: Optional[QWidget],
- title: Text,
- label: Text,
+ title: str,
+ label: str,
mode: QLineEdit.EchoMode = QLineEdit.EchoMode.Normal,
- text: Text = '',
+ text: str = '',
flags: Union[Qt.WindowType, Qt.WindowFlags] = Qt.WindowType.Widget,
-) -> Tuple[Text, bool]:
+) -> Tuple[str, bool]:
flags |= (Qt.WindowType.CustomizeWindowHint | Qt.WindowType.WindowTitleHint
| Qt.WindowType.WindowCloseButtonHint)
dlg = _EncodingSafeInputDialog(parent, flags)
@@ -1580,7 +1580,7 @@
return r and dlg.textValue() or '', bool(r)

def keysequence(
- o: Union[QKeySequence, QKeySequence.StandardKey, Text, int],
+ o: Union[QKeySequence, QKeySequence.StandardKey, str, int],
) -> Union[QKeySequence, QKeySequence.StandardKey]:
"""Create QKeySequence from string or QKeySequence"""
if isinstance(o, (QKeySequence, QKeySequence.StandardKey)):
diff --git a/tortoisehg/hgqt/rebase.py b/tortoisehg/hgqt/rebase.py
--- a/tortoisehg/hgqt/rebase.py
+++ b/tortoisehg/hgqt/rebase.py
@@ -260,7 +260,7 @@
sess = self._runCommand(cmdline)
sess.commandFinished.connect(self._abortFinished)

- def _runCommand(self, cmdline: List[Text]) -> cmdcore.CmdSession:
+ def _runCommand(self, cmdline: List[str]) -> cmdcore.CmdSession:
assert self._cmdsession.isFinished()
self._cmdsession = sess = self._repoagent.runCommand(cmdline, self)
sess.commandFinished.connect(self._stbar.clearProgress)
@@ -314,7 +314,7 @@
self.abortbtn.setEnabled(False)
return False

- def linkActivated(self, cmd: Text) -> None:
+ def linkActivated(self, cmd: str) -> None:
if cmd == 'resolve':
dlg = resolve.ResolveDialog(self._repoagent, self)
dlg.exec()
diff --git a/tortoisehg/hgqt/rename.py b/tortoisehg/hgqt/rename.py
--- a/tortoisehg/hgqt/rename.py
+++ b/tortoisehg/hgqt/rename.py
@@ -50,7 +50,7 @@

class RenameWidget(cmdui.AbstractCmdWidget):

- def __init__(self, repoagent: RepoAgent, parent: Optional[QWidget] = None, source: Optional[Text] = None, destination: Optional[Text] = None,
+ def __init__(self, repoagent: RepoAgent, parent: Optional[QWidget] = None, source: Optional[str] = None, destination: Optional[str] = None,
iscopy: bool = False) -> None:
super().__init__(parent)
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
@@ -114,17 +114,17 @@
def repo(self):
return self._repoagent.rawRepo()

- def source(self) -> Text:
+ def source(self) -> str:
return self.src_txt.text()

- def destination(self) -> Text:
+ def destination(self) -> str:
return self.dest_txt.text()

- def _sourceFile(self) -> Text:
+ def _sourceFile(self) -> str:
root = self._repoagent.rootPath()
return os.path.normpath(os.path.join(root, self.source()))

- def _destinationFile(self) -> Text:
+ def _destinationFile(self) -> str:
root = self._repoagent.rootPath()
return os.path.normpath(os.path.join(root, self.destination()))

@@ -161,7 +161,7 @@
return
self.dest_txt.setText(relpath)

- def to_relative_path(self, fullpath: Text) -> Optional[Text]:
+ def to_relative_path(self, fullpath: str) -> Optional[str]:
if not fullpath:
return
fullpath = hglib.normpath(fullpath)
@@ -182,12 +182,12 @@
fullsrc, fulldest = self._sourceFile(), self._destinationFile()
return fullsrc.upper() == fulldest.upper() and sys.platform == 'win32'

- def compose_command(self) -> List[Text]:
+ def compose_command(self) -> List[str]:
name = self.isCopyCommand() and 'copy' or 'rename'
return hglib.buildcmdargs(name, self.source(), self.destination(),
v=True, f=True)

- def show_command(self, cmdline: List[Text]) -> None:
+ def show_command(self, cmdline: List[str]) -> None:
self.hgcmd_txt.setText('hg %s' % hglib.prettifycmdline(cmdline))

def canRunCommand(self) -> bool:
@@ -225,7 +225,7 @@

class RenameDialog(cmdui.CmdControlDialog):

- def __init__(self, repoagent: RepoAgent, parent: Optional[QWidget] = None, source: Optional[Text] = None, destination: Optional[Text] = None,
+ def __init__(self, repoagent: RepoAgent, parent: Optional[QWidget] = None, source: Optional[str] = None, destination: Optional[str] = None,
iscopy: bool = False) -> None:
super().__init__(parent)
self._repoagent = repoagent
diff --git a/tortoisehg/hgqt/repofilter.py b/tortoisehg/hgqt/repofilter.py
--- a/tortoisehg/hgqt/repofilter.py
+++ b/tortoisehg/hgqt/repofilter.py
@@ -69,7 +69,7 @@
'tagged()', 'bookmark()',
'file(".hgsubstate") or file(".hgsub")')

-def _firstword(query: Text) -> Optional[bytes]:
+def _firstword(query: str) -> Optional[bytes]:
lquery = hglib.fromunicode(query)
try:
for token, value, _pos in hglib.tokenizerevspec(lquery):
@@ -78,7 +78,7 @@
except error.ParseError:
pass

-def _querytype(repo: localrepo.localrepository, query: Text) -> Optional[Text]:
+def _querytype(repo: localrepo.localrepository, query: str) -> Optional[str]:
r"""
>>> # TODO: maybe replace with real repo
>>> origisrevsymbol = scmutil.isrevsymbol
@@ -302,11 +302,11 @@
self.entrydlg.entry.setFocus()
self.entrydlg.setVisible(True)

- def queryIssued(self, query: Text) -> None:
+ def queryIssued(self, query: str) -> None:
self.revsetcombo.setEditText(query)
self.runQuery()

- def _prepareQuery(self) -> Text:
+ def _prepareQuery(self) -> str:
query = self.revsetcombo.currentText().strip()
if _querytype(self._repo, query) == 'keyword':
return hglib.formatrevspec('keyword(%s)', query)
@@ -352,7 +352,7 @@
margins.setRight(w + 1)
le.setContentsMargins(margins)

- def setQuery(self, query: Text) -> None:
+ def setQuery(self, query: str) -> None:
self.revsetcombo.setCurrentIndex(self.revsetcombo.findText(query))
self.revsetcombo.setEditText(query)

@@ -500,13 +500,13 @@
self._emitBranchChanged() # falls back to "show all"

@pyqtSlot(str)
- def setBranch(self, branch: Text) -> None:
+ def setBranch(self, branch: str) -> None:
"""Change the current branch by name [unicode]"""
index = self._branchCombo.findData(branch)
if index >= 0:
self._branchCombo.setCurrentIndex(index)

- def branch(self) -> Text:
+ def branch(self) -> str:
"""Return the current branch name [unicode]"""
index = self._branchCombo.currentIndex()
branch = self._branchCombo.itemData(index)
diff --git a/tortoisehg/hgqt/repomodel.py b/tortoisehg/hgqt/repomodel.py
--- a/tortoisehg/hgqt/repomodel.py
+++ b/tortoisehg/hgqt/repomodel.py
@@ -127,7 +127,7 @@
GraphNodeRole = Qt.ItemDataRole.UserRole + 0
LabelsRole = Qt.ItemDataRole.UserRole + 1 # [(text, style), ...]

-def _parsebranchcolors(value: Text) -> List[Tuple[Text, Text]]:
+def _parsebranchcolors(value: str) -> List[Tuple[str, str]]:
r"""Parse tortoisehg.branchcolors setting

>>> _parsebranchcolors('foo:#123456 bar:#789abc ')
@@ -232,7 +232,7 @@
self._branch_colors.update(_parsebranchcolors(
self._repoagent.configString('tortoisehg', 'branchcolors')))

- def setBranch(self, branch: Text, allparents: bool = False) -> None:
+ def setBranch(self, branch: str, allparents: bool = False) -> None:
branchchanged = (branch != self._filterbranch)
parentchanged = (allparents != self._allparents)
self._filterbranch = branch
@@ -348,10 +348,10 @@
self._emitAllDataChanged()
self.revsUpdated.emit()

- def revset(self) -> Text:
+ def revset(self) -> str:
return self._revspec

- def setRevset(self, revspec: Text) -> None:
+ def setRevset(self, revspec: str) -> None:
if revspec == self._revspec:
return
self._revspec = revspec
@@ -425,7 +425,7 @@
bottomright = self.index(self._rowcount - 1, self.columnCount() - 1)
self.dataChanged.emit(self.index(0, 0), bottomright)

- def branch(self) -> Text:
+ def branch(self) -> str:
return self._filterbranch

def canFetchMore(self, parent: QModelIndex) -> bool:
@@ -489,7 +489,7 @@
return 0
return len(self.allColumns())

- def maxWidthValueForColumn(self, column: int) -> Optional[Text]:
+ def maxWidthValueForColumn(self, column: int) -> Optional[str]:
if column == RevColumn:
return '8' * len(str(len(self.repo))) + '+'
if column in (NodeColumn, GitNodeColumn):
@@ -523,14 +523,14 @@
return -1
return gnode.rev

- def _user_color(self, user: Text) -> Text:
+ def _user_color(self, user: str) -> str:
'deprecated, please replace with hgtk color scheme'
if user not in self._user_colors:
idx = graph.hashcolor(user)
self._user_colors[user] = graph.COLORS[idx]
return self._user_colors[user]

- def _namedbranch_color(self, branch: Text) -> Text:
+ def _namedbranch_color(self, branch: str) -> str:
'deprecated, please replace with hgtk color scheme'
if branch not in self._branch_colors:
idx = graph.hashcolor(branch)
@@ -655,7 +655,7 @@
or (self._revspec and not self._selectedrevs
and not self._querysess.isFinished()))

- def mimeTypes(self) -> List[Text]:
+ def mimeTypes(self) -> List[str]:
return [mqpatchmimetype]

def supportedDropActions(self):
@@ -704,7 +704,7 @@
def headerData(self,
section: int,
orientation: int,
- role: int = Qt.ItemDataRole.DisplayRole) -> Optional[Text]:
+ role: int = Qt.ItemDataRole.DisplayRole) -> Optional[str]:
if orientation == Qt.Orientation.Horizontal and role == Qt.ItemDataRole.DisplayRole:
return self.allColumnHeaders()[section][1]

@@ -746,7 +746,7 @@
return QModelIndex()
return self.index(row, 0)

- def _getbranch(self, ctx: context.changectx) -> Text:
+ def _getbranch(self, ctx: context.changectx) -> str:
b = hglib.tounicode(ctx.branch())
assert b is not None
if ctx.extra().get(b'close'):
@@ -756,7 +756,7 @@
b += u'--'
return b

- def _getlatesttags(self, ctx: context.changectx) -> Text:
+ def _getlatesttags(self, ctx: context.changectx) -> str:
rev = ctx.rev()
todo = [rev]
repo = self.repo
@@ -786,13 +786,13 @@
self._latesttags[rev] = pdate, pdist + 1, ptag
return self._latesttags[rev][2]

- def _gettags(self, ctx: context.changectx) -> Text:
+ def _gettags(self, ctx: context.changectx) -> str:
if ctx.rev() is None:
return ''
tags = [hglib.tounicode(t) for t in ctx.tags() if t not in self._mqtags]
return ','.join(tags)

- def _getrev(self, ctx: context.changectx) -> Text:
+ def _getrev(self, ctx: context.changectx) -> str:
rev = ctx.rev()
if isinstance(rev, int):
return str(rev)
@@ -801,7 +801,7 @@
else:
return ''

- def _getauthor(self, ctx: context.changectx) -> Text:
+ def _getauthor(self, ctx: context.changectx) -> str:
try:
user = ctx.user()
if not self._fullauthorname:
@@ -810,7 +810,7 @@
except error.Abort:
return _('Mercurial User')

- def _getlog(self, ctx: context.changectx) -> Text:
+ def _getlog(self, ctx: context.changectx) -> str:
if ctx.rev() is None:
if self.unicodestar:
# The Unicode symbol is a black star:
@@ -823,7 +823,7 @@
limit = None # first line
return hglib.longsummary(ctx.description(), limit)

- def _getrevlabels(self, ctx: context.changectx) -> List[Tuple[Text, Text]]:
+ def _getrevlabels(self, ctx: context.changectx) -> List[Tuple[str, str]]:
labels = []

# as of hg 4.4.2, repo.branchheads() can be slow because of
@@ -880,7 +880,7 @@

return labels

- def _getchanges(self, ctx: context.changectx) -> List[Tuple[Text, Text]]:
+ def _getchanges(self, ctx: context.changectx) -> List[Tuple[str, str]]:
"""Return the MAR status for the given ctx."""
labels = []

@@ -894,7 +894,7 @@
labels.append((str(len(R)), 'log.removed'))
return labels

- def _getconv(self, ctx: context.changectx) -> Text:
+ def _getconv(self, ctx: context.changectx) -> str:
if ctx.rev() is not None:
extra = ctx.extra()
cvt = extra.get(b'convert_revision', b'')
@@ -912,7 +912,7 @@
return hglib.tounicode(cvt)
return ''

- def _getphase(self, ctx: context.changectx) -> Text:
+ def _getphase(self, ctx: context.changectx) -> str:
if ctx.rev() is None:
return ''
try:
@@ -920,13 +920,13 @@
except:
return 'draft'

- def _gettopic(self, ctx: context.changectx) -> Optional[Text]:
+ def _gettopic(self, ctx: context.changectx) -> Optional[str]:
return hglib.tounicode(ctx.extra().get(b'topic'))

def _hasFileColumn(self) -> bool:
return False # no FileColumn

- def allColumns(self) -> Tuple[Text, ...]:
+ def allColumns(self) -> Tuple[str, ...]:
if self._hasFileColumn():
return ALLCOLUMNS
else:
diff --git a/tortoisehg/hgqt/repowidget.py b/tortoisehg/hgqt/repowidget.py
--- a/tortoisehg/hgqt/repowidget.py
+++ b/tortoisehg/hgqt/repowidget.py
@@ -163,7 +163,7 @@
_SELECTION_ISTRUE = 'istrue'
_SELECTION_ISDRAFTORWD = 'isdraftorwd'

-_KNOWN_SELECTION_ATTRS: Set[Text] = {
+_KNOWN_SELECTION_ATTRS: Set[str] = {
_SELECTION_SINGLE,
_SELECTION_PAIR,
_SELECTION_SOME,
@@ -187,7 +187,7 @@
}

# selection attributes which may be specified by user
-_CUSTOM_TOOLS_SELECTION_ATTRS: Set[Text] = {
+_CUSTOM_TOOLS_SELECTION_ATTRS: Set[str] = {
_SELECTION_ISREV,
_SELECTION_ISWD,
_SELECTION_ISCTX,
@@ -220,7 +220,7 @@
repoLinkClicked = pyqtSignal(str)
"""Emitted when clicked a link to open repository"""

- _actions: Dict[Text, Tuple[QAction, Set[Text], Set[Text]]]
+ _actions: Dict[str, Tuple[QAction, Set[str], Set[str]]]

def __init__(self, actionregistry, repoagent, parent=None, bundle=None):
QWidget.__init__(self, parent, acceptDrops=True)
@@ -1197,7 +1197,7 @@
return (len(self.repoview.selectedRevisions()) == 2
and not self._isUnappliedPatchSelected())

- def _selectionAttributes(self) -> Set[Text]:
+ def _selectionAttributes(self) -> Set[str]:
"""Returns a set of keywords that describe the selected revisions"""
attributes = {_SELECTION_ISTRUE}

@@ -1265,7 +1265,7 @@

return attributes

- def _selectedIntRevisionsAndUnappliedPatches(self) -> Tuple[List[int], List[Text]]:
+ def _selectedIntRevisionsAndUnappliedPatches(self) -> Tuple[List[int], List[str]]:
"""Returns lists of selected change/workingctx revisions and unapplied
patches"""
revisions = []
@@ -1312,7 +1312,7 @@
# simply disable lazy evaluation as we won't handle slow query
return list(self.repo.revs(b'%d::%d', rev0, rev1))

- def _selectedUnappliedPatches(self) -> List[Text]:
+ def _selectedUnappliedPatches(self) -> List[str]:
"""Returns a list of selected unapplied patches"""
_revisions, patches = self._selectedIntRevisionsAndUnappliedPatches()
return patches
@@ -1512,10 +1512,10 @@
menu.popup(point)

def _createNamedAction(self,
- name: Text,
- attrs: Set[Text],
- exts: Optional[Set[Text]] = None,
- icon: Optional[Text] = None,
+ name: str,
+ attrs: Set[str],
+ exts: Optional[Set[str]] = None,
+ icon: Optional[str] = None,
cb: Optional[Callable] = None) -> QAction:
act = QAction(self)
act.setShortcutContext(Qt.ShortcutContext.WidgetWithChildrenShortcut)
@@ -1527,10 +1527,10 @@
return act

def _addNamedAction(self,
- name: Text,
+ name: str,
act: QAction,
- attrs: Set[Text],
- exts: Optional[Set[Text]] = None) -> None:
+ attrs: Set[str],
+ exts: Optional[Set[str]] = None) -> None:
assert name not in self._actions, name
assert attrs.issubset(_KNOWN_SELECTION_ATTRS), attrs
# RepoWidget actions act on revisions selected in the graph view, so
@@ -1544,7 +1544,7 @@

def _addNamedActionsToMenu(self,
menu: QMenu,
- names: List[Optional[Text]]) -> None:
+ names: List[Optional[str]]) -> None:
for n in names:
if n:
menu.addAction(self._actions[n][0])
@@ -1559,7 +1559,7 @@
act.setEnabled(attrs.issubset(selattrs))
act.setVisible(not exts or bool(exts & enabledexts))

- def _addCustomToolsSubMenu(self, menu: QMenu, location: Text) -> None:
+ def _addCustomToolsSubMenu(self, menu: QMenu, location: str) -> None:
tools, toollist = hglib.tortoisehgtools(self.repo.ui,
selectedlocation=location)

@@ -2450,8 +2450,8 @@
"""Make REV the top applied patch"""
self._qpushRevision(move=True)

- def runCustomCommand(self, command: Text, showoutput: bool = False, workingdir: Text = '',
- files: Optional[List[Text]] = None) -> Optional[Union[int, subprocess.Popen]]:
+ def runCustomCommand(self, command: str, showoutput: bool = False, workingdir: str = '',
+ files: Optional[List[str]] = None) -> Optional[Union[int, subprocess.Popen]]:
"""Execute 'custom commands', on the selected repository"""
# Perform variable expansion
# This is done in two steps:
@@ -2466,7 +2466,7 @@
workingdir = os.path.expandvars(workingdir).strip()

# 2. Expand internal workbench variables
- def filelist2str(filelist: List[Text]) -> Text:
+ def filelist2str(filelist: List[str]) -> str:
return hglib.tounicode(b' '.join(
procutil.shellquote(
os.path.normpath(self.repo.wjoin(hglib.fromunicode(filename))))
@@ -2478,7 +2478,7 @@

selection = self.repoview.selectedRevisions()

- def selectionfiles2str(source: Text) -> Text:
+ def selectionfiles2str(source: str) -> str:
files = set()
for rev in selection:
files.update(
diff --git a/tortoisehg/hgqt/resolve.py b/tortoisehg/hgqt/resolve.py
--- a/tortoisehg/hgqt/resolve.py
+++ b/tortoisehg/hgqt/resolve.py
@@ -278,7 +278,7 @@
paths.append((root, wfile))
return paths

- def runCommand(self, tree: QTreeView, cmdline: List[Text]) -> None:
+ def runCommand(self, tree: QTreeView, cmdline: List[str]) -> None:
cmdlines = []
selected = self.getSelectedPaths(tree)
while selected:
@@ -524,7 +524,7 @@

def data(self,
index: QModelIndex,
- role: int = Qt.ItemDataRole.DisplayRole) -> Optional[Text]:
+ role: int = Qt.ItemDataRole.DisplayRole) -> Optional[str]:
if not index.isValid():
return None
if role == Qt.ItemDataRole.DisplayRole:
@@ -542,7 +542,7 @@
def headerData(self,
col: int,
orientation: int,
- role: int = Qt.ItemDataRole.DisplayRole) -> Optional[Text]:
+ role: int = Qt.ItemDataRole.DisplayRole) -> Optional[str]:
if role != Qt.ItemDataRole.DisplayRole or orientation != Qt.Orientation.Horizontal:
return None
else:
@@ -553,7 +553,7 @@
row = index.row()
return self.rows[row][2], self.rows[row][0]

- def mimeTypes(self) -> List[Text]:
+ def mimeTypes(self) -> List[str]:
return ['text/uri-list']

def mimeData(self, indexes: List[QModelIndex]) -> QMimeData:
diff --git a/tortoisehg/hgqt/serve.py b/tortoisehg/hgqt/serve.py
--- a/tortoisehg/hgqt/serve.py
+++ b/tortoisehg/hgqt/serve.py
@@ -121,7 +121,7 @@

self._agent.runCommand(self._cmdargs())

- def _cmdargs(self) -> List[Text]:
+ def _cmdargs(self) -> List[str]:
"""Build command args to run server"""
a = ['serve', '--port', str(self.port), '-v']
if self._singlerepo:
@@ -130,7 +130,7 @@
a += ['--web-conf', self._tempwebconf()]
return a

- def _tempwebconf(self) -> Text:
+ def _tempwebconf(self) -> str:
"""Save current webconf to temporary file; return its path"""
webconf = self._webconf
if not hasattr(webconf, 'write'):
@@ -153,7 +153,7 @@
return self._webconf_form.webconf

@property
- def _singlerepo(self) -> Optional[Text]:
+ def _singlerepo(self) -> Optional[str]:
"""Return repository path if serving single repository"""
# TODO: The caller crashes if this returns None with:
# `'ServeDialog' object has no attribute '_singlerepo'`
@@ -178,7 +178,7 @@
return self._agent.isBusy()

@property
- def rooturl(self) -> Text:
+ def rooturl(self) -> str:
"""Returns the root URL of the web server"""
# TODO: scheme, hostname ?
return 'http://localhost:%d' % self.port
diff --git a/tortoisehg/hgqt/settings.py b/tortoisehg/hgqt/settings.py
--- a/tortoisehg/hgqt/settings.py
+++ b/tortoisehg/hgqt/settings.py
@@ -115,7 +115,7 @@

class SettingsCombo(QComboBox):

- defaults: List[Text]
+ defaults: List[str]

def __init__(self, parent=None, **opts):
QComboBox.__init__(self, parent, toolTip=opts['tooltip'])
diff --git a/tortoisehg/hgqt/shortcutregistry.py b/tortoisehg/hgqt/shortcutregistry.py
--- a/tortoisehg/hgqt/shortcutregistry.py
+++ b/tortoisehg/hgqt/shortcutregistry.py
@@ -41,12 +41,12 @@

_KeySequencesD = Union[
QKeySequence.StandardKey,
- Text,
- Tuple[Text, QKeySequence.StandardKey], # std key with custom modifier
+ str,
+ Tuple[str, QKeySequence.StandardKey], # std key with custom modifier
]
_KeySequencesDefs = Union[_KeySequencesD, List[_KeySequencesD], None]

-_ACTIONS_TABLE: Dict[Text, Tuple[Text, _KeySequencesDefs]] = {
+_ACTIONS_TABLE: Dict[str, Tuple[str, _KeySequencesDefs]] = {
# MQ operations:
# TODO: merge or give better name to deletePatches_, pushMovePatch_,
# and renamePatch_
@@ -193,15 +193,15 @@
return [QKeySequence('%s+%s' % (mod, kstr), QKeySequence.SequenceFormat.PortableText)]
return QKeySequence.keyBindings(data)

-def _parseUserKeySequences(data: List[Text]) -> List[QKeySequence]:
+def _parseUserKeySequences(data: List[str]) -> List[QKeySequence]:
return [QKeySequence(s, QKeySequence.SequenceFormat.PortableText) for s in data]

-def _formatKeySequences(seqs: List[QKeySequence]) -> List[Text]:
+def _formatKeySequences(seqs: List[QKeySequence]) -> List[str]:
return [b.toString(QKeySequence.SequenceFormat.PortableText) for b in seqs]

-def _formatToolTip(label: Text,
- toolTip: Text,
- seqs: List[QKeySequence]) -> Text:
+def _formatToolTip(label: str,
+ toolTip: str,
+ seqs: List[QKeySequence]) -> str:
"""Build tool tip from current label/toolTip and shortcuts

>>> stext = '%s(%s)%s' % (_TOOLTIP_SHORTCUT_START_TAG, 'A',
@@ -245,7 +245,7 @@
and QAction instances.
"""

- _userKeys: Dict[Text, List[QKeySequence]]
+ _userKeys: Dict[str, List[QKeySequence]]

def __init__(self):
self._defaultKeys = {name: _parseDefaultKeySequences(seq)
@@ -285,28 +285,28 @@
qs.remove(name)
qs.endGroup()

- def allNames(self) -> List[Text]:
+ def allNames(self) -> List[str]:
"""List of all known action names"""
return sorted(_ACTIONS_TABLE)

- def actionLabel(self, name: Text) -> Text:
+ def actionLabel(self, name: str) -> str:
label, _default = _ACTIONS_TABLE[name]
return label

- def defaultKeySequences(self, name: Text) -> List[QKeySequence]:
+ def defaultKeySequences(self, name: str) -> List[QKeySequence]:
return self._defaultKeys[name]

- def keySequences(self, name: Text) -> List[QKeySequence]:
+ def keySequences(self, name: str) -> List[QKeySequence]:
if name in self._userKeys:
return self._userKeys[name]
return self.defaultKeySequences(name)

- def hasUserKeySequences(self, name: Text) -> bool:
+ def hasUserKeySequences(self, name: str) -> bool:
assert name in _ACTIONS_TABLE, name
return name in self._userKeys

def setUserKeySequences(self,
- name: Text,
+ name: str,
seqs: List[QKeySequence]) -> None:
"""Stores new shortcuts of the specified action

@@ -318,7 +318,7 @@
assert name in _ACTIONS_TABLE, name
self._userKeys[name] = seqs

- def unsetUserKeySequences(self, name: Text) -> None:
+ def unsetUserKeySequences(self, name: str) -> None:
"""Restores the shortcuts of the specified action to default

You'll also want to call saveSettings() and applyChangesToActions().
@@ -330,7 +330,7 @@
class ActionRegistry(ShortcutRegistry):
"""Manages user-configurable shortcuts and QAction instances"""

- _actionsMap: Dict[Text, weakref.WeakSet[QAction]]
+ _actionsMap: Dict[str, weakref.WeakSet[QAction]]

def __init__(self):
super().__init__()
@@ -345,13 +345,13 @@
for name, actions in self._actionsMap.items():
self._updateActions(name, actions)

- def registerAction(self, name: Text, action: QAction) -> None:
+ def registerAction(self, name: str, action: QAction) -> None:
"""Register QAction instance to be updated on applyChangesToActions()"""
assert name in _ACTIONS_TABLE, name
self._actionsMap[name].add(action)
self._updateActions(name, [action])

- def _updateActions(self, name: Text, actions: Iterable[QAction]) -> None:
+ def _updateActions(self, name: str, actions: Iterable[QAction]) -> None:
label = self.actionLabel(name)
seqs = self.keySequences(name)
for a in actions:
diff --git a/tortoisehg/hgqt/shortcutsettings.py b/tortoisehg/hgqt/shortcutsettings.py
--- a/tortoisehg/hgqt/shortcutsettings.py
+++ b/tortoisehg/hgqt/shortcutsettings.py
@@ -128,7 +128,7 @@
def registry(self) -> shortcutregistry.ShortcutRegistry:
return self._registry

- def _currentName(self) -> Text:
+ def _currentName(self) -> str:
it = self._view.currentItem()
if not it:
return ''
diff --git a/tortoisehg/hgqt/tag.py b/tortoisehg/hgqt/tag.py
--- a/tortoisehg/hgqt/tag.py
+++ b/tortoisehg/hgqt/tag.py
@@ -60,9 +60,9 @@
def __init__(self,
repoagent: RepoAgent,
tag: bytes = b'',
- rev: Text = 'tip',
+ rev: str = 'tip',
parent: Optional[QWidget] = None,
- opts: Optional[Dict[Text, Union[bool, bytes]]] = None) -> None:
+ opts: Optional[Dict[str, Union[bool, bytes]]] = None) -> None:
super().__init__(parent)
if opts is None:
opts = {}
@@ -251,8 +251,8 @@
self.customTextLineEdit.setVisible(visible)

def set_status(self,
- text: Text,
- icon: Optional[Union[bool, Text, QIcon]]) -> None:
+ text: str,
+ icon: Optional[Union[bool, str, QIcon]]) -> None:
self.status.setVisible(True)
self.sep.setVisible(True)
self.status.set_status(text, icon)
@@ -261,7 +261,7 @@
self.status.setHidden(True)
self.sep.setHidden(True)

- def _runTag(self, tagname: Text, **opts) -> None:
+ def _runTag(self, tagname: str, **opts) -> None:
if not self._cmdsession.isFinished():
self.set_status(_('Repository command still running'), False)
return
diff --git a/tortoisehg/hgqt/thgrepo.py b/tortoisehg/hgqt/thgrepo.py
--- a/tortoisehg/hgqt/thgrepo.py
+++ b/tortoisehg/hgqt/thgrepo.py
@@ -452,33 +452,33 @@
return hglib.tounicode(self._repo.root)

def configBool(self,
- section: Text,
- name: Text,
+ section: str,
+ name: str,
default: bool = hgconfig.UNSET_DEFAULT) -> bool:
return self._config.configBool(section, name, default)

def configInt(self,
- section: Text,
- name: Text,
+ section: str,
+ name: str,
default: int = hgconfig.UNSET_DEFAULT) -> int:
return self._config.configInt(section, name, default)

def configString(self,
- section: Text,
- name: Text,
- default: Text = hgconfig.UNSET_DEFAULT) -> Text:
+ section: str,
+ name: str,
+ default: str = hgconfig.UNSET_DEFAULT) -> str:
return self._config.configString(section, name, default)

def configStringList(self,
- section: Text,
- name: Text,
- default: List[Text] = hgconfig.UNSET_DEFAULT) -> List[Text]:
+ section: str,
+ name: str,
+ default: List[str] = hgconfig.UNSET_DEFAULT) -> List[str]:
return self._config.configStringList(section, name, default)

- def configStringItems(self, section: Text) -> List[Tuple[Text, Text]]:
+ def configStringItems(self, section: str) -> List[Tuple[str, str]]:
return self._config.configStringItems(section)

- def hasConfig(self, section: Text, name: Text) -> bool:
+ def hasConfig(self, section: str, name: str) -> bool:
return self._config.hasConfig(section, name)

def displayName(self):
@@ -613,7 +613,7 @@
self.busyChanged.emit(busy)

def runCommand(self,
- cmdline: List[Text],
+ cmdline: List[str],
uihandler: Optional[Union[QWidget, cmdcore.UiHandler]] = None,
overlay: bool = True) -> cmdcore.CmdSession:
"""Executes a single command asynchronously in this repository"""
@@ -621,14 +621,14 @@
return self._cmdagent.runCommand(cmdline, uihandler)

def runCommandSequence(self,
- cmdlines: List[List[Text]],
+ cmdlines: List[List[str]],
uihandler: Optional[Union[QWidget, cmdcore.UiHandler]] = None,
overlay: bool = True) -> cmdcore.CmdSession:
"""Executes a series of commands asynchronously in this repository"""
cmdlines = [self._extendCmdline(l, overlay) for l in cmdlines]
return self._cmdagent.runCommandSequence(cmdlines, uihandler)

- def _extendCmdline(self, cmdline: List[Text], overlay: bool) -> List[Text]:
+ def _extendCmdline(self, cmdline: List[str], overlay: bool) -> List[str]:
if self.hiddenRevsIncluded():
cmdline = ['--hidden'] + cmdline
if overlay and self._overlayurl:
diff --git a/tortoisehg/hgqt/thgstrip.py b/tortoisehg/hgqt/thgstrip.py
--- a/tortoisehg/hgqt/thgstrip.py
+++ b/tortoisehg/hgqt/thgstrip.py
@@ -54,9 +54,9 @@

def __init__(self,
repoagent: RepoAgent,
- rev: Optional[Text] = None,
+ rev: Optional[str] = None,
parent: Optional[QWidget] = None,
- opts: Optional[Dict[Text, Any]] = None) -> None:
+ opts: Optional[Dict[str, Any]] = None) -> None:
super().__init__(parent)
if opts is None:
opts = {}
@@ -208,9 +208,9 @@


def createStripDialog(repoagent: RepoAgent,
- rev: Optional[Text] = None,
+ rev: Optional[str] = None,
parent: Optional[QWidget] = None,
- opts: Optional[Dict[Text, Any]] = None) -> cmdui.CmdControlDialog:
+ opts: Optional[Dict[str, Any]] = None) -> cmdui.CmdControlDialog:
if opts is None:
opts = {}
dlg = cmdui.CmdControlDialog(parent)
diff --git a/tortoisehg/hgqt/update.py b/tortoisehg/hgqt/update.py
--- a/tortoisehg/hgqt/update.py
+++ b/tortoisehg/hgqt/update.py
@@ -50,14 +50,14 @@
from .qtgui import QWidget
from .thgrepo import RepoAgent

- UpdateOpts = Dict[Text, Any]
+ UpdateOpts = Dict[str, Any]


class UpdateWidget(cmdui.AbstractCmdWidget):

def __init__(self,
repoagent: RepoAgent,
- rev: Optional[Union[Text, pycompat.unicode]] = None,
+ rev: Optional[Union[str, pycompat.unicode]] = None,
parent: Optional[QWidget] = None,
opts: Optional[UpdateOpts] = None) -> None:
# TODO: unify the `rev` type
@@ -245,7 +245,7 @@
cmdline += ['--verbose']
cmdline += ['--config', 'ui.merge=internal:' +
(self.autoresolve_chk.isChecked() and 'merge' or 'fail')]
- rev: Text = self.rev_combo.currentText()
+ rev: str = self.rev_combo.currentText()

activatebookmarkmode = self._repoagent.configString(
'tortoisehg', 'activatebookmarks')
@@ -355,7 +355,7 @@
pa = p1.ancestor(p2)
return not clean \
and (p1.rev() == pa.rev() or p2.rev() == pa.rev())
- def confirmupdate() -> Optional[Text]:
+ def confirmupdate() -> Optional[str]:
msg = _('Detected uncommitted local changes in working tree.\n'
'Please select to continue:\n')
data = {'discard': (_('&Discard'),
@@ -426,7 +426,7 @@

def __init__(self,
repoagent: RepoAgent,
- rev: Optional[Union[Text, pycompat.unicode]] = None,
+ rev: Optional[Union[str, pycompat.unicode]] = None,
parent: Optional[QWidget] = None,
opts: Optional[UpdateOpts] = None) -> None:
super().__init__(parent)
diff --git a/tortoisehg/hgqt/visdiff.py b/tortoisehg/hgqt/visdiff.py
--- a/tortoisehg/hgqt/visdiff.py
+++ b/tortoisehg/hgqt/visdiff.py
@@ -187,7 +187,7 @@

def launchtool(cmd: bytes,
opts: Sequence[bytes],
- replace: Dict[Text, Union[bytes, Text]],
+ replace: Dict[str, Union[bytes, str]],
block: bool) -> None:
# TODO: fix up the bytes vs str in the replacement mapping
def quote(match):
@@ -210,7 +210,7 @@
_('Tool launch failure'),
_('%s : %s') % (hglib.tounicode(cmd), hglib.exception_str(e)))

-def filemerge(ui: uimod.ui, fname: Text, patchedfname: Text) -> None:
+def filemerge(ui: uimod.ui, fname: str, patchedfname: str) -> None:
'Launch the preferred visual diff tool for two text files'
detectedtools = hglib.difftools(ui)
if not detectedtools:
@@ -258,7 +258,7 @@
def visualdiff(ui: uimod.ui,
repo: localrepo.localrepository,
pats: Sequence[bytes],
- opts: Dict[Text, Any]) -> Optional[FileSelectionDialog]:
+ opts: Dict[str, Any]) -> Optional[FileSelectionDialog]:
revs = opts.get('rev', [])
change = opts.get('change')

@@ -451,7 +451,7 @@
repoagent = repo._pyqtobj # TODO

# TODO: sort out bytes vs str
- replace: Dict[Text, Union[bytes, Text]] = {
+ replace: Dict[str, Union[bytes, str]] = {
"parent": dir1a,
"parent1": dir1a,
"parent2": dir1b,
@@ -595,7 +595,7 @@
def get_status(file: bytes,
mod: Set[bytes],
add: Set[bytes],
- rem: Set[bytes]) -> Text:
+ rem: Set[bytes]) -> str:
if file in mod:
return 'M'
if file in add:
@@ -611,7 +611,7 @@
self.list.addItem(row)

@pyqtSlot(str)
- def onToolSelected(self, tool: Text) -> None:
+ def onToolSelected(self, tool: str) -> None:
'user selected a tool from the tool combo'
tool = hglib.fromunicode(tool) # pytype: disable=annotation-type-mismatch
assert tool in self.tools, tool
@@ -666,7 +666,7 @@
d2 = self.repo.ui.configbool(b'merge-tools', tool + b'.dirdiff')
self.dbutton.setEnabled(bool(d2))

- def launch(self, fname: Text) -> None:
+ def launch(self, fname: str) -> None:
fname = hglib.fromunicode(fname) # pytype: disable=annotation-type-mismatch
source = self.copies.get(fname, None)
dir1a, dir1b, dir2 = self.dirs
@@ -708,7 +708,7 @@
label2 += b'[merged]'

# Function to quote file/dir names in the argument string
- replace: Dict[Text, Union[bytes, Text]] = {
+ replace: Dict[str, Union[bytes, str]] = {
"parent": file1a,
"parent1": file1a,
"plabel1": label1a,
@@ -729,7 +729,7 @@
rev1a, rev1b, rev2 = self.revs
ctx1a, ctx1b, ctx2 = self.ctxs

- replace: Dict[Text, Union[bytes, Text]] = {
+ replace: Dict[str, Union[bytes, str]] = {
"parent": dir1a,
"parent1": dir1a,
"plabel1": rev1a,
@@ -749,7 +749,7 @@
rev1a, rev1b, rev2 = self.revs
ctx1a, ctx1b, ctx2 = self.ctxs

- replace: Dict[Text, Union[bytes, Text]] = {
+ replace: Dict[str, Union[bytes, str]] = {
"parent": dir1b,
"parent1": dir1b,
"plabel1": rev1b,
@@ -769,7 +769,7 @@
rev1a, rev1b, rev2 = self.revs
ctx1a, ctx1b, ctx2 = self.ctxs

- replace: Dict[Text, Union[bytes, Text]] = {
+ replace: Dict[str, Union[bytes, str]] = {
"parent": dir1a,
"parent1": dir1a,
"plabel1": rev1a,
diff --git a/tortoisehg/hgqt/webconf.py b/tortoisehg/hgqt/webconf.py
--- a/tortoisehg/hgqt/webconf.py
+++ b/tortoisehg/hgqt/webconf.py
@@ -155,7 +155,7 @@
if path:
self.openwebconf(path)

- def openwebconf(self, path: Text) -> None:
+ def openwebconf(self, path: str) -> None:
"""load the specified webconf file"""
path = hglib.fromunicode(path)
c = wconfig.readfile(path)
@@ -170,15 +170,15 @@
if path:
self.savewebconf(path)

- def savewebconf(self, path: Text) -> None:
+ def savewebconf(self, path: str) -> None:
"""save current webconf to the specified file"""
wconfig.writefile(self.webconf, hglib.fromunicode(path))
self.openwebconf(path) # reopen in case file path changed

@pyqtSlot()
def _addpathmap(self,
- path: Optional[Text] = None,
- localpath: Optional[Text] = None) -> None:
+ path: Optional[str] = None,
+ localpath: Optional[str] = None) -> None:
path, localpath = _PathDialog.getaddpathmap(
self, path=path, localpath=localpath,
invalidpaths=self._webconfmodel.paths)
@@ -214,8 +214,8 @@

class _PathDialog(QDialog):
"""Dialog to add/edit path mapping"""
- def __init__(self, title: Text, acceptlabel: Text, path: Optional[Text] = None, localpath: Optional[Text] = None,
- invalidpaths: Optional[Iterable[Text]] = None, parent: Optional[QWidget] = None) -> None:
+ def __init__(self, title: str, acceptlabel: str, path: Optional[str] = None, localpath: Optional[str] = None,
+ invalidpaths: Optional[Iterable[str]] = None, parent: Optional[QWidget] = None) -> None:
super().__init__(parent)
self.setWindowFlags((self.windowFlags() | Qt.WindowType.WindowMinimizeButtonHint)
& ~Qt.WindowType.WindowContextHelpButtonHint)
@@ -250,7 +250,7 @@
addfield('localpath', _('Local Path:'), self._localpath_browse_button)
self._localpath_browse_button.clicked.connect(self._browse_localpath)

- def _initbuttons(self, acceptlabel: Text) -> None:
+ def _initbuttons(self, acceptlabel: str) -> None:
"""initialize dialog buttons"""
self._buttons = QDialogButtonBox(self)
self._accept_button = self._buttons.addButton(QDialogButtonBox.StandardButton.Ok)
@@ -261,12 +261,12 @@
self.layout().addRow(self._buttons)

@property
- def path(self) -> Text:
+ def path(self) -> str:
"""value of path field"""
return self._path_edit.text()

@property
- def localpath(self) -> Text:
+ def localpath(self) -> str:
"""value of localpath field"""
return self._localpath_edit.text()

@@ -296,9 +296,9 @@
@classmethod
def getaddpathmap(cls,
parent: Optional[QWidget],
- path: Optional[Text] = None,
- localpath: Optional[Text] = None,
- invalidpaths: Optional[Iterable[Text]] = None) -> Tuple[Optional[Text], Optional[Text]]:
+ path: Optional[str] = None,
+ localpath: Optional[str] = None,
+ invalidpaths: Optional[Iterable[str]] = None) -> Tuple[Optional[str], Optional[str]]:
d = cls(title=_('Add Path to Serve'), acceptlabel=_('Add'),
path=path, localpath=localpath,
invalidpaths=invalidpaths, parent=parent)
@@ -310,9 +310,9 @@
@classmethod
def geteditpathmap(cls,
parent: Optional[QWidget],
- path: Optional[Text] = None,
- localpath: Optional[Text] = None,
- invalidpaths: Optional[Iterable[Text]] = None) -> Tuple[Optional[Text], Optional[Text]]:
+ path: Optional[str] = None,
+ localpath: Optional[str] = None,
+ invalidpaths: Optional[Iterable[str]] = None) -> Tuple[Optional[str], Optional[str]]:
d = cls(title=_('Edit Path to Serve'), acceptlabel=_('Edit'),
path=path, localpath=localpath,
invalidpaths=invalidpaths, parent=parent)
@@ -356,17 +356,17 @@
return self._COLUMNS[section][0]

@property
- def paths(self) -> List[Text]:
+ def paths(self) -> List[str]:
"""return list of known paths"""
return [hglib.tounicode(e) for e in self._config[b'paths']]

- def getpathmapat(self, row: int) -> Tuple[Text, ...]:
+ def getpathmapat(self, row: int) -> Tuple[str, ...]:
"""return pair of (path, localpath) at the specified index"""
assert 0 <= row and row < self.rowCount(), row
return tuple(hglib.tounicode(e)
for e in self._config.items(b'paths')[row])

- def addpathmap(self, path: Text, localpath: Text) -> None:
+ def addpathmap(self, path: str, localpath: str) -> None:
"""add path mapping to serve"""
assert path not in self.paths, path
self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
@@ -376,7 +376,7 @@
finally:
self.endInsertRows()

- def setpathmap(self, path: Text, localpath: Text) -> None:
+ def setpathmap(self, path: str, localpath: str) -> None:
"""change path mapping at the specified index"""
self._config.set(b'paths', hglib.fromunicode(path),
hglib.fromunicode(localpath))
@@ -384,7 +384,7 @@
self.dataChanged.emit(self.index(row, 0),
self.index(row, self.columnCount()))

- def removepathmap(self, path: Text) -> None:
+ def removepathmap(self, path: str) -> None:
"""remove path from mapping"""
row = self._indexofpath(path)
self.beginRemoveRows(QModelIndex(), row, row)
@@ -393,7 +393,7 @@
finally:
self.endRemoveRows()

- def _indexofpath(self, path: Text) -> int:
+ def _indexofpath(self, path: str) -> int:
path = hglib.fromunicode(path)
assert path in self._config[b'paths'], path
return list(self._config[b'paths']).index(path)
diff --git a/tortoisehg/util/cachethg.py b/tortoisehg/util/cachethg.py
--- a/tortoisehg/util/cachethg.py
+++ b/tortoisehg/util/cachethg.py
@@ -27,8 +27,8 @@
debugging = False
enabled = True
localonly = False
-includepaths: List[Text] = []
-excludepaths: List[Text] = []
+includepaths: List[str] = []
+excludepaths: List[str] = []

try:
from mercurial.windows import winreg
@@ -79,10 +79,10 @@
UNRESOLVED = 'U'

# file status cache
-overlay_cache: Dict[Optional[Text], Optional[Text]] = {}
+overlay_cache: Dict[Optional[str], Optional[str]] = {}
cache_tick_count = 0
-cache_root: Optional[Text] = None
-cache_pdir: Optional[Text] = None
+cache_root: Optional[str] = None
+cache_pdir: Optional[str] = None


def add_dirs(list: List[bytes]) -> None:
@@ -99,8 +99,8 @@
list.extend(dirs)


-def get_state(upath: Text,
- repo: Optional[localrepo.localrepository] = None) -> Text:
+def get_state(upath: str,
+ repo: Optional[localrepo.localrepository] = None) -> str:
"""
Get the state of a given path in source control.
"""
@@ -108,8 +108,8 @@
return states and states[0] or NOT_IN_REPO


-def get_states(path: Text,
- repo: Optional[localrepo.localrepository] = None) -> Text:
+def get_states(path: str,
+ repo: Optional[localrepo.localrepository] = None) -> str:
"""
Get the states of a given path in source control.
"""
@@ -262,5 +262,5 @@
return status


-def add(path: Text, state: Text) -> None:
+def add(path: str, state: str) -> None:
overlay_cache[path] = overlay_cache.get(path, '') + state
diff --git a/tortoisehg/util/gpg.py b/tortoisehg/util/gpg.py
--- a/tortoisehg/util/gpg.py
+++ b/tortoisehg/util/gpg.py
@@ -23,7 +23,7 @@
if os.name == 'nt':
from mercurial.windows import winreg

- def findgpg(ui: uimod.ui) -> List[Text]:
+ def findgpg(ui: uimod.ui) -> List[str]:
path = []
for key in (r"Software\GNU\GnuPG", r"Software\Wow6432Node\GNU\GnuPG"):
try:
@@ -42,5 +42,5 @@
return path

else:
- def findgpg(ui: uimod.ui) -> List[Text]:
+ def findgpg(ui: uimod.ui) -> List[str]:
return []
diff --git a/tortoisehg/util/hglib.py b/tortoisehg/util/hglib.py
--- a/tortoisehg/util/hglib.py
+++ b/tortoisehg/util/hglib.py
@@ -155,10 +155,10 @@

if TYPE_CHECKING:
@overload
- def fromunicode(s: Text, errors: Text = 'strict') -> bytes:
+ def fromunicode(s: str, errors: str = 'strict') -> bytes:
pass
@overload
- def fromunicode(s: None, errors: Text = 'strict') -> None:
+ def fromunicode(s: None, errors: str = 'strict') -> None:
pass

def fromunicode(s, errors='strict'):
@@ -288,7 +288,7 @@
if repo.branchtip(branch) == ctx.node():
return branch

-def getrevisionlabel(repo, rev: Optional[int]) -> Optional[Text]:
+def getrevisionlabel(repo, rev: Optional[int]) -> Optional[str]:
"""Return symbolic name for the specified revision or stringfy it"""
if rev is None:
return None # no symbol for working revision
@@ -317,7 +317,7 @@
cur = cur[8:]
return cur

-def gitcommit_full(ctx) -> Optional[Text]:
+def gitcommit_full(ctx) -> Optional[str]:
"""
If the hggit extension is loaded, and the repository is a git clone,
returns the complete git commit hash of the current revision
@@ -334,7 +334,7 @@

return fullgitnode

-def gitcommit_short(ctx) -> Optional[Text]:
+def gitcommit_short(ctx) -> Optional[str]:
"""
If the hggit extension is loaded, and the repository is a git clone,
returns the short (12 digits) git commit hash of the current revision
@@ -343,7 +343,7 @@
fullgitnode = gitcommit_full(ctx)
return None if fullgitnode is None else fullgitnode[:12]

-def getqqueues(repo) -> List[Text]:
+def getqqueues(repo) -> List[str]:
ui = repo.ui.copy()
ui.quiet = True # don't append "(active)"
ui.pushbuffer()
@@ -386,7 +386,7 @@
return operation_in_progress(repo, b"rebasestate")


-def readundodesc(repo) -> Tuple[Text, int]:
+def readundodesc(repo) -> Tuple[str, int]:
"""Read short description and changelog size of last transaction"""
if os.path.exists(repo.sjoin(b'undo')):
try:
@@ -411,17 +411,17 @@
text = b''.join(sum((list(hlines) for _hrange, hlines in hunks), []))
return b'\n'.join(headers) + b'\n' + text

-def enabledextensions() -> Dict[Text, bytes]:
+def enabledextensions() -> Dict[str, bytes]:
"""Return the {name: shortdesc} dict of enabled extensions

shortdesc is in local encoding.
"""
return {pycompat.sysstr(k): v for k, v in extensions.enabled().items()}

-def disabledextensions() -> Dict[Text, bytes]:
+def disabledextensions() -> Dict[str, bytes]:
return {pycompat.sysstr(k): v for k, v in extensions.disabled().items()}

-def allextensions() -> Dict[Text, bytes]:
+def allextensions() -> Dict[str, bytes]:
"""Return the {name: shortdesc} dict of known extensions

shortdesc is in local encoding.
@@ -444,7 +444,7 @@

return exts

-def validateextensions(enabledexts: AbstractSet[Text]) -> Dict[Text, bytes]:
+def validateextensions(enabledexts: AbstractSet[str]) -> Dict[str, bytes]:
"""Report extensions which should be disabled

Returns the dict {name: message} of extensions expected to be disabled.
@@ -520,13 +520,13 @@
return canonpats


-def normpath(path: Text) -> Text:
+def normpath(path: str) -> str:
"""Normalize a path in the same manner as mercurial.util.normpath()."""
# TODO: Do a unicode port of util.normpath() here.
return tounicode(util.normpath(fromunicode(path)))


-def normreporoot(path: Text) -> Text:
+def normreporoot(path: str) -> str:
"""Normalize repo root path in the same manner as localrepository"""
# see localrepo.localrepository and scmutil.vfs
lpath = fromunicode(path)
@@ -619,7 +619,7 @@
)

def tortoisehgtools(uiorconfig: Union[IniConfig, uimod.ui],
- selectedlocation: Optional[Text] = None) -> Tuple[Dict[Text, Dict[Text, Union[Text, bool]]], List[Text]]:
+ selectedlocation: Optional[str] = None) -> Tuple[Dict[str, Dict[str, Union[str, bool]]], List[str]]:
"""Parse 'tortoisehg-tools' section of ini file.

>>> from pprint import pprint
@@ -735,7 +735,7 @@
def configlist(section, name):
return uiorconfig.get(section, name, b'').split()

- tools: Dict[Text, Dict[Text, Union[Text, bool]]] = {}
+ tools: Dict[str, Dict[str, Union[str, bool]]] = {}
for key, value in configitems(b'tortoisehg-tools'):
toolname, field = tounicode(key).split('.', 1)
if toolname not in tools:
@@ -759,8 +759,8 @@

guidef = configlist(b'tortoisehg',
pycompat.sysbytes(selectedlocation)) or []
- toollist: List[Text] = []
- selectedtools: Dict[Text, Dict[Text, Union[Text, bool]]] = {}
+ toollist: List[str] = []
+ selectedtools: Dict[str, Dict[str, Union[str, bool]]] = {}
for name in guidef:
name = tounicode(name)
if name != '|':
@@ -808,7 +808,7 @@
return
return name

-def extractchoices(prompttext: Text) -> Tuple[Text, List[Tuple[Text, Text]]]:
+def extractchoices(prompttext: str) -> Tuple[str, List[Tuple[str, str]]]:
"""Extract prompt message and list of choice (char, label) pairs

This is slightly different from ui.extractchoices() in that
@@ -966,8 +966,8 @@
summary = l and l[0] or ''
return u'%s@%s%s:%s "%s"' % (author, rev, source, date, summary)

-def longsummary(description: Union[bytes, Text],
- limit: Optional[int] = None) -> Text:
+def longsummary(description: Union[bytes, str],
+ limit: Optional[int] = None) -> str:
summary = tounicode(description)
lines = summary.splitlines()
if not lines:
@@ -1031,7 +1031,7 @@
return os.path.join(wsub, wsubsub), wfileinsub, sctx
return None, wfile, ctx

-def getLineSeparator(line: Text) -> Text:
+def getLineSeparator(line: str) -> str:
"""Get the line separator used on a given line"""
# By default assume the default OS line separator
linesep = os.linesep
@@ -1080,7 +1080,7 @@
def _escapecharrepl(m):
return _escapecharmap[ord(m.group(0))]

-def escapeascii(s: Text) -> Text:
+def escapeascii(s: str) -> str:
r"""Escape string to be embedded as a literal; like Python string_escape,
but keeps 8bit characters and can process unicode

@@ -1092,7 +1092,7 @@
s = _stringify(s)
return _escapecharre.sub(_escapecharrepl, s)

-def escapepath(path: Text) -> Text:
+def escapepath(path: str) -> str:
r"""Convert path to command-line-safe string; path must be relative to
the repository root

@@ -1108,7 +1108,7 @@
else:
return p

-def escaperev(rev: int, default: Optional[Text] = None) -> Text:
+def escaperev(rev: int, default: Optional[str] = None) -> str:
"""Convert revision number to command-line-safe string"""
if rev is None:
return default
@@ -1123,7 +1123,7 @@
else:
return '%s:%s' % (escaperev(a), escaperev(b))

-def compactrevs(revs: List[int]) -> Text:
+def compactrevs(revs: List[int]) -> str:
"""Build command-line-safe revspec from list of revision numbers; revs
should be sorted in ascending order to get compact form

@@ -1208,7 +1208,7 @@

return ''.join(ret)

-def formatfilespec(expr: Text, *args) -> Text:
+def formatfilespec(expr: str, *args) -> str:
"""Build fileset expression by template and positional arguments

Supported arguments:
@@ -1224,7 +1224,7 @@
listfuncs = {}
return _formatspec(expr, args, filesetlang.parse, listfuncs)

-def formatrevspec(expr: Text, *args) -> Text:
+def formatrevspec(expr: str, *args) -> str:
r"""Build revset expression by template and positional arguments

Supported arguments:
@@ -1250,7 +1250,7 @@
listfuncs = {'d': '_intlist', 's': '_list'}
return _formatspec(expr, args, revsetlang.parse, listfuncs)

-def buildcmdargs(name: Text, *args, **opts) -> List[Text]:
+def buildcmdargs(name: str, *args, **opts) -> List[str]:
r"""Build list of command-line arguments

>>> buildcmdargs('push', branch='foo')
@@ -1342,7 +1342,7 @@
else:
return arg

-def prettifycmdline(cmdline: List[Text]) -> Text:
+def prettifycmdline(cmdline: List[str]) -> str:
r"""Build pretty command-line string for display

>>> prettifycmdline(['log', 'foo\\bar', '', 'foo bar', 'foo"bar'])
@@ -1359,7 +1359,7 @@
"""
return ' '.join(_reprcmdarg(e) for e in cmdline)

-def parsecmdline(cmdline: Text, cwd: Text) -> List[Text]:
+def parsecmdline(cmdline: str, cwd: str) -> List[str]:
r"""Split command line string to imitate a unix shell

>>> origfuncs = glob.glob, os.path.expanduser, os.path.expandvars
diff --git a/tortoisehg/util/menuthg.py b/tortoisehg/util/menuthg.py
--- a/tortoisehg/util/menuthg.py
+++ b/tortoisehg/util/menuthg.py
@@ -30,7 +30,7 @@
MenuT = List[Union["TortoiseMenu", "TortoiseMenuSep"]]


-def _(msgid: Text) -> Dict[Text, Text]:
+def _(msgid: str) -> Dict[str, str]:
return {'id': msgid, 'str': gettext(msgid)}

thgcmenu = {
@@ -115,10 +115,10 @@
class TortoiseMenu:

def __init__(self,
- menutext: Text,
- helptext: Text,
- hgcmd: Optional[Text],
- icon: Optional[Text] = None,
+ menutext: str,
+ helptext: str,
+ hgcmd: Optional[str],
+ icon: Optional[str] = None,
state: bool = True) -> None:
self.menutext = menutext
self.helptext = helptext
@@ -136,20 +136,20 @@
class TortoiseSubmenu(TortoiseMenu):

def __init__(self,
- menutext: Text,
- helptext: Text,
+ menutext: str,
+ helptext: str,
menus: Optional[MenuT] = None,
- icon: Optional[Text] = None) -> None:
+ icon: Optional[str] = None) -> None:
TortoiseMenu.__init__(self, menutext, helptext, None, icon)
if menus is None:
menus: MenuT = []
self.menus = menus[:]

def add_menu(self,
- menutext: Text,
- helptext: Text,
- hgcmd: Optional[Text],
- icon: Optional[Text] = None,
+ menutext: str,
+ helptext: str,
+ hgcmd: Optional[str],
+ icon: Optional[str] = None,
state: bool = True) -> None:
self.menus.append(TortoiseMenu(menutext, helptext,
hgcmd, icon, state))
@@ -184,8 +184,8 @@

def __init__(self,
ui: uimod.ui,
- promoted: List[Text],
- name: Text = "TortoiseHg") -> None:
+ promoted: List[str],
+ name: str = "TortoiseHg") -> None:
self.menus = [[]]
self.ui = ui
self.name = name
@@ -193,8 +193,8 @@
self.promoted = promoted

def add_menu(self,
- hgcmd: Text,
- icon: Optional[Text] = None,
+ hgcmd: str,
+ icon: Optional[str] = None,
state: bool = True) -> None:
if hgcmd in self.promoted:
pos = 0
@@ -226,7 +226,7 @@
return iter(self.get())


-def open_repo(path: Text) -> Optional[localrepo.localrepository]:
+def open_repo(path: str) -> Optional[localrepo.localrepository]:
root = paths.find_root(path)
if root:
try:
@@ -263,8 +263,8 @@


def get_commands_dragdrop(self,
- srcfiles: List[Text],
- destfolder: Text) -> Union[List[Text], thg_menu]:
+ srcfiles: List[str],
+ destfolder: str) -> Union[List[str], thg_menu]:
"""
Get a list of commands valid for the current selection.

@@ -295,7 +295,7 @@
menu.add_menu('dndsynch')
return menu

- def get_norepo_commands(self, cwd: Text, files: List[Text]) -> thg_menu:
+ def get_norepo_commands(self, cwd: str, files: List[str]) -> thg_menu:
menu = thg_menu(hglib.loadui(), self.promoted, self.name)
menu.add_menu('clone')
menu.add_menu('init')
@@ -307,8 +307,8 @@

def get_commands(self,
repo: localrepo.localrepository,
- cwd: Text,
- files: List[Text]) -> thg_menu:
+ cwd: str,
+ files: List[str]) -> thg_menu:
"""
Get a list of commands valid for the current selection.

diff --git a/tortoisehg/util/paths.py b/tortoisehg/util/paths.py
--- a/tortoisehg/util/paths.py
+++ b/tortoisehg/util/paths.py
@@ -40,7 +40,7 @@
)

@overload
- def _find_root(p: Text, dn: Text) -> Optional[Text]:
+ def _find_root(p: str, dn: str) -> Optional[str]:
pass
@overload
def _find_root(p: bytes, dn: bytes) -> Optional[bytes]:
@@ -57,13 +57,13 @@
return None
return p

-def find_root(path: Optional[Text] = None) -> Optional[Text]:
+def find_root(path: Optional[str] = None) -> Optional[str]:
return _find_root(path or os.getcwd(), '.hg')

def find_root_bytes(path: Optional[bytes] = None) -> Optional[bytes]:
return _find_root(path or encoding.getcwd(), b'.hg')

-def get_tortoise_icon(icon: Text) -> Optional[Text]:
+def get_tortoise_icon(icon: str) -> Optional[str]:
"Find a tortoisehg icon"
icopath = os.path.join(get_icon_path(), icon)
if os.path.isfile(icopath):
@@ -72,22 +72,22 @@
print('icon not found', icon)
return None

-def get_icon_path() -> Text:
+def get_icon_path() -> str:
global icon_path
return icon_path or os.path.join(get_prog_root(), 'icons')

-def get_license_path() -> Text:
+def get_license_path() -> str:
global license_path
return license_path or os.path.join(get_prog_root(), 'COPYING.txt')

-def get_locale_path() -> Text:
+def get_locale_path() -> str:
global locale_path
return locale_path or os.path.join(get_prog_root(), 'locale')

-def _get_hg_path() -> Text:
+def _get_hg_path() -> str:
return os.path.abspath(os.path.join(mercurial.__file__, '..', '..'))

-def get_hg_command() -> List[Text]:
+def get_hg_command() -> List[str]:
"""List of command to execute hg (equivalent to mercurial.util.hgcmd)"""
global _hg_command
if _hg_command is None:
@@ -104,7 +104,7 @@
if os.name == 'nt':
import win32file # pytype: disable=import-error

- def find_in_path(pgmname: Text) -> Optional[Text]:
+ def find_in_path(pgmname: str) -> Optional[str]:
"return first executable found in search path"
global bin_path
ospath = os.environ['PATH'].split(os.pathsep)
@@ -118,7 +118,7 @@
return ppath + ext
return None

- def _find_hg_command() -> List[Text]:
+ def _find_hg_command() -> List[str]:
if hasattr(sys, 'frozen'):
progdir = get_prog_root()
exe = os.path.join(progdir, 'hg.exe')
@@ -143,12 +143,12 @@
return [python, exe[:-4]]
return [exe]

- def get_prog_root() -> Text:
+ def get_prog_root() -> str:
if getattr(sys, 'frozen', False):
return os.path.dirname(sys.executable)
return os.path.dirname(os.path.dirname(os.path.dirname(__file__)))

- def get_thg_command() -> List[Text]:
+ def get_thg_command() -> List[str]:
if getattr(sys, 'frozen', False):
return [sys.executable]
return [sys.executable] + sys.argv[:1]
@@ -170,7 +170,7 @@

else: # Not Windows

- def find_in_path(pgmname: Text) -> Optional[Text]:
+ def find_in_path(pgmname: str) -> Optional[str]:
""" return first executable found in search path """
global bin_path
ospath = os.environ['PATH'].split(os.pathsep)
@@ -181,7 +181,7 @@
return ppath
return None

- def _find_hg_command() -> List[Text]:
+ def _find_hg_command() -> List[str]:
# look for in-place build, i.e. "make local"
exe = os.path.join(_get_hg_path(), 'hg')
if os.path.exists(exe):
@@ -192,11 +192,11 @@
return ['hg']
return [exe]

- def get_prog_root() -> Text:
+ def get_prog_root() -> str:
path = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
return path

- def get_thg_command() -> List[Text]:
+ def get_thg_command() -> List[str]:
return sys.argv[:1]

def is_unc_path(path: bytes) -> bool:
diff --git a/tortoisehg/util/version.py b/tortoisehg/util/version.py
--- a/tortoisehg/util/version.py
+++ b/tortoisehg/util/version.py
@@ -27,7 +27,7 @@


@util.cachefunc
-def liveversion() -> Tuple[Text, Text]:
+def liveversion() -> Tuple[str, str]:
'Attempt to read the version from the live repository'
utilpath = os.path.dirname(os.path.realpath(__file__))
thgpath = os.path.dirname(os.path.dirname(utilpath))
@@ -64,7 +64,7 @@
version = pycompat.sysstr(u.popbuffer()).rpartition(':')[2] + l[0]
return pycompat.sysstr(repo[None].branch()), version

-def version() -> Text:
+def version() -> str:
try:
branch, version = liveversion()
return version
@@ -79,7 +79,7 @@
def version_bytes() -> bytes:
return encoding.strtolocal(version())

-def package_version() -> Text:
+def package_version() -> str:
try:
branch, version = liveversion()
return _build_package_version(branch, version)
@@ -91,7 +91,7 @@
except ImportError:
return 'unknown'

-def _build_package_version(branch: Text, version: Text) -> Text:
+def _build_package_version(branch: str, version: str) -> str:
"""
>>> _build_package_version('default', '4.8+10')
'4.8.5010'

Matt Harbison

unread,
Feb 28, 2025, 5:15:03 PMFeb 28
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1740675598 18000
# Thu Feb 27 11:59:58 2025 -0500
# Branch stable
# Node ID a1e52bfadae280d6c4e3f57959364e466720966e
# Parent 8e77415b51c469213c150842146176002ffb00c7
# EXP-Topic pyupgrade
pyupgrade: replace `dict(...)` with dict comprehensions

This was rewritten by the `dict_literals` fixer in `pyupgrade`. See
hg d903647abbd3.

diff --git a/tests/graph_test.py b/tests/graph_test.py
--- a/tests/graph_test.py
+++ b/tests/graph_test.py
@@ -39,8 +39,8 @@
if not node:
continue
# draw overlapped lines in the same way as HgRepoListModel
- lt = dict((p, predicate(p, e)) for p, e
- in sorted(node.bottomlines, key=lambda pe: pe[1].importance))
+ lt = {p: predicate(p, e) for p, e
+ in sorted(node.bottomlines, key=lambda pe: pe[1].importance)}
# and sort them in (start, end) order
lines = [l for p, l in sorted(lt.items(), key=lambda pl: pl[0])]
table[node.rev] = lines
@@ -1014,7 +1014,7 @@
""")

def buildpathtable(grapher):
- return dict((n.rev, n.extra[0]) for n in grapher)
+ return {n.rev: n.extra[0] for n in grapher}

def test_filelog_movedpath():
repo = openrepo(b'movedfile')
diff --git a/tortoisehg/hgqt/customtools.py b/tortoisehg/hgqt/customtools.py
--- a/tortoisehg/hgqt/customtools.py
+++ b/tortoisehg/hgqt/customtools.py
@@ -911,7 +911,7 @@
return toolname, toolconfig

def _enable2label(self, value: str) -> Optional[str]:
- return dict((v, l) for l, v in self._enablemappings).get(value)
+ return {v: l for l, v in self._enablemappings}.get(value)

def validateForm(self) -> str:
name, config = self.value()
diff --git a/tortoisehg/hgqt/fileview.py b/tortoisehg/hgqt/fileview.py
--- a/tortoisehg/hgqt/fileview.py
+++ b/tortoisehg/hgqt/fileview.py
@@ -1083,8 +1083,8 @@
annfunc = [annfields[n] for n in aformat]

uniqfctxs = set(fctx for fctx, _origline in self._links)
- return dict((fctx.rev(), ' : '.join(f(fctx) for f in annfunc))
- for fctx in uniqfctxs)
+ return {fctx.rev(): ' : '.join(f(fctx) for f in annfunc)
+ for fctx in uniqfctxs}

def _emitRevisionHintAtLine(self, line):
if line < 0 or line >= len(self._links):
diff --git a/tortoisehg/hgqt/graft.py b/tortoisehg/hgqt/graft.py
--- a/tortoisehg/hgqt/graft.py
+++ b/tortoisehg/hgqt/graft.py
@@ -213,7 +213,7 @@
def graft(self) -> None:
self.graftbtn.setEnabled(False)
self.cancelbtn.setVisible(False)
- opts = dict((n, w.isChecked()) for n, w in self._optchks.items())
+ opts = {n: w.isChecked() for n, w in self._optchks.items()}
itool = 'merge' if opts.pop('autoresolve') else 'fail'
opts['config'] = 'ui.merge=internal:%s' % itool
if hglib.graft_in_progress(self.repo):
diff --git a/tortoisehg/hgqt/graphopt.py b/tortoisehg/hgqt/graphopt.py
--- a/tortoisehg/hgqt/graphopt.py
+++ b/tortoisehg/hgqt/graphopt.py
@@ -339,7 +339,7 @@
"""

clog = self._repo.changelog
- parentrevs = dict([(r, clog.parentrevs(r)) for r in clog])
+ parentrevs = {r: clog.parentrevs(r) for r in clog}
parentrevs[None] = self._workingdir_parents()
actedge = collections.defaultdict(list)
revs = []
diff --git a/tortoisehg/hgqt/mq.py b/tortoisehg/hgqt/mq.py
--- a/tortoisehg/hgqt/mq.py
+++ b/tortoisehg/hgqt/mq.py
@@ -74,7 +74,7 @@
def _checkForRejects(repo, rawoutput, parent=None):
"""Parse output of qpush/qpop to resolve hunk failure manually"""
rejre = re.compile(r'saving rejects to file (.*)\.rej')
- rejfiles = dict((m.group(1), False) for m in rejre.finditer(rawoutput))
+ rejfiles = {m.group(1): False for m in rejre.finditer(rawoutput)}
for ufile in sorted(rejfiles):
wfile = hglib.fromunicode(ufile)
if not os.path.exists(repo.wjoin(wfile)):
diff --git a/tortoisehg/hgqt/repowidget.py b/tortoisehg/hgqt/repowidget.py
--- a/tortoisehg/hgqt/repowidget.py
+++ b/tortoisehg/hgqt/repowidget.py
@@ -354,8 +354,8 @@
self.taskTabsWidget.setCurrentIndex(self._namedTabs.get(name, 0))

def currentTaskTabName(self):
- indexmap = dict((idx, name)
- for name, idx in self._namedTabs.items())
+ indexmap = {idx: name
+ for name, idx in self._namedTabs.items()}
return indexmap.get(self.taskTabsWidget.currentIndex())

@pyqtSlot(str)
@@ -919,7 +919,7 @@
"""Open grep task tab"""
if opts is None:
opts = {}
- opts = dict((str(k), str(v)) for k, v in opts.items())
+ opts = {str(k): str(v) for k, v in opts.items()}
self.taskTabsWidget.setCurrentIndex(self._namedTabs['grep'])
self.grepDemand.setSearch(pattern, **opts)
self.grepDemand.runSearch()
diff --git a/tortoisehg/hgqt/status.py b/tortoisehg/hgqt/status.py
--- a/tortoisehg/hgqt/status.py
+++ b/tortoisehg/hgqt/status.py
@@ -332,7 +332,7 @@
if wfile in self.partials:
# merge selection state from old hunk list to new hunk list
oldhunks = self.partials[wfile].hunks
- oldstates = dict([(c.fromline, c.excluded) for c in oldhunks])
+ oldstates = {c.fromline: c.excluded for c in oldhunks}
for chunk in changes.hunks:
if chunk.fromline in oldstates:
fd.setChunkExcluded(chunk, oldstates[chunk.fromline])
@@ -730,8 +730,8 @@
continue
val = statusTypes[stat]
if self.opts[val.name]:
- d = dict([(fn, precheckfn(i))
- for fn in getattr(status, val.name)])
+ d = {fn: precheckfn(i)
+ for fn in getattr(status, val.name)}
patchecked.update(d)
wctx = context.workingctx(self.repo, changes=status)
self.patchecked = patchecked
diff --git a/tortoisehg/util/hgcommands.py b/tortoisehg/util/hgcommands.py
--- a/tortoisehg/util/hgcommands.py
+++ b/tortoisehg/util/hgcommands.py
@@ -103,8 +103,8 @@
open(os.path.join(dest, b'.hgignore'), 'a').close()

def _applymovemqpatches(q, after, patches):
- fullindexes = dict((q.guard_re.split(rpn, 1)[0], i)
- for i, rpn in enumerate(q.fullseries))
+ fullindexes = {q.guard_re.split(rpn, 1)[0]: i
+ for i, rpn in enumerate(q.fullseries)}
fullmap = {} # patch: line in series file
for i, n in sorted([(fullindexes[n], n) for n in patches], reverse=True):
fullmap[n] = q.fullseries.pop(i)

Matt Harbison

unread,
Feb 28, 2025, 5:15:07 PMFeb 28
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1740675747 18000
# Thu Feb 27 12:02:27 2025 -0500
# Branch stable
# Node ID 4de430479a76598cc65db9646443ecaf95342ae0
# Parent a1e52bfadae280d6c4e3f57959364e466720966e
# EXP-Topic pyupgrade
pyupgrade: use set literals where possible

This was rewritten by the `set_literals` fixer in `pyupgrade`. See hg
f066fc0bdc7a.

diff --git a/contrib/thgdebugtools/widgets.py b/contrib/thgdebugtools/widgets.py
--- a/contrib/thgdebugtools/widgets.py
+++ b/contrib/thgdebugtools/widgets.py
@@ -48,9 +48,9 @@
def zombieWidgets():
"""List of possibly-deleted widgets but referenced from Python"""
# weakref.proxy isn't hashable and shouldn't be counted as referenced
- referenced = set(w for w in gc.get_objects()
+ referenced = {w for w in gc.get_objects()
if (isinstance(w, QWidget)
- and not isinstance(w, weakref.ProxyTypes)))
+ and not isinstance(w, weakref.ProxyTypes))}
return referenced - set(QApplication.allWidgets())

class WidgetsMenuActions(dbgutil.BaseMenuActions):
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -557,8 +557,8 @@
if 'py2exe' in sys.argv:
import hgext
hgextdir = os.path.dirname(hgext.__file__)
- hgextmods = set(["hgext." + os.path.splitext(f)[0]
- for f in os.listdir(hgextdir)])
+ hgextmods = {"hgext." + os.path.splitext(f)[0]
+ for f in os.listdir(hgextdir)}
# most icons are packed into Qt resource, but .ico files must reside
# in filesystem so that shell extension can read them
root = 'icons'
diff --git a/tests/helpers.py b/tests/helpers.py
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -406,7 +406,7 @@

next_revs[i] = parents

- if (set(i for (i, c) in enumerate(prevline) if c in r'|\/')
+ if ({i for (i, c) in enumerate(prevline) if c in r'|\/'}
- visitededges):
raise InvalidGraphLine('isolated edge')

diff --git a/tortoisehg/hgqt/clone.py b/tortoisehg/hgqt/clone.py
--- a/tortoisehg/hgqt/clone.py
+++ b/tortoisehg/hgqt/clone.py
@@ -65,7 +65,7 @@

def _startrev_available() -> bool:
entry = cmdutil.findcmd(b'clone', commands.table)[1]
- longopts = set(e[1] for e in entry[1])
+ longopts = {e[1] for e in entry[1]}
return b'startrev' in longopts

def _suggesteddest(src: str, basedest: str) -> str:
diff --git a/tortoisehg/hgqt/fileview.py b/tortoisehg/hgqt/fileview.py
--- a/tortoisehg/hgqt/fileview.py
+++ b/tortoisehg/hgqt/fileview.py
@@ -1082,7 +1082,7 @@
}
annfunc = [annfields[n] for n in aformat]

- uniqfctxs = set(fctx for fctx, _origline in self._links)
+ uniqfctxs = {fctx for fctx, _origline in self._links}
return {fctx.rev(): ' : '.join(f(fctx) for f in annfunc)
for fctx in uniqfctxs}

diff --git a/tortoisehg/hgqt/graph.py b/tortoisehg/hgqt/graph.py
--- a/tortoisehg/hgqt/graph.py
+++ b/tortoisehg/hgqt/graph.py
@@ -758,8 +758,8 @@
# We filter out parents of added node.
# A parent could already be in flogheads if still a
# head on the server, but not anymore in local repository
- flogheads -= set([node.hex(pfctx.filenode())
- for pfctx in fctx.parents()])
+ flogheads -= {node.hex(pfctx.filenode())
+ for pfctx in fctx.parents()}
except error.ManifestLookupError:
pass

diff --git a/tortoisehg/hgqt/graphopt.py b/tortoisehg/hgqt/graphopt.py
--- a/tortoisehg/hgqt/graphopt.py
+++ b/tortoisehg/hgqt/graphopt.py
@@ -148,7 +148,7 @@
self._revset_set = self._revset_set & frozenset(revs)
else:
self._revset_set = frozenset(revs)
- prevs = set([pctx.rev() for pctx in self._repo[None].parents()])
+ prevs = {pctx.rev() for pctx in self._repo[None].parents()}
if prevs & self._revset_set:
add_none = True

@@ -246,7 +246,7 @@

remove = set()
for candidate in candidates:
- remove |= set([c for c, _ in family[candidate]])
+ remove |= {c for c, _ in family[candidate]}

return sorted(rv + list(set(candidates) - remove), reverse=True)

diff --git a/tortoisehg/hgqt/grep.py b/tortoisehg/hgqt/grep.py
--- a/tortoisehg/hgqt/grep.py
+++ b/tortoisehg/hgqt/grep.py
@@ -742,7 +742,7 @@
while rows:
defer = []
crev = rows[0][0]
- files = set([rows[0][1]])
+ files = {rows[0][1]}
for rev, path, line in rows[1:]:
if rev == crev:
files.add(path)
diff --git a/tortoisehg/hgqt/qtapp.py b/tortoisehg/hgqt/qtapp.py
--- a/tortoisehg/hgqt/qtapp.py
+++ b/tortoisehg/hgqt/qtapp.py
@@ -203,7 +203,7 @@
for args in self.errors)}
etype, evalue = self.errors[0][:2]
parent = self._mainapp.activeWindow()
- if (len(set(e[0] for e in self.errors)) == 1
+ if (len({e[0] for e in self.errors}) == 1
and etype in _recoverableexc):
opts['values'] = [hglib.exception_str(evalue)]
errstr = _recoverableexc[etype]
diff --git a/tortoisehg/hgqt/repofilter.py b/tortoisehg/hgqt/repofilter.py
--- a/tortoisehg/hgqt/repofilter.py
+++ b/tortoisehg/hgqt/repofilter.py
@@ -471,9 +471,9 @@
curbranch = self.branch()

if self._abranchAction.isChecked():
- branches = sorted(set([self._repo[n].branch()
+ branches = sorted({self._repo[n].branch()
for n in self._repo.heads()
- if not self._repo[n].extra().get(b'close')]))
+ if not self._repo[n].extra().get(b'close')})
elif self._cbranchAction.isChecked():
branches: List[bytes] = sorted(self._repo.branchmap())
else:
diff --git a/tortoisehg/hgqt/settings.py b/tortoisehg/hgqt/settings.py
--- a/tortoisehg/hgqt/settings.py
+++ b/tortoisehg/hgqt/settings.py
@@ -1860,9 +1860,9 @@
@pyqtSlot()
def validateextensions(self):
enabledexts = hglib.enabledextensions()
- selectedexts = set(chk.opts['label']
+ selectedexts = {chk.opts['label']
for chk in self.pages['extensions'][2]
- if chk.isChecked())
+ if chk.isChecked()}
invalidexts = hglib.validateextensions(selectedexts)

def getinival(cpath):
diff --git a/tortoisehg/hgqt/thgrepo.py b/tortoisehg/hgqt/thgrepo.py
--- a/tortoisehg/hgqt/thgrepo.py
+++ b/tortoisehg/hgqt/thgrepo.py
@@ -856,7 +856,7 @@
if not hasattr(self, 'mq'): return []

q = self.mq
- applied = set([p.name for p in q.applied])
+ applied = {p.name for p in q.applied}

return [pname for pname in q.series if pname not in applied]

diff --git a/tortoisehg/util/obsoleteutil.py b/tortoisehg/util/obsoleteutil.py
--- a/tortoisehg/util/obsoleteutil.py
+++ b/tortoisehg/util/obsoleteutil.py
@@ -31,7 +31,7 @@

start = clog.node(rev)
markers = predecessorsmarkers(obsstore, start)
- candidates = set(mark[0] for mark in markers)
+ candidates = {mark[0] for mark in markers}
seen = set(candidates)
if start in candidates:
candidates.remove(start)

Matt Harbison

unread,
Feb 28, 2025, 5:15:14 PMFeb 28
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1740681984 18000
# Thu Feb 27 13:46:24 2025 -0500
# Branch stable
# Node ID 88e4996a2772af18030b0a1b1079afeaa5c9dc40
# Parent 4de430479a76598cc65db9646443ecaf95342ae0
# EXP-Topic pyupgrade
pyupgrade: drop redundant `open()` modes

I think this is silly, and I'd rather be explicit. But there's no way to turn
off this transform from the command line, and accepting these changes means less
noise when running this in the future. See hg 3e84e001b6c1.

diff --git a/i18n/msgfmt.py b/i18n/msgfmt.py
--- a/i18n/msgfmt.py
+++ b/i18n/msgfmt.py
@@ -64,7 +64,7 @@
output = []
if isinstance(self.po, str):
# self.read() expects an iterable of "str" lines
- output = open(self.po, 'r', encoding='utf-8')
+ output = open(self.po, encoding='utf-8')
elif isinstance(self.po, file):
self.po.seek(0)
self.openfile = True
diff --git a/tortoisehg/hgqt/about.py b/tortoisehg/hgqt/about.py
--- a/tortoisehg/hgqt/about.py
+++ b/tortoisehg/hgqt/about.py
@@ -192,7 +192,7 @@
self.lic_txt.setTextInteractionFlags(
Qt.TextInteractionFlag.TextSelectableByKeyboard|Qt.TextInteractionFlag.TextSelectableByMouse)
try:
- with open(paths.get_license_path(), 'r') as fp:
+ with open(paths.get_license_path()) as fp:
lic = fp.read()
self.lic_txt.setPlainText(lic)
except OSError:

Matt Harbison

unread,
Feb 28, 2025, 5:15:23 PMFeb 28
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1740682148 18000
# Thu Feb 27 13:49:08 2025 -0500
# Branch stable
# Node ID 2e8bfded4d9854491344412380c16815f6231d4d
# Parent 88e4996a2772af18030b0a1b1079afeaa5c9dc40
# EXP-Topic pyupgrade
pyupgrade: convert `str.format()` to f-strings

This is the `fstrings` fixer in `pyupgrade`. See hg 5027ae0d89b3.

diff --git a/contrib/packaging/thgpackaging/util.py b/contrib/packaging/thgpackaging/util.py
--- a/contrib/packaging/thgpackaging/util.py
+++ b/contrib/packaging/thgpackaging/util.py
@@ -133,7 +133,7 @@

def __repr__(self):
return 'environ({{{}}})'.format(', '.join(
- ('{!r}: {!r}'.format(self.decodekey(key), self.decodevalue(value))
+ (f'{self.decodekey(key)!r}: {self.decodevalue(value)!r}'
for key, value in self._data.items())))

def copy(self):

Matt Harbison

unread,
Feb 28, 2025, 5:15:24 PMFeb 28
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1740716658 18000
# Thu Feb 27 23:24:18 2025 -0500
# Branch stable
# Node ID b72c249428a559a645df775da78446caaf07896b
# Parent 2e8bfded4d9854491344412380c16815f6231d4d
# EXP-Topic pyupgrade
pyupgrade: drop `coding=UTF-8` comments

PEP-3120[1] (Python 3.0 in 2007) says that UTF-8 is the default encoding. That
should be long enough ago that no reasonable editor would trip over this, and
certainly any supported version of Python won't. `msgfmt.py` was already UTF-8
formatted. See hg f19a3f1437f3.

The comments were probably harmless, but as `pyupgrade` has no mechanism to
disable this change, omitting this change makes it unusable as a code checking
tool, and makes it a pain to use occasionally to upgrade the source (since these
changes would need to be manually reverted).

[1] https://peps.python.org/pep-3120/

diff --git a/doc/source-cs/conf.py b/doc/source-cs/conf.py
--- a/doc/source-cs/conf.py
+++ b/doc/source-cs/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# TortoiseHg documentation build configuration file, created by
# sphinx-quickstart on Tue Jul 21 23:42:44 2009.
diff --git a/doc/source-ja/conf.py b/doc/source-ja/conf.py
--- a/doc/source-ja/conf.py
+++ b/doc/source-ja/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# TortoiseHg documentation build configuration file, created by
# sphinx-quickstart on Tue Jul 21 23:42:44 2009.
diff --git a/doc/source/conf.py b/doc/source/conf.py
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
#
# TortoiseHg documentation build configuration file, created by
# sphinx-quickstart on Tue Jul 21 23:42:44 2009.
diff --git a/i18n/msgfmt.py b/i18n/msgfmt.py
--- a/i18n/msgfmt.py
+++ b/i18n/msgfmt.py
@@ -1,5 +1,4 @@
#! /usr/bin/env python
-# -*- coding: iso-8859-1 -*-
# Written by Martin v. Loewis <loe...@informatik.hu-berlin.de>
#
# Changed by Christian 'Tiran' Heimes <ti...@cheimes.de> for the placeless

Matt Harbison

unread,
Feb 28, 2025, 5:15:30 PMFeb 28
to thg...@googlegroups.com
# HG changeset patch
# User Matt Harbison <matt_h...@yahoo.com>
# Date 1740716719 18000
# Thu Feb 27 23:25:19 2025 -0500
# Branch stable
# Node ID d7192ec3ab242ac5ae485189d1634916c3dbf3b3
# Parent b72c249428a559a645df775da78446caaf07896b
# EXP-Topic pyupgrade
py3: drop redundant `u''` prefixes on string literals

Strings are unicode on Python 3. These were rewritten by `pyupgrade`. See hg
9db77d46de79.

diff --git a/TortoiseHgOverlayServer.py b/TortoiseHgOverlayServer.py
--- a/TortoiseHgOverlayServer.py
+++ b/TortoiseHgOverlayServer.py

@@ -424,9 +424,9 @@
plist = [i.strip() for i in promoted.split(',')]

with CreateKey(HKEY_CURRENT_USER, r'Software\TortoiseHg') as hkey2:
- if u'log' in plist:
- idx = plist.index(u'log')
- plist[idx] = u'workbench'
+ if 'log' in plist:
+ idx = plist.index('log')
+ plist[idx] = 'workbench'
SetValueEx(hkey2, 'PromotedItems', 0, REG_SZ, ','.join(plist))
SetValueEx(hkey2, 'ContextMenuVersion', 0, REG_SZ, '2')
except OSError:


diff --git a/doc/source-cs/conf.py b/doc/source-cs/conf.py
--- a/doc/source-cs/conf.py
+++ b/doc/source-cs/conf.py

@@ -42,8 +42,8 @@
master_doc = 'index'

# General information about the project.
-project = u'TortoiseHg'
-copyright = u'2010-2025, Steve Borho and others'
+project = 'TortoiseHg'
+copyright = '2010-2025, Steve Borho and others'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the


diff --git a/doc/source-ja/conf.py b/doc/source-ja/conf.py
--- a/doc/source-ja/conf.py
+++ b/doc/source-ja/conf.py

@@ -42,8 +42,8 @@
master_doc = 'index'

# General information about the project.
-project = u'TortoiseHg'
-copyright = u'2010-2025, Steve Borho、他'
+project = 'TortoiseHg'
+copyright = '2010-2025, Steve Borho、他'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the


diff --git a/doc/source/conf.py b/doc/source/conf.py
--- a/doc/source/conf.py
+++ b/doc/source/conf.py

@@ -42,8 +42,8 @@
master_doc = 'index'

# General information about the project.
-project = u'TortoiseHg'
-copyright = u'2010-2025, Steve Borho and others'
+project = 'TortoiseHg'
+copyright = '2010-2025, Steve Borho and others'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -169,8 +169,8 @@
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, document class [howto/manual]).
latex_documents = [
- ('index', 'TortoiseHg.tex', u'TortoiseHg Documentation',
- u'Steve Borho and others', 'manual'),
+ ('index', 'TortoiseHg.tex', 'TortoiseHg Documentation',
+ 'Steve Borho and others', 'manual'),
]

# The name of an image file (relative to this directory) to place at the top of
diff --git a/tests/hglib_encoding_test.py b/tests/hglib_encoding_test.py
--- a/tests/hglib_encoding_test.py
+++ b/tests/hglib_encoding_test.py
@@ -6,7 +6,7 @@

import helpers

-JAPANESE_KANA_I = u'\u30a4' # Japanese katakana "i"
+JAPANESE_KANA_I = '\u30a4' # Japanese katakana "i"

@pytest.mark.skipif(helpers.QTextCodec is None, reason="Qt6 not supported")
@helpers.with_encoding('utf-8')
@@ -85,7 +85,7 @@
@helpers.with_encoding('gbk')
def test_gbk_roundtrip():
# gbk byte sequence can also be interpreted as utf-8 (issue #3299)
- MOKU = u'\u76ee'
+ MOKU = '\u76ee'
l = bytes(hglib.fromunicode(MOKU))
assert hglib.tounicode(l) == MOKU

@@ -100,7 +100,7 @@
@pytest.mark.skipif(helpers.QTextCodec is None, reason="Qt6 not supported")
@helpers.with_encoding('euc-jp')
def test_lossless_unicode_double_mapped():
- YEN = u'\u00a5' # "yen" and "back-slash" are mapped to the same code
+ YEN = '\u00a5' # "yen" and "back-slash" are mapped to the same code
l = hglib.fromunicode(YEN)
assert l == b'\\'
assert hglib.tounicode(l) == YEN


diff --git a/tests/qt_cmdagent_test.py b/tests/qt_cmdagent_test.py
--- a/tests/qt_cmdagent_test.py
+++ b/tests/qt_cmdagent_test.py

@@ -334,7 +334,7 @@
self.assertTrue(worker.serviceState() in failstates)

def test_unicode_error_in_runcommand(self):
- sess = self.agent.runCommand(['files', '-X', u'\u3000'])
+ sess = self.agent.runCommand(['files', '-X', '\u3000'])
CmdWaiter(sess).wait()
self.assertEqual(-1, sess.exitCode())
self.assertTrue('failed to encode command' in sess.errorString())
diff --git a/tests/qt_manifestmodel_test.py b/tests/qt_manifestmodel_test.py
--- a/tests/qt_manifestmodel_test.py
+++ b/tests/qt_manifestmodel_test.py
@@ -677,7 +677,7 @@
self.assertEqual('C', m.fileStatus(m.indexFromPath('baz/large')))


-_aloha_ja = u'\u3042\u308d\u306f\u30fc'
+_aloha_ja = '\u3042\u308d\u306f\u30fc'

class ManifestModelEucjpTest(unittest.TestCase):
@classmethod
diff --git a/tests/widget/sync_save_dialog_test.py b/tests/widget/sync_save_dialog_test.py
--- a/tests/widget/sync_save_dialog_test.py
+++ b/tests/widget/sync_save_dialog_test.py
@@ -16,9 +16,9 @@
self.repo = None # use mock instead?

def test_clearcb_save(self):
- origurl = u'http://foo:b...@example.org/baz'
- safeurl = u'http://foo:***@example.org/baz'
- cleanurl = u'http://example.org/baz'
+ origurl = 'http://foo:b...@example.org/baz'
+ safeurl = 'http://foo:***@example.org/baz'
+ cleanurl = 'http://example.org/baz'
dlg = sync.SaveDialog(self.repo, b'default', origurl, parent=None,
edit=False)
self.assertTrue(dlg.clearcb.isChecked())
@@ -30,14 +30,14 @@
self.assertEqual(origurl, dlg.urlentry.text())

def test_clearcb_not_exist_on_save_noauth(self):
- url = u'http://example.org/'
+ url = 'http://example.org/'
dlg = sync.SaveDialog(self.repo, b'default', url, parent=None,
edit=False)
self.assertFalse(dlg.clearcb.isVisibleTo(dlg))
self.assertEqual(url, dlg.urllabel.text())

def test_clearcb_not_exist_on_edit(self):
- url = u'http://foo:b...@example.org/'
+ url = 'http://foo:b...@example.org/'
dlg = sync.SaveDialog(self.repo, b'default', url, parent=None,
edit=True)
self.assertFalse(dlg.clearcb.isVisibleTo(dlg))
@@ -51,7 +51,7 @@
self.hg.init()

def test_save_new(self):
- url = u'http://example.org/'
+ url = 'http://example.org/'
repoagent = thgrepo.repository(path=self.hg.path)._pyqtobj
dlg = sync.SaveDialog(repoagent, b'default', url, parent=None,
edit=False)
@@ -61,7 +61,7 @@

@mock.patch('tortoisehg.hgqt.qtlib.QuestionMsgBox', return_value=True)
def test_save_unchanged(self, mock_msgbox):
- url = u'http://example.org/'
+ url = 'http://example.org/'
self.hg.fwrite(b'.hg/hgrc',
b'[paths]\ndefault = %s\n' % url.encode('ascii'))
repoagent = thgrepo.repository(path=self.hg.path)._pyqtobj
@@ -72,7 +72,7 @@
self.hg.fread(b'.hg/hgrc').splitlines()[-2:])

def test_save_new_alias(self):
- url = u'http://example.org/'
+ url = 'http://example.org/'
self.hg.fwrite(b'.hg/hgrc',
b'[paths]\ndefault = %s\n' % url.encode('ascii'))
repoagent = thgrepo.repository(path=self.hg.path)._pyqtobj
@@ -85,7 +85,7 @@
self.hg.fread(b'.hg/hgrc').splitlines()[-3:])

def test_edit_alias(self):
- url = u'http://example.org/'
+ url = 'http://example.org/'
self.hg.fwrite(b'.hg/hgrc',
b'[paths]\ndefault = %s\n' % url.encode('ascii'))
repoagent = thgrepo.repository(path=self.hg.path)._pyqtobj
@@ -98,8 +98,8 @@

@mock.patch('tortoisehg.hgqt.qtlib.QuestionMsgBox', return_value=True)
def test_edit_url(self, mock_msgbox):
- origurl = u'http://example.org/'
- newurl = u'http://example.org/new/'
+ origurl = 'http://example.org/'
+ newurl = 'http://example.org/new/'
self.hg.fwrite(b'.hg/hgrc',
b'[paths]\ndefault = %s\n' % origurl.encode('ascii'))
repoagent = thgrepo.repository(path=self.hg.path)._pyqtobj


diff --git a/tortoisehg/hgqt/archive.py b/tortoisehg/hgqt/archive.py
--- a/tortoisehg/hgqt/archive.py
+++ b/tortoisehg/hgqt/archive.py

@@ -99,7 +99,7 @@
hglib.fromunicode(minrev)).parents()
if parents:
for p in parents:
- possibleroots.append(u'%d' % p.rev())
+ possibleroots.append('%d' % p.rev())
else:
possibleroots.append('null')



diff --git a/tortoisehg/hgqt/backout.py b/tortoisehg/hgqt/backout.py
--- a/tortoisehg/hgqt/backout.py
+++ b/tortoisehg/hgqt/backout.py

@@ -203,7 +203,7 @@

if parentbackout:
lbl = _('Backing out a parent revision is a single step operation')
- self.layout().addWidget(QLabel(u'<b>%s</b>' % lbl))
+ self.layout().addWidget(QLabel('<b>%s</b>' % lbl))

## backout revision
style = csinfo.panelstyle(contents=csinfo.PANEL_DEFAULT)


diff --git a/tortoisehg/hgqt/chunks.py b/tortoisehg/hgqt/chunks.py
--- a/tortoisehg/hgqt/chunks.py
+++ b/tortoisehg/hgqt/chunks.py

@@ -235,7 +235,7 @@
for line in ui.popbuffer().splitlines():
if rejfilere.search(line):
if qtlib.QuestionMsgBox(_('Manually resolve rejected chunks?'),
- hglib.tounicode(line) + u'<br><br>' +
+ hglib.tounicode(line) + '<br><br>' +
_('Edit patched file and rejects?'),
parent=self):
dlg = rejects.RejectsDialog(repo.ui, repo.wjoin(wfile),
@@ -793,7 +793,7 @@
chunk.write(buf)
chunk.lines = buf.getvalue().splitlines()
utext.append(buf.getvalue().decode(fd.textEncoding(), 'replace'))
- self.sci.setText(u'\n'.join(utext))
+ self.sci.setText('\n'.join(utext))

start = 0
self.sci.markerDeleteAll(-1)


diff --git a/tortoisehg/hgqt/commit.py b/tortoisehg/hgqt/commit.py
--- a/tortoisehg/hgqt/commit.py
+++ b/tortoisehg/hgqt/commit.py

@@ -842,7 +842,7 @@
if topic:
topic = hglib.tounicode(topic)
else:
- topic = u"None"
+ topic = "None"
self.topicbutton.setText(_('Topic: ') + topic)

# Update options label, showing only whitelisted options.


diff --git a/tortoisehg/hgqt/filedata.py b/tortoisehg/hgqt/filedata.py
--- a/tortoisehg/hgqt/filedata.py
+++ b/tortoisehg/hgqt/filedata.py

@@ -111,8 +111,8 @@


self.error: Optional[str] = None
self.olddata: Optional[bytes] = None
self.diff: Optional[bytes] = None

- self.flabel: str = u''
- self.elabel: str = u''
+ self.flabel: str = ''
+ self.elabel: str = ''


self.changes: Optional[patch.header] = None

self._textencoding = fileencoding.contentencoding(ctx.repo().ui)

@@ -353,7 +353,7 @@
isbfile = False
repo = ctx.repo()
maxdiff = repo.maxdiff
- self.flabel = u'<b>%s</b>' % self.filePath()
+ self.flabel = '<b>%s</b>' % self.filePath()

if ctx2:
# If a revision to compare to was provided, we must put it in
@@ -544,7 +544,7 @@



def load(self, changeselect: bool = False, force: bool = False) -> None:

self.error = None
- self.flabel = u'<b>%s</b>' % self.filePath()
+ self.flabel = '<b>%s</b>' % self.filePath()

# TODO: enforce maxdiff before generating diff?
ctx = self._ctx
@@ -559,7 +559,7 @@
if not force:
self.error = _checkdifferror(self.diff, ctx.repo().maxdiff)
if self.error:
- self.error += u'\n\n' + forcedisplaymsg
+ self.error += '\n\n' + forcedisplaymsg



def isDir(self) -> bool:
return True

@@ -573,7 +573,7 @@
maxdiff = ctx.repo().maxdiff

self.error = None
- self.flabel = u'<b>%s</b>' % self.filePath()
+ self.flabel = '<b>%s</b>' % self.filePath()

try:
self.diff = ctx.thgmqpatchdata(wfile)
@@ -595,7 +595,7 @@
if not force:
self.error = _checkdifferror(self.diff, maxdiff)
if self.error:
- self.error += u'\n\n' + forcedisplaymsg
+ self.error += '\n\n' + forcedisplaymsg

def rev(self) -> int:
# avoid mixing integer and localstr
@@ -613,7 +613,7 @@



def load(self, changeselect: bool = False, force: bool = False) -> None:

self.error = None
- self.flabel = u'<b>%s</b>' % self.filePath()
+ self.flabel = '<b>%s</b>' % self.filePath()

ctx = cast(patchctx.patchctx, self._ctx)
try:
@@ -626,7 +626,7 @@
if not force:
self.error = _checkdifferror(self.diff, ctx.repo().maxdiff)
if self.error:
- self.error += u'\n\n' + forcedisplaymsg
+ self.error += '\n\n' + forcedisplaymsg

def rev(self) -> int:
# avoid mixing integer and localstr
@@ -673,7 +673,7 @@
wfile = self._wfile

self.error = None
- self.flabel = u'<b>%s</b>' % self.filePath()
+ self.flabel = '<b>%s</b>' % self.filePath()

try:


def genSubrepoRevChangedDescription(subrelpath: bytes, sfrom: str, sto: str,

@@ -689,7 +689,7 @@
commands.log(_ui, srepo, **opts)
logOutput = _ui.popbuffer()
if not logOutput:
- return _('Initial revision') + u'\n'
+ return _('Initial revision') + '\n'
except error.ParseError as e:
# Some mercurial versions have a bug that results in
# saving a subrepo node id in the .hgsubstate file
@@ -721,17 +721,17 @@
if not sfrom and not sto:
sstatedesc = 'new'
out.append(_('Subrepo created and set to initial '
- 'revision.') + u'\n\n')
+ 'revision.') + '\n\n')
return out, sstatedesc
elif not sfrom:
sstatedesc = 'new'
- header = _('Subrepo initialized to revision:') + u'\n\n'
+ header = _('Subrepo initialized to revision:') + '\n\n'
elif not sto:
sstatedesc = 'removed'
out.append(_('Subrepo removed from repository.')
- + u'\n\n')
+ + '\n\n')
out.append(_('Previously the subrepository was '
- 'at the following revision:') + u'\n\n')
+ 'at the following revision:') + '\n\n')
subinfo = getLog(_ui, srepo,
{'rev': [hglib.fromunicode(sfrom)]})
slog = hglib.tounicode(subinfo)
@@ -740,41 +740,41 @@
elif sfrom == sto:
sstatedesc = 'unchanged'
header = _('Subrepo was not changed.')
- slog = _('changeset: %s') % sfrom[:12] + u'\n'
+ slog = _('changeset: %s') % sfrom[:12] + '\n'
if missingsub:
header = _('[WARNING] Missing subrepo. '
'Update to this revision to clone it.') \
- + u'\n\n' + header
+ + '\n\n' + header
else:
try:
slog = getLog(_ui, srepo, opts)
except error.RepoError:
header = _('[WARNING] Incomplete subrepo. '
'Update to this revision to pull it.') \
- + u'\n\n' + header
- out.append(header + u' ')
- out.append(_('Subrepo state is:') + u'\n\n' + slog)
+ + '\n\n' + header
+ out.append(header + ' ')
+ out.append(_('Subrepo state is:') + '\n\n' + slog)
return out, sstatedesc
else:
sstatedesc = 'changed'

- header = _('Revision has changed to:') + u'\n\n'
- sfromlog = _('changeset: %s') % sfrom[:12] + u'\n\n'
+ header = _('Revision has changed to:') + '\n\n'
+ sfromlog = _('changeset: %s') % sfrom[:12] + '\n\n'
if not missingsub:
try:
sfromlog = getLog(_ui, srepo, opts)
except error.RepoError:
sfromlog = _('changeset: %s '
'(not found on subrepository)') \
- % sfrom[:12] + u'\n\n'
- sfromlog = _('From:') + u'\n' + sfromlog
+ % sfrom[:12] + '\n\n'
+ sfromlog = _('From:') + '\n' + sfromlog

stolog = ''
if missingsub:
header = _(
'[WARNING] Missing changed subrepository. '
'Update to this revision to clone it.') \
- + u'\n\n' + header
+ + '\n\n' + header
stolog = _('changeset: %s') % sto[:12] + '\n\n'
sfromlog += _(
'Subrepository not found in the working '
@@ -787,10 +787,10 @@
header = _(
'[WARNING] Incomplete changed subrepository. '
'Update to this revision to pull it.') \
- + u'\n\n' + header
+ + '\n\n' + header
stolog = _('changeset: %s '
'(not found on subrepository)') \
- % sto[:12] + u'\n\n'
+ % sto[:12] + '\n\n'
out.append(header)
out.append(stolog)



@@ -818,7 +818,7 @@
return

except error.Abort as e:
self.error = (_('Error previewing subrepo: %s')
- % hglib.exception_str(e)) + u'\n\n'
+ % hglib.exception_str(e)) + '\n\n'
self.error += _('Subrepo may be damaged or '
'inaccessible.')
return
@@ -839,10 +839,10 @@
removed=True, deleted=True)
data = _ui.popbuffer()
if data:
- out.append(_('The subrepository is dirty.') + u' '
- + _('File Status:') + u'\n')
+ out.append(_('The subrepository is dirty.') + ' '
+ + _('File Status:') + '\n')
out.append(hglib.tounicode(data))
- out.append(u'\n')
+ out.append('\n')

sstatedesc = 'changed'


if ctx.rev() is not None:

@@ -864,7 +864,7 @@
sstatedesc += ' and dirty'
elif srev and not sactual:
sstatedesc = 'removed'
- self.ucontents = u''.join(out).strip()
+ self.ucontents = ''.join(out).strip()

lbl = {
'changed': _('(is a changed sub-repository)'),


diff --git a/tortoisehg/hgqt/filedialogs.py b/tortoisehg/hgqt/filedialogs.py
--- a/tortoisehg/hgqt/filedialogs.py
+++ b/tortoisehg/hgqt/filedialogs.py

@@ -813,7 +813,7 @@
self._diffmatch = {'left': [x[1:3] for x in blocks],
'right': [x[3:5] for x in blocks]}
for side in sides:
- self.viewers[side].setText(u'\n'.join(self.filedata[side]))
+ self.viewers[side].setText('\n'.join(self.filedata[side]))
self.update_page_steps(keeppos)
self.timer.start()



diff --git a/tortoisehg/hgqt/fileview.py b/tortoisehg/hgqt/fileview.py
--- a/tortoisehg/hgqt/fileview.py
+++ b/tortoisehg/hgqt/fileview.py

@@ -195,7 +195,7 @@

self._fd = self._nullfd = filedata.createNullData(repo)
self._lostMode = _NullMode
- self._lastSearch = u'', False
+ self._lastSearch = '', False

self._modeToggleGroup = QActionGroup(self)
self._modeToggleGroup.triggered.connect(self._setModeByAction)


diff --git a/tortoisehg/hgqt/grep.py b/tortoisehg/hgqt/grep.py
--- a/tortoisehg/hgqt/grep.py
+++ b/tortoisehg/hgqt/grep.py

@@ -138,8 +138,8 @@
'Exclusion patterns are applied after inclusion patterns.')
ihelpstr = _('Comma separated list of inclusion file patterns. '
'By default, the entire repository is searched.')
- incle.setPlaceholderText(u' '.join([u'###', ihelpstr, u'###']))
- excle.setPlaceholderText(u' '.join([u'###', ehelpstr, u'###']))
+ incle.setPlaceholderText(' '.join(['###', ihelpstr, '###']))
+ excle.setPlaceholderText(' '.join(['###', ehelpstr, '###']))
grid.addWidget(ilabel, 1, 2)
grid.addWidget(incle, 1, 3, 1, 2)
grid.addWidget(elabel, 2, 2)


diff --git a/tortoisehg/hgqt/messageentry.py b/tortoisehg/hgqt/messageentry.py
--- a/tortoisehg/hgqt/messageentry.py
+++ b/tortoisehg/hgqt/messageentry.py

@@ -204,7 +204,7 @@
return line + 1

group = [lines[l] for l in pycompat.xrange(b, e+1)]
- MARKER = u'\033\033\033\033\033'
+ MARKER = '\033\033\033\033\033'
curlinenum, curcol = self.getCursorPosition()
if b <= curlinenum <= e:
# insert a "marker" at the cursor position


diff --git a/tortoisehg/hgqt/phabreview.py b/tortoisehg/hgqt/phabreview.py
--- a/tortoisehg/hgqt/phabreview.py
+++ b/tortoisehg/hgqt/phabreview.py

@@ -409,14 +409,14 @@
reviewers = [reviewerlist.item(i).data(role).username
for i in pycompat.xrange(reviewerlist.count())]
if reviewers:
- reviewers = u', '.join(reviewers)
+ reviewers = ', '.join(reviewers)
else:
- reviewers = u'None'
+ reviewers = 'None'

- preview.append(u'Server: %s\n' % hglib.tounicode(url))
- preview.append(u'Callsign: %s\n' % hglib.tounicode(callsign))
- preview.append(u'Reviewers: %s\n' % reviewers)
- preview.append(u'\n\n')
+ preview.append('Server: %s\n' % hglib.tounicode(url))
+ preview.append('Callsign: %s\n' % hglib.tounicode(callsign))
+ preview.append('Reviewers: %s\n' % reviewers)
+ preview.append('\n\n')

preview.append(exported)



diff --git a/tortoisehg/hgqt/postreview.py b/tortoisehg/hgqt/postreview.py
--- a/tortoisehg/hgqt/postreview.py
+++ b/tortoisehg/hgqt/postreview.py

@@ -102,7 +102,7 @@
msg = _("Invalid reviewboard plugin. Please download the "
"Mercurial reviewboard plugin version 3.5 or higher "
"from the website below.\n\n %s") % \
- u'https://foss.heptapod.net/mercurial/tortoisehg/thg-build-deps/mercurial-reviewboard'
+ 'https://foss.heptapod.net/mercurial/tortoisehg/thg-build-deps/mercurial-reviewboard'

self.dialog.error_message = msg



diff --git a/tortoisehg/hgqt/qdelete.py b/tortoisehg/hgqt/qdelete.py
--- a/tortoisehg/hgqt/qdelete.py
+++ b/tortoisehg/hgqt/qdelete.py

@@ -34,8 +34,8 @@
self.setLayout(QVBoxLayout())

msg = _('Remove patches from queue?')
- patchesu = u'<li>'.join(patches)
- lbl = QLabel(u'<b>%s<ul><li>%s</ul></b>' % (msg, patchesu))
+ patchesu = '<li>'.join(patches)
+ lbl = QLabel('<b>%s<ul><li>%s</ul></b>' % (msg, patchesu))
self.layout().addWidget(lbl)

self._keepchk = QCheckBox(_('Keep patch files'))


diff --git a/tortoisehg/hgqt/qfold.py b/tortoisehg/hgqt/qfold.py
--- a/tortoisehg/hgqt/qfold.py
+++ b/tortoisehg/hgqt/qfold.py

@@ -144,7 +144,7 @@
descs = [hglib.revsymbol(self.repo, b'qtip').description()]
# lookup of unapplied patches is handled by thgrepo hack
descs.extend(self.repo[p].description() for p in patches)
- return u'\n* * *\n'.join(map(hglib.tounicode, descs))
+ return '\n* * *\n'.join(map(hglib.tounicode, descs))

@pyqtSlot()
def configChanged(self):


diff --git a/tortoisehg/hgqt/qtapp.py b/tortoisehg/hgqt/qtapp.py
--- a/tortoisehg/hgqt/qtapp.py
+++ b/tortoisehg/hgqt/qtapp.py

@@ -208,8 +208,8 @@


opts['values'] = [hglib.exception_str(evalue)]
errstr = _recoverableexc[etype]

if etype is error.Abort and evalue.hint:
- errstr = u''.join([errstr, u'<br><b>', _('hint:'),
- u'</b> %(arg1)s'])
+ errstr = ''.join([errstr, '<br><b>', _('hint:'),
+ '</b> %(arg1)s'])
opts['values'] = [
hglib.exception_str(evalue), hglib.tounicode(evalue.hint)
]


diff --git a/tortoisehg/hgqt/qtlib.py b/tortoisehg/hgqt/qtlib.py
--- a/tortoisehg/hgqt/qtlib.py
+++ b/tortoisehg/hgqt/qtlib.py

@@ -291,7 +291,7 @@
except OSError as e:


QMessageBox.warning(parent,
_('Editor launch failure'),

- u'%s : %s' % (hglib.tounicode(cmdline),
+ '%s : %s' % (hglib.tounicode(cmdline),
hglib.exception_str(e)))

def openshell(
@@ -562,7 +562,7 @@
msg = hglib.tounicode(msg) # TODO: enforce unicode arg?
msg = htmlescape(msg, False)


msg = msg.replace('\n', '<br />')

- return u'<span style="%s">%s</span>' % (style, msg)
+ return '<span style="%s">%s</span>' % (style, msg)



def descriptionhtmlizer(ui: uimod.ui) -> Callable[[AnyStr], str]:
"""Return a function to mark up ctx.description() as an HTML

diff --git a/tortoisehg/hgqt/rejects.py b/tortoisehg/hgqt/rejects.py
--- a/tortoisehg/hgqt/rejects.py
+++ b/tortoisehg/hgqt/rejects.py

@@ -308,7 +308,7 @@
elif line[0] == '-':
removed.append(i)
self.markerDeleteAll(-1)
- self.setText(u''.join(utext))
+ self.setText(''.join(utext))
for i in added:
self.markerAdd(i, self.addedMark)
self.markerAdd(i, self.addedColor)


diff --git a/tortoisehg/hgqt/repofilter.py b/tortoisehg/hgqt/repofilter.py
--- a/tortoisehg/hgqt/repofilter.py
+++ b/tortoisehg/hgqt/repofilter.py

@@ -151,7 +151,7 @@
showHiddenChanged = pyqtSignal(bool)
showGraftSourceChanged = pyqtSignal(bool)

- _allBranchesLabel = u'\u2605 ' + _('Show all') + u' \u2605'
+ _allBranchesLabel = '\u2605 ' + _('Show all') + ' \u2605'

def __init__(self,
repoagent: thgrepo.RepoAgent,
@@ -173,8 +173,8 @@
self.filterEnabled = True

#Check if the font contains the glyph needed by the branch combo
- if not QFontMetrics(self.font()).inFont(u'\u2605'):
- self._allBranchesLabel = u'*** %s ***' % _('Show all')
+ if not QFontMetrics(self.font()).inFont('\u2605'):
+ self._allBranchesLabel = '*** %s ***' % _('Show all')

self.entrydlg = revset.RevisionSetQuery(repoagent, self)
self.entrydlg.queryIssued.connect(self.queryIssued)


diff --git a/tortoisehg/hgqt/repomodel.py b/tortoisehg/hgqt/repomodel.py
--- a/tortoisehg/hgqt/repomodel.py
+++ b/tortoisehg/hgqt/repomodel.py

@@ -751,9 +751,9 @@


assert b is not None
if ctx.extra().get(b'close'):

if self.unicodexinabox:
- b += u' \u2327'
+ b += ' \u2327'
else:
- b += u'--'
+ b += '--'
return b



def _getlatesttags(self, ctx: context.changectx) -> str:

@@ -797,7 +797,7 @@


if isinstance(rev, int):
return str(rev)

elif rev is None:
- return u'%d+' % ctx.p1().rev()
+ return '%d+' % ctx.p1().rev()
else:
return ''

@@ -814,7 +814,7 @@


if ctx.rev() is None:
if self.unicodestar:
# The Unicode symbol is a black star:

- return u'\u2605 ' + _('Working Directory') + u' \u2605'
+ return '\u2605 ' + _('Working Directory') + ' \u2605'
else:
return '*** ' + _('Working Directory') + ' ***'
if self._repoagent.configBool('tortoisehg', 'longsummary'):


diff --git a/tortoisehg/hgqt/repoview.py b/tortoisehg/hgqt/repoview.py
--- a/tortoisehg/hgqt/repoview.py
+++ b/tortoisehg/hgqt/repoview.py

@@ -231,9 +231,9 @@
# logical columns are vary by model class
self._loadColumnSettings()
#Check if the font contains the glyph needed by the model
- if not QFontMetrics(self.font()).inFont(u'\u2605'):
+ if not QFontMetrics(self.font()).inFont('\u2605'):
model.unicodestar = False
- if not QFontMetrics(self.font()).inFont(u'\u2327'):
+ if not QFontMetrics(self.font()).inFont('\u2327'):
model.unicodexinabox = False
self.selectionModel().currentRowChanged.connect(self.onRowChange)
self._rev_history = []


diff --git a/tortoisehg/hgqt/repowidget.py b/tortoisehg/hgqt/repowidget.py
--- a/tortoisehg/hgqt/repowidget.py
+++ b/tortoisehg/hgqt/repowidget.py

@@ -410,7 +410,7 @@
if self._repoagent.overlayUrl():
return _('%s <incoming>') % name
elif self.repomodel.branch():
- return u'%s [%s]' % (name, self.repomodel.branch())
+ return '%s [%s]' % (name, self.repomodel.branch())
else:
return name

@@ -1848,10 +1848,10 @@
udir)

warningMessage += \
- _('What do you want to do?\n') + u'\n' + \
- u'- ' + _('Replace the existing patch files.\n') + \
- u'- ' + _('Append the changes to the existing patch files.\n') + \
- u'- ' + _('Abort the export operation.\n')
+ _('What do you want to do?\n') + '\n' + \
+ '- ' + _('Replace the existing patch files.\n') + \
+ '- ' + _('Append the changes to the existing patch files.\n') + \
+ '- ' + _('Abort the export operation.\n')

res = qtlib.CustomPrompt(_('Patch files already exist'),
warningMessage,


diff --git a/tortoisehg/hgqt/resolve.py b/tortoisehg/hgqt/resolve.py
--- a/tortoisehg/hgqt/resolve.py
+++ b/tortoisehg/hgqt/resolve.py

@@ -445,7 +445,7 @@
txt = _('All conflicts are resolved.')
else:
txt = _('There are no conflicting file merges.')
- self.stlabel.setText(u'<h2>' + txt + u'</h2>')
+ self.stlabel.setText('<h2>' + txt + '</h2>')

def reject(self):
s = QSettings()


diff --git a/tortoisehg/hgqt/revset.py b/tortoisehg/hgqt/revset.py
--- a/tortoisehg/hgqt/revset.py
+++ b/tortoisehg/hgqt/revset.py

@@ -283,12 +283,12 @@
pos = self.entry.positionFromLineIndex(line, index)
if len(text) <= pos:
# cursor at end of text, append
- if text and text[-1] != u' ':
- text = text + u' '
+ if text and text[-1] != ' ':
+ text = text + ' '
newtext = text + itext
self.entry.setText(newtext)
self.entry.setSelection(line, len(text), line, len(newtext))
- elif text[pos] == u' ':
+ elif text[pos] == ' ':
# cursor is at a space, insert item
newtext = text[:pos] + itext + text[pos:]
self.entry.setText(newtext)
@@ -296,9 +296,9 @@
else:
# cursor is on text, wrap current word
start, end = pos, pos
- while start and text[start-1] != u' ':
+ while start and text[start-1] != ' ':
start = start-1
- while end < len(text) and text[end] != u' ':
+ while end < len(text) and text[end] != ' ':
end = end+1
bopen = itext.index('(')
newtext = text[:start] + itext[:bopen+1] + text[start:end] + \


diff --git a/tortoisehg/hgqt/sync.py b/tortoisehg/hgqt/sync.py
--- a/tortoisehg/hgqt/sync.py
+++ b/tortoisehg/hgqt/sync.py

@@ -109,9 +109,9 @@
u = urlutil.url(hglib.fromunicode(url))
if u.scheme in (b'http', b'https'):
safe = urlutil.hidepassword(hglib.fromunicode(url))
- return u'<a href="%s">%s</a>' % (url, hglib.tounicode(safe))
+ return '<a href="%s">%s</a>' % (url, hglib.tounicode(safe))
elif u.scheme is None or u.scheme == b'file':
- return u'<a href="%s">%s</a>' % (url, hglib.tounicode(u.path))
+ return '<a href="%s">%s</a>' % (url, hglib.tounicode(u.path))
else:
return url

@@ -784,7 +784,7 @@
def linkifyWithTarget(self, url: str) -> str:
link = linkify(url)
if self.targetcheckbox.isChecked():
- link += u" (%s)" % self.targetcombo.currentText()
+ link += " (%s)" % self.targetcombo.currentText()
return link

def inclicked(self):


diff --git a/tortoisehg/hgqt/topic.py b/tortoisehg/hgqt/topic.py
--- a/tortoisehg/hgqt/topic.py
+++ b/tortoisehg/hgqt/topic.py

@@ -107,10 +107,10 @@

def revUpdated(self):
if self.rev is None:
- hasunicodestar = QFontMetrics(self.font()).inFont(u'\u2605')
+ hasunicodestar = QFontMetrics(self.font()).inFont('\u2605')
if hasunicodestar:


# The Unicode symbol is a black star:

- revText = u'\u2605 ' + _('Working Directory') + u' \u2605'
+ revText = '\u2605 ' + _('Working Directory') + ' \u2605'
else:
revText = '*** ' + _('Working Directory') + ' ***'
else:


diff --git a/tortoisehg/hgqt/workbench.py b/tortoisehg/hgqt/workbench.py
--- a/tortoisehg/hgqt/workbench.py
+++ b/tortoisehg/hgqt/workbench.py

@@ -481,7 +481,7 @@
for n, a in enumerate(aliases):
# text, (pull-alias, push-alias)
if isinstance(a, tuple):
- itemtext = u'\u2193 %s | %s \u2191' % a
+ itemtext = '\u2193 %s | %s \u2191' % a
itemdata = tuple(pathdict[alias] for alias in a)
tooltip = _('pull: %s\npush: %s') % itemdata
else:


diff --git a/tortoisehg/util/hglib.py b/tortoisehg/util/hglib.py
--- a/tortoisehg/util/hglib.py
+++ b/tortoisehg/util/hglib.py

@@ -958,13 +958,13 @@
rev = fctx.rev()
# If the source path matches the current path, don't bother including it.
if curpath and curpath == fctx.path():
- source = u''
+ source = ''
else:
- source = u'(%s)' % tounicode(fctx.path())
+ source = '(%s)' % tounicode(fctx.path())
date = age(fctx.date()).decode('utf-8')
l = tounicode(fctx.description()).splitlines()


summary = l and l[0] or ''

- return u'%s@%s%s:%s "%s"' % (author, rev, source, date, summary)
+ return '%s@%s%s:%s "%s"' % (author, rev, source, date, summary)



def longsummary(description: Union[bytes, str],

limit: Optional[int] = None) -> str:

@@ -980,14 +980,14 @@
break
line = raw_line.strip().replace('\t', ' ')
if line:
- summary += u' ' + line
+ summary += ' ' + line
if len(summary) > limit:
add_ellipsis = True
summary = summary[0:limit]
elif len(lines) > 1:
add_ellipsis = True
if add_ellipsis:
- summary += u' \u2026' # ellipsis ...
+ summary += ' \u2026' # ellipsis ...
return summary

def getDeepestSubrepoContainingFile(wfile: bytes,
diff --git a/win32/reggen.py b/win32/reggen.py
--- a/win32/reggen.py
+++ b/win32/reggen.py
@@ -35,19 +35,19 @@

from tortoisehg.util.menuthg import thgcmenu

-regkeytmpl = u'[HKEY_CURRENT_USER\\Software\\TortoiseHg\\CMenu\\%s\\%s]'
-regheaders = ( u'Windows Registry Editor Version 5.00',
- u'',
- u'[HKEY_CURRENT_USER\\Software\\TortoiseHg]',
- u'"CMenuLang"="%(lang)s"',
- u'',
- u'[HKEY_CURRENT_USER\\Software\\TortoiseHg\\CMenu]',
- u'',
- u'[HKEY_CURRENT_USER\\Software\\TortoiseHg\\CMenu\\%(lang)s]')
+regkeytmpl = '[HKEY_CURRENT_USER\\Software\\TortoiseHg\\CMenu\\%s\\%s]'
+regheaders = ( 'Windows Registry Editor Version 5.00',
+ '',
+ '[HKEY_CURRENT_USER\\Software\\TortoiseHg]',
+ '"CMenuLang"="%(lang)s"',
+ '',
+ '[HKEY_CURRENT_USER\\Software\\TortoiseHg\\CMenu]',
+ '',
+ '[HKEY_CURRENT_USER\\Software\\TortoiseHg\\CMenu\\%(lang)s]')

# regex patterns used to extract strings from PO files
-pat_id = re.compile(u'^msgid "([^\\"]+)"')
-pat_str = re.compile(u'^msgstr "([^\\"]+)"')
+pat_id = re.compile('^msgid "([^\\"]+)"')
+pat_str = re.compile('^msgstr "([^\\"]+)"')
def lookup(file):
def stripmsg(line, pat):
m = pat.match(line)
@@ -69,7 +69,7 @@
foundmsgid = False
f = codecs.open(file, 'r', 'utf-8')
for line in f.readlines():
- line = line.rstrip(u'\r\n')
+ line = line.rstrip('\r\n')
if foundmsgid:
msgstr = stripmsg(line, pat_str)
if msgstr:
@@ -89,28 +89,28 @@
if isinstance(lines, (str, pycompat.unicode)):
buf = lines
else:
- buf = u'\r\n'.join(lines)
- buf = (buf + (u'\r\n' * newlines))
+ buf = '\r\n'.join(lines)
+ buf = (buf + ('\r\n' * newlines))
newfile.write(buf)
def close():
newfile.close()
return write, close

# enumerate available languages
-langinfo = [{'code': u'en_US', 'file': None}]
-lang_pat = re.compile(u'([^\\.]+)\\.po$')
-for file in glob.glob(u'../i18n/tortoisehg/*.po'):
+langinfo = [{'code': 'en_US', 'file': None}]
+lang_pat = re.compile('([^\\.]+)\\.po$')
+for file in glob.glob('../i18n/tortoisehg/*.po'):
m = lang_pat.match(os.path.basename(file))
if m:
langinfo.append({'code': m.group(1), 'file': os.path.abspath(file)})

# output REG files
for lang in langinfo:
- write, close = wopen(u'thg-cmenu-%s.reg' % lang['code'])
+ write, close = wopen('thg-cmenu-%s.reg' % lang['code'])
write([h % {'lang': lang['code']} for h in regheaders])
i18n = lookup(lang['file'])
for hgcmd, cmenu in thgcmenu.items():
write(regkeytmpl % (lang['code'], hgcmd), 1)
- write((u'"menuText"="%s"' % i18n[cmenu['label']['id']],
- u'"helpText"="%s"' % i18n[cmenu['help']['id']]))
+ write(('"menuText"="%s"' % i18n[cmenu['label']['id']],
+ '"helpText"="%s"' % i18n[cmenu['help']['id']]))
close()

Antonio Muci

unread,
Feb 28, 2025, 7:03:42 PMFeb 28
to thg...@googlegroups.com, Matt Harbison
In ruff these could be ignored adding explicitly # noqa: UP015 after the incriminated lines, or the rule could be disabled globally in configuration.

Pyupgrade does not offer this apparently by design (https://github.com/asottile/pyupgrade/issues/574), so the removal of the open modes will have to do.


For some months now I was wondering whether to propose a big and dumb PR that modernized the codebase using safe transformations via ruff, but I always refrained. I am glad you are doing it now.


In the coming days I'd like to write an email with some little proposals about this topic.

Antonio

Matt Harbison

unread,
Feb 28, 2025, 7:36:29 PMFeb 28
to TortoiseHg Developers
On Friday, February 28, 2025 at 7:03:42 PM UTC-5 Antonio Muci wrote:
In ruff these could be ignored adding explicitly # noqa: UP015 after the incriminated lines, or the rule could be disabled globally in configuration.

Pyupgrade does not offer this apparently by design (https://github.com/asottile/pyupgrade/issues/574), so the removal of the open modes will have to do.

Yeah, I think I saw that.  It's actually pretty easy to hack the code to turn things on and off once you understand how the decorator works (though the token fixer function does several things at once).  I didn't do that because my intention was to add a config for `hg fix`, so that we could use it going forward.  Unfortunately the tool writes str to stdout using print(), so it 1) mojibakes on Windows, and 2) changes LF to CRLF.  I submitted a ~1 line fix to write binary output to fix both issues, but the maintainer rejected it because "your terminal is misconfigured".  I didn't feel like arguing that the default config is not a misconfiguration and that there's no configuration setting for modifying EOL, exactly because of other discussions like you linked.  So now we just have to run it manually, on occasion.

For some months now I was wondering whether to propose a big and dumb PR that modernized the codebase using safe transformations via ruff, but I always refrained. I am glad you are doing it now.


In the coming days I'd like to write an email with some little proposals about this topic.

Go for it.

This pyupgrade thing came out of a discussion in IRC about how there are now tools that maintain import statements better (among other code maintenance things), so we could get rid of some of the custom tools that nobody understands anymore.  I do remember ruff being mentioned; I forget if that was the tool the conflicted with black.  (Whatever tool it was, there was a fork of it to play nice.)  I jumped on this when I saw it could strip out the quotes around type hints, because I didn't want to do that manually.

You might want to direct the proposal to the hg project first to get more people discussing it, and then we can follow that here.  I still intend to run black on this code because some of the formatting is... not great.  But maybe I'll wait and see when hg is going to upgrade black again before doing that.

Yuya Nishihara

unread,
Mar 1, 2025, 6:08:17 AMMar 1
to Matt Harbison, thg...@googlegroups.com
On Fri, 28 Feb 2025 17:14:07 -0500, Matt Harbison wrote:
> # HG changeset patch
> # User Matt Harbison <matt_h...@yahoo.com>
> # Date 1736203889 18000
> # Mon Jan 06 17:51:29 2025 -0500
> # Branch stable
> # Node ID 34fea09137806ea96b8b6c598d86c501d149d50a
> # Parent b9b153e52d1f9cd707dff64e3e5a6cd7fee8046a
> # EXP-Topic pyupgrade
> py3: convert to new style classes

Queued, thanks.
Reply all
Reply to author
Forward
0 new messages