Author: philz
Date: Mon Apr 22 17:50:57 2013
New Revision: 1470635
URL: http://svn.apache.org/r1470635
Log:
AVRO-1296. Python: Fix schemas retrieved from protocol types to not ignore
namespaces. Contributed by Jeremy Kahn.
Modified:
avro/trunk/CHANGES.txt
avro/trunk/lang/py/src/avro/protocol.py
avro/trunk/lang/py/src/avro/schema.py
avro/trunk/lang/py/test/test_protocol.py
Modified: avro/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1470635&r1=1470634&r2=1470635&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Mon Apr 22 17:50:57 2013
@@ -30,6 +30,9 @@ Trunk (not yet released)
BUG FIXES
+ AVRO-1296. Python: Fix schemas retrieved from protocol types
+ to not ignore namespaces. (Jeremy Kahn via philz)
+
AVRO-1266. Java: Fix mapred.AvroMultipleOutputs to support multiple
different schemas. (Ashish Nagavaram via martinkl)
Modified: avro/trunk/lang/py/src/avro/protocol.py
URL:
http://svn.apache.org/viewvc/avro/trunk/lang/py/src/avro/protocol.py?rev=1470635&r1=1470634&r2=1470635&view=diff
==============================================================================
--- avro/trunk/lang/py/src/avro/protocol.py (original)
+++ avro/trunk/lang/py/src/avro/protocol.py Mon Apr 22 17:50:57 2013
@@ -123,7 +123,7 @@ class Protocol(object):
def to_json(self):
to_dump = {}
to_dump['protocol'] = self.name
- names = schema.Names()
+ names = schema.Names(default_namespace=self.namespace)
if self.namespace:
to_dump['namespace'] = self.namespace
if self.types:
Modified: avro/trunk/lang/py/src/avro/schema.py
URL:
http://svn.apache.org/viewvc/avro/trunk/lang/py/src/avro/schema.py?rev=1470635&r1=1470634&r2=1470635&view=diff
==============================================================================
--- avro/trunk/lang/py/src/avro/schema.py (original)
+++ avro/trunk/lang/py/src/avro/schema.py Mon Apr 22 17:50:57 2013
@@ -234,7 +234,24 @@ class Names(object):
if not self.names.has_key(test):
return None
return self.names[test]
-
+
+ def prune_namespace(self, properties):
+ """given a properties, return properties with namespace removed if
+ it matches the own default namespace"""
+ if self.default_namespace is None:
+ # I have no default -- no change
+ return properties
+ if 'namespace' not in properties:
+ # he has no namespace - no change
+ return properties
+ if properties['namespace'] != self.default_namespace:
+ # we're different - leave his stuff alone
+ return properties
+ # we each have a namespace and it's redundant. delete his.
+ prunable = properties.copy()
+ del(prunable['namespace'])
+ return prunable
+
def add_name(self, name_attr, space_attr, new_schema):
"""
Add a new schema object to the name set.
@@ -414,7 +431,7 @@ class FixedSchema(NamedSchema):
return self.name_ref(names)
else:
names.names[self.fullname] = self
- return self.props
+ return names.prune_namespace(self.props)
def __eq__(self, that):
return self.props == that.props
@@ -450,7 +467,7 @@ class EnumSchema(NamedSchema):
return self.name_ref(names)
else:
names.names[self.fullname] = self
- return self.props
+ return names.prune_namespace(self.props)
def __eq__(self, that):
return self.props == that.props
@@ -671,7 +688,7 @@ class RecordSchema(NamedSchema):
else:
names.names[self.fullname] = self
- to_dump = self.props.copy()
+ to_dump = names.prune_namespace(self.props.copy())
to_dump['fields'] = [ f.to_json(names) for f in self.fields ]
return to_dump
@@ -709,7 +726,7 @@ def make_avsc_object(json_data, names=No
return PrimitiveSchema(type)
elif type in NAMED_TYPES:
name = json_data.get('name')
- namespace = json_data.get('namespace')
+ namespace = json_data.get('namespace', names.default_namespace)
if type == 'fixed':
size = json_data.get('size')
return FixedSchema(name, namespace, size, names, other_props)
Modified: avro/trunk/lang/py/test/test_protocol.py
URL:
http://svn.apache.org/viewvc/avro/trunk/lang/py/test/test_protocol.py?rev=1470635&r1=1470634&r2=1470635&view=diff
==============================================================================
--- avro/trunk/lang/py/test/test_protocol.py (original)
+++ avro/trunk/lang/py/test/test_protocol.py Mon Apr 22 17:50:57 2013
@@ -38,9 +38,7 @@ class ExampleProtocol(object):
#
# Example Protocols
#
-
-EXAMPLES = [
- ExampleProtocol("""\
+HELLO_WORLD = ExampleProtocol("""\
{
"namespace": "com.acme",
"protocol": "HelloWorld",
@@ -60,7 +58,9 @@ EXAMPLES = [
}
}
}
- """, True),
+ """, True)
+EXAMPLES = [
+ HELLO_WORLD,
ExampleProtocol("""\
{"namespace": "org.apache.avro.test",
"protocol": "Simple",
@@ -364,6 +364,23 @@ class TestProtocol(unittest.TestCase):
(num_correct, len(EXAMPLES))
self.assertEqual(num_correct, len(EXAMPLES), fail_msg)
+ def test_inner_namespace_set(self):
+ print ''
+ print 'TEST INNER NAMESPACE'
+ print '==================='
+ print ''
+ proto = protocol.parse(HELLO_WORLD.protocol_string)
+ self.assertEqual(proto.namespace, "com.acme")
+ greeting_type = proto.types_dict['Greeting']
+ self.assertEqual(greeting_type.namespace, 'com.acme')
+
+ def test_inner_namespace_not_rendered(self):
+ proto = protocol.parse(HELLO_WORLD.protocol_string)
+ self.assertEqual('com.acme.Greeting', proto.types[0].fullname)
+ self.assertEqual('Greeting', proto.types[0].name)
+ # but there shouldn't be 'namespace' rendered to json on the inner type
+ self.assertNotIn('namespace', proto.to_json()['types'][0])
+
def test_valid_cast_to_string_after_parse(self):
"""
Test that the string generated by an Avro Protocol object