# HG changeset patch # User Paul Boddie # Date 1480203230 -3600 # Node ID 41e0c7358ddf6ec5371eb9e4089a45bfbe0940f0 # Parent d35cdc51ff845ca8ee2240d67aed67396bd7adf0 Introduced the remaining store operations, raising TypeError for class-relative assignments via instances, permitting object-relative accesses and signalling inappropriate accessors at run-time. diff -r d35cdc51ff84 -r 41e0c7358ddf templates/ops.c --- a/templates/ops.c Sat Nov 26 23:07:09 2016 +0100 +++ b/templates/ops.c Sun Nov 27 00:33:50 2016 +0100 @@ -41,6 +41,14 @@ return 1; } +int __get_class_and_store(__ref obj, int pos, __attr value) +{ + /* Forbid class-relative assignments. */ + + __raise_type_error(); + return 0; +} + /* Introspection. */ int __is_instance(__ref obj) @@ -124,6 +132,14 @@ /* Attribute testing and storage operations. */ +int __check_and_store_via_class(__ref obj, int pos, int code, __attr value) +{ + /* Forbid class-relative assignments. */ + + __raise_type_error(); + return 0; +} + int __check_and_store_via_object(__ref obj, int pos, int code, __attr value) { if (__HASATTR(obj, pos, code)) @@ -131,6 +147,10 @@ __store_via_object(obj, pos, value); return 1; } + + /* No suitable attribute. */ + + __raise_type_error(); return 0; } @@ -138,7 +158,11 @@ { if (__check_and_store_via_object(obj, pos, code, value)) return 1; - return __check_and_store_via_object(__get_class(obj), pos, code, value); + + /* Forbid class-relative assignments. */ + + __raise_type_error(); + return 0; } /* Context-related operations. */ diff -r d35cdc51ff84 -r 41e0c7358ddf templates/ops.h --- a/templates/ops.h Sat Nov 26 23:07:09 2016 +0100 +++ b/templates/ops.h Sun Nov 27 00:33:50 2016 +0100 @@ -19,6 +19,7 @@ /* Direct storage operations. */ int __store_via_object(__ref obj, int pos, __attr value); +int __get_class_and_store(__ref obj, int pos, __attr value); /* Introspection. */ @@ -43,6 +44,7 @@ /* Attribute testing and storage operations. */ +int __check_and_store_via_class(__ref obj, int pos, int code, __attr value); int __check_and_store_via_object(__ref obj, int pos, int code, __attr value); int __check_and_store_via_any(__ref obj, int pos, int code, __attr value); diff -r d35cdc51ff84 -r 41e0c7358ddf tests/attr_providers.py --- a/tests/attr_providers.py Sat Nov 26 23:07:09 2016 +0100 +++ b/tests/attr_providers.py Sun Nov 27 00:33:50 2016 +0100 @@ -1,6 +1,7 @@ class C: def __init__(self): self.a = 1 + self.c = 3 b = 2 @@ -22,11 +23,35 @@ x.a = 7 x.b = 8 + return f(x) + +def h(x): + x.c + x.a = 4 + x.b + return f(x) c = C() d = D() e = E() -result1 = f(c) # (1, 2) -result2 = f(d) # (3, 4) -result3 = f(e) # (5, 6) +print f(c) # (1, 2) +print f(d) # (3, 4) +print f(e) # (5, 6) +print f(E) # (5, 6) + +try: + print g(c) # should fail with an error caused by a test +except TypeError: + print "g(c): c is not a suitable argument." + +print g(d) # (7, 8) + +try: + print g(e) # should fail with an error caused by a test +except TypeError: + print "g(e): e is not a suitable argument." + +print g(E) # (7, 8) + +print h(c) # (4, 5)