-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dependency on py3dns causes namespace issues on OSX #2
Comments
My preferred solution is found in Milter/dns.py in the pymilter project. This is a simplified dns API that includes a short term cache suitable for email applications like pyspf, dkim, etc. dkimpy has a copy of it. It should be it's own module and shared, and that is what pyspf should use. Or we can just make another copy in pyspf... Besides pydns and dnspython, there are other dns libraries that I'd like to use. Including a C library gaining popularity I want to wrap, but can't remember the name for the life of me. aarrrggghhh. While dnspython is much more complete and supported, I still prefer pydns for my email applications because it is much more lightweight. So I do not want to hardwire dnspython. I do need to move pyspf to using the plugin that dkimpy and pymilter user, however. I think one suggested name was dnsplug. |
For your situation, if it was me I would actually rename the module from DNS to pydns, keeping the lightweight library but fixing the name conflict. I will talk to Fedora packagers about renaming and maybe including a symlink for backward compatibility. |
Thank you for the feedback, Stuart. Without having approached the py3dns maintainer, my assumption would be that it is a hard sell to have them make such a disruptive change to handle the admittedly weird semantics of the OSX file system, a problem that is invisible to most users. I will make an attempt though. It is also unclear to me how the thin abstraction layer would resolve the underlying conflict. I guess one could provide a |
The dnsplug.py implementation in dkimpy simply tries all supported libraries in order of preference: try:
# prefer dnspython (the more complete library)
import dns
import dns.resolver # http://www.dnspython.org
import dns.exception
if not hasattr(dns.rdatatype,'SPF'):
# patch in type99 support
dns.rdatatype.SPF = 99
dns.rdatatype._by_text['SPF'] = dns.rdatatype.SPF
DNSLookup = DNSLookup_dnspython
except:
import DNS # http://pydns.sourceforge.net
if not hasattr(DNS.Type, 'SPF'):
# patch in type99 support
DNS.Type.SPF = 99
DNS.Type.typemap[99] = 'SPF'
DNS.Lib.RRunpacker.getSPFdata = DNS.Lib.RRunpacker.getTXTdata
# Fails on Mac OS X? Add domain to /etc/resolv.conf
DNS.DiscoverNameServers()
DNSLookup = DNSLookup_pydns |
Also, I am the maintainer of py3dns :-) |
Ah, that code would would neatly solve my problem. I'll come up with a PR to move to that. For longer term reduction of confusing debug sessions, what would be the proper forum for bringing up a discussion about changing the namespace of py3dns? The code seems to be maintained on launchpad.net, but my assumption would be that https://bugs.launchpad.net/py3dns is fairly ubuntu-centric, right? |
I moved py3dns to launchpad because Scott Kitterman is a Debian/Ubuntu maintainer, and a primary user of pydns. But he is now in the process of moving to git. |
Ah, the resolver I was interested in trying with pyspf is python-unbound. |
Scott and I hang out on #spf and #dkim on freenode.net to discuss pyspf/pydns/dkimpy issues. |
https://bugs.launchpad.net/py3dns is upstream. Launchpad is used for both Ubuntu and upstream projects. I use it since I prefer free software based systems. Also, it's on irc.perl.org (for historical reasons, I know it's odd). |
PyDNS goes back to roughly Python 1.6/2000. If a rename is needed, I think the newer project gets to do it (dnspython had it's 1.0 release in November 2012). |
I have opened a task with dnspython here: rthalley/dnspython#303 |
There is also the consideration of which project has the most users. My subjective impression, unsubstantiated by any survey, is that pydns has a loyal (myself included) but smaller following. |
This is only a problem on file systems which, IMO, are broken with respect to Python name spaces. In Python they are case sensitive and if the file system can't support that, then I don't think it properly supports Python. |
So, it seems both maintainers of the underlying dns lookup implementations are in agreement that if any project should change it's the other one. Well, it was worth a try. I agree that having a case insensitive file system was a bad engineering decision, but sometimes you are stuck with bad decisions for a long time. Obviously, it's any maintainer's prerogative to decide to not support any target platform for any reason, and I'm not going to argue with that. Moving forward, I had a look at the dns module in pymilter and I think that your suggested approach of breaking it out into a separate module and have that one implement a fallback using dnspython if pydns is not available is a good one. I created a repo at https://github.com/nresare/dnsplug that currently only holds a copy of dns.py and a single trivial test case. If you agree that this is a good way to proceed, I would be happy to clean up the code, fix the fallback to dnspython, comprehensive testing for several platforms, and modify pymilter, pyspf and any other project that might benefit. |
Also, if you want to host the project under your github user, I'm happy to transfer the project to you. Some of the things I would like to do:
Please feel free to raise any questions or concerns :) |
Here are the reflections of the same concept that need to be reconciled:
Some milters import Milter.dns - but that can, of course, just import from dnsplug. The change will introduce a new dependency - unless I embed dnsplug.py as I did with dkimpy. At one point, I thought all users of dkimpy and pyspf would also be using pymilter - but that is of course silly in hind sight. The pyspf test suite also exercises the Session caching - which is surprisingly non-trivial, and several bugs have fixed and tests added. So checking that pyspf still passes the test suite is important for testing dnsplug (the Session cache part). Now, if I could see my way forward to have all those projects import dnsplug without breaking distro packages (maybe release notes would do the job), I would make dnsplug a package, and have plugin modules for each python dns implementation: pydns(py3dns), dnspython, testspf, python-unbound. That last one has not been used in any pymilter projects yet that I know of. |
I guess the first step is a simple one file dnsplug.py that handles pydns/dnspython and testspf. |
I used the dnsplug.py from dkimpy in dkimpy-milter, which led to me having to do some unfun hackery in setup.py to get the install_requires correct. I'd love to see a dnsplug.py on pypi that I could just depend on and let the complexity of which DNS implementation is chosen hide behind it. I think that the dnsplug.py from dkimpy is the best thing to start from. I would suggest (and am willing to help with):
Last I checked (and it's been a few years) the Unbound python bindings did not support TXT. Someone will need to check on that and then we'll have to wait for an unbound release if it's still missing. |
I hope you both have had a good easter weekend. Circling back to this, I have now added support to fallback to dnspython, with tests for both protocol implementations set up with tox. I would like to hear if you think that I'm on the right track here. I'm not interested working on this unless we can get this code merged and released fairly soon. The latest code is available here. Please have a look. Some thoughts in bullet form:
|
I don't like using if-else to select between pydns_lookup and dnspython_lookup. There may be other choices. What was the reason for not simply assigning DNSLookup = [some implementation] ? |
While fixing issue #10, I thought of calling using the name "anydns" instead of "dnsplug". For poorly understood and purely subjective reasons, I feel more motivated to work on "anydns" than "dnsplug". It may be because python has "anydbm" already, or because "plug" just feels "klunky". |
This is related I think. It occurs on Windows 10 Pro and not Windows 10 Home. Then a simple snippet like the following works on both...
But on Windows 10 Pro (Microsoft Windows [Version 10.0.17763.437]) continue with...
This does not happen with Windows 10 Home (10.0.17134.706)
Is this a known issue? Any suggestions on tracking it down or working around it? |
(This is a proposed solution to the issue that I encountered and described in SpamExperts/OrangeAssassin#81)
While I was trying to get OrangeAssassin running on my OSX machine I noted that there were some strange namespace issues, caused by the fact that both py3dns and dnspython were installed in parallel. py3dns installs itself in top level module
DNS
and dnspython indns
, which turns out to be the same directory on a default install OSX machine due to filesystem case insensitivity.I understand that pyspf has not seen a lot of development in the last few years, and my understanding is that dnspython is by far the more widely used library these days. It also happens to be the dns library used by other parts of OrangeAssassin.
I would be happy to create a diff that changes the dns library dependency in pyspf from py3dns to dnspython (along the lines of the code present in master) and also introduces a dependency declaration on dnspython (so that pip will handle the dependency for you) if you were interested in accepting it and releasing a new pyspf. What do you think?
The text was updated successfully, but these errors were encountered: