Package proton :: Module _wrapper
[frames] | no frames]

Source Code for Module proton._wrapper

  1  # 
  2  # Licensed to the Apache Software Foundation (ASF) under one 
  3  # or more contributor license agreements.  See the NOTICE file 
  4  # distributed with this work for additional information 
  5  # regarding copyright ownership.  The ASF licenses this file 
  6  # to you under the Apache License, Version 2.0 (the 
  7  # "License"); you may not use this file except in compliance 
  8  # with the License.  You may obtain a copy of the License at 
  9  # 
 10  #   http://www.apache.org/licenses/LICENSE-2.0 
 11  # 
 12  # Unless required by applicable law or agreed to in writing, 
 13  # software distributed under the License is distributed on an 
 14  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 15  # KIND, either express or implied.  See the License for the 
 16  # specific language governing permissions and limitations 
 17  # under the License. 
 18  # 
 19   
 20  from __future__ import absolute_import 
 21   
 22  from cproton import pn_incref, pn_decref, \ 
 23      pn_py2void, pn_void2py, \ 
 24      pn_record_get, pn_record_def, pn_record_set, \ 
 25      PN_PYREF 
 26   
 27  from ._exceptions import ProtonException 
 28   
 29   
30 -class EmptyAttrs:
31
32 - def __contains__(self, name):
33 return False
34
35 - def __getitem__(self, name):
36 raise KeyError(name)
37
38 - def __setitem__(self, name, value):
39 raise TypeError("does not support item assignment")
40 41 42 EMPTY_ATTRS = EmptyAttrs() 43 44
45 -class Wrapper(object):
46 """ Wrapper for python objects that need to be stored in event contexts and be retrived again from them 47 Quick note on how this works: 48 The actual *python* object has only 3 attributes which redirect into the wrapped C objects: 49 _impl The wrapped C object itself 50 _attrs This is a special pn_record_t holding a PYCTX which is a python dict 51 every attribute in the python object is actually looked up here 52 _record This is the C record itself (so actually identical to _attrs really but 53 a different python type 54 55 Because the objects actual attributes are stored away they must be initialised *after* the wrapping 56 is set up. This is the purpose of the _init method in the wrapped object. Wrapper.__init__ will call 57 eht subclass _init to initialise attributes. So they *must not* be initialised in the subclass __init__ 58 before calling the superclass (Wrapper) __init__ or they will not be accessible from the wrapper at all. 59 60 """ 61
62 - def __init__(self, impl_or_constructor, get_context=None):
63 init = False 64 if callable(impl_or_constructor): 65 # we are constructing a new object 66 impl = impl_or_constructor() 67 if impl is None: 68 self.__dict__["_impl"] = impl 69 self.__dict__["_attrs"] = EMPTY_ATTRS 70 self.__dict__["_record"] = None 71 raise ProtonException( 72 "Wrapper failed to create wrapped object. Check for file descriptor or memory exhaustion.") 73 init = True 74 else: 75 # we are wrapping an existing object 76 impl = impl_or_constructor 77 pn_incref(impl) 78 79 if get_context: 80 record = get_context(impl) 81 attrs = pn_void2py(pn_record_get(record, PYCTX)) 82 if attrs is None: 83 attrs = {} 84 pn_record_def(record, PYCTX, PN_PYREF) 85 pn_record_set(record, PYCTX, pn_py2void(attrs)) 86 init = True 87 else: 88 attrs = EMPTY_ATTRS 89 init = False 90 record = None 91 self.__dict__["_impl"] = impl 92 self.__dict__["_attrs"] = attrs 93 self.__dict__["_record"] = record 94 if init: self._init()
95
96 - def __getattr__(self, name):
97 attrs = self.__dict__["_attrs"] 98 if name in attrs: 99 return attrs[name] 100 else: 101 raise AttributeError(name + " not in _attrs")
102
103 - def __setattr__(self, name, value):
104 if hasattr(self.__class__, name): 105 object.__setattr__(self, name, value) 106 else: 107 attrs = self.__dict__["_attrs"] 108 attrs[name] = value
109
110 - def __delattr__(self, name):
111 attrs = self.__dict__["_attrs"] 112 if attrs: 113 del attrs[name]
114
115 - def __hash__(self):
116 return hash(addressof(self._impl))
117
118 - def __eq__(self, other):
119 if isinstance(other, Wrapper): 120 return addressof(self._impl) == addressof(other._impl) 121 return False
122
123 - def __ne__(self, other):
124 if isinstance(other, Wrapper): 125 return addressof(self._impl) != addressof(other._impl) 126 return True
127
128 - def __del__(self):
129 pn_decref(self._impl)
130
131 - def __repr__(self):
132 return '<%s.%s 0x%x ~ 0x%x>' % (self.__class__.__module__, 133 self.__class__.__name__, 134 id(self), addressof(self._impl))
135 136 137 PYCTX = int(pn_py2void(Wrapper)) 138 addressof = int 139