3
3
from unittest .mock import call
4
4
from code import InteractiveConsole
5
5
from contextlib import suppress
6
+ from functools import partial
7
+ import rlcompleter
8
+ import os
6
9
7
10
from _pyrepl .readline import ReadlineAlikeReader
8
11
from _pyrepl .readline import ReadlineConfig
@@ -24,10 +27,10 @@ def more_lines(unicodetext, namespace=None):
24
27
return code is None
25
28
26
29
27
- def multiline_input (reader ):
30
+ def multiline_input (reader , namespace = None ):
28
31
saved = reader .more_lines
29
32
try :
30
- reader .more_lines = more_lines
33
+ reader .more_lines = partial ( more_lines , namespace = namespace )
31
34
reader .ps1 = reader .ps2 = ">>>"
32
35
reader .ps3 = reader .ps4 = "..."
33
36
return reader .readline (returns_unicode = True )
@@ -160,6 +163,7 @@ def prepare_reader(self, events):
160
163
console = FakeConsole (events )
161
164
reader = ReadlineAlikeReader (console )
162
165
reader .config = ReadlineConfig ()
166
+ reader .config .readline_completer = None
163
167
return reader
164
168
165
169
def test_basic (self ):
@@ -294,5 +298,92 @@ def test_history_search(self):
294
298
self .assertEqual (output , "1+1" )
295
299
296
300
301
+ class TestPyReplCompleter (TestCase ):
302
+ def prepare_reader (self , events , namespace ):
303
+ console = FakeConsole (events )
304
+ reader = ReadlineAlikeReader (console )
305
+ reader .config = ReadlineConfig ()
306
+ reader .config .readline_completer = rlcompleter .Completer (namespace ).complete
307
+ return reader
308
+
309
+ def test_simple_completion (self ):
310
+ events = [
311
+ Event (evt = "key" , data = "o" , raw = bytearray (b"o" )),
312
+ Event (evt = "key" , data = "s" , raw = bytearray (b"s" )),
313
+ Event (evt = "key" , data = "." , raw = bytearray (b"." )),
314
+ Event (evt = "key" , data = "g" , raw = bytearray (b"g" )),
315
+ Event (evt = "key" , data = "e" , raw = bytearray (b"e" )),
316
+ Event (evt = "key" , data = "t" , raw = bytearray (b"t" )),
317
+ Event (evt = "key" , data = "e" , raw = bytearray (b"e" )),
318
+ Event (evt = "key" , data = "n" , raw = bytearray (b"n" )),
319
+ Event (evt = "key" , data = "\t " , raw = bytearray (b"\t " )),
320
+ Event (evt = "key" , data = "\n " , raw = bytearray (b"\n " )),
321
+ ]
322
+
323
+ namespace = {"os" : os }
324
+ reader = self .prepare_reader (events , namespace )
325
+
326
+ output = multiline_input (reader , namespace )
327
+ self .assertEqual (output , "os.getenv" )
328
+
329
+ def test_completion_with_many_options (self ):
330
+ events = [
331
+ Event (evt = "key" , data = "o" , raw = bytearray (b"o" )),
332
+ Event (evt = "key" , data = "s" , raw = bytearray (b"s" )),
333
+ Event (evt = "key" , data = "." , raw = bytearray (b"." )),
334
+ Event (evt = "key" , data = "\t " , raw = bytearray (b"\t " )),
335
+ Event (evt = "key" , data = "\t " , raw = bytearray (b"\t " )),
336
+ Event (evt = "key" , data = "O" , raw = bytearray (b"O" )),
337
+ Event (evt = "key" , data = "_" , raw = bytearray (b"_" )),
338
+ Event (evt = "key" , data = "A" , raw = bytearray (b"A" )),
339
+ Event (evt = "key" , data = "S" , raw = bytearray (b"S" )),
340
+ Event (evt = "key" , data = "\t " , raw = bytearray (b"\t " )),
341
+ Event (evt = "key" , data = "\n " , raw = bytearray (b"\n " )),
342
+ ]
343
+
344
+ namespace = {"os" : os }
345
+ reader = self .prepare_reader (events , namespace )
346
+
347
+ output = multiline_input (reader , namespace )
348
+ self .assertEqual (output , "os.O_ASYNC" )
349
+
350
+ def test_empty_namespace_completion (self ):
351
+ events = [
352
+ Event (evt = "key" , data = "o" , raw = bytearray (b"o" )),
353
+ Event (evt = "key" , data = "s" , raw = bytearray (b"s" )),
354
+ Event (evt = "key" , data = "." , raw = bytearray (b"." )),
355
+ Event (evt = "key" , data = "g" , raw = bytearray (b"g" )),
356
+ Event (evt = "key" , data = "e" , raw = bytearray (b"e" )),
357
+ Event (evt = "key" , data = "t" , raw = bytearray (b"t" )),
358
+ Event (evt = "key" , data = "e" , raw = bytearray (b"e" )),
359
+ Event (evt = "key" , data = "n" , raw = bytearray (b"n" )),
360
+ Event (evt = "key" , data = "\t " , raw = bytearray (b"\t " )),
361
+ Event (evt = "key" , data = "\n " , raw = bytearray (b"\n " )),
362
+ ]
363
+
364
+ namespace = {}
365
+ reader = self .prepare_reader (events , namespace )
366
+
367
+ output = multiline_input (reader , namespace )
368
+ self .assertEqual (output , "os.geten" )
369
+
370
+ def test_global_namespace_completion (self ):
371
+ events = [
372
+ Event (evt = "key" , data = "p" , raw = bytearray (b"p" )),
373
+ Event (evt = "key" , data = "\t " , raw = bytearray (b"\t " )),
374
+ Event (evt = "key" , data = "\n " , raw = bytearray (b"\n " )),
375
+ ]
376
+
377
+ namespace = {"python" : None }
378
+ reader = self .prepare_reader (events , namespace )
379
+
380
+ output = multiline_input (reader , namespace )
381
+ self .assertEqual (output , "python" )
382
+
383
+
384
+ if __name__ == "__main__" :
385
+ unittest .main ()
386
+
387
+
297
388
if __name__ == "__main__" :
298
389
unittest .main ()
0 commit comments