def test_subtype_abstract(self): import abc class AbstractClass(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod def define_me(self): pass SubAbstractClass = subtype( of=AbstractClass, name="SubAbstractClass", where=lambda v: v.define_me() > 0 ) self.assertEqual( str(SubAbstractClass), "<ABCMetaSubtype SubAbstractClass of AbstractClass>", ) class ConcreteClass(AbstractClass): def __init__(self, what): self.what = what def define_me(self): return self.what self.assertIsInstance(ConcreteClass(1), SubAbstractClass) self.assertNotIsInstance(ConcreteClass(-1), SubAbstractClass)
def test_subtype_subtype(self): NaturalNumber = subtype( of=int, name="NaturalNumber", where=lambda i: i > 0, ) SmallNaturalNumber = subtype( of=NaturalNumber, name="SmallNaturalNumber", where=lambda i: i <= 100, ) self.assertTrue(issubclass(SmallNaturalNumber, NaturalNumber)) self.assertTrue(issubclass(SmallNaturalNumber, int)) self.assertTrue(isinstance(10, SmallNaturalNumber)) self.assertFalse(isinstance(101, SmallNaturalNumber)) self.assertFalse(isinstance(0, SmallNaturalNumber))
def test_subtype_coerce(self): NaturalNumber = subtype( of=int, name="NaturalNumber", where=lambda i: i > 0, ) self.assertEqual(NaturalNumber(3), 3) with self.assertRaises(exc.CoercionError): NaturalNumber(-3) ScalarNaturalNumber = subtype( of=int, name="ScalarNaturalNumber", where=lambda i: i > 0, coerce=lambda i: abs(i), ) self.assertEqual(ScalarNaturalNumber(3), 3) self.assertEqual(ScalarNaturalNumber(-3), 3) self.assertRaises(TypeError, ScalarNaturalNumber, 0)
def test_sub_types(self): NaturalNumber = subtype( of=int, name="NaturalNumber", where=lambda i: i > 0, ) self.assertIsInstance(NaturalNumber, type) self.assertTrue(issubclass(NaturalNumber, int)) self.assertIsInstance(50, NaturalNumber) self.assertFalse(isinstance(-50, NaturalNumber)) self.assertEqual(str(NaturalNumber), "<subtype NaturalNumber of int>") BigNaturalNumber = subtype( of=long, name="BigNaturalNumber", where=lambda i: i > 0, ) class NaturalBornObject(Record): count = Property( isa=(NaturalNumber, BigNaturalNumber), coerce=lambda x: ( abs(int(x)) if abs(long(x)) < sys.maxint else abs(long(x)) ), check=lambda N: N > 0, ) nbo = NaturalBornObject() # regular coercions: type mismatches nbo.count = "256" self.assertEqual(nbo.count, 256) nbo.count = 1.832e19 self.assertEqual(nbo.count, 18320000000000000000L) # type matches, but subtype doesn't nbo.count = -10 self.assertEqual(nbo.count, 10) with self.assertRaises(TypeError): nbo.count = 0.5
def test_squash_coerce(self): # tests that coerce to None on initialization works MaybeNaturalNumber = subtype( "MaybeNaturalNumber", int, where=lambda i: i > 0, coerce=lambda i: abs(int(i)) or None, ) class Squasher(Record): number_or_none = Property(isa=MaybeNaturalNumber) s = Squasher(number_or_none=0) with self.assertRaises(AttributeError): s.number_or_none