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__)