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 <[EMAIL PROTECTED]> wrote:
> 1402289
>
> On 1/10/06, Aahz <[EMAIL PROTECTED]> 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 ([EMAIL PROTECTED])           <*>         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 <[EMAIL PROTECTED]>
> monket.samedi-studios.com
>


--
Crutcher Dunnavant <[EMAIL PROTECTED]>
monket.samedi-studios.com
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to