Não ficou claro como o match() funciona, uma vez que no código é passado a URL completa inclusive com os parâmetros. Ele retornou algo porquê estava no inicio da string? Ou caso o padrão procurado estivesse no meio haveria erro?
def valida_url(self):
if not self.url: #chama o bool()
raise ValueError("A URL está vazia")
padrao_url = re.compile('(http(s)?://)?(www.)?bytebank.com(.br)?/(cambio)')
match = padrao_url.match(self.url)
if not match:
raise ValueError("A URL não é válida")
else:
print("A URL é válida")
url = "bytebank.com/cambio?quantidade=100&moedaOrigem=real&moedaDestino=dolar"