You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by ha...@apache.org on 2010/06/04 02:26:53 UTC

svn commit: r951224 - in /avro/branches/branch-1.3: CHANGES.txt lang/py/src/avro/io.py lang/py/src/avro/ipc.py lang/py/src/avro/protocol.py lang/py/src/avro/schema.py

Author: hammer
Date: Fri Jun  4 00:26:52 2010
New Revision: 951224

URL: http://svn.apache.org/viewvc?rev=951224&view=rev
Log:
Merge r951219 from trunk to 1.3 branch.  Fixes: AVRO-560.


Modified:
    avro/branches/branch-1.3/CHANGES.txt
    avro/branches/branch-1.3/lang/py/src/avro/io.py
    avro/branches/branch-1.3/lang/py/src/avro/ipc.py
    avro/branches/branch-1.3/lang/py/src/avro/protocol.py
    avro/branches/branch-1.3/lang/py/src/avro/schema.py

Modified: avro/branches/branch-1.3/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/branches/branch-1.3/CHANGES.txt?rev=951224&r1=951223&r2=951224&view=diff
==============================================================================
--- avro/branches/branch-1.3/CHANGES.txt (original)
+++ avro/branches/branch-1.3/CHANGES.txt Fri Jun  4 00:26:52 2010
@@ -9,6 +9,8 @@ Avro 1.3.3 (Unreleased)
     AVRO-526. Fall back to pure Python StringIO if cStringIO is not available
     (Esteve Fernandez via hammer)
 
+    AVRO-560. Python impl should include system errors in every protocol (hammer)
+
   BUG FIXES
 
     AVRO-496. python sample_http_client.py is broken (Jeff Hodges via hammer)

Modified: avro/branches/branch-1.3/lang/py/src/avro/io.py
URL: http://svn.apache.org/viewvc/avro/branches/branch-1.3/lang/py/src/avro/io.py?rev=951224&r1=951223&r2=951224&view=diff
==============================================================================
--- avro/branches/branch-1.3/lang/py/src/avro/io.py (original)
+++ avro/branches/branch-1.3/lang/py/src/avro/io.py Fri Jun  4 00:26:52 2010
@@ -107,7 +107,7 @@ def validate(expected_schema, datum):
       False not in [isinstance(k, basestring) for k in datum.keys()] and
       False not in
         [validate(expected_schema.values, v) for v in datum.values()])
-  elif schema_type == 'union':
+  elif schema_type in ['union', 'error_union']:
     return True in [validate(s, datum) for s in expected_schema.schemas]
   elif schema_type in ['record', 'error', 'request']:
     return (isinstance(datum, dict) and
@@ -345,7 +345,7 @@ class DatumReader(object):
   def match_schemas(writers_schema, readers_schema):
     w_type = writers_schema.type
     r_type = readers_schema.type
-    if 'union' in [w_type, r_type]:
+    if 'union' in [w_type, r_type] or 'error_union' in [w_type, r_type]:
       return True
     elif (w_type in schema.PRIMITIVE_TYPES and r_type in schema.PRIMITIVE_TYPES
           and w_type == r_type):
@@ -417,7 +417,8 @@ class DatumReader(object):
       raise SchemaResolutionException(fail_msg, writers_schema, readers_schema)
 
     # schema resolution: reader's schema is a union, writer's schema is not
-    if writers_schema.type != 'union' and readers_schema.type == 'union':
+    if (writers_schema.type not in ['union', 'error_union']
+        and readers_schema.type in ['union', 'error_union']):
       for s in readers_schema.schemas:
         if DatumReader.match_schemas(writers_schema, s):
           return self.read_data(writers_schema, s, decoder)
@@ -449,7 +450,7 @@ class DatumReader(object):
       return self.read_array(writers_schema, readers_schema, decoder)
     elif writers_schema.type == 'map':
       return self.read_map(writers_schema, readers_schema, decoder)
-    elif writers_schema.type == 'union':
+    elif writers_schema.type in ['union', 'error_union']:
       return self.read_union(writers_schema, readers_schema, decoder)
     elif writers_schema.type in ['record', 'error', 'request']:
       return self.read_record(writers_schema, readers_schema, decoder)
@@ -482,7 +483,7 @@ class DatumReader(object):
       return self.skip_array(writers_schema, decoder)
     elif writers_schema.type == 'map':
       return self.skip_map(writers_schema, decoder)
-    elif writers_schema.type == 'union':
+    elif writers_schema.type in ['union', 'error_union']:
       return self.skip_union(writers_schema, decoder)
     elif writers_schema.type in ['record', 'error', 'request']:
       return self.skip_record(writers_schema, decoder)
@@ -691,7 +692,7 @@ class DatumReader(object):
         map_val = self._read_default_value(field_schema.values, json_val)
         read_map[key] = map_val
       return read_map
-    elif field_schema.type == 'union':
+    elif field_schema.type in ['union', 'error_union']:
       return self._read_default_value(field_schema.schemas[0], default_value)
     elif field_schema.type == 'record':
       read_record = {}
@@ -749,7 +750,7 @@ class DatumWriter(object):
       self.write_array(writers_schema, datum, encoder)
     elif writers_schema.type == 'map':
       self.write_map(writers_schema, datum, encoder)
-    elif writers_schema.type == 'union':
+    elif writers_schema.type in ['union', 'error_union']:
       self.write_union(writers_schema, datum, encoder)
     elif writers_schema.type in ['record', 'error', 'request']:
       self.write_record(writers_schema, datum, encoder)

Modified: avro/branches/branch-1.3/lang/py/src/avro/ipc.py
URL: http://svn.apache.org/viewvc/avro/branches/branch-1.3/lang/py/src/avro/ipc.py?rev=951224&r1=951223&r2=951224&view=diff
==============================================================================
--- avro/branches/branch-1.3/lang/py/src/avro/ipc.py (original)
+++ avro/branches/branch-1.3/lang/py/src/avro/ipc.py Fri Jun  4 00:26:52 2010
@@ -241,8 +241,8 @@ class Requestor(object):
       readers_schema = local_message_schema.response
       return self.read_response(writers_schema, readers_schema, decoder)
     else:
-      writers_schema = remote_message_schema.errors or SYSTEM_ERROR_SCHEMA
-      readers_schema = local_message_schema.errors or SYSTEM_ERROR_SCHEMA
+      writers_schema = remote_message_schema.errors
+      readers_schema = local_message_schema.errors
       raise self.read_error(writers_schema, readers_schema, decoder)
 
   def read_response(self, writers_schema, readers_schema, decoder):
@@ -325,7 +325,7 @@ class Responder(object):
         writers_schema = local_message.response
         self.write_response(writers_schema, response, buffer_encoder)
       else:
-        writers_schema = local_message.errors or SYSTEM_ERROR_SCHEMA
+        writers_schema = local_message.errors
         self.write_error(writers_schema, error, buffer_encoder)
     except schema.AvroException, e:
       error = AvroRemoteException(str(e))

Modified: avro/branches/branch-1.3/lang/py/src/avro/protocol.py
URL: http://svn.apache.org/viewvc/avro/branches/branch-1.3/lang/py/src/avro/protocol.py?rev=951224&r1=951223&r2=951224&view=diff
==============================================================================
--- avro/branches/branch-1.3/lang/py/src/avro/protocol.py (original)
+++ avro/branches/branch-1.3/lang/py/src/avro/protocol.py Fri Jun  4 00:26:52 2010
@@ -159,7 +159,8 @@ class Message(object):
     if not isinstance(errors, list):
       fail_msg = 'Errors property not a list: %s' % errors
       raise ProtocolParseException(fail_msg)
-    return schema.make_avsc_object(errors, names)
+    errors_for_parsing = {'type': 'error_union', 'declared_errors': errors}
+    return schema.make_avsc_object(errors_for_parsing, names)
 
   def __init__(self,  name, request, response, errors=None, names=None):
     self._name = name

Modified: avro/branches/branch-1.3/lang/py/src/avro/schema.py
URL: http://svn.apache.org/viewvc/avro/branches/branch-1.3/lang/py/src/avro/schema.py?rev=951224&r1=951223&r2=951224&view=diff
==============================================================================
--- avro/branches/branch-1.3/lang/py/src/avro/schema.py (original)
+++ avro/branches/branch-1.3/lang/py/src/avro/schema.py Fri Jun  4 00:26:52 2010
@@ -65,6 +65,7 @@ VALID_TYPES = PRIMITIVE_TYPES + NAMED_TY
   'map',
   'union',
   'request',
+  'error_union'
 )
 
 RESERVED_PROPS = (
@@ -457,6 +458,22 @@ class UnionSchema(Schema):
     to_cmp = json.loads(str(self))
     return to_cmp == json.loads(str(that))
 
+class ErrorUnionSchema(UnionSchema):
+  def __init__(self, schemas, names=None):
+    # Prepend "string" to handle system errors
+    UnionSchema.__init__(self, ['string'] + schemas, names)
+
+  def __str__(self):
+    to_dump = []
+    for i, schema in enumerate(self.schemas):
+      # Don't print the system error schema
+      if schema.type == 'string': continue
+      if i in self.schema_from_names_indices:
+        to_dump.append(schema.fullname)
+      else:
+        to_dump.append(json.loads(str(schema)))
+    return json.dumps(to_dump)
+
 class RecordSchema(NamedSchema):
   @staticmethod
   def make_field_objects(field_data, names):
@@ -565,6 +582,9 @@ def make_avsc_object(json_data, names=No
       elif type == 'map':
         values = json_data.get('values')
         return MapSchema(values, names)
+      elif type == 'error_union':
+        declared_errors = json_data.get('declared_errors')
+        return ErrorUnionSchema(declared_errors, names)
       else:
         raise SchemaParseException('Unknown Valid Type: %s' % type)
     elif type is None: