@@ -393,28 +393,21 @@ class CompletionResult(Iterable[str]):
393393 Class to hold completion results.
394394 """
395395
396- def __init__ (self , output : str , items : Optional [Iterable [ str ] ] = None ):
396+ def __init__ (self , output : Optional [str ] = None ):
397397 """
398- When items are specified, they are used as the base for comparisons
399- provided by this class. When not, regular expressions are used instead.
400- This is because it is not always possible to unambiguously split a
401- completion output string into individual items, for example when the
402- items contain whitespace.
403-
404398 :param output: All completion output as-is.
405- :param items: Completions as individual items. Should be specified
406- only in cases where the completions are robustly known to be
407- exactly the specified ones.
408399 """
409- self .output = output
410- self ._items = None if items is None else sorted (items )
400+ self .output = output or ""
411401
412402 def endswith (self , suffix : str ) -> bool :
413403 return self .output .endswith (suffix )
414404
415405 def startswith (self , prefix : str ) -> bool :
416406 return self .output .startswith (prefix )
417407
408+ def _items (self ) -> List [str ]:
409+ return [x .strip () for x in self .output .strip ().splitlines ()]
410+
418411 def __eq__ (self , expected : object ) -> bool :
419412 """
420413 Returns True if completion contains expected items, and no others.
@@ -428,44 +421,19 @@ def __eq__(self, expected: object) -> bool:
428421 return False
429422 else :
430423 expiter = expected
431- if self ._items is not None :
432- return self ._items == expiter
433- return bool (
434- re .match (
435- r"^\s*" + r"\s+" .join (re .escape (x ) for x in expiter ) + r"\s*$" ,
436- self .output ,
437- )
438- )
424+ return self ._items () == expiter
439425
440426 def __contains__ (self , item : str ) -> bool :
441- if self ._items is not None :
442- return item in self ._items
443- return bool (
444- re .search (r"(^|\s)%s(\s|$)" % re .escape (item ), self .output )
445- )
427+ return item in self ._items ()
446428
447429 def __iter__ (self ) -> Iterator [str ]:
448- """
449- Note that iteration over items may not be accurate when items were not
450- specified to the constructor, if individual items in the output contain
451- whitespace. In those cases, it errs on the side of possibly returning
452- more items than there actually are, and intends to never return fewer.
453- """
454- return iter (
455- self ._items
456- if self ._items is not None
457- else re .split (r" {2,}|\r\n" , self .output .strip ())
458- )
430+ return iter (self ._items ())
459431
460432 def __len__ (self ) -> int :
461- """
462- Uses __iter__, see caveat in it. While possibly inaccurate, this is
463- good enough for truthiness checks.
464- """
465- return len (list (iter (self )))
433+ return len (self ._items ())
466434
467435 def __repr__ (self ) -> str :
468- return "<CompletionResult %s>" % list ( self )
436+ return "<CompletionResult %s>" % self . _items ( )
469437
470438
471439def assert_complete (
@@ -527,14 +495,10 @@ def assert_complete(
527495 result = CompletionResult (output )
528496 elif got == 2 :
529497 output = bash .match .group (1 )
530- result = CompletionResult (
531- output ,
532- # Note that this causes returning the sole completion *unescaped*
533- [shlex .split (cmd + output )[- 1 ]],
534- )
498+ result = CompletionResult (output )
535499 else :
536500 # TODO: warn about EOF/TIMEOUT?
537- result = CompletionResult ("" , [] )
501+ result = CompletionResult ()
538502 finally :
539503 bash .sendintr ()
540504 bash .expect_exact (PS1 )
@@ -564,7 +528,7 @@ def assert_complete(
564528def completion (request , bash : pexpect .spawn ) -> CompletionResult :
565529 marker = request .node .get_closest_marker ("complete" )
566530 if not marker :
567- return CompletionResult ("" , [] )
531+ return CompletionResult ()
568532 for pre_cmd in marker .kwargs .get ("pre_cmds" , []):
569533 assert_bash_exec (bash , pre_cmd )
570534 cmd = getattr (request .cls , "cmd" , None )
@@ -630,7 +594,7 @@ def assert_complete_at_point(
630594 bash .expect (fullexpected )
631595 else :
632596 # TODO: warn about EOF/TIMEOUT?
633- result = CompletionResult ("" , [] )
597+ result = CompletionResult ()
634598
635599 return result
636600
0 commit comments