Skip to content

Commit 1402e97

Browse files
authored
Merge pull request #117 from MightyCreak/pylint
Fix lint messages in src/utils.py
2 parents f5a59b9 + 812ca17 commit 1402e97

File tree

5 files changed

+109
-91
lines changed

5 files changed

+109
-91
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
- name: Pylint
2424
uses: cclauss/GitHub-Action-for-pylint@master
2525
with:
26-
args: "pylint src/vcs/"
26+
args: "pylint src/utils.py src/vcs/"
2727

2828
meson-build-test:
2929
runs-on: ubuntu-latest

.pylintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ disable=raw-checker-failed,
9494
missing-function-docstring,
9595
import-error,
9696
no-self-use,
97+
too-many-arguments,
9798
too-many-branches,
9899
too-many-locals,
99100
too-many-statements,

src/main.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,25 +29,16 @@
2929
import unicodedata
3030
import webbrowser
3131

32+
# pylint: disable=wrong-import-position
3233
import gi
33-
3434
gi.require_version('GObject', '2.0')
35-
from gi.repository import GObject
36-
3735
gi.require_version('Gtk', '3.0')
38-
from gi.repository import Gtk
39-
4036
gi.require_version('Gdk', '3.0')
41-
from gi.repository import Gdk
42-
4337
gi.require_version('GdkPixbuf', '2.0')
44-
from gi.repository import GdkPixbuf
45-
4638
gi.require_version('Pango', '1.0')
47-
from gi.repository import Pango
48-
4939
gi.require_version('PangoCairo', '1.0')
50-
from gi.repository import PangoCairo
40+
from gi.repository import GObject, Gtk, Gdk, GdkPixbuf, Pango, PangoCairo
41+
# pylint: enable=wrong-import-position
5142

5243
from urllib.parse import urlparse
5344

@@ -6088,7 +6079,7 @@ def loadState(self, statepath):
60886079
if os.path.isfile(statepath):
60896080
try:
60906081
f = open(statepath, 'r')
6091-
ss = readlines(f)
6082+
ss = utils.readlines(f)
60926083
f.close()
60936084
for j, s in enumerate(ss):
60946085
try:

src/utils.py

Lines changed: 72 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,28 @@
2323
import subprocess
2424
import traceback
2525

26+
# pylint: disable=wrong-import-position
2627
import gi
27-
2828
gi.require_version('Gtk', '3.0')
2929
from gi.repository import Gtk
30+
# pylint: enable=wrong-import-position
3031

3132
from diffuse import constants
3233

3334
# convenience class for displaying a message dialogue
3435
class MessageDialog(Gtk.MessageDialog):
35-
def __init__(self, parent, type, s):
36-
if type == Gtk.MessageType.ERROR:
36+
def __init__(self, parent, message_type, s):
37+
if message_type == Gtk.MessageType.ERROR:
3738
buttons = Gtk.ButtonsType.OK
3839
else:
3940
buttons = Gtk.ButtonsType.OK_CANCEL
40-
Gtk.MessageDialog.__init__(self, parent = parent, destroy_with_parent = True, message_type = type, buttons = buttons, text = s)
41+
Gtk.MessageDialog.__init__(
42+
self,
43+
parent=parent,
44+
destroy_with_parent=True,
45+
message_type=message_type,
46+
buttons=buttons,
47+
text=s)
4148
self.set_title(constants.APP_NAME)
4249

4350
# platform test
@@ -76,13 +83,17 @@ def make_subdirs(p, ss):
7683
pass
7784
return p
7885

79-
def useFlatpak():
80-
return constants.use_flatpak
86+
# returns the Windows drive or share from a from an absolute path
87+
def _drive_from_path(path):
88+
d = path.split(os.sep)
89+
if len(d) > 3 and d[0] == '' and d[1] == '':
90+
return os.path.join(d[:4])
91+
return d[0]
8192

8293
# constructs a relative path from 'a' to 'b', both should be absolute paths
8394
def relpath(a, b):
8495
if isWindows():
85-
if drive_from_path(a) != drive_from_path(b):
96+
if _drive_from_path(a) != _drive_from_path(b):
8697
return b
8798
c1 = [ c for c in a.split(os.sep) if c != '' ]
8899
c2 = [ c for c in b.split(os.sep) if c != '' ]
@@ -104,24 +115,25 @@ def safeRelativePath(abspath1, name, prefs, cygwin_pref):
104115
s = s.replace('/', '\\')
105116
return s
106117

107-
# returns the Windows drive or share from a from an absolute path
108-
def drive_from_path(s):
109-
c = s.split(os.sep)
110-
if len(c) > 3 and c[0] == '' and c[1] == '':
111-
return os.path.join(c[:4])
112-
return c[0]
113-
114118
# escape arguments for use with bash
115-
def bashEscape(s):
119+
def _bash_escape(s):
116120
return "'" + s.replace("'", "'\\''") + "'"
117121

122+
def _use_flatpak():
123+
return constants.use_flatpak
124+
118125
# use popen to read the output of a command
119126
def popenRead(dn, cmd, prefs, bash_pref, success_results=None):
120127
if success_results is None:
121128
success_results = [ 0 ]
122129
if isWindows() and prefs.getBool(bash_pref):
123130
# launch the command from a bash shell is requested
124-
cmd = [ prefs.convertToNativePath('/bin/bash.exe'), '-l', '-c', 'cd {}; {}'.format(bashEscape(dn), ' '.join([ bashEscape(arg) for arg in cmd ])) ]
131+
cmd = [
132+
prefs.convertToNativePath('/bin/bash.exe'),
133+
'-l',
134+
'-c',
135+
f"cd {_bash_escape(dn)}; {' '.join([ _bash_escape(arg) for arg in cmd ])}"
136+
]
125137
dn = None
126138
# use subprocess.Popen to retrieve the file contents
127139
if isWindows():
@@ -130,57 +142,26 @@ def popenRead(dn, cmd, prefs, bash_pref, success_results=None):
130142
info.wShowWindow = subprocess.SW_HIDE
131143
else:
132144
info = None
133-
if useFlatpak():
145+
if _use_flatpak():
134146
cmd = [ 'flatpak-spawn', '--host' ] + cmd
135-
proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=dn, startupinfo=info)
136-
proc.stdin.close()
137-
proc.stderr.close()
138-
fd = proc.stdout
139-
# read the command's output
140-
s = fd.read()
141-
fd.close()
142-
if proc.wait() not in success_results:
143-
raise IOError('Command failed.')
144-
return s
145-
146-
# use popen to read the output of a command
147-
def popenReadLines(dn, cmd, prefs, bash_pref, success_results=None):
148-
return strip_eols(splitlines(popenRead(dn, cmd, prefs, bash_pref, success_results).decode('utf-8', errors='ignore')))
149-
150-
# simulate use of popen with xargs to read the output of a command
151-
def popenXArgsReadLines(dn, cmd, args, prefs, bash_pref):
152-
# os.sysconf() is only available on Unix
153-
if hasattr(os, 'sysconf'):
154-
maxsize = os.sysconf('SC_ARG_MAX')
155-
maxsize -= sum([ len(k) + len(v) + 2 for k, v in os.environ.items() ])
156-
else:
157-
# assume the Window's limit to CreateProcess()
158-
maxsize = 32767
159-
maxsize -= sum([ len(k) + 1 for k in cmd ])
160-
161-
ss = []
162-
i, s, a = 0, 0, []
163-
while i < len(args):
164-
f = (len(a) == 0)
165-
if f:
166-
# start a new command line
167-
a = cmd[:]
168-
elif s + len(args[i]) + 1 <= maxsize:
169-
f = True
170-
if f:
171-
# append another argument to the current command line
172-
a.append(args[i])
173-
s += len(args[i]) + 1
174-
i += 1
175-
if i == len(args) or not f:
176-
ss.extend(popenReadLines(dn, a, prefs, bash_pref))
177-
s, a = 0, []
178-
return ss
179-
180-
# escape special glob characters
181-
def globEscape(s):
182-
m = dict([ (c, f'[{c}]') for c in '[]?*' ])
183-
return ''.join([ m.get(c, c) for c in s ])
147+
with (
148+
subprocess.Popen(
149+
cmd,
150+
stdin=subprocess.PIPE,
151+
stdout=subprocess.PIPE,
152+
stderr=subprocess.PIPE,
153+
cwd=dn,
154+
startupinfo=info) as proc
155+
):
156+
proc.stdin.close()
157+
proc.stderr.close()
158+
fd = proc.stdout
159+
# read the command's output
160+
s = fd.read()
161+
fd.close()
162+
if proc.wait() not in success_results:
163+
raise IOError('Command failed.')
164+
return s
184165

185166
# returns the number of characters in the string excluding any line ending
186167
# characters
@@ -196,20 +177,35 @@ def len_minus_line_ending(s):
196177

197178
# returns the string without the line ending characters
198179
def strip_eol(s):
199-
if s is not None:
200-
return s[:len_minus_line_ending(s)]
180+
if s:
181+
s = s[:len_minus_line_ending(s)]
182+
return s
183+
184+
# returns the list of strings without line ending characters
185+
def _strip_eols(ss):
186+
return [ strip_eol(s) for s in ss ]
187+
188+
# use popen to read the output of a command
189+
def popenReadLines(dn, cmd, prefs, bash_pref, success_results=None):
190+
return _strip_eols(splitlines(popenRead(
191+
dn, cmd, prefs, bash_pref, success_results).decode('utf-8', errors='ignore')))
192+
193+
# escape special glob characters
194+
def globEscape(s):
195+
m = { c: f'[{c}]' for c in '[]?*' }
196+
return ''.join([ m.get(c, c) for c in s ])
201197

202198
# split string into lines based upon DOS, Mac, and Unix line endings
203-
def splitlines(s):
199+
def splitlines(text: str) -> list[str]:
204200
# split on new line characters
205-
temp, i, n = [], 0, len(s)
201+
temp, i, n = [], 0, len(text)
206202
while i < n:
207-
j = s.find('\n', i)
203+
j = text.find('\n', i)
208204
if j < 0:
209-
temp.append(s[i:])
205+
temp.append(text[i:])
210206
break
211207
j += 1
212-
temp.append(s[i:j])
208+
temp.append(text[i:j])
213209
i = j
214210
# split on carriage return characters
215211
ss = []
@@ -229,7 +225,7 @@ def splitlines(s):
229225

230226
# also recognize old Mac OS line endings
231227
def readlines(fd):
232-
return [ strip_eol(s) for s in splitlines(fd.read()) ]
228+
return _strip_eols(splitlines(fd.read()))
233229

234230
# use the program's location as a starting place to search for supporting files
235231
# such as icon and help documentation
@@ -249,8 +245,8 @@ def readlines(fd):
249245
if v in os.environ:
250246
lang = os.environ[v]
251247
# remove any additional languages, encodings, or modifications
252-
for v in ':.@':
253-
lang = lang.split(v)[0]
248+
for c in ':.@':
249+
lang = lang.split(c)[0]
254250
break
255251
else:
256252
if lang is not None:

src/vcs/rcs.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,36 @@ def getCommitTemplate(self, prefs, rev, names):
5959
utils.logError(_('Error parsing revision %s.') % (rev, ))
6060
return result
6161

62+
# simulate use of popen with xargs to read the output of a command
63+
def _popen_xargs_readlines(self, dn, cmd, args, prefs, bash_pref):
64+
# os.sysconf() is only available on Unix
65+
if hasattr(os, 'sysconf'):
66+
maxsize = os.sysconf('SC_ARG_MAX')
67+
maxsize -= sum([ len(k) + len(v) + 2 for k, v in os.environ.items() ])
68+
else:
69+
# assume the Window's limit to CreateProcess()
70+
maxsize = 32767
71+
maxsize -= sum([ len(k) + 1 for k in cmd ])
72+
73+
ss = []
74+
i, s, a = 0, 0, []
75+
while i < len(args):
76+
f = (len(a) == 0)
77+
if f:
78+
# start a new command line
79+
a = cmd[:]
80+
elif s + len(args[i]) + 1 <= maxsize:
81+
f = True
82+
if f:
83+
# append another argument to the current command line
84+
a.append(args[i])
85+
s += len(args[i]) + 1
86+
i += 1
87+
if i == len(args) or not f:
88+
ss.extend(utils.popenReadLines(dn, a, prefs, bash_pref))
89+
s, a = 0, []
90+
return ss
91+
6292
def getFolderTemplate(self, prefs, names):
6393
# build command
6494
cmd = [ prefs.getString('rcs_bin_rlog'), '-L', '-h' ]
@@ -108,7 +138,7 @@ def getFolderTemplate(self, prefs, names):
108138
args = [ utils.safeRelativePath(self.root, k, prefs, 'rcs_cygwin') for k in r ]
109139
# run command
110140
r, k = {}, ''
111-
for line in utils.popenXArgsReadLines(self.root, cmd, args, prefs, 'rcs_bash'):
141+
for line in self._popen_xargs_readlines(self.root, cmd, args, prefs, 'rcs_bash'):
112142
# parse response
113143
if line.startswith('Working file: '):
114144
k = prefs.convertToNativePath(line[14:])

0 commit comments

Comments
 (0)