Package dns :: Module exception
[hide private]
[frames] | no frames]

Source Code for Module dns.exception

  1  # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license 
  2   
  3  # Copyright (C) 2003-2017 Nominum, Inc. 
  4  # 
  5  # Permission to use, copy, modify, and distribute this software and its 
  6  # documentation for any purpose with or without fee is hereby granted, 
  7  # provided that the above copyright notice and this permission notice 
  8  # appear in all copies. 
  9  # 
 10  # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 
 11  # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 
 12  # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 
 13  # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
 14  # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
 15  # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 
 16  # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
 17   
 18  """Common DNS Exceptions. 
 19   
 20  Dnspython modules may also define their own exceptions, which will 
 21  always be subclasses of ``DNSException``. 
 22  """ 
 23   
24 -class DNSException(Exception):
25 """Abstract base class shared by all dnspython exceptions. 26 27 It supports two basic modes of operation: 28 29 a) Old/compatible mode is used if ``__init__`` was called with 30 empty *kwargs*. In compatible mode all *args* are passed 31 to the standard Python Exception class as before and all *args* are 32 printed by the standard ``__str__`` implementation. Class variable 33 ``msg`` (or doc string if ``msg`` is ``None``) is returned from ``str()`` 34 if *args* is empty. 35 36 b) New/parametrized mode is used if ``__init__`` was called with 37 non-empty *kwargs*. 38 In the new mode *args* must be empty and all kwargs must match 39 those set in class variable ``supp_kwargs``. All kwargs are stored inside 40 ``self.kwargs`` and used in a new ``__str__`` implementation to construct 41 a formatted message based on the ``fmt`` class variable, a ``string``. 42 43 In the simplest case it is enough to override the ``supp_kwargs`` 44 and ``fmt`` class variables to get nice parametrized messages. 45 """ 46 47 msg = None # non-parametrized message 48 supp_kwargs = set() # accepted parameters for _fmt_kwargs (sanity check) 49 fmt = None # message parametrized with results from _fmt_kwargs 50
51 - def __init__(self, *args, **kwargs):
52 self._check_params(*args, **kwargs) 53 if kwargs: 54 self.kwargs = self._check_kwargs(**kwargs) 55 self.msg = str(self) 56 else: 57 self.kwargs = dict() # defined but empty for old mode exceptions 58 if self.msg is None: 59 # doc string is better implicit message than empty string 60 self.msg = self.__doc__ 61 if args: 62 super(DNSException, self).__init__(*args) 63 else: 64 super(DNSException, self).__init__(self.msg)
65
66 - def _check_params(self, *args, **kwargs):
67 """Old exceptions supported only args and not kwargs. 68 69 For sanity we do not allow to mix old and new behavior.""" 70 if args or kwargs: 71 assert bool(args) != bool(kwargs), \ 72 'keyword arguments are mutually exclusive with positional args'
73
74 - def _check_kwargs(self, **kwargs):
75 if kwargs: 76 assert set(kwargs.keys()) == self.supp_kwargs, \ 77 'following set of keyword args is required: %s' % ( 78 self.supp_kwargs) 79 return kwargs
80
81 - def _fmt_kwargs(self, **kwargs):
82 """Format kwargs before printing them. 83 84 Resulting dictionary has to have keys necessary for str.format call 85 on fmt class variable. 86 """ 87 fmtargs = {} 88 for kw, data in kwargs.items(): 89 if isinstance(data, (list, set)): 90 # convert list of <someobj> to list of str(<someobj>) 91 fmtargs[kw] = list(map(str, data)) 92 if len(fmtargs[kw]) == 1: 93 # remove list brackets [] from single-item lists 94 fmtargs[kw] = fmtargs[kw].pop() 95 else: 96 fmtargs[kw] = data 97 return fmtargs
98
99 - def __str__(self):
100 if self.kwargs and self.fmt: 101 # provide custom message constructed from keyword arguments 102 fmtargs = self._fmt_kwargs(**self.kwargs) 103 return self.fmt.format(**fmtargs) 104 else: 105 # print *args directly in the same way as old DNSException 106 return super(DNSException, self).__str__()
107 108
109 -class FormError(DNSException):
110 """DNS message is malformed."""
111 112
113 -class SyntaxError(DNSException):
114 """Text input is malformed."""
115 116
117 -class UnexpectedEnd(SyntaxError):
118 """Text input ended unexpectedly."""
119 120
121 -class TooBig(DNSException):
122 """The DNS message is too big."""
123 124
125 -class Timeout(DNSException):
126 """The DNS operation timed out.""" 127 supp_kwargs = {'timeout'} 128 fmt = "The DNS operation timed out after {timeout} seconds"
129