Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 15 additions & 58 deletions Lib/idlelib/autocomplete.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,10 @@
import string
import sys

# These constants represent the two different types of completions.
# They must be defined here so autocomple_w can import them.
COMPLETE_ATTRIBUTES, COMPLETE_FILES = range(1, 2+1)

from idlelib import autocomplete_w
from idlelib.config import idleConf
from idlelib.hyperparser import HyperParser
import __main__
from idlelib.run import COMPLETE_ATTRIBUTES, COMPLETE_FILES, completion_list
from idlelib import autocomplete_w

# This string includes all chars that may be in an identifier.
# TODO Update this here and elsewhere.
Expand Down Expand Up @@ -158,74 +154,35 @@ def open_completions(self, evalfuncs, complete, userWantsWin, mode=None):
return None
comp_lists = self.fetch_completions(comp_what, mode)
if not comp_lists[0]:
return None
return None, 1
self.autocompletewindow = self._make_autocomplete_window()
return not self.autocompletewindow.show_window(
comp_lists, "insert-%dc" % len(comp_start),
complete, mode, userWantsWin)

def fetch_completions(self, what, mode):
"""Return a pair of lists of completions for something. The first list
is a sublist of the second. Both are sorted.
"""Return a pair of sorted lists of completions for something.

The first list is a sublist of the second.

If there is a Python subprocess, get the comp. list there. Otherwise,
either fetch_completions() is running in the subprocess itself or it
was called in an IDLE EditorWindow before any script had been run.
If there is a Python subprocess, get the list there. Otherwise,
IDLE is running in a single process or fetch_completions() was
called in an IDLE EditorWindow before any script had been run.

The subprocess environment is that of the most recently run script. If
two unrelated modules are being edited some calltips in the current
module may be inoperative if the module was not the last to run.
The subprocess environment is that of the most recently run
script. If two unrelated modules are being edited some calltips
in the current module may be inoperative if the module was not
the last to run.
"""
try:
rpcclt = self.editwin.flist.pyshell.interp.rpcclt
except:
except AttributeError:
rpcclt = None
if rpcclt:
return rpcclt.remotecall("exec", "get_the_completion_list",
(what, mode), {})
else:
if mode == COMPLETE_ATTRIBUTES:
if what == "":
namespace = __main__.__dict__.copy()
namespace.update(__main__.__builtins__.__dict__)
bigl = eval("dir()", namespace)
bigl.sort()
if "__all__" in bigl:
smalll = sorted(eval("__all__", namespace))
else:
smalll = [s for s in bigl if s[:1] != '_']
else:
try:
entity = self.get_entity(what)
bigl = dir(entity)
bigl.sort()
if "__all__" in bigl:
smalll = sorted(entity.__all__)
else:
smalll = [s for s in bigl if s[:1] != '_']
except:
return [], []

elif mode == COMPLETE_FILES:
if what == "":
what = "."
try:
expandedpath = os.path.expanduser(what)
bigl = os.listdir(expandedpath)
bigl.sort()
smalll = [s for s in bigl if s[:1] != '.']
except OSError:
return [], []

if not smalll:
smalll = bigl
return smalll, bigl

def get_entity(self, name):
"""Lookup name in a namespace spanning sys.modules and __main.dict__"""
namespace = sys.modules.copy()
namespace.update(__main__.__dict__)
return eval(name, namespace)
return completion_list(what, mode)


if __name__ == '__main__':
Expand Down
7 changes: 1 addition & 6 deletions Lib/idlelib/idle_test/test_autocomplete.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
''' Test autocomplete and autocomple_w
''' Test idlelib.autocomplete and idlelib.autocomple_w

Coverage of autocomple: 56%
'''
Expand Down Expand Up @@ -139,11 +139,6 @@ def test_fetch_completions(self):
# and a small list containing files that do not start with '.'
pass

def test_get_entity(self):
# Test that a name is in the namespace of sys.modules and
# __main__.__dict__
pass


if __name__ == '__main__':
unittest.main(verbosity=2)
58 changes: 55 additions & 3 deletions Lib/idlelib/run.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import io
import linecache
import os
import queue
import sys
import time
Expand All @@ -10,7 +11,6 @@

import tkinter # Tcl, deletions, messagebox if startup fails

from idlelib import autocomplete # AutoComplete, fetch_encodings
from idlelib import calltips # CallTips
from idlelib import debugger_r # start_debugger
from idlelib import debugobj_r # remote_object_tree_item
Expand Down Expand Up @@ -440,13 +440,64 @@ def decode_interrupthook(self):
thread.interrupt_main()


# Functions used in Executive methods and sometimes in IDLE process.
# Constants and completion_list are imported into autocomplete.

# Define the two different types of completions.
COMPLETE_ATTRIBUTES, COMPLETE_FILES = 1, 2


def completion_list(what, mode):
"""Return a pair of sorted lists of completions for something.

The first list is a sublist of the second.
"""
if mode == COMPLETE_ATTRIBUTES:
if what == "":
namespace = __main__.__dict__.copy()
namespace.update(__main__.__builtins__.__dict__)
big = eval("dir()", namespace)
big.sort()
if "__all__" in big:
small = sorted(eval("__all__", namespace))
else:
small = [s for s in big if s[:1] != '_']
else:
try:
namespace = sys.modules.copy()
namespace.update(__main__.__dict__)
entity = eval(name, namespace)
big = dir(entity)
big.sort()
if "__all__" in big:
small = sorted(entity.__all__)
else:
small = [s for s in big if s[:1] != '_']
except:
return [], []

elif mode == COMPLETE_FILES:
if what == "":
what = "."
try:
expandedpath = os.path.expanduser(what)
big = os.listdir(expandedpath)
big.sort()
small = [s for s in big if s[:1] != '.']
except OSError:
return [], []

if not small:
small = big
return small, big

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line has trailing whitespace.


class Executive(object):

def __init__(self, rpchandler):
self.rpchandler = rpchandler
self.locals = __main__.__dict__
self.calltip = calltips.CallTips()
self.autocomplete = autocomplete.AutoComplete()

def runcode(self, code):
global interruptable
Expand Down Expand Up @@ -488,7 +539,7 @@ def get_the_calltip(self, name):
return self.calltip.fetch_tip(name)

def get_the_completion_list(self, what, mode):
return self.autocomplete.fetch_completions(what, mode)
return completion_list(what, mode)

def stackviewer(self, flist_oid=None):
if self.usr_exc_info:
Expand All @@ -505,4 +556,5 @@ def stackviewer(self, flist_oid=None):
item = stackviewer.StackTreeItem(flist, tb)
return debugobj_r.remote_object_tree_item(item)


capture_warnings(False) # Make sure turned off; see issue 18081