test_rlcompleter.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import unittest
  2. from unittest.mock import patch
  3. import builtins
  4. import rlcompleter
  5. class CompleteMe:
  6. """ Trivial class used in testing rlcompleter.Completer. """
  7. spam = 1
  8. _ham = 2
  9. class TestRlcompleter(unittest.TestCase):
  10. def setUp(self):
  11. self.stdcompleter = rlcompleter.Completer()
  12. self.completer = rlcompleter.Completer(dict(spam=int,
  13. egg=str,
  14. CompleteMe=CompleteMe))
  15. # forces stdcompleter to bind builtins namespace
  16. self.stdcompleter.complete('', 0)
  17. def test_namespace(self):
  18. class A(dict):
  19. pass
  20. class B(list):
  21. pass
  22. self.assertTrue(self.stdcompleter.use_main_ns)
  23. self.assertFalse(self.completer.use_main_ns)
  24. self.assertFalse(rlcompleter.Completer(A()).use_main_ns)
  25. self.assertRaises(TypeError, rlcompleter.Completer, B((1,)))
  26. def test_global_matches(self):
  27. # test with builtins namespace
  28. self.assertEqual(sorted(self.stdcompleter.global_matches('di')),
  29. [x+'(' for x in dir(builtins) if x.startswith('di')])
  30. self.assertEqual(sorted(self.stdcompleter.global_matches('st')),
  31. [x+'(' for x in dir(builtins) if x.startswith('st')])
  32. self.assertEqual(self.stdcompleter.global_matches('akaksajadhak'), [])
  33. # test with a customized namespace
  34. self.assertEqual(self.completer.global_matches('CompleteM'),
  35. ['CompleteMe()'])
  36. self.assertEqual(self.completer.global_matches('eg'),
  37. ['egg('])
  38. # XXX: see issue5256
  39. self.assertEqual(self.completer.global_matches('CompleteM'),
  40. ['CompleteMe()'])
  41. def test_attr_matches(self):
  42. # test with builtins namespace
  43. self.assertEqual(self.stdcompleter.attr_matches('str.s'),
  44. ['str.{}('.format(x) for x in dir(str)
  45. if x.startswith('s')])
  46. self.assertEqual(self.stdcompleter.attr_matches('tuple.foospamegg'), [])
  47. expected = sorted({'None.%s%s' % (x, '(' if x != '__doc__' else '')
  48. for x in dir(None)})
  49. self.assertEqual(self.stdcompleter.attr_matches('None.'), expected)
  50. self.assertEqual(self.stdcompleter.attr_matches('None._'), expected)
  51. self.assertEqual(self.stdcompleter.attr_matches('None.__'), expected)
  52. # test with a customized namespace
  53. self.assertEqual(self.completer.attr_matches('CompleteMe.sp'),
  54. ['CompleteMe.spam'])
  55. self.assertEqual(self.completer.attr_matches('Completeme.egg'), [])
  56. self.assertEqual(self.completer.attr_matches('CompleteMe.'),
  57. ['CompleteMe.mro()', 'CompleteMe.spam'])
  58. self.assertEqual(self.completer.attr_matches('CompleteMe._'),
  59. ['CompleteMe._ham'])
  60. matches = self.completer.attr_matches('CompleteMe.__')
  61. for x in matches:
  62. self.assertTrue(x.startswith('CompleteMe.__'), x)
  63. self.assertIn('CompleteMe.__name__', matches)
  64. self.assertIn('CompleteMe.__new__(', matches)
  65. with patch.object(CompleteMe, "me", CompleteMe, create=True):
  66. self.assertEqual(self.completer.attr_matches('CompleteMe.me.me.sp'),
  67. ['CompleteMe.me.me.spam'])
  68. self.assertEqual(self.completer.attr_matches('egg.s'),
  69. ['egg.{}('.format(x) for x in dir(str)
  70. if x.startswith('s')])
  71. def test_excessive_getattr(self):
  72. """Ensure getattr() is invoked no more than once per attribute"""
  73. # note the special case for @property methods below; that is why
  74. # we use __dir__ and __getattr__ in class Foo to create a "magic"
  75. # class attribute 'bar'. This forces `getattr` to call __getattr__
  76. # (which is doesn't necessarily do).
  77. class Foo:
  78. calls = 0
  79. bar = ''
  80. def __getattribute__(self, name):
  81. if name == 'bar':
  82. self.calls += 1
  83. return None
  84. return super().__getattribute__(name)
  85. f = Foo()
  86. completer = rlcompleter.Completer(dict(f=f))
  87. self.assertEqual(completer.complete('f.b', 0), 'f.bar')
  88. self.assertEqual(f.calls, 1)
  89. def test_property_method_not_called(self):
  90. class Foo:
  91. _bar = 0
  92. property_called = False
  93. @property
  94. def bar(self):
  95. self.property_called = True
  96. return self._bar
  97. f = Foo()
  98. completer = rlcompleter.Completer(dict(f=f))
  99. self.assertEqual(completer.complete('f.b', 0), 'f.bar')
  100. self.assertFalse(f.property_called)
  101. def test_uncreated_attr(self):
  102. # Attributes like properties and slots should be completed even when
  103. # they haven't been created on an instance
  104. class Foo:
  105. __slots__ = ("bar",)
  106. completer = rlcompleter.Completer(dict(f=Foo()))
  107. self.assertEqual(completer.complete('f.', 0), 'f.bar')
  108. @unittest.mock.patch('rlcompleter._readline_available', False)
  109. def test_complete(self):
  110. completer = rlcompleter.Completer()
  111. self.assertEqual(completer.complete('', 0), '\t')
  112. self.assertEqual(completer.complete('a', 0), 'and ')
  113. self.assertEqual(completer.complete('a', 1), 'as ')
  114. self.assertEqual(completer.complete('as', 2), 'assert ')
  115. self.assertEqual(completer.complete('an', 0), 'and ')
  116. self.assertEqual(completer.complete('pa', 0), 'pass')
  117. self.assertEqual(completer.complete('Fa', 0), 'False')
  118. self.assertEqual(completer.complete('el', 0), 'elif ')
  119. self.assertEqual(completer.complete('el', 1), 'else')
  120. self.assertEqual(completer.complete('tr', 0), 'try:')
  121. self.assertEqual(completer.complete('_', 0), '_')
  122. self.assertEqual(completer.complete('match', 0), 'match ')
  123. self.assertEqual(completer.complete('case', 0), 'case ')
  124. def test_duplicate_globals(self):
  125. namespace = {
  126. 'False': None, # Keyword vs builtin vs namespace
  127. 'assert': None, # Keyword vs namespace
  128. 'try': lambda: None, # Keyword vs callable
  129. 'memoryview': None, # Callable builtin vs non-callable
  130. 'Ellipsis': lambda: None, # Non-callable builtin vs callable
  131. }
  132. completer = rlcompleter.Completer(namespace)
  133. self.assertEqual(completer.complete('False', 0), 'False')
  134. self.assertIsNone(completer.complete('False', 1)) # No duplicates
  135. # Space or colon added due to being a reserved keyword
  136. self.assertEqual(completer.complete('assert', 0), 'assert ')
  137. self.assertIsNone(completer.complete('assert', 1))
  138. self.assertEqual(completer.complete('try', 0), 'try:')
  139. self.assertIsNone(completer.complete('try', 1))
  140. # No opening bracket "(" because we overrode the built-in class
  141. self.assertEqual(completer.complete('memoryview', 0), 'memoryview')
  142. self.assertIsNone(completer.complete('memoryview', 1))
  143. self.assertEqual(completer.complete('Ellipsis', 0), 'Ellipsis()')
  144. self.assertIsNone(completer.complete('Ellipsis', 1))
  145. if __name__ == '__main__':
  146. unittest.main()