The changelog of pyspf-2.0.7 claims pyspf works with python3, tested with python 3.2. Yet this is not the case. If you check spf.py, line 1971, the parenthesises are missing around the argument of print(), and this is not compatible with python3.2. Running 2to3 on the code fixes these, but then other error messages are coming from the usage, eg.:
res = spf.check2(ip, sender, helo)
File "/usr/lib64/python3.2/site-packages/spf.py", line 310, in check2
receiver=receiver,timeout=timeout,verbose=verbose,querytime=querytime).check()
File "/usr/lib64/python3.2/site-packages/spf.py", line 538, in check
spf = self.dns_spf(self.d)
File "/usr/lib64/python3.2/site-packages/spf.py", line 1094, in dns_spf
a = [t for t in self.dns_txt(domain) if RE_SPF.match(t)]
File "/usr/lib64/python3.2/site-packages/spf.py", line 1131, in dns_txt
for a in self.dns(domainname, 'TXT')]
File "/usr/lib64/python3.2/site-packages/spf.py", line 1131, in <listcomp>
for a in self.dns(domainname, 'TXT')]
File "/usr/lib64/python3.2/site-packages/spf.py", line 1130, in <genexpr>
return [''.join(s.decode("ascii") for s in a)
AttributeError: 'str' object has no attribute 'decode'
Removing the decode() call part fixes it for python3 (the string at that point is already decoded in 3).
Even after fixing the issues I fixed for Debian/Ubuntu, there is still an IPv6 issue. Reduced test case:
python3 /usr/lib/python3/dist-packages/spf.py 2001:7b8:206:1::53 test@unbound.net unbound.net
Fix for that:
--- pyspf-2.0.7.orig/spf.py 2013-05-25 23:35:47.738250685 -0400
+++ pyspf-2.0.7/spf.py 2013-05-25 23:42:34.254238674 -0400
@@ -1279,7 +1279,7 @@
def cidrmatch(self, ipaddrs, n):
"""Match connect IP against a list of other IP addresses."""
try:
- if self.v == 'ip6':
+ if self.v == 'ip6' and sys.version_info[0] ==2:
MASK = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
bin = bin2long6
else:
This was a bad idea. The right solution to this problem was to fix it in py3dns, which is now done. https://launchpad.net/py3dns/trunk/3.0.3/+download/py3dns-3.0.3.tar.gz
There's also this patch:
Index: pyspf-2.0.7/spf.py
--- pyspf-2.0.7.orig/spf.py 2012-02-09 17:05:32.039191110 -0500
+++ pyspf-2.0.7/spf.py 2012-02-09 17:09:08.479184717 -0500
@@ -1968,9 +1984,9 @@
elif len(argv) == 3:
q = query(i=argv[0], s=argv[1], h=argv[2],
receiver=socket.gethostname(), verbose=verbose)
- print q.check(),q.mechanism
+ print(q.check(),q.mechanism)
if q.perm_error and q.perm_error.ext:
- print q.perm_error.ext
+ print(q.perm_error.ext)
elif len(argv) == 4:
i, s, h = argv[1:]
q = query(i=i, s=s, h=h, receiver=socket.gethostname(),
diff -r1.108.2.84 spf.py
1182c1182
< if type(dns_list[0][0]) is 'bytes':
is a better fix than removing the decode. The type check wasn't working so the code meant for python was getting executed in python3. I've committed this to CVS.
This issue only applied to CVS, not 2.0.7.
This is fixed and should be closed.
Yes, it's fixed. But i can't find any handle to close this bug.
As I recall, it was mostly fixed by changing py3dns to be more reasonable.
I think the project owner will have to close it.