trivial class used in testing rlcompleter completer spam 1 ham 2 class testrlcompleterunittest testcase def setupself self stdcompleter rlcompleter completer self completer rlcompleter completerdictspamint eggstr completemecompleteme forces stdcompleter to bind builtins namespace self stdcompleter complete 0 def testnamespaceself class adict pass class blist pass self asserttrueself stdcompleter usemainns self assertfalseself completer usemainns self assertfalserlcompleter completera usemainns self assertraisestypeerror rlcompleter completer b1 def testglobalmatchesself test with builtins namespace self assertequalsortedself stdcompleter globalmatches di x for x in dirbuiltins if x startswith di self assertequalsortedself stdcompleter globalmatches st x for x in dirbuiltins if x startswith st self assertequalself stdcompleter globalmatches akaksajadhak test with a customized namespace self assertequalself completer globalmatches completem completeme self assertequalself completer globalmatches eg egg xxx see issue5256 self assertequalself completer globalmatches completem completeme def testattrmatchesself test with builtins namespace self assertequalself stdcompleter attrmatches str s str formatx for x in dirstr if x startswith s self assertequalself stdcompleter attrmatches tuple foospamegg expected sorted none ss x if x initsubclass else if x doc else for x in dirnone self assertequalself stdcompleter attrmatches none expected self assertequalself stdcompleter attrmatches none expected self assertequalself stdcompleter attrmatches none expected test with a customized namespace self assertequalself completer attrmatches completeme sp completeme spam self assertequalself completer attrmatches completeme egg self assertequalself completer attrmatches completeme completeme mro completeme spam self assertequalself completer attrmatches completeme completeme ham matches self completer attrmatches completeme for x in matches self asserttruex startswith completeme x self assertin completeme name matches self assertin completeme new matches with patch objectcompleteme me completeme createtrue self assertequalself completer attrmatches completeme me me sp completeme me me spam self assertequalself completer attrmatches egg s egg formatx for x in dirstr if x startswith s def testexcessivegetattrself note the special case for property methods below that is why we use dir and getattr in class foo to create a magic class attribute bar this forces getattr to call getattr which is doesn t necessarily do attributes like properties and slots should be completed even when they haven t been created on an instance space or colon added due to being a reserved keyword no opening bracket because we overrode the builtin class trivial class used in testing rlcompleter completer forces stdcompleter to bind builtins namespace test with builtins namespace test with a customized namespace xxx see issue5256 test with builtins namespace test with a customized namespace ensure getattr is invoked no more than once per attribute note the special case for property methods below that is why we use __dir__ and __getattr__ in class foo to create a magic class attribute bar this forces getattr to call __getattr__ which is doesn t necessarily do attributes like properties and slots should be completed even when they haven t been created on an instance keyword vs builtin vs namespace keyword vs namespace keyword vs callable callable builtin vs non callable non callable builtin vs callable no duplicates space or colon added due to being a reserved keyword no opening bracket because we overrode the built in class
import unittest
from unittest.mock import patch
import builtins
import rlcompleter

class CompleteMe:
    
    spam = 1
    _ham = 2


class TestRlcompleter(unittest.TestCase):
    def setUp(self):
        self.stdcompleter = rlcompleter.Completer()
        self.completer = rlcompleter.Completer(dict(spam=int,
                                                    egg=str,
                                                    CompleteMe=CompleteMe))

        
        self.stdcompleter.complete('', 0)

    def test_namespace(self):
        class A(dict):
            pass
        class B(list):
            pass

        self.assertTrue(self.stdcompleter.use_main_ns)
        self.assertFalse(self.completer.use_main_ns)
        self.assertFalse(rlcompleter.Completer(A()).use_main_ns)
        self.assertRaises(TypeError, rlcompleter.Completer, B((1,)))

    def test_global_matches(self):
        
        self.assertEqual(sorted(self.stdcompleter.global_matches('di')),
                         [x+'(' for x in dir(builtins) if x.startswith('di')])
        self.assertEqual(sorted(self.stdcompleter.global_matches('st')),
                         [x+'(' for x in dir(builtins) if x.startswith('st')])
        self.assertEqual(self.stdcompleter.global_matches('akaksajadhak'), [])

        
        self.assertEqual(self.completer.global_matches('CompleteM'),
                         ['CompleteMe()'])
        self.assertEqual(self.completer.global_matches('eg'),
                         ['egg('])
        
        self.assertEqual(self.completer.global_matches('CompleteM'),
                         ['CompleteMe()'])

    def test_attr_matches(self):
        
        self.assertEqual(self.stdcompleter.attr_matches('str.s'),
                         ['str.{}('.format(x) for x in dir(str)
                          if x.startswith('s')])
        self.assertEqual(self.stdcompleter.attr_matches('tuple.foospamegg'), [])
        expected = sorted({'None.%s%s' % (x,
                                          '()' if x == '__init_subclass__'
                                          else '' if x == '__doc__'
                                          else '(')
                           for x in dir(None)})
        self.assertEqual(self.stdcompleter.attr_matches('None.'), expected)
        self.assertEqual(self.stdcompleter.attr_matches('None._'), expected)
        self.assertEqual(self.stdcompleter.attr_matches('None.__'), expected)

        
        self.assertEqual(self.completer.attr_matches('CompleteMe.sp'),
                         ['CompleteMe.spam'])
        self.assertEqual(self.completer.attr_matches('Completeme.egg'), [])
        self.assertEqual(self.completer.attr_matches('CompleteMe.'),
                         ['CompleteMe.mro()', 'CompleteMe.spam'])
        self.assertEqual(self.completer.attr_matches('CompleteMe._'),
                         ['CompleteMe._ham'])
        matches = self.completer.attr_matches('CompleteMe.__')
        for x in matches:
            self.assertTrue(x.startswith('CompleteMe.__'), x)
        self.assertIn('CompleteMe.__name__', matches)
        self.assertIn('CompleteMe.__new__(', matches)

        with patch.object(CompleteMe, "me", CompleteMe, create=True):
            self.assertEqual(self.completer.attr_matches('CompleteMe.me.me.sp'),
                             ['CompleteMe.me.me.spam'])
            self.assertEqual(self.completer.attr_matches('egg.s'),
                             ['egg.{}('.format(x) for x in dir(str)
                              if x.startswith('s')])

    def test_excessive_getattr(self):
        

        
        
        
        
        class Foo:
            calls = 0
            bar = ''
            def __getattribute__(self, name):
                if name == 'bar':
                    self.calls += 1
                    return None
                return super().__getattribute__(name)

        f = Foo()
        completer = rlcompleter.Completer(dict(f=f))
        self.assertEqual(completer.complete('f.b', 0), 'f.bar')
        self.assertEqual(f.calls, 1)

    def test_property_method_not_called(self):
        class Foo:
            _bar = 0
            property_called = False

            @property
            def bar(self):
                self.property_called = True
                return self._bar

        f = Foo()
        completer = rlcompleter.Completer(dict(f=f))
        self.assertEqual(completer.complete('f.b', 0), 'f.bar')
        self.assertFalse(f.property_called)


    def test_uncreated_attr(self):
        
        
        class Foo:
            __slots__ = ("bar",)
        completer = rlcompleter.Completer(dict(f=Foo()))
        self.assertEqual(completer.complete('f.', 0), 'f.bar')

    @unittest.mock.patch('rlcompleter._readline_available', False)
    def test_complete(self):
        completer = rlcompleter.Completer()
        self.assertEqual(completer.complete('', 0), '\t')
        self.assertEqual(completer.complete('a', 0), 'and ')
        self.assertEqual(completer.complete('a', 1), 'as ')
        self.assertEqual(completer.complete('as', 2), 'assert ')
        self.assertEqual(completer.complete('an', 0), 'and ')
        self.assertEqual(completer.complete('pa', 0), 'pass')
        self.assertEqual(completer.complete('Fa', 0), 'False')
        self.assertEqual(completer.complete('el', 0), 'elif ')
        self.assertEqual(completer.complete('el', 1), 'else')
        self.assertEqual(completer.complete('tr', 0), 'try:')
        self.assertEqual(completer.complete('_', 0), '_')
        self.assertEqual(completer.complete('match', 0), 'match ')
        self.assertEqual(completer.complete('case', 0), 'case ')

    def test_duplicate_globals(self):
        namespace = {
            'False': None,  
            'assert': None,  
            'try': lambda: None,  
            'memoryview': None,  
            'Ellipsis': lambda: None,  
        }
        completer = rlcompleter.Completer(namespace)
        self.assertEqual(completer.complete('False', 0), 'False')
        self.assertIsNone(completer.complete('False', 1))  
        
        self.assertEqual(completer.complete('assert', 0), 'assert ')
        self.assertIsNone(completer.complete('assert', 1))
        self.assertEqual(completer.complete('try', 0), 'try:')
        self.assertIsNone(completer.complete('try', 1))
        
        self.assertEqual(completer.complete('memoryview', 0), 'memoryview')
        self.assertIsNone(completer.complete('memoryview', 1))
        self.assertEqual(completer.complete('Ellipsis', 0), 'Ellipsis()')
        self.assertIsNone(completer.complete('Ellipsis', 1))

if __name__ == '__main__':
    unittest.main()