Skip to content

Commit 8ac41b0

Browse files
authored
Merge pull request #140 from MightyCreak/static-types
Convert some functions to static typing
2 parents f7aeb79 + d420d7a commit 8ac41b0

File tree

15 files changed

+173
-159
lines changed

15 files changed

+173
-159
lines changed

.mypy.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
[mypy]
22
warn_unused_ignores = True
3+
disallow_incomplete_defs = True

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2222
- Renamed application name from "Diffuse Merge Tool" to "Diffuse"
2323
- Linters can be run sooner (before installation)
2424
- Better messages when an error occurs while parsing the config file
25+
- Start converting the code to static types
2526

2627
### Fixed
2728
- Removed the lasting lint errors (i.e. in main.py)

src/diffuse/constants.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@
1818
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1919

2020
from gettext import gettext as _
21+
from typing import Final
2122

22-
APP_NAME = 'Diffuse'
23-
COPYRIGHT = '''{copyright} © 2006-2019 Derrick Moser
23+
APP_NAME: Final[str] = 'Diffuse'
24+
COPYRIGHT: Final[str] = '''{copyright} © 2006-2019 Derrick Moser
2425
{copyright} © 2015-2021 Romain Failliot'''.format(copyright=_("Copyright"))
25-
WEBSITE = 'https://mightycreak.github.io/diffuse/'
26+
WEBSITE: Final[str] = 'https://mightycreak.github.io/diffuse/'
2627

2728
# Constants are set in main()
28-
VERSION = '0.0.0'
29+
VERSION: str = '0.0.0'

src/diffuse/dialogs.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
# the about dialog
3434
class AboutDialog(Gtk.AboutDialog):
35-
def __init__(self):
35+
def __init__(self) -> None:
3636
Gtk.AboutDialog.__init__(self)
3737
self.set_logo_icon_name('io.github.mightycreak.Diffuse')
3838
self.set_program_name(constants.APP_NAME)
@@ -104,13 +104,13 @@ def __init__(self, title, parent, prefs, action, accept, rev=False):
104104
def set_encoding(self, encoding):
105105
self.encoding.set_text(encoding)
106106

107-
def get_encoding(self):
107+
def get_encoding(self) -> str:
108108
return self.encoding.get_text()
109109

110-
def get_revision(self):
110+
def get_revision(self) -> str:
111111
return self.revision.get_text()
112112

113-
def get_filename(self):
113+
def get_filename(self) -> str:
114114
# convert from UTF-8 string to unicode
115115
return Gtk.FileChooserDialog.get_filename(self)
116116

src/diffuse/main.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@
2626
import webbrowser
2727

2828
from gettext import gettext as _
29+
from typing import Optional
2930
from urllib.parse import urlparse
3031

3132
from diffuse import constants
3233
from diffuse import utils
3334
from diffuse.dialogs import AboutDialog, FileChooserDialog, NumericDialog, SearchDialog
3435
from diffuse.preferences import Preferences
3536
from diffuse.resources import theResources
37+
from diffuse.utils import LineEnding
3638
from diffuse.vcs.vcs_registry import VcsRegistry
3739
from diffuse.widgets import FileDiffViewerBase
3840
from diffuse.widgets import createMenu, LINE_MODE, CHAR_MODE, ALIGN_MODE
@@ -118,7 +120,7 @@ class Diffuse(Gtk.Window):
118120
class FileDiffViewer(FileDiffViewerBase):
119121
# pane header
120122
class PaneHeader(Gtk.Box):
121-
def __init__(self):
123+
def __init__(self) -> None:
122124
Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
123125
_append_buttons(self, Gtk.IconSize.MENU, [
124126
[Gtk.STOCK_OPEN, self.button_cb, 'open', _('Open File...')],
@@ -171,7 +173,7 @@ def setEdits(self, has_edits):
171173

172174
# pane footer
173175
class PaneFooter(Gtk.Box):
174-
def __init__(self):
176+
def __init__(self) -> None:
175177
Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
176178
self.cursor = label = Gtk.Label.new()
177179
self.cursor.set_size_request(-1, -1)
@@ -212,11 +214,11 @@ def updateCursor(self, viewer, f):
212214
# set the format label
213215
def setFormat(self, s):
214216
v = []
215-
if s & utils.DOS_FORMAT:
217+
if s & LineEnding.DOS_FORMAT:
216218
v.append('DOS')
217-
if s & utils.MAC_FORMAT:
219+
if s & LineEnding.MAC_FORMAT:
218220
v.append('Mac')
219-
if s & utils.UNIX_FORMAT:
221+
if s & LineEnding.UNIX_FORMAT:
220222
v.append('Unix')
221223
self.format.set_text('/'.join(v))
222224

@@ -1108,7 +1110,7 @@ def remove_tab_cb(self, widget, data):
11081110
self.quit_cb(widget, data)
11091111

11101112
# convenience method to request confirmation when closing the last tab
1111-
def _confirm_tab_close(self):
1113+
def _confirm_tab_close(self) -> bool:
11121114
dialog = utils.MessageDialog(
11131115
self.get_toplevel(),
11141116
Gtk.MessageType.WARNING,
@@ -1193,7 +1195,7 @@ def syntax_changed_cb(self, widget, s):
11931195
self.setSyntax(s)
11941196

11951197
# create an empty viewer with 'n' panes
1196-
def newFileDiffViewer(self, n):
1198+
def newFileDiffViewer(self, n: int) -> FileDiffViewer:
11971199
self.viewer_count += 1
11981200
tabname = _('File Merge %d') % (self.viewer_count, )
11991201
tab = NotebookTab(tabname, Gtk.STOCK_FILE)
@@ -1338,13 +1340,13 @@ def createModifiedFileTabs(self, items, labels, options):
13381340
)
13391341

13401342
# close all tabs without differences
1341-
def closeOnSame(self):
1343+
def closeOnSame(self) -> None:
13421344
for i in range(self.notebook.get_n_pages() - 1, -1, -1):
13431345
if not self.notebook.get_nth_page(i).hasDifferences():
13441346
self.notebook.remove_page(i)
13451347

13461348
# returns True if the application can safely quit
1347-
def confirmQuit(self):
1349+
def confirmQuit(self) -> bool:
13481350
nb = self.notebook
13491351
return self.confirmCloseViewers([nb.get_nth_page(i) for i in range(nb.get_n_pages())])
13501352

@@ -1356,7 +1358,7 @@ def delete_cb(self, widget, event):
13561358
return True
13571359

13581360
# returns the currently focused viewer
1359-
def getCurrentViewer(self):
1361+
def getCurrentViewer(self) -> Optional[Gtk.Widget]:
13601362
return self.notebook.get_nth_page(self.notebook.get_current_page())
13611363

13621364
# callback for the open file menu item
@@ -1570,7 +1572,7 @@ def go_to_line_cb(self, widget, data):
15701572
self.getCurrentViewer().go_to_line_cb(widget, data)
15711573

15721574
# notify all viewers of changes to the preferences
1573-
def preferences_updated(self):
1575+
def preferences_updated(self) -> None:
15741576
n = self.notebook.get_n_pages()
15751577
self.notebook.set_show_tabs(self.prefs.getBool('tabs_always_show') or n > 1)
15761578
for i in range(n):
@@ -1712,7 +1714,7 @@ def _append_buttons(box, size, specs):
17121714

17131715

17141716
# constructs a full URL for the named file
1715-
def _path2url(path, proto='file'):
1717+
def _path2url(path: str, proto: str = 'file') -> str:
17161718
r = [proto, ':///']
17171719
s = os.path.abspath(path)
17181720
i = 0

src/diffuse/preferences.py

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def __init__(self, path):
199199
self.path = path
200200
if os.path.isfile(self.path):
201201
try:
202-
with open(self.path, 'r', encoding='utf-8') as f:
202+
with open(self.path, 'r', encoding='utf-8') as f:
203203
ss = utils.readconfiglines(f)
204204
for j, s in enumerate(ss):
205205
try:
@@ -342,7 +342,7 @@ def _buildPrefsDialog(self, parent, widgets, template):
342342
if tpl[0] in ['Font', 'Integer']:
343343
entry = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 0)
344344
if tpl[0] == 'Font':
345-
button = _FontButton()
345+
button = Gtk.FontButton()
346346
button.set_font(self.string_prefs[tpl[1]])
347347
else:
348348
button = Gtk.SpinButton.new(
@@ -368,28 +368,28 @@ def _buildPrefsDialog(self, parent, widgets, template):
368368
return table
369369

370370
# get/set methods to manipulate the preference values
371-
def getBool(self, name):
371+
def getBool(self, name: str) -> bool:
372372
return self.bool_prefs[name]
373373

374-
def setBool(self, name, value):
374+
def setBool(self, name: str, value: bool) -> None:
375375
self.bool_prefs[name] = value
376376

377-
def getInt(self, name):
377+
def getInt(self, name: str) -> int:
378378
return self.int_prefs[name]
379379

380-
def getString(self, name):
380+
def getString(self, name: str) -> str:
381381
return self.string_prefs[name]
382382

383-
def setString(self, name, value):
383+
def setString(self, name: str, value: str) -> None:
384384
self.string_prefs[name] = value
385385

386386
def getEncodings(self):
387387
return self.encodings
388388

389-
def _getDefaultEncodings(self):
389+
def _getDefaultEncodings(self) -> list[str]:
390390
return self.string_prefs['encoding_auto_detect_codecs'].split()
391391

392-
def getDefaultEncoding(self):
392+
def getDefaultEncoding(self) -> str:
393393
return self.string_prefs['encoding_default_codec']
394394

395395
# attempt to convert a string to unicode from an unknown encoding
@@ -412,7 +412,7 @@ def convertToUnicode(self, s):
412412

413413
# cygwin and native applications can be used on windows, use this method
414414
# to convert a path to the usual form expected on sys.platform
415-
def convertToNativePath(self, s):
415+
def convertToNativePath(self, s: str) -> str:
416416
if utils.isWindows() and s.find('/') >= 0:
417417
# treat as a cygwin path
418418
s = s.replace(os.sep, '/')
@@ -436,15 +436,6 @@ def convertToNativePath(self, s):
436436
return s
437437

438438

439-
# adaptor class to allow a Gtk.FontButton to be read like a Gtk.Entry
440-
class _FontButton(Gtk.FontButton):
441-
def __init__(self):
442-
Gtk.FontButton.__init__(self)
443-
444-
def get_text(self):
445-
return self.get_font_name()
446-
447-
448439
# text entry widget with a button to help pick file names
449440
class _FileEntry(Gtk.Box):
450441
def __init__(self, parent, title):
@@ -475,8 +466,8 @@ def chooseFile(self, widget):
475466
self.entry.set_text(dialog.get_filename())
476467
dialog.destroy()
477468

478-
def set_text(self, s):
469+
def set_text(self, s: str) -> None:
479470
self.entry.set_text(s)
480471

481-
def get_text(self):
472+
def get_text(self) -> str:
482473
return self.entry.get_text()

src/diffuse/resources.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
from distutils import util
3333
from gettext import gettext as _
34+
from typing import Final
3435

3536
from diffuse import utils
3637

@@ -529,7 +530,7 @@ def parse(self, file_name):
529530

530531
# colour resources
531532
class _Colour:
532-
def __init__(self, r, g, b, a=1.0):
533+
def __init__(self, r: float, g: float, b: float, a: float = 1.0):
533534
# the individual colour components as floats in the range [0, 1]
534535
self.red = r
535536
self.green = g
@@ -601,4 +602,4 @@ def parse(self, state_name, s):
601602
return state_name, blocks
602603

603604

604-
theResources = Resources()
605+
theResources: Final[Resources] = Resources()

0 commit comments

Comments
 (0)