match = re.match(r'^((?P<scheme>sip|sips):)?(?P<username>.+?)(@(?P<domain>.+?)(:(?P<port>\d+?))?)?(;(?P<parameters>.+?))?(\?(?P<headers>.+?))?$', address)
if match is None:
return False
components = match.groupdict()
if components['scheme'] is not None:
expected_scheme = 'sips' if self.secure else 'sip'
if components['scheme'] != expected_scheme:
return False
if components['username'] != self.user:
return False
if components['domain'] is not None and components['domain'] != self.host:
return False
if components['port'] is not None and int(components['port']) != self.port:
return False
if components['parameters']:
parameters = dict([(name, value) for name, sep, value in [param.partition('=') for param in components['parameters'].split(';')]])
expected_parameters = dict([(name, str(value) if value is not None else None) for name, value in self.parameters.iteritems() if name in parameters])
if parameters != expected_parameters:
return False
if components['headers']:
headers = dict([(name, value) for name, sep, value in [header.partition('=') for header in components['headers'].split('&')]])
expected_headers = dict([(name, str(value) if value is not None else None) for name, value in self.headers.iteritems() if name in headers])
def __richcmp__(self, other, op): # since we define __hash__, __richcmp__ is not inherited (see https://docs.python.org/2/c-api/typeobj.html#c.PyTypeObject.tp_richcompare)
if not isinstance(other, BaseSIPURI):
return NotImplemented
if op == 2: # 2 is ==
return all(getattr(self, name) == getattr(other, name) for name in ("user", "password", "host", "port", "secure", "parameters", "headers"))
elif op == 3: # 3 is !=
return any(getattr(self, name) != getattr(other, name) for name in ("user", "password", "host", "port", "secure", "parameters", "headers"))