def test_init_enhanced_type_var(self): """ Verifies that Enhanced TypeVar can be initialised like any other TypeVar or directly from an existing TypeVar """ T = TypeVar('T') ET = EnhancedTypeVar('T', type_var=T) self.assertEqual(T.__name__, ET.__name__) self.assertEqual(T.__bound__, ET.__bound__) self.assertEqual(T.__covariant__, ET.__covariant__) self.assertEqual(T.__contravariant__, ET.__contravariant__) self.assertEqual(T.__constraints__, ET.__constraints__) self.assertEqual(repr(T), repr(ET)) name = 'ET' covariant = True contravariant = False bound = None constraints = (str, int) ET = EnhancedTypeVar(name, *constraints, covariant=covariant, contravariant=contravariant, bound=bound) self.assertEqual(ET.__name__, name) self.assertEqual(ET.__bound__, bound) self.assertEqual(ET.__covariant__, covariant) self.assertEqual(ET.__contravariant__, contravariant) self.assertEqual(ET.__constraints__, constraints)
def test_equality(self): """ Verifies that enhanced type variable can be compared to other enhanced variables """ ETA = EnhancedTypeVar('ET', int, str, covariant=True, contravariant=True) ETB = EnhancedTypeVar('ET', int, str, covariant=True, contravariant=True) ETC = EnhancedTypeVar('ET', int, str, covariant=True, contravariant=False) ETD = TypeVar('ET', int, str, covariant=True, contravariant=False) self.assertEqual(ETA, ETB) self.assertNotEqual(ETA, ETC) self.assertNotEqual(ETB, ETC) self.assertEqual(ETC, ETD)
def test_single_constraint(self): """ Verifies that a single constraint is not allowed and TypeError is raised """ ET = EnhancedTypeVar('ET') ET = EnhancedTypeVar('ET', int, str) with self.assertRaises(TypeError): ET = EnhancedTypeVar('ET', int)
def test_representation(self): """ Verifies that a consistent with TypeVar representation is shown when an Enhanced TypeVar is used The symbol for bivariant was randomly chosen as '*' """ ET = EnhancedTypeVar('ET', covariant=True, contravariant=True) self.assertEqual(repr(ET), '*ET') ET = EnhancedTypeVar('ET', covariant=True) self.assertEqual(repr(ET), '+ET') ET = EnhancedTypeVar('ET', contravariant=True) self.assertEqual(repr(ET), '-ET') ET = EnhancedTypeVar('ET') self.assertEqual(repr(ET), '~ET')
def test_bivariant_type_var(self): """ Verifies that it is possible to initialise a bivariant Enhanced TypeVar """ ET = EnhancedTypeVar('ET', covariant=True, contravariant=True) self.assertTrue(ET.__covariant__) self.assertTrue(ET.__contravariant__)
def test_type_var_bounded(self): """ Verifies that type checking works with bounded TypeVars It uses Enhanced TypeVars for bivariant tests as default TypeVars cannot be bivariant """ T = TypeVar('T', bound=Animal) self.assertTrue(is_type_of_type(Animal, T)) self.assertFalse(is_type_of_type(Pet, T)) self.assertFalse(is_type_of_type(Chihuahua, T)) self.assertFalse(is_type_of_type(int, T)) self.assertFalse(is_type_of_type(None, T)) T = TypeVar('T', covariant=True, bound=Animal) self.assertTrue(is_type_of_type(Animal, T)) self.assertTrue(is_type_of_type(Pet, T)) self.assertTrue(is_type_of_type(Chihuahua, T)) self.assertFalse(is_type_of_type(int, T)) self.assertFalse(is_type_of_type(None, T)) T = TypeVar('T', contravariant=True, bound=Pet) self.assertTrue(is_type_of_type(Animal, T)) self.assertTrue(is_type_of_type(Pet, T)) self.assertFalse(is_type_of_type(Chihuahua, T)) self.assertFalse(is_type_of_type(int, T)) self.assertFalse(is_type_of_type(None, T)) # Bivariant TypeVars are not supported by default # Therefore, testing it with an Enhanced version of TypeVar T = EnhancedTypeVar('T', covariant=True, contravariant=True, bound=Pet) self.assertTrue(is_type_of_type(Animal, T)) self.assertTrue(is_type_of_type(Pet, T)) self.assertTrue(is_type_of_type(Chihuahua, T)) self.assertFalse(is_type_of_type(int, T)) self.assertFalse(is_type_of_type(None, T))
def test_constraints(self): """ Verifies that enhanced variable can return its constraints further constrained by the __bound__ value Also verifies that the result is always as a tuple """ ETA = EnhancedTypeVar('ETA') ETB = EnhancedTypeVar('ETB', int, str) ETC = EnhancedTypeVar('ETC', bound=int) ETD = EnhancedTypeVar('ETD', int, str, bound=Boolean) self.assertEqual(ETA.constraints, tuple()) self.assertEqual(ETB.constraints, (int, str)) self.assertEqual(ETC.constraints, (int, )) self.assertEqual(ETD.constraints, (Boolean, )) self.assertIs(type(ETA.constraints), tuple) self.assertIs(type(ETB.constraints), tuple) self.assertIs(type(ETC.constraints), tuple) self.assertIs(type(ETD.constraints), tuple)
def test_enhanced_type_var_bivariant(self): """ Default TypeVars cannot be bivariant This test verifies if an Enhanced version of it will properly checked """ T = EnhancedTypeVar('T', Pet, int, covariant=True, contravariant=True) self.assertTrue(is_type_of_type(Animal, T)) self.assertTrue(is_type_of_type(Pet, T)) self.assertTrue(is_type_of_type(Chihuahua, T)) self.assertTrue(is_type_of_type(int, T)) self.assertFalse(is_type_of_type(None, T))
def test_enhanced_type_var(self): """ Verifies that type checking behaves exactly the same with an Enhanced TypeVar as it would with a default TypeVar """ T = EnhancedTypeVar('T', str, int, Animal) self.assertTrue(is_type_of_type(Animal, T)) self.assertTrue(is_type_of_type(int, T)) self.assertTrue(is_type_of_type(str, T)) self.assertFalse(is_type_of_type(Pet, T)) self.assertFalse(is_type_of_type(None, T))
def test_bivariant_type_var(self): class B: pass class C(B): pass class D(C): pass A = EnhancedTypeVar("A", bound=C, covariant=True, contravariant=True) b = B() c = C() d = D() type_var_func = self.get_type_var_func(type_var=A) self.assertIs(type_var_func(c), c) self.assertIs(type_var_func(b), b) self.assertIs(type_var_func(d), d) with self.assertRaises(RuntimeTypeError): type_var_func("bad")
def test_bound_and_constrained(self): """ Verifies that the Enhanced Type Variable can be both bound and constrained """ ET = EnhancedTypeVar('T', int, str, bound=Boolean)