[ 
https://issues.apache.org/jira/browse/AVRO-2234?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16678360#comment-16678360
 ] 

ASF GitHub Bot commented on AVRO-2234:
--------------------------------------

Fokko closed pull request #337: AVRO-2234 Use MappingProxyType, not 
ImmutableDict
URL: https://github.com/apache/avro/pull/337
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/lang/py3/avro/protocol.py b/lang/py3/avro/protocol.py
index 629d2fdc4..2568fb467 100644
--- a/lang/py3/avro/protocol.py
+++ b/lang/py3/avro/protocol.py
@@ -21,6 +21,7 @@
 Protocol implementation.
 """
 
+from types import MappingProxyType
 
 import hashlib
 import json
@@ -28,8 +29,6 @@
 
 from avro import schema
 
-ImmutableDict = schema.ImmutableDict
-
 # 
------------------------------------------------------------------------------
 # Constants
 
@@ -146,8 +145,7 @@ def __init__(
 
     self._types = tuple(types)
     # Map: type full name -> type schema
-    self._type_map = (
-        ImmutableDict((type.fullname, type) for type in self._types))
+    self._type_map = MappingProxyType({type.fullname: type for type in 
self._types})
     # This assertion cannot fail unless we don't track named schemas properly:
     assert (len(self._types) == len(self._type_map)), (
         'Type list %r does not match type map: %r'
@@ -158,8 +156,7 @@ def __init__(
 
     # Map: message name -> Message
     # Note that message names are simple names unique within the protocol.
-    self._message_map = ImmutableDict(
-        items=((message.name, message) for message in self._messages))
+    self._message_map = MappingProxyType({message.name: message for message in 
self._messages})
     if len(self._messages) != len(self._message_map):
       raise ProtocolParseException(
           'Invalid protocol %s with duplicate message name: %r'
@@ -227,7 +224,7 @@ def to_json(self):
     return to_dump
 
   def __str__(self):
-    return json.dumps(self.to_json())
+    return json.dumps(self.to_json(), cls=schema.MappingProxyEncoder)
 
   def __eq__(self, that):
     to_cmp = json.loads(str(self))
@@ -319,7 +316,7 @@ def props(self):
     return self._props
 
   def __str__(self):
-    return json.dumps(self.to_json())
+    return json.dumps(self.to_json(), cls=schema.MappingProxyEncoder)
 
   def to_json(self, names=None):
     if names is None:
@@ -399,4 +396,3 @@ def Parse(json_string):
         % (json_string, exn))
 
   return ProtocolFromJSONData(json_data)
-
diff --git a/lang/py3/avro/schema.py b/lang/py3/avro/schema.py
index 7ed3b541b..0ebd41ffc 100644
--- a/lang/py3/avro/schema.py
+++ b/lang/py3/avro/schema.py
@@ -38,6 +38,7 @@
  - Null.
 """
 
+from types import MappingProxyType
 
 import abc
 import collections
@@ -45,7 +46,7 @@
 import logging
 import re
 
-logger = logging.getLogger(__name__) 
+logger = logging.getLogger(__name__)
 
 # 
------------------------------------------------------------------------------
 # Constants
@@ -149,49 +150,13 @@ class SchemaParseException(AvroException):
   """Error while parsing a JSON schema descriptor."""
   pass
 
-
 # 
------------------------------------------------------------------------------
-
-
-class ImmutableDict(dict):
-  """Dictionary guaranteed immutable.
-
-  All mutations raise an exception.
-  Behaves exactly as a dict otherwise.
-  """
-
-  def __init__(self, items=None, **kwargs):
-    if items is not None:
-      super(ImmutableDict, self).__init__(items)
-      assert (len(kwargs) == 0)
-    else:
-      super(ImmutableDict, self).__init__(**kwargs)
-
-  def __setitem__(self, key, value):
-    raise Exception(
-        'Attempting to map key %r to value %r in ImmutableDict %r'
-        % (key, value, self))
-
-  def __delitem__(self, key):
-    raise Exception(
-        'Attempting to remove mapping for key %r in ImmutableDict %r'
-        % (key, self))
-
-  def clear(self):
-    raise Exception('Attempting to clear ImmutableDict %r' % self)
-
-  def update(self, items=None, **kwargs):
-    raise Exception(
-        'Attempting to update ImmutableDict %r with items=%r, kwargs=%r'
-        % (self, args, kwargs))
-
-  def pop(self, key, default=None):
-    raise Exception(
-        'Attempting to pop key %r from ImmutableDict %r' % (key, self))
-
-  def popitem(self):
-    raise Exception('Attempting to pop item from ImmutableDict %r' % self)
-
+# Utilities
+class MappingProxyEncoder(json.JSONEncoder):
+  def default(self, obj):
+    if isinstance(obj, MappingProxyType):
+      return obj.copy()
+    return json.JSONEncoder.default(self, obj)
 
 # 
------------------------------------------------------------------------------
 
@@ -255,7 +220,7 @@ def props(self):
     Returns:
       A read-only dictionary of properties associated to this schema.
     """
-    return ImmutableDict(self._props)
+    return MappingProxyType(self._props)
 
   @property
   def other_props(self):
@@ -264,7 +229,7 @@ def other_props(self):
 
   def __str__(self):
     """Returns: the JSON representation of this schema."""
-    return json.dumps(self.to_json())
+    return json.dumps(self.to_json(), cls=MappingProxyEncoder)
 
   @abc.abstractmethod
   def to_json(self, names):
@@ -620,7 +585,7 @@ def other_props(self):
     return FilterKeysOut(items=self._props, keys=FIELD_RESERVED_PROPS)
 
   def __str__(self):
-    return json.dumps(self.to_json())
+    return json.dumps(self.to_json(), cls=MappingProxyEncoder)
 
   def to_json(self, names=None):
     if names is None:
@@ -1003,7 +968,7 @@ def _MakeFieldMap(fields):
         raise SchemaParseException(
             'Duplicate field name %r in list %r.' % (field.name, 
field_desc_list))
       field_map[field.name] = field
-    return ImmutableDict(field_map)
+    return MappingProxyType(field_map)
 
   def __init__(
       self,


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


> Use native MappingProxyType instead of hand-written ImmutableDict
> -----------------------------------------------------------------
>
>                 Key: AVRO-2234
>                 URL: https://issues.apache.org/jira/browse/AVRO-2234
>             Project: Avro
>          Issue Type: Improvement
>          Components: python
>            Reporter: Michael A. Smith
>            Priority: Major
>             Fix For: 1.9.0
>
>
> Per the rejection notice in 
> [PEP-416,|https://www.python.org/dev/peps/pep-0416/] there is no native 
> ImmutableDict in Python. However, there is a MappingProxyType that makes a 
> proxy to the mapping of a dictionary, and is fully native. For most purposes, 
> including avro's, it's a fully suitable replacement for a real ImmutableDict 
> implementation (except for a minor detail about JSON encoding that is easier 
> to solve and support than maintaining a complete implementation of 
> ImmutableDict.)
> I propose that we drop ImmutableDict and replace it with MappingProxyType.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to