[3.12] gh-96905: In IDLE code, stop redefining built-ins 'dict' and 'object' (GH-114227) (#114228)

Prefix 'dict' with 'o', 'g', or 'l' for 'object', 'global', or 'local'.
Suffix 'object' with '_'.
(cherry picked from commit 6f4b242a03)

Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
This commit is contained in:
Miss Islington (bot) 2024-01-18 06:09:26 +01:00 committed by GitHub
parent 35e330ba85
commit e7a5577b53
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 45 additions and 42 deletions

View file

@ -4,6 +4,8 @@ Released after 2023-10-02
========================= =========================
gh-96905: In idlelib code, stop redefining built-ins 'dict' and 'object'.
gh-72284: Improve the lists of features, editor key bindings, gh-72284: Improve the lists of features, editor key bindings,
and shell key bingings in the IDLE doc. and shell key bingings in the IDLE doc.

View file

@ -508,11 +508,11 @@ class StackViewer(ScrolledList):
class NamespaceViewer: class NamespaceViewer:
"Global/local namespace viewer for debugger GUI." "Global/local namespace viewer for debugger GUI."
def __init__(self, master, title, dict=None): def __init__(self, master, title, odict=None): # XXX odict never passed.
width = 0 width = 0
height = 40 height = 40
if dict: if odict:
height = 20*len(dict) # XXX 20 == observed height of Entry widget height = 20*len(odict) # XXX 20 == observed height of Entry widget
self.master = master self.master = master
self.title = title self.title = title
import reprlib import reprlib
@ -533,24 +533,24 @@ class NamespaceViewer:
canvas["yscrollcommand"] = vbar.set canvas["yscrollcommand"] = vbar.set
self.subframe = subframe = Frame(canvas) self.subframe = subframe = Frame(canvas)
self.sfid = canvas.create_window(0, 0, window=subframe, anchor="nw") self.sfid = canvas.create_window(0, 0, window=subframe, anchor="nw")
self.load_dict(dict) self.load_dict(odict)
dict = -1 prev_odict = -1 # Needed for initial comparison below.
def load_dict(self, dict, force=0, rpc_client=None): def load_dict(self, odict, force=0, rpc_client=None):
if dict is self.dict and not force: if odict is self.prev_odict and not force:
return return
subframe = self.subframe subframe = self.subframe
frame = self.frame frame = self.frame
for c in list(subframe.children.values()): for c in list(subframe.children.values()):
c.destroy() c.destroy()
self.dict = None self.prev_odict = None
if not dict: if not odict:
l = Label(subframe, text="None") l = Label(subframe, text="None")
l.grid(row=0, column=0) l.grid(row=0, column=0)
else: else:
#names = sorted(dict) #names = sorted(dict)
### #
# Because of (temporary) limitations on the dict_keys type (not yet # Because of (temporary) limitations on the dict_keys type (not yet
# public or pickleable), have the subprocess to send a list of # public or pickleable), have the subprocess to send a list of
# keys, not a dict_keys object. sorted() will take a dict_keys # keys, not a dict_keys object. sorted() will take a dict_keys
@ -560,12 +560,12 @@ class NamespaceViewer:
# interpreter gets into a loop requesting non-existing dict[0], # interpreter gets into a loop requesting non-existing dict[0],
# dict[1], dict[2], etc from the debugger_r.DictProxy. # dict[1], dict[2], etc from the debugger_r.DictProxy.
# TODO recheck above; see debugger_r 159ff, debugobj 60. # TODO recheck above; see debugger_r 159ff, debugobj 60.
keys_list = dict.keys() keys_list = odict.keys()
names = sorted(keys_list) names = sorted(keys_list)
###
row = 0 row = 0
for name in names: for name in names:
value = dict[name] value = odict[name]
svalue = self.repr.repr(value) # repr(value) svalue = self.repr.repr(value) # repr(value)
# Strip extra quotes caused by calling repr on the (already) # Strip extra quotes caused by calling repr on the (already)
# repr'd value sent across the RPC interface: # repr'd value sent across the RPC interface:
@ -577,7 +577,7 @@ class NamespaceViewer:
l.insert(0, svalue) l.insert(0, svalue)
l.grid(row=row, column=1, sticky="nw") l.grid(row=row, column=1, sticky="nw")
row = row+1 row = row+1
self.dict = dict self.prev_odict = odict
# XXX Could we use a <Configure> callback for the following? # XXX Could we use a <Configure> callback for the following?
subframe.update_idletasks() # Alas! subframe.update_idletasks() # Alas!
width = subframe.winfo_reqwidth() width = subframe.winfo_reqwidth()

View file

@ -125,16 +125,16 @@ class IdbAdapter:
def frame_globals(self, fid): def frame_globals(self, fid):
frame = frametable[fid] frame = frametable[fid]
dict = frame.f_globals gdict = frame.f_globals
did = id(dict) did = id(gdict)
dicttable[did] = dict dicttable[did] = gdict
return did return did
def frame_locals(self, fid): def frame_locals(self, fid):
frame = frametable[fid] frame = frametable[fid]
dict = frame.f_locals ldict = frame.f_locals
did = id(dict) did = id(ldict)
dicttable[did] = dict dicttable[did] = ldict
return did return did
def frame_code(self, fid): def frame_code(self, fid):
@ -158,20 +158,17 @@ class IdbAdapter:
def dict_keys(self, did): def dict_keys(self, did):
raise NotImplementedError("dict_keys not public or pickleable") raise NotImplementedError("dict_keys not public or pickleable")
## dict = dicttable[did] ## return dicttable[did].keys()
## return dict.keys()
### Needed until dict_keys is type is finished and pickealable. ### Needed until dict_keys type is finished and pickleable.
# xxx finished. pickleable?
### Will probably need to extend rpc.py:SocketIO._proxify at that time. ### Will probably need to extend rpc.py:SocketIO._proxify at that time.
def dict_keys_list(self, did): def dict_keys_list(self, did):
dict = dicttable[did] return list(dicttable[did].keys())
return list(dict.keys())
def dict_item(self, did, key): def dict_item(self, did, key):
dict = dicttable[did] value = dicttable[did][key]
value = dict[key] return reprlib.repr(value) # Can't pickle module 'builtins'.
value = reprlib.repr(value) ### can't pickle module 'builtins'
return value
#----------end class IdbAdapter---------- #----------end class IdbAdapter----------

View file

@ -1,3 +1,5 @@
"""Define tree items for debug stackviewer, which is only user.
"""
# XXX TO DO: # XXX TO DO:
# - popup menu # - popup menu
# - support partial or total redisplay # - support partial or total redisplay
@ -17,9 +19,9 @@ myrepr.maxstring = 100
myrepr.maxother = 100 myrepr.maxother = 100
class ObjectTreeItem(TreeItem): class ObjectTreeItem(TreeItem):
def __init__(self, labeltext, object, setfunction=None): def __init__(self, labeltext, object_, setfunction=None):
self.labeltext = labeltext self.labeltext = labeltext
self.object = object self.object = object_
self.setfunction = setfunction self.setfunction = setfunction
def GetLabelText(self): def GetLabelText(self):
return self.labeltext return self.labeltext
@ -51,8 +53,8 @@ class ObjectTreeItem(TreeItem):
item = make_objecttreeitem( item = make_objecttreeitem(
str(key) + " =", str(key) + " =",
value, value,
lambda value, key=key, object=self.object: lambda value, key=key, object_=self.object:
setattr(object, key, value)) setattr(object_, key, value))
sublist.append(item) sublist.append(item)
return sublist return sublist
@ -85,8 +87,8 @@ class SequenceTreeItem(ObjectTreeItem):
value = self.object[key] value = self.object[key]
except KeyError: except KeyError:
continue continue
def setfunction(value, key=key, object=self.object): def setfunction(value, key=key, object_=self.object):
object[key] = value object_[key] = value
item = make_objecttreeitem(f"{key!r}:", value, setfunction) item = make_objecttreeitem(f"{key!r}:", value, setfunction)
sublist.append(item) sublist.append(item)
return sublist return sublist
@ -111,13 +113,13 @@ dispatch = {
type: ClassTreeItem, type: ClassTreeItem,
} }
def make_objecttreeitem(labeltext, object, setfunction=None): def make_objecttreeitem(labeltext, object_, setfunction=None):
t = type(object) t = type(object_)
if t in dispatch: if t in dispatch:
c = dispatch[t] c = dispatch[t]
else: else:
c = ObjectTreeItem c = ObjectTreeItem
return c(labeltext, object, setfunction) return c(labeltext, object_, setfunction)
def _debug_object_browser(parent): # htest # def _debug_object_browser(parent): # htest #

View file

@ -79,6 +79,7 @@ class Get_argspecTest(unittest.TestCase):
tiptest(list.append, '(self, object, /)' + append_doc) tiptest(list.append, '(self, object, /)' + append_doc)
tiptest(List.append, '(self, object, /)' + append_doc) tiptest(List.append, '(self, object, /)' + append_doc)
tiptest([].append, '(object, /)' + append_doc) tiptest([].append, '(object, /)' + append_doc)
# The use of 'object' above matches the signature text.
tiptest(types.MethodType, tiptest(types.MethodType,
'(function, instance, /)\n' '(function, instance, /)\n'

View file

@ -158,8 +158,8 @@ class SocketIO:
s = s + " " + str(a) s = s + " " + str(a)
print(s, file=sys.__stderr__) print(s, file=sys.__stderr__)
def register(self, oid, object): def register(self, oid, object_):
self.objtable[oid] = object self.objtable[oid] = object_
def unregister(self, oid): def unregister(self, oid):
try: try:

View file

@ -106,8 +106,8 @@ class VariablesTreeItem(ObjectTreeItem):
value = self.object[key] value = self.object[key]
except KeyError: except KeyError:
continue continue
def setfunction(value, key=key, object=self.object): def setfunction(value, key=key, object_=self.object):
object[key] = value object_[key] = value
item = make_objecttreeitem(key + " =", value, setfunction) item = make_objecttreeitem(key + " =", value, setfunction)
sublist.append(item) sublist.append(item)
return sublist return sublist

View file

@ -0,0 +1 @@
In idlelib code, stop redefining built-ins 'dict' and 'object'.