Source code for netaddr.core
# -----------------------------------------------------------------------------
# Copyright (c) 2008 by David P. D. Moss. All rights reserved.
#
# Released under the BSD license. See the LICENSE file for details.
# -----------------------------------------------------------------------------
"""Common code shared between various netaddr sub modules"""
import sys as _sys
import pprint as _pprint
#: True if platform is natively big endian, False otherwise.
BIG_ENDIAN_PLATFORM = _sys.byteorder == 'big'
#: Use inet_pton() semantics instead of inet_aton() when parsing IPv4.
INET_PTON = 1
#: Remove any preceding zeros from IPv4 address octets before parsing.
ZEROFILL = 2
#: Remove any host bits found to the right of an applied CIDR prefix.
NOHOST = 4
#: Use legacy ``inet_aton()`` semantics when parsing IPv4.
INET_ATON = 8
# -----------------------------------------------------------------------------
# Custom exceptions.
# -----------------------------------------------------------------------------
[docs]
class AddrFormatError(Exception):
"""
An Exception indicating a network address is not correctly formatted.
"""
pass
[docs]
class AddrConversionError(Exception):
"""
An Exception indicating a failure to convert between address types or
notations.
"""
pass
[docs]
class NotRegisteredError(Exception):
"""
An Exception indicating that an OUI or IAB was not found in the IEEE
Registry.
"""
pass
class Subscriber(object):
"""
An abstract class defining the interface expected by a Publisher.
"""
def update(self, data):
"""
A callback method used by a Publisher to notify this Subscriber about
updates.
:param data: a Python object containing data provided by Publisher.
"""
raise NotImplementedError('cannot invoke virtual method!')
class PrettyPrinter(Subscriber):
"""
A concrete Subscriber that employs the pprint in the standard library to
format all data from updates received, writing them to a file-like
object.
Useful as a debugging aid.
"""
def __init__(self, fh=_sys.stdout, write_eol=True):
"""
Constructor.
:param fh: a file-like object to write updates to.
Default: sys.stdout.
:param write_eol: if ``True`` this object will write newlines to
output, if ``False`` it will not.
"""
self.fh = fh
self.write_eol = write_eol
def update(self, data):
"""
A callback method used by a Publisher to notify this Subscriber about
updates.
:param data: a Python object containing data provided by Publisher.
"""
self.fh.write(_pprint.pformat(data))
if self.write_eol:
self.fh.write('\n')
class Publisher(object):
"""
A 'push' Publisher that maintains a list of Subscriber objects notifying
them of state changes by passing them update data when it encounter events
of interest.
"""
def __init__(self):
"""Constructor"""
self.subscribers = []
def attach(self, subscriber):
"""
Add a new subscriber.
:param subscriber: a new object that implements the Subscriber object
interface.
"""
if hasattr(subscriber, 'update') and hasattr(subscriber.update, '__call__'):
if subscriber not in self.subscribers:
self.subscribers.append(subscriber)
else:
raise TypeError('%r does not support required interface!' % subscriber)
def detach(self, subscriber):
"""
Remove an existing subscriber.
:param subscriber: a new object that implements the Subscriber object
interface.
"""
try:
self.subscribers.remove(subscriber)
except ValueError:
pass
def notify(self, data):
"""
Send update data to to all registered Subscribers.
:param data: the data to be passed to each registered Subscriber.
"""
for subscriber in self.subscribers:
subscriber.update(data)
class DictDotLookup(object):
"""
Creates objects that behave much like a dictionaries, but allow nested
key access using object '.' (dot) lookups.
Recipe 576586: Dot-style nested lookups over dictionary based data
structures - http://code.activestate.com/recipes/576586/
"""
def __init__(self, d):
for k in d:
if isinstance(d[k], dict):
self.__dict__[k] = DictDotLookup(d[k])
elif isinstance(d[k], (list, tuple)):
l = []
for v in d[k]:
if isinstance(v, dict):
l.append(DictDotLookup(v))
else:
l.append(v)
self.__dict__[k] = l
else:
self.__dict__[k] = d[k]
def __getitem__(self, name):
if name in self.__dict__:
return self.__dict__[name]
def __iter__(self):
return self.__dict__.keys()
def __repr__(self):
return _pprint.pformat(self.__dict__)