def input(self, prompt='', x=None, y=None, maxlength=None, fgcolor=None, bgcolor=None, promptfgcolor=None, promptbgcolor=None, whitelistchars=None, blacklistchars=None, callbackfn=None, fps=60, repeat=20, delay=0.25):
        clock = pygame.time.Clock()
        inputObj = PygcurseInput(self, prompt, x, y, maxlength, fgcolor, bgcolor, promptfgcolor, promptbgcolor, whitelistchars, blacklistchars, self)
        self.inputcursor = inputObj.startx, inputObj.starty

        counter = 0
        held_down = []
        while True: # the event loop
            counter += 1
            if counter >= fps//repeat:
                counter = 0
                for e, t in held_down:
                    if time.time() - t >= delay:
                        inputObj.sendkeyevent(e)

            self._inputcursormode = inputObj.insertMode and 'insert' or 'underline'

            #The only thing a callbackfn might want to have access to that it couldn't legitimately have access to
            #through closures is our inputobj - so we hand it to it! You'll also note that we call it before processing
            #the pygame event queue so that it has first pick of the incoming events.
            #Of course, we only call callbackfn if it is non-None.
            if callbackfn:
                try:
                    callbackfn(inputObj)
                except TypeError as e:
                    #However, old callbackfn()s might not expect a parameter - so if we get such an error,
                    #we just call it again without the parameter.
                    #Gotta make sure it was this specific thing that caused the error, though.
                    if e.args[0] == "callbackfn() takes 0 positional arguments but 1 was given":
                        callbackfn()
                    else:
                        #if not, reraise it.
                        raise

            #As explained in a comment in waitforkeypress, only pulling out specific event types causes the
            #program to hang if other events happen.
            for event in pygame.event.get(): # TODO - handle holding down the keys
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()

                if event.type == KEYUP:
                    held_down = [(e,t) for (e,t) in held_down if e.key != event.key]

                elif event.type == KEYDOWN:
                    if all(e[0] != event for e in held_down):
                        held_down.append((event, time.time(),))

                if event.type in (KEYDOWN, KEYUP):
                    inputObj.sendkeyevent(event)
                    if inputObj.done:
                        return ''.join(inputObj.buffer)

            inputObj.update()
            self.update()

            clock.tick(fps)
A pygcurse version of the input() and raw_input() functions. When called, it displays a cursor on the screen and lets the user type in a string. This function blocks until the user presses Enter, and it returns the string the user typed in.
dataset/ETHPy150Open asweigart/pygcurse/pygcurse/__init__.py/PygcurseSurface.input