-
Notifications
You must be signed in to change notification settings - Fork 156
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
using versioneer in multiple setuptools dependant projects leads to interchanged version numbers #52
Comments
since the dependency resolution takes place in the same python process, my guess is that the same versionfile_source is being taken into account in setup of B. |
forced reloading of versioneer module in setup.py of B seems to help 👍 Maybe this should be default behaviour of versioneer (have an import hook, which reloads)?
|
Oh, that's tricky.. so the Hm. I see the problem, and it's ugly, but I'm hesitant to dive into force-reloads and module-loader internals. Is it possible to have |
If versioneer is on same level as setup.py it should work as expected. |
Hm. Maybe we could do:
Then the config info could get curried into the command classes, and there wouldn't be any global state to get confused between separate uses of the same module. |
If we do it that way, we'd also need What if we put a import versioneer
cmdclass=versioneer.cmdclass()
setup(... version=versioneer.get_version(), cmdclass=cmdclass, ...) We can probably make that backwards-compatible too, by requiring those values to be set if a .ini file isn't found. Or add a |
I vote for the [versioneer] section in setup.cfg. This seems to be the right solution! |
FYI, #74 is where this is happening. Give it a whirl and see if it does what you need. (might still be a bit touchy, let me know if you run into problems) |
Ok, I just landed the setup.cfg change (1fe079a). I think that should fix this issue. Could you take a look and close it if so? |
I've been doing a deep-dive of distutils/setuptools internals, and this problem has arisen again. The setup.cfg helps, although I think the current code is looking for setup.cfg relative to the Once we fix that, the remaining problem is if A and B are using different versions of Versioneer. The specific problem has to do with the way that setuptools' This will be troublesome when we make the next release, because it switches to using setup.cfg . So if B is expecting versioneer-0.14 (and configuring it with I can think of a few options, and I don't like any of them:
Does anyone have any bright ideas that might let us avoid these (ugly) choices? Or any preferences among them? |
I landed the use-cwd-for-root (instead of relative-to-versioneer.py) change, so that problem is fixed. I still need to come up with an answer for the second problem.. I'm leaning towards |
why is a clean uncached import so inconvenient in your opinion? Having
different names for versioneer.py looks ugly
|
I guess I didn't want to ask devs to put a weird-looking Fortunately, I lucked upon a better approach. It turns out that setuptools has a sandbox of sorts: when it builds dependencies (as part of So we just have to keep the top project's import from affecting the dependency, and we can do that by just The other reason this solution is great is because we can tolerate a dependency that is using an older Versioneer (which doesn't have this trick). If we instead made a new version of Versioneer that somehow auto-reloaded itself correctly, that would help the case where the dependency was using the new version (even if the top-level project were not), but it wouldn't help when the dependency was using an old version (it'd be hopelessly stuck with the pre-imported versioneer.py). That would leave developers in a bad spot: they couldn't use the new Versioneer until all of their dependencies had upgraded first. This trick seems to decouple the two. Thank goodness setuptools had that sandbox in place already: even though it's only protecting us in one direction, if it wasn't there, we'd still have that troublesome upgrade path. |
This fixes the "python setup.py develop" case (also 'install' and 'easy_install .'), in which subdependencies of the main project are built (using setup.py bdist_egg) in the same python process. Assume a main project A and a dependency B, which use different versions of Versioneer. A's setup.py imports A's Versioneer, leaving it in sys.modules by the time B's setup.py is executed, causing B to run with the wrong versioneer. Setuptools wraps the sub-dep builds in a sandbox that restores sys.modules to it's pre-build state, so the parent is protected against the child's "import versioneer". By removing ourselves from sys.modules here, before the child build happens, we protect the child from the parent's versioneer too. Fixes #52.
Thanks, sounds like a practical solution. Does it also work for
distutils based projects, where there is no sandbox?
I mean I'm happy with this approach, but it may exclude distutils
people, which should then at least be documented somewhere.
|
Yeah, it should cover distutils too, at least in any case where it makes a difference. If A depends upon B, then A must be using setuptools, because there's no way to express the It doesn't matter whether B is using distutils or setuptools because the commands that can provoke a subdependency build (like |
I know only distutils is supported. But still I wanted to report this (maybe to avoid others run into this). I will try to figure out whats going on.
Lets say A depends B (both using versioneer). B is in on pypi with a source tarball, so have a static _version.py file.
A drags in B during setup phase, and version of B gets replaced by version of A.
Can be observed here: https://travis-ci.org/markovmodel/PyEMMA/builds/40644627#L623
Maybe this also occurs if A and B are using distutils (have not tested).
The text was updated successfully, but these errors were encountered: