[Python-Dev] [PATCH] Fix dictionary subclass semantics when used as global dictionaries (original) (raw)

Crutcher Dunnavant crutcher at gmail.com
Wed Jan 11 02:09:27 CET 2006


This is the unittest that checks it. On trunk, the global and fall through cases will fail, but they pass with the patch.

import unittest from test import test_support

class DictSubclass(dict): get_notify_func = None def getitem(self, key): if self.get_notify_func: self.get_notify_func(key) return dict.getitem(self, key)

set_notify_func = None
def __setitem__(self, key, value):
    if self.set_notify_func:
        self.set_notify_func(key)
    return dict.__setitem__(self, key, value)

del_notify_func = None
def __delitem__(self, key):
    if self.del_notify_func:
        self.del_notify_func(key)
    return dict.__delitem__(self, key)

class DictSubclassExecTest(unittest.TestCase): def test_subclassexec_setlocal(self): d = DictSubclass() l = [] d.set_notify_func = l.append exec "a = 1" in d d.set_notify_func = None self.assert_(d['a'] == 1) self.assert_('a' in l)

def test_subclassexec_getlocal(self):
    d = DictSubclass()
    l = []
    d.get_notify_func = l.append
    exec "a = 1; a" in d
    d.get_notify_func = None
    self.assert_(d['a'] == 1)
    self.assert_('a' in l)

def test_subclassexec_dellocal(self):
    d = DictSubclass()
    l = []
    d.del_notify_func = l.append
    exec "a = 1; del a" in d
    d.del_notify_func = None
    self.assert_(not d.has_key('a'))
    self.assert_('a' in l)

def test_subclassexec_setglobal(self):
    d = DictSubclass()
    l = []
    d.set_notify_func = l.append
    exec "a = 1\ndef foo():\n\tglobal a\n\tpass" in d
    d.set_notify_func = None
    self.assert_(d['a'] == 1)
    self.assert_('a' in l)

def test_subclassexec_getglobal(self):
    d = DictSubclass()
    l = []
    d.get_notify_func = l.append
    exec "a = 1; a\ndef foo():\n\tglobal a\n\tpass" in d
    d.get_notify_func = None
    self.assert_(d['a'] == 1)
    self.assert_('a' in l)

def test_subclassexec_delglobal(self):
    d = DictSubclass()
    l = []
    d.del_notify_func = l.append
    exec "a = 1; del a\ndef foo():\n\tglobal a\n\tpass" in d
    d.del_notify_func = None
    self.assert_(not d.has_key('a'))
    self.assert_('a' in l)

def test_subclassexec_getfallthrough(self):
    ld = DictSubclass()
    ll = []
    ld.get_notify_func = ll.append
    gd = DictSubclass()
    gl = []
    gd.get_notify_func = gl.append
    gd['a'] = 1
    exec 'b = a' in gd, ld
    gd.del_notify_func = None
    ld.del_notify_func = None
    self.assert_(ld['b'] == 1)
    self.assert_('a' in ll)
    self.assert_('a' in gl)

def test_main(): test_support.run_unittest( DictSubclassExecTest, )

if name == "main": test_main()

On 1/10/06, Crutcher Dunnavant <crutcher at gmail.com> wrote:

1402289

On 1/10/06, Aahz <aahz at pythoncraft.com> wrote: > On Tue, Jan 10, 2006, Crutcher Dunnavant wrote: > > > > There is an inconsistancy in the way that dictionary subclasses behave > > when they are used as as namespaces in execs. > > > > Basically, while python 2.4 permits the usage of dictionary subclasses > > for local environments, it still bypasses the subclass functions and > > uses the C API for global environments. The attached patch (and > > unittest!) addresses this issue. > > Please submit the patch to SourceForge and report back with the SF ID. > -- > Aahz (aahz at pythoncraft.com) <*> http://www.pythoncraft.com/ > > "19. A language that doesn't affect the way you think about programming, > is not worth knowing." --Alan Perlis >

-- Crutcher Dunnavant <crutcher at gmail.com> monket.samedi-studios.com

-- Crutcher Dunnavant <crutcher at gmail.com> monket.samedi-studios.com



More information about the Python-Dev mailing list