@@ -72,6 +72,20 @@ class ParseError(Exception):
72
72
pass
73
73
74
74
75
+ class InvalidSchemaSpecification (object ):
76
+ """
77
+ Utility class that can be used to raise an exception on schema usage.
78
+
79
+ This is used in the schema store as a placeholder for invalid schemas. Instead of raising when a schema is
80
+ registered in the store, something that happens on import, we use this class to raise on usage.
81
+ """
82
+ def __init__ (self , exception_msg ):
83
+ self .exception_msg = exception_msg
84
+
85
+ def __getattr__ (self , item ):
86
+ raise ValueError (self .exception_msg )
87
+
88
+
75
89
class SchemaStore (object ):
76
90
def __init__ (self ):
77
91
self ._schema_map = {}
@@ -86,8 +100,9 @@ def add_record(self, schema, _bump_stack_level=False):
86
100
Can be used as a class decorator
87
101
"""
88
102
full_name = get_full_name (schema )
89
- self ._force_add (full_name , schema , _bump_stack_level )
90
- if '.' in full_name and schema .__name__ not in self ._schema_map :
103
+ has_namespace = '.' in full_name
104
+ self ._force_add (full_name , schema , _bump_stack_level , _raise_on_existing = has_namespace )
105
+ if has_namespace and schema .__name__ not in self ._schema_map :
91
106
self ._force_add (schema .__name__ , schema , _bump_stack_level )
92
107
return schema
93
108
@@ -109,9 +124,9 @@ def add_enum(self, enum_definition):
109
124
# return the definition to allow the method to be used as a decorator
110
125
return enum_definition
111
126
112
- def _force_add (self , used_name , schema , _bump_stack_level = False ):
127
+ def _force_add (self , used_name , schema , _bump_stack_level = False , _raise_on_existing = False ):
113
128
existing = self ._schema_map .get (used_name , None )
114
- if existing :
129
+ if existing and existing != schema :
115
130
full_name = get_full_name (schema )
116
131
explanation = "(actually {0})" .format () if full_name != used_name else ""
117
132
@@ -122,6 +137,16 @@ def _force_add(self, used_name, schema, _bump_stack_level=False):
122
137
prev_module = existing .__module__ ,
123
138
new_module = schema .__module__ ),
124
139
stacklevel = 4 if _bump_stack_level else 3 )
140
+
141
+ if _raise_on_existing :
142
+ if not isinstance (existing , InvalidSchemaSpecification ):
143
+ schema = InvalidSchemaSpecification (
144
+ 'Attempted to access data from a dubious schema specification. '
145
+ 'The schema for: {used_name} was provided by both {existing} and {new}'
146
+ .format (used_name = used_name , existing = existing , new = schema ))
147
+ else :
148
+ schema = existing
149
+
125
150
self ._schema_map [used_name ] = schema
126
151
127
152
def get (self , record_name ):
0 commit comments