New immutable object type that is properly frozen. Part of #155

This commit is contained in:
Daniel Greenfeld 2013-05-30 12:11:49 +02:00
parent b2fb02b976
commit 096267c674
2 changed files with 50 additions and 0 deletions

View file

@ -0,0 +1,36 @@
from django.test import TestCase
from ..types import immutable_admin_factory
class ModelAdmin(object):
model_admin_attributes = ['a', 'b', 'c']
a = 1 # covered
b = 2 # covered
c = 3 # covered
d = 4 # not covered
class ImmutableAdminFactoryTests(TestCase):
def setUp(self):
self.immutable_admin = immutable_admin_factory(ModelAdmin)
def test_immutability(self):
with self.assertRaises(AttributeError):
# can't set attribute
self.immutable_admin.a = 10
with self.assertRaises(AttributeError):
# 'ImmutableAdmin' object has no attribute 'e'
self.immutable_admin.e = 5
with self.assertRaises(AttributeError):
# can't delete attribute
del self.immutable_admin.a
def test_attributes(self):
self.assertEquals(self.immutable_admin.a, 1)
self.assertEquals(self.immutable_admin.b, 2)
self.assertEquals(self.immutable_admin.c, 3)
with self.assertRaises(AttributeError):
# 'ImmutableAdmin' object has no attribute 'd'
self.immutable_admin.d

14
djadmin2/types.py Normal file
View file

@ -0,0 +1,14 @@
from collections import namedtuple
def immutable_admin_factory(model_admin):
""" Provide an ImmutableAdmin to make it harder for developers to dig themselves into holes.
See https://github.com/twoscoops/django-admin2/issues/99
Frozen class implementation as namedtuple suggested by Audrey Roy
Note: This won't stop developers from saving mutable objects to the result, but hopefully
developers attempting that 'workaround/hack' will read our documentation.
"""
ImmutableAdmin = namedtuple("ImmutableAdmin", model_admin.model_admin_attributes, verbose=False)
return ImmutableAdmin(*[getattr(model_admin, x) for x in model_admin.model_admin_attributes])