]> granicus.if.org Git - libnl/commitdiff
netlink.nlattr re-implemented in more pythonic way
authorКоренберг Марк <mark@ideco.ru>
Thu, 7 Jun 2012 07:48:06 +0000 (13:48 +0600)
committerКоренберг Марк (ноутбук дома) <socketpair@gmail.com>
Fri, 8 Jun 2012 16:26:35 +0000 (22:26 +0600)
python/netlink/core.py
python/netlink/route/address.py
python/netlink/route/link.py
python/netlink/route/links/inet.py
python/netlink/route/links/vlan.py
python/netlink/route/qdisc/htb.py
python/netlink/route/tc.py
python/netlink/util.py

index 23286b5a0c4fbfaaf030e3327c2ac2267a70f7de..05420ef0b35c7a439620ba43ec72d4b9be99c4f8 100644 (file)
@@ -381,21 +381,6 @@ class Object(object):
         obj, attr = self._resolve(attr)
         return hasattr(obj, attr)
 
-    def apply(self, attr, val):
-        try:
-            d = attrs[self._name + '.' + attr]
-        except KeyError:
-            raise KeyError('Unknown ' + self._name +
-                       ' attribute: ' + attr)
-
-        if 'immutable' in d:
-            raise ImmutableError(attr)
-
-        if not self._hasattr(attr):
-            raise KeyError('Invalid ' + self._name +
-                       ' attribute: ' + attr)
-        self._setattr(attr, val)
-
 class ObjIterator(object):
     def __init__(self, cache, obj):
         self._cache = cache
@@ -733,42 +718,27 @@ class AbstractAddress(object):
         capi.nl_addr_set_family(self._nl_addr, int(value))
 
 
-# global dictionay for all object attributes
-#
-# attrs[type][keyword] : value
-#
 # keyword:
 #   type = { int | str }
 #   immutable = { True | False }
 #   fmt = func (formatting function)
-#
-attrs = {}
-
-def add_attr(name, **kwds):
-    attrs[name] = {}
-    for k in kwds:
-        attrs[name][k] = kwds[k]
+#   title = string
 
-def nlattr(name, **kwds):
+def nlattr(**kwds):
     """netlink object attribute decorator
 
     decorator used to mark mutable and immutable properties
     of netlink objects. All properties marked as such are
     regarded to be accessable.
 
-    @netlink.nlattr('my_type.my_attr', type=int)
     @property
+    @netlink.nlattr(type=int)
     def my_attr(self):
         return self._my_attr
 
     """
 
-    attrs[name] = {}
-    for k in kwds:
-        attrs[name][k] = kwds[k]
-
     def wrap_fn(func):
+        func.formatinfo = kwds
         return func
-
     return wrap_fn
-
index 42c50598795c6ce0fb20f4e10eaa74536206ba4c..cab2a97ba18e9158075f0714779eb8ea1f2edb13 100644 (file)
@@ -86,9 +86,8 @@ class Address(netlink.Object):
     def _new_instance(obj):
         return Address(obj)
 
-    @netlink.nlattr('address.ifindex', type=int, immutable=True,
-            fmt=util.num)
     @property
+    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
     def ifindex(self):
         """interface index"""
         return capi.rtnl_addr_get_ifindex(self._rtnl_addr)
@@ -101,8 +100,8 @@ class Address(netlink.Object):
 
         self.link = link
 
-    @netlink.nlattr('address.link', type=str, fmt=util.string)
     @property
+    @netlink.nlattr(type=str, fmt=util.string)
     def link(self):
         link = capi.rtnl_addr_get_link(self._rtnl_addr)
         if not link:
@@ -125,8 +124,8 @@ class Address(netlink.Object):
         if capi.rtnl_addr_get_ifindex(self._orig) == 0:
             capi.rtnl_addr_set_ifindex(self._orig, value.ifindex)
 
-    @netlink.nlattr('address.label', type=str, fmt=util.string)
     @property
+    @netlink.nlattr(type=str, fmt=util.string)
     def label(self):
         """address label"""
         return capi.rtnl_addr_get_label(self._rtnl_addr)
@@ -135,8 +134,8 @@ class Address(netlink.Object):
     def label(self, value):
         capi.rtnl_addr_set_label(self._rtnl_addr, value)
 
-    @netlink.nlattr('address.flags', type=str, fmt=util.string)
     @property
+    @netlink.nlattr(type=str, fmt=util.string)
     def flags(self):
         """Flags
 
@@ -170,9 +169,8 @@ class Address(netlink.Object):
         else:
             self._set_flag(value)
 
-    @netlink.nlattr('address.family', type=int, immutable=True,
-            fmt=util.num)
     @property
+    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
     def family(self):
         """Address family"""
         fam = capi.rtnl_addr_get_family(self._rtnl_addr)
@@ -185,8 +183,8 @@ class Address(netlink.Object):
 
         capi.rtnl_addr_set_family(self._rtnl_addr, int(value))
 
-    @netlink.nlattr('address.scope', type=int, fmt=util.num)
     @property
+    @netlink.nlattr(type=int, fmt=util.num)
     def scope(self):
         """Address scope"""
         scope = capi.rtnl_addr_get_scope(self._rtnl_addr)
@@ -198,9 +196,8 @@ class Address(netlink.Object):
             value = capi.rtnl_str2scope(value)
         capi.rtnl_addr_set_scope(self._rtnl_addr, value)
 
-    @netlink.nlattr('address.local', type=str, immutable=True,
-            fmt=util.addr)
     @property
+    @netlink.nlattr(type=str, immutable=True, fmt=util.addr)
     def local(self):
         """Local address"""
         a = capi.rtnl_addr_get_local(self._rtnl_addr)
@@ -216,8 +213,8 @@ class Address(netlink.Object):
         if capi.rtnl_addr_get_local(self._orig) is None:
             capi.rtnl_addr_set_local(self._orig, a._nl_addr)
 
-    @netlink.nlattr('address.peer', type=str, fmt=util.addr)
     @property
+    @netlink.nlattr(type=str, fmt=util.addr)
     def peer(self):
         """Peer address"""
         a = capi.rtnl_addr_get_peer(self._rtnl_addr)
@@ -228,8 +225,8 @@ class Address(netlink.Object):
         a = netlink.AbstractAddress(value)
         capi.rtnl_addr_set_peer(self._rtnl_addr, a._nl_addr)
 
-    @netlink.nlattr('address.broadcast', type=str, fmt=util.addr)
     @property
+    @netlink.nlattr(type=str, fmt=util.addr)
     def broadcast(self):
         """Broadcast address"""
         a = capi.rtnl_addr_get_broadcast(self._rtnl_addr)
@@ -240,8 +237,8 @@ class Address(netlink.Object):
         a = netlink.AbstractAddress(value)
         capi.rtnl_addr_set_broadcast(self._rtnl_addr, a._nl_addr)
 
-    @netlink.nlattr('address.multicast', type=str, fmt=util.addr)
     @property
+    @netlink.nlattr(type=str, fmt=util.addr)
     def multicast(self):
         """multicast address"""
         a = capi.rtnl_addr_get_multicast(self._rtnl_addr)
@@ -256,8 +253,8 @@ class Address(netlink.Object):
 
         capi.rtnl_addr_set_multicast(self._rtnl_addr, a._nl_addr)
 
-    @netlink.nlattr('address.anycast', type=str, fmt=util.addr)
     @property
+    @netlink.nlattr(type=str, fmt=util.addr)
     def anycast(self):
         """anycast address"""
         a = capi.rtnl_addr_get_anycast(self._rtnl_addr)
@@ -268,9 +265,8 @@ class Address(netlink.Object):
         a = netlink.AbstractAddress(value)
         capi.rtnl_addr_set_anycast(self._rtnl_addr, a._nl_addr)
 
-    @netlink.nlattr('address.valid_lifetime', type=int, immutable=True,
-            fmt=util.num)
     @property
+    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
     def valid_lifetime(self):
         """Valid lifetime"""
         msecs = capi.rtnl_addr_get_valid_lifetime(self._rtnl_addr)
@@ -283,9 +279,8 @@ class Address(netlink.Object):
     def valid_lifetime(self, value):
         capi.rtnl_addr_set_valid_lifetime(self._rtnl_addr, int(value))
 
-    @netlink.nlattr('address.preferred_lifetime', type=int,
-            immutable=True, fmt=util.num)
     @property
+    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
     def preferred_lifetime(self):
         """Preferred lifetime"""
         msecs = capi.rtnl_addr_get_preferred_lifetime(self._rtnl_addr)
@@ -298,17 +293,15 @@ class Address(netlink.Object):
     def preferred_lifetime(self, value):
         capi.rtnl_addr_set_preferred_lifetime(self._rtnl_addr, int(value))
 
-    @netlink.nlattr('address.create_time', type=int, immutable=True,
-            fmt=util.num)
     @property
+    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
     def create_time(self):
         """Creation time"""
         hsec = capi.rtnl_addr_get_create_time(self._rtnl_addr)
         return datetime.timedelta(milliseconds=10*hsec)
 
-    @netlink.nlattr('address.last_update', type=int, immutable=True,
-            fmt=util.num)
     @property
+    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
     def last_update(self):
         """Last update"""
         hsec = capi.rtnl_addr_get_last_update_time(self._rtnl_addr)
index 4cd9f8a85a5bf528acdff9803bf18bfa62eeb5eb..a537cd54b1bc8e6011f584e0f295eb3d0221c5f3 100644 (file)
@@ -170,8 +170,8 @@ class Link(netlink.Object):
 
         return Link(obj)
 
-    @netlink.nlattr('link.ifindex', type=int, immutable=True, fmt=util.num)
     @property
+    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
     def ifindex(self):
         """interface index"""
         return capi.rtnl_link_get_ifindex(self._rtnl_link)
@@ -185,8 +185,8 @@ class Link(netlink.Object):
         if capi.rtnl_link_get_ifindex(self._orig) == 0:
             capi.rtnl_link_set_ifindex(self._orig, int(value))
 
-    @netlink.nlattr('link.name', type=str, fmt=util.bold)
     @property
+    @netlink.nlattr(type=str, fmt=util.bold)
     def name(self):
         """Name of link"""
         return capi.rtnl_link_get_name(self._rtnl_link)
@@ -202,8 +202,8 @@ class Link(netlink.Object):
         if capi.rtnl_link_get_name(self._orig) is None:
             capi.rtnl_link_set_name(self._orig, value)
 
-    @netlink.nlattr('link.flags', type=str, fmt=util.string)
     @property
+    @netlink.nlattr(type=str, fmt=util.string)
     def flags(self):
         """Flags
         Setting this property will *Not* reset flags to value you supply in
@@ -235,8 +235,8 @@ class Link(netlink.Object):
         else:
             self._set_flag(value)
 
-    @netlink.nlattr('link.mtu', type=int, fmt=util.num)
     @property
+    @netlink.nlattr(type=int, fmt=util.num)
     def mtu(self):
         """Maximum Transmission Unit"""
         return capi.rtnl_link_get_mtu(self._rtnl_link)
@@ -245,8 +245,8 @@ class Link(netlink.Object):
     def mtu(self, value):
         capi.rtnl_link_set_mtu(self._rtnl_link, int(value))
 
-    @netlink.nlattr('link.family', type=int, immutable=True, fmt=util.num)
     @property
+    @netlink.nlattr(type=int, immutable=True, fmt=util.num)
     def family(self):
         """Address family"""
         return capi.rtnl_link_get_family(self._rtnl_link)
@@ -255,8 +255,8 @@ class Link(netlink.Object):
     def family(self, value):
         capi.rtnl_link_set_family(self._rtnl_link, value)
 
-    @netlink.nlattr('link.address', type=str, fmt=util.addr)
     @property
+    @netlink.nlattr(type=str, fmt=util.addr)
     def address(self):
         """Hardware address (MAC address)"""
         a = capi.rtnl_link_get_addr(self._rtnl_link)
@@ -266,8 +266,8 @@ class Link(netlink.Object):
     def address(self, value):
         capi.rtnl_link_set_addr(self._rtnl_link, value._addr)
 
-    @netlink.nlattr('link.broadcast', type=str, fmt=util.addr)
     @property
+    @netlink.nlattr(type=str, fmt=util.addr)
     def broadcast(self):
         """Hardware broadcast address"""
         a = capi.rtnl_link_get_broadcast(self._rtnl_link)
@@ -277,8 +277,8 @@ class Link(netlink.Object):
     def broadcast(self, value):
         capi.rtnl_link_set_broadcast(self._rtnl_link, value._addr)
 
-    @netlink.nlattr('link.qdisc', type=str, immutable=True, fmt=util.string)
     @property
+    @netlink.nlattr(type=str, immutable=True, fmt=util.string)
     def qdisc(self):
         """Name of qdisc (cannot be changed)"""
         return capi.rtnl_link_get_qdisc(self._rtnl_link)
@@ -287,8 +287,8 @@ class Link(netlink.Object):
     def qdisc(self, value):
         capi.rtnl_link_set_qdisc(self._rtnl_link, value)
 
-    @netlink.nlattr('link.txqlen', type=int, fmt=util.num)
     @property
+    @netlink.nlattr(type=int, fmt=util.num)
     def txqlen(self):
         """Length of transmit queue"""
         return capi.rtnl_link_get_txqlen(self._rtnl_link)
@@ -297,8 +297,8 @@ class Link(netlink.Object):
     def txqlen(self, value):
         capi.rtnl_link_set_txqlen(self._rtnl_link, int(value))
 
-    @netlink.nlattr('link.weight', type=str, fmt=util.string)
     @property
+    @netlink.nlattr(type=str, fmt=util.string)
     def weight(self):
         """Weight"""
         v = capi.rtnl_link_get_weight(self._rtnl_link)
@@ -315,8 +315,8 @@ class Link(netlink.Object):
             v = int(value)
         capi.rtnl_link_set_weight(self._rtnl_link, v)
 
-    @netlink.nlattr('link.arptype', type=str, immutable=True, fmt=util.string)
     @property
+    @netlink.nlattr(type=str, immutable=True, fmt=util.string)
     def arptype(self):
         """Type of link (cannot be changed)"""
         type_ = capi.rtnl_link_get_arptype(self._rtnl_link)
@@ -327,9 +327,8 @@ class Link(netlink.Object):
         i = core_capi.nl_str2llproto(value)
         capi.rtnl_link_set_arptype(self._rtnl_link, i)
 
-    @netlink.nlattr('link.operstate', type=str, immutable=True,
-            fmt=util.string, title='state')
     @property
+    @netlink.nlattr(type=str, immutable=True, fmt=util.string, title='state')
     def operstate(self):
         """Operational status"""
         operstate = capi.rtnl_link_get_operstate(self._rtnl_link)
@@ -340,8 +339,8 @@ class Link(netlink.Object):
         i = capi.rtnl_link_str2operstate(value)
         capi.rtnl_link_set_operstate(self._rtnl_link, i)
 
-    @netlink.nlattr('link.mode', type=str, immutable=True, fmt=util.string)
     @property
+    @netlink.nlattr(type=str, immutable=True, fmt=util.string)
     def mode(self):
         """Link mode"""
         mode = capi.rtnl_link_get_linkmode(self._rtnl_link)
@@ -352,8 +351,8 @@ class Link(netlink.Object):
         i = capi.rtnl_link_str2mode(value)
         capi.rtnl_link_set_linkmode(self._rtnl_link, i)
 
-    @netlink.nlattr('link.alias', type=str, fmt=util.string)
     @property
+    @netlink.nlattr(type=str, fmt=util.string)
     def alias(self):
         """Interface alias (SNMP)"""
         return capi.rtnl_link_get_ifalias(self._rtnl_link)
@@ -362,8 +361,8 @@ class Link(netlink.Object):
     def alias(self, value):
         capi.rtnl_link_set_ifalias(self._rtnl_link, value)
 
-    @netlink.nlattr('link.type', type=str, fmt=util.string)
     @property
+    @netlink.nlattr(type=str, fmt=util.string)
     def type(self):
         """Link type"""
         return capi.rtnl_link_get_type(self._rtnl_link)
index 32fe3bc3a27f7027c10cd21bb0de5f545c91fe51..f5f45cb35741e0e4b82ef4347166237acbbe08b3 100644 (file)
@@ -73,8 +73,8 @@ class InetLink(object):
         return capi.rtnl_link_inet_set_conf(self._link._rtnl_link,
                         _resolve(id), int(value))
 
-    @netlink.nlattr('link.inet.forwarding', type=bool, fmt=util.boolean)
     @property
+    @netlink.nlattr(type=bool, fmt=util.boolean)
     def forwarding(self):
         return bool(self.get_conf(DEVCONF_FORWARDING))
 
@@ -82,8 +82,9 @@ class InetLink(object):
     def forwarding(self, value):
         self.set_conf(DEVCONF_FORWARDING, int(value))
 
-    @netlink.nlattr('link.inet.mc_forwarding', type=bool, fmt=util.boolean)
+
     @property
+    @netlink.nlattr(type=bool, fmt=util.boolean)
     def mc_forwarding(self):
         return bool(self.get_conf(DEVCONF_MC_FORWARDING))
 
@@ -91,8 +92,9 @@ class InetLink(object):
     def mc_forwarding(self, value):
         self.set_conf(DEVCONF_MC_FORWARDING, int(value))
 
-    @netlink.nlattr('link.inet.proxy_arp', type=bool, fmt=util.boolean)
+
     @property
+    @netlink.nlattr(type=bool, fmt=util.boolean)
     def proxy_arp(self):
         return bool(self.get_conf(DEVCONF_PROXY_ARP))
 
@@ -100,8 +102,8 @@ class InetLink(object):
     def proxy_arp(self, value):
         self.set_conf(DEVCONF_PROXY_ARP, int(value))
 
-    @netlink.nlattr('link.inet.accept_redirects', type=bool, fmt=util.boolean)
     @property
+    @netlink.nlattr(type=bool, fmt=util.boolean)
     def accept_redirects(self):
         return bool(self.get_conf(DEVCONF_ACCEPT_REDIRECTS))
 
@@ -109,8 +111,8 @@ class InetLink(object):
     def accept_redirects(self, value):
         self.set_conf(DEVCONF_ACCEPT_REDIRECTS, int(value))
 
-    @netlink.nlattr('link.inet.secure_redirects', type=bool, fmt=util.boolean)
     @property
+    @netlink.nlattr(type=bool, fmt=util.boolean)
     def secure_redirects(self):
         return bool(self.get_conf(DEVCONF_SECURE_REDIRECTS))
 
@@ -118,8 +120,8 @@ class InetLink(object):
     def secure_redirects(self, value):
         self.set_conf(DEVCONF_SECURE_REDIRECTS, int(value))
 
-    @netlink.nlattr('link.inet.send_redirects', type=bool, fmt=util.boolean)
     @property
+    @netlink.nlattr(type=bool, fmt=util.boolean)
     def send_redirects(self):
         return bool(self.get_conf(DEVCONF_SEND_REDIRECTS))
 
@@ -127,8 +129,8 @@ class InetLink(object):
     def send_redirects(self, value):
         self.set_conf(DEVCONF_SEND_REDIRECTS, int(value))
 
-    @netlink.nlattr('link.inet.shared_media', type=bool, fmt=util.boolean)
     @property
+    @netlink.nlattr(type=bool, fmt=util.boolean)
     def shared_media(self):
         return bool(self.get_conf(DEVCONF_SHARED_MEDIA))
 
index 646ce15ccb03390add0dcdc43aef981edde16a47..70045d53856f32e2815c603f6f12ba1b06cd01a7 100644 (file)
@@ -15,8 +15,8 @@ class VLANLink(object):
     def __init__(self, link):
         self._link = link
 
-    @netlink.nlattr('link.vlan.id', type=int)
     @property
+    @netlink.nlattr(type=int)
     def id(self):
         """vlan identifier"""
         return capi.rtnl_link_vlan_get_id(self._link)
@@ -25,8 +25,8 @@ class VLANLink(object):
     def id(self, value):
         capi.rtnl_link_vlan_set_id(self._link, int(value))
 
-    @netlink.nlattr('link.vlan.flags', type=str)
     @property
+    @netlink.nlattr(type=str)
     def flags(self):
         """ VLAN flags
         Setting this property will *Not* reset flags to value you supply in
index 2d3ea94de0829bf5cad65a91643795f8ddb12c78..d051c8db1b666ca639f555f397995708a9915d5b 100644 (file)
@@ -17,8 +17,8 @@ class HTBQdisc(object):
     def __init__(self, qdisc):
         self._qdisc = qdisc
 
-    @netlink.nlattr('qdisc.htb.default_class', type=int)
     @property
+    @netlink.nlattr(type=int)
     def default_class(self):
         return tc.Handle(capi.rtnl_htb_get_defcls(self._qdisc._rtnl_qdisc))
 
@@ -26,8 +26,8 @@ class HTBQdisc(object):
     def default_class(self, value):
         capi.rtnl_htb_set_defcls(self._qdisc._rtnl_qdisc, int(value))
 
-    @netlink.nlattr('qdisc.htb.r2q', type=int)
     @property
+    @netlink.nlattr('r2q', type=int)
     def r2q(self):
         return capi.rtnl_htb_get_rate2quantum(self._qdisc._rtnl_qdisc)
 
@@ -50,8 +50,8 @@ class HTBClass(object):
     def __init__(self, cl):
         self._class = cl
 
-    @netlink.nlattr('class.htb.rate', type=str)
     @property
+    @netlink.nlattr(type=str)
     def rate(self):
         rate = capi.rtnl_htb_get_rate(self._class._rtnl_class)
         return util.Rate(rate)
@@ -60,8 +60,8 @@ class HTBClass(object):
     def rate(self, value):
         capi.rtnl_htb_set_rate(self._class._rtnl_class, int(value))
 
-    @netlink.nlattr('class.htb.ceil', type=str)
     @property
+    @netlink.nlattr(type=str)
     def ceil(self):
         ceil = capi.rtnl_htb_get_ceil(self._class._rtnl_class)
         return util.Rate(ceil)
@@ -70,8 +70,8 @@ class HTBClass(object):
     def ceil(self, value):
         capi.rtnl_htb_set_ceil(self._class._rtnl_class, int(value))
 
-    @netlink.nlattr('class.htb.burst', type=str)
     @property
+    @netlink.nlattr(type=str)
     def burst(self):
         burst = capi.rtnl_htb_get_rbuffer(self._class._rtnl_class)
         return util.Size(burst)
@@ -80,8 +80,8 @@ class HTBClass(object):
     def burst(self, value):
         capi.rtnl_htb_set_rbuffer(self._class._rtnl_class, int(value))
 
-    @netlink.nlattr('class.htb.ceil_burst', type=str)
     @property
+    @netlink.nlattr(type=str)
     def ceil_burst(self):
         burst = capi.rtnl_htb_get_cbuffer(self._class._rtnl_class)
         return util.Size(burst)
@@ -90,8 +90,8 @@ class HTBClass(object):
     def ceil_burst(self, value):
         capi.rtnl_htb_set_cbuffer(self._class._rtnl_class, int(value))
 
-    @netlink.nlattr('class.htb.prio', type=int)
     @property
+    @netlink.nlattr(type=int)
     def prio(self):
         return capi.rtnl_htb_get_prio(self._class._rtnl_class)
 
@@ -99,8 +99,8 @@ class HTBClass(object):
     def prio(self, value):
         capi.rtnl_htb_set_prio(self._class._rtnl_class, int(value))
 
-    @netlink.nlattr('class.htb.quantum', type=int)
     @property
+    @netlink.nlattr(type=int)
     def quantum(self):
         return capi.rtnl_htb_get_quantum(self._class._rtnl_class)
 
@@ -108,8 +108,8 @@ class HTBClass(object):
     def quantum(self, value):
         capi.rtnl_htb_set_quantum(self._class._rtnl_class, int(value))
 
-    @netlink.nlattr('class.htb.level', type=int)
     @property
+    @netlink.nlattr(type=int)
     def level(self):
         return capi.rtnl_htb_get_level(self._class._rtnl_class)
 
index 503f5a497a84c86d8ad4701ea43692ed8718d939..0689b71d0fc357c8598e37e4450082869552c108 100644 (file)
@@ -157,6 +157,7 @@ class Tc(netlink.Object):
         capi.rtnl_tc_set_linktype(self._rtnl_tc, int(value))
 
     @property
+    @netlink.nlattr(fmt=util.handle)
     def handle(self):
         return Handle(capi.rtnl_tc_get_handle(self._rtnl_tc))
 
@@ -165,6 +166,7 @@ class Tc(netlink.Object):
         capi.rtnl_tc_set_handle(self._rtnl_tc, int(value))
 
     @property
+    @netlink.nlattr(fmt=util.handle)
     def parent(self):
         return Handle(capi.rtnl_tc_get_parent(self._rtnl_tc))
 
@@ -173,6 +175,7 @@ class Tc(netlink.Object):
         capi.rtnl_tc_set_parent(self._rtnl_tc, int(value))
 
     @property
+    @netlink.nlattr(fmt=util.bold)
     def kind(self):
         return capi.rtnl_tc_get_kind(self._rtnl_tc)
 
@@ -262,10 +265,6 @@ class Qdisc(Tc):
         self._rtnl_qdisc = self._obj2type(self._nl_object)
         self._rtnl_tc = capi.obj2tc(self._nl_object)
 
-        netlink.add_attr('qdisc.handle', fmt=util.handle)
-        netlink.add_attr('qdisc.parent', fmt=util.handle)
-        netlink.add_attr('qdisc.kind', fmt=util.bold)
-
         if self.kind:
             self._tc_module_lookup()
 
@@ -418,10 +417,6 @@ class TcClass(Tc):
         self._rtnl_class = self._obj2type(self._nl_object)
         self._rtnl_tc = capi.obj2tc(self._nl_object)
 
-        netlink.add_attr('class.handle', fmt=util.handle)
-        netlink.add_attr('class.parent', fmt=util.handle)
-        netlink.add_attr('class.kind', fmt=util.bold)
-
         if self.kind:
             self._tc_module_lookup()
 
@@ -492,10 +487,6 @@ class Classifier(Tc):
         self._rtnl_cls = self._obj2type(self._nl_object)
         self._rtnl_tc = capi.obj2tc(self._nl_object)
 
-        netlink.add_attr('cls.handle', fmt=util.handle)
-        netlink.add_attr('cls.parent', fmt=util.handle)
-        netlink.add_attr('cls.kind', fmt=util.bold)
-
     @classmethod
     def from_capi(cls, obj):
         return cls(capi.cls2obj(obj))
index 0f2e54759b93271cf78d8056f6a46d88bf7098fe..23940336fde80bad1ddc41c9e9e17b68a71e88ed 100644 (file)
@@ -80,24 +80,19 @@ class MyFormatter(Formatter):
         self._indent = indent
 
     def _nlattr(self, key):
-        value = getattr(self._obj, key)
-        title_ = None
+        value = getattr(self._obj.__class__, key)
+        if not isinstance(value, property):
+            raise ValueError('Invalid formatting string {0}'.format(key))
 
-        if isinstance(value, types.MethodType):
-            value = value()
+        d = getattr(value.fget, 'formatinfo', dict())
 
-        try:
-            d = netlink.attrs[self._obj._name + '.' + key]
+        # value = value.fget() is exactly the same
+        value = getattr(self._obj, key)
 
-            if 'fmt' in d:
-                value = d['fmt'](value)
+        if 'fmt' in d:
+            value = d['fmt'](value)
 
-            if 'title' in d:
-                title_ = d['title']
-        except KeyError:
-            pass
-        except AttributeError:
-            pass
+        title_ = d.get('title', None)
 
         return title_, str(value)