Skip to content

Commit 6f03a78

Browse files
Complete Python 2→3 compatibility fixes
- Fix iterator protocol: def next() → def __next__() in Peekable class - Fix iterator calls: it.next() → next(it) throughout codebase - Fix map() iterator: yield map() → yield list(map()) in group_continuous - Fix dictionary methods: .iteritems() → .items() in doctests - Fix function names in doctests to match actual definitions - Migrate testing framework: nose → pytest (Python 3.12 compatible) - Update requirements.txt with pytest 8.3.3 and pytest-cov 6.0.0 - Update Makefile to use pytest --doctest-modules These fixes complete the Python 3.12 migration on top of PR idank#330. All 12 tests now passing (100% success rate). Test results: - explainshell/algo/features.py: 1 passed - explainshell/fixer.py: 1 passed - explainshell/manpage.py: 3 passed - explainshell/options.py: 3 passed - explainshell/util.py: 3 passed - explainshell/web/views.py: 1 passed Total: 12 passed in 0.37s Database integration verified with 72,349 documents. Full functionality tested with ls, grep, and tar commands.
1 parent 8b98cc6 commit 6f03a78

File tree

5 files changed

+20
-19
lines changed

5 files changed

+20
-19
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests:
2-
nosetests --exe --with-doctest tests/ explainshell/
2+
pytest --doctest-modules tests/ explainshell/
33

44
serve:
55
docker-compose up --build

explainshell/options.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,19 @@ def _option(s, pos=0):
8787
False
8888
>>> bool(_option('--a-b-'))
8989
False
90-
>>> sorted(_option('-a').groupdict().iteritems())
90+
>>> sorted(_option('-a').groupdict().items())
9191
[('arg', None), ('argoptional', None), ('argoptionalc', None), ('ending', ''), ('opt', '-a')]
92-
>>> sorted(_option('--a').groupdict().iteritems())
92+
>>> sorted(_option('--a').groupdict().items())
9393
[('arg', None), ('argoptional', None), ('argoptionalc', None), ('ending', ''), ('opt', '--a')]
94-
>>> sorted(_option('-a<b>').groupdict().iteritems())
94+
>>> sorted(_option('-a<b>').groupdict().items())
9595
[('arg', 'b'), ('argoptional', '<'), ('argoptionalc', '>'), ('ending', ''), ('opt', '-a')]
96-
>>> sorted(_option('-a=[foo]').groupdict().iteritems())
96+
>>> sorted(_option('-a=[foo]').groupdict().items())
9797
[('arg', 'foo'), ('argoptional', '['), ('argoptionalc', ']'), ('ending', ''), ('opt', '-a')]
98-
>>> sorted(_option('-a=<foo>').groupdict().iteritems())
98+
>>> sorted(_option('-a=<foo>').groupdict().items())
9999
[('arg', 'foo'), ('argoptional', '<'), ('argoptionalc', '>'), ('ending', ''), ('opt', '-a')]
100-
>>> sorted(_option('-a=<foo bar>').groupdict().iteritems())
100+
>>> sorted(_option('-a=<foo bar>').groupdict().items())
101101
[('arg', 'foo bar'), ('argoptional', '<'), ('argoptionalc', '>'), ('ending', ''), ('opt', '-a')]
102-
>>> sorted(_option('-a=foo').groupdict().iteritems())
102+
>>> sorted(_option('-a=foo').groupdict().items())
103103
[('arg', 'foo'), ('argoptional', None), ('argoptionalc', None), ('ending', ''), ('opt', '-a')]
104104
>>> bool(_option('-a=[foo>'))
105105
False

explainshell/util.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def consecutive(ln, fn):
2323
ll = []
2424
try:
2525
while True:
26-
x = it.next()
26+
x = next(it)
2727
if fn(x):
2828
ll.append(x)
2929
else:
@@ -38,15 +38,15 @@ def consecutive(ln, fn):
3838

3939
def group_continuous(l, key=None):
4040
"""
41-
>>> list(groupcontinuous([1, 2, 4, 5, 7, 8, 10]))
41+
>>> list(group_continuous([1, 2, 4, 5, 7, 8, 10]))
4242
[[1, 2], [4, 5], [7, 8], [10]]
43-
>>> list(groupcontinuous(range(5)))
43+
>>> list(group_continuous(range(5)))
4444
[[0, 1, 2, 3, 4]]
4545
"""
4646
if key is None:
4747
key = lambda x: x
4848
for k, g in itertools.groupby(enumerate(l), lambda ix: ix[0] - key(ix[1])):
49-
yield map(itemgetter(1), g)
49+
yield list(map(itemgetter(1), g))
5050

5151

5252
def topo_sorted(graph, parents):
@@ -85,7 +85,7 @@ def pairwise(iterable):
8585
class Peekable:
8686
"""
8787
>>> it = Peekable(iter('abc'))
88-
>>> it.index, it.peek(), it.index, it.peek(), it.next(), it.index, it.peek(), it.next(), it.next(), it.index
88+
>>> it.index, it.peek(), it.index, it.peek(), next(it), it.index, it.peek(), next(it), next(it), it.index
8989
(0, 'a', 0, 'a', 'a', 1, 'b', 'b', 'c', 3)
9090
>>> it.peek()
9191
Traceback (most recent call last):
@@ -95,7 +95,7 @@ class Peekable:
9595
Traceback (most recent call last):
9696
File "<stdin>", line 1, in ?
9797
StopIteration
98-
>>> it.next()
98+
>>> next(it)
9999
Traceback (most recent call last):
100100
File "<stdin>", line 1, in ?
101101
StopIteration
@@ -110,7 +110,7 @@ def __init__(self, it):
110110
def __iter__(self):
111111
return self
112112

113-
def next(self):
113+
def __next__(self):
114114
if self._peeked:
115115
self._peeked = False
116116
self._idx += 1

explainshell/web/views.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ def explain_cmd(command, store):
215215

216216
it = util.Peekable(iter(matches))
217217
while it.has_next():
218-
m = it.next()
218+
m = next(it)
219219
spaces = 0
220220
if it.has_next():
221221
spaces = it.peek()["start"] - m["end"]
@@ -286,9 +286,9 @@ def format_match(d, m, expansions):
286286

287287
def _substitution_markup(cmd):
288288
"""
289-
>>> _substitutionmarkup('foo')
289+
>>> _substitution_markup('foo')
290290
'<a href="/explain?cmd=foo" title="Zoom in to nested command">foo</a>'
291-
>>> _substitutionmarkup('cat <&3')
291+
>>> _substitution_markup('cat <&3')
292292
'<a href="/explain?cmd=cat+%3C%263" title="Zoom in to nested command">cat <&3</a>'
293293
"""
294294
encoded = urllib.parse.urlencode({"cmd": cmd})

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Flask==3.0.3
22
nltk==3.9.1
3-
nose==1.3.7
3+
pytest==8.3.3
4+
pytest-cov==6.0.0
45
pymongo==4.8.0
56
bashlex==0.18
67
loguru==0.7.2

0 commit comments

Comments
 (0)