Home > database >  pythondns - two identical strings return not equal
pythondns - two identical strings return not equal

Time:10-09

I have the following code and in the last if statement I just want to compare the two strings.

import dns.resolver

domain = "google.co.uk"

spf_wrong ='"v=spf1 -all"'

test_spf = dns.resolver.resolve(domain , 'TXT')
try:
    for dns_data in test_spf:
        if 'spf1' in str(dns_data):
            dns_correct = dns_data
except:
    print("SPF record not found")
    pass

if dns_data == spf_wrong:
    print("same")
else:
    print("not same")
    print(dns_correct)
    print(spf_wrong)

To me, the output shows the exact same text. There is nothing different about it but I get the output:

not same
"v=spf1 -all"
"v=spf1 -all"

Finding another thread I then modified the if statement to the following:

if dns_data == spf_wrong:
    print("same")
else:
    print("not same")
    print(repr(dns_correct))
    print(repr(spf_wrong))

And now I get the following output:

not same
<DNS IN TXT rdata: "v=spf1 -all">
'"v=spf1 -all"'

So my question is, how do I act on this? Python thinks these strings are different and I think using the repr() function shows they are different, but I am not sure how to fix this.

CodePudding user response:

dns_correct is not a string it's a <class 'dns.rdtypes.ANY.TXT.TXT'>

A string will probably never be == to this class.

When you call print() you're implicity calling the __str__() function on rdtypes.ANY.TEXT.TEXT which is why it looks like they are the same when you print them.

You can think of print as doing this:

print(str(dns_correct))

Here's the python3 repl session I used. It should clarify further.

>>> import dns.resolver
>>>
>>> domain = "google.co.uk"
>>>
>>> spf_wrong ='"v=spf1 -all"'
>>>
>>> test_spf = dns.resolver.resolve(domain , 'TXT')
>>> try:
...     for dns_data in test_spf:
...             if 'spf1' in str(dns_data):
...                     dns_correct = dns_data
... except:
...     print("except")
...
>>> dns_correct
<DNS IN TXT rdata: "v=spf1 -all">
>>> print(dns_correct)
"v=spf1 -all"
>>> type(dns_correct)
<class 'dns.rdtypes.ANY.TXT.TXT'>
>>> str(dns_correct) == spf_wrong
True
>>> dns_correct == spf_wrong
False

If you look @ the source we find __str__ function calls another func called to_text which produces the output you see when you print

# https://www.dnspython.org/docs/1.16.0/dns.rdata-pysrc.html#Rdata.__str__
186 -    def __str__(self): 
187          return self.to_text() 
# https://www.dnspython.org/docs/1.16.0/dns.rdtypes.txtbase-pysrc.html#TXTBase.to_text
49 -    def to_text(self, origin=None, relativize=True, **kw): 
50          txt = '' 
51          prefix = '' 
52          for s in self.strings: 
53              txt  = '{}"{}"'.format(prefix, dns.rdata._escapify(s)) 
54              prefix = ' ' 
55          return txt 
  • Related