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
Don't import the package to get the version #1
Comments
The explanation is that setup.py is ran prior to the dependencies being installed (in fact it is ran to determine what the dependencies are). So if, for example, you're writing a library called foo, and doing That being said I have a slightly nicer trick that involves putting an |
@dstufft Thanks, this is very helpful. |
@dstufft WTF? I don't think this is "nicer", exec'ing an arbitrary file in a setup.py is contrary to how metadata like a version number should be handled. It's like you're asking for trouble. I find it funny you're doing that in your crypto package's setup.py. @audreyr I would strongly recommend using a safe approach like |
@jezdez shrug, at that point you're already executing arbitrary python (setup.py). Not like adding a little bit extra is any more or less dangerous. I prefer to keep the business of tokenzing and parsing a .py file to the python interpreter instead of attempting to create a regex to parse it out. A |
@dstufft I agree. By the time it gets to setup.py anything could be run there anyways. The original problem seems to be solving the importing dependencies before they are installed. Why can't we just have the This should avoid the imports that could be in |
|
@dstufft Ah, i wasn't sure on that one. My bad, rescinded. |
@dstufft So your argument is that adding another way of how setup.py can be abused is not a problem? I beg to differ, any extension of what setup.py does (other than build the kwargs for the setup function locally) further solidifies the antipattern setup.py itself is. I'm sad you don't seem to realize that the best practices you're advocating here and in other places are the exact reason we're still stuck with setup.py after years of PEPs with new metadata standards -- making them toothless tigers at best. I hoped PEP 426 would encourage a new non-executable metadata file to be advocated instead of using hacks like using exec or my regex solution. But if one of the coauthors of the PEP even thinks that it's fair game to ignore this new effort, I'm not sure I want to even be part of this discussion anymore. Since all we get instead is more pseudo standards that make the PEP system laughable. For the others -- and for completeness sake -- there is also d2to1 which was supposed to be the transitional package for projects supporting both distutils and distutils2/packaging (when distutil2/packaging was still a thing). https://pypi.python.org/pypi/d2to1 I strongly believe that a similar solution should be created for the metadata standard that was proposed with PEP 426. |
@jezdez PEP426 has nothing to do with how the metadata is derived simply what it looks like inside of the packaged file. A big part of it's goals is to enable any type of source for the data as long as whatever you use to build the package generates a package with the proper JSON file. Their is no sdist 2.0 yet, however there is Wheel. So the way that it is expected to migrate is that setup.py will be used to create a Wheel file which will (eventually) have a pymeta.json file inside of it. So as long as the setup.py is deterministic it will always create the same Wheel file and anything you write inside of it is fine. Once there is a sdist 2.0 it will similarly work by not having a setup.py inside of it but instead having a pymeta.json and will similarly work fine as long as setup.py is deterministic. The real power behind the approach of defining how a package looks versus what the developers of a program interact with is that it enables developers to generate the packages however they want as long as it ends up with the simple package file with static metadata. So that means continueing to use a setup.py file that simply generates a sdist 2.0 and a Wheel file (possibly using So I look at having setup.py as a reasonable thing to do in setup.py's role as a developer oriented build script. In it's role as an entry point for sdist 2.0 metadata I look at it as merely an extension of existing brokenness but one that is easily replaced with no effort of the developer once setuptools is able to generate sdist 2.0 files as easily as it is replaced in Wheel files today. |
In other words I find the conflation of the developer oriented build tooling that creates packages and the meta-data inside of the package to be one of the problems with the existing solutions and with distutils2. I also don't find setup.py itself to be a bad thing (although I don't think it's the best possible thing) for a developer to run on his machine, but I do think it's a horrible thing for the packaging formats to standardize on. |
@dstufft Yeah, we disagree in that regard. I detest setup.py files with the heat of thousand suns (and I've written a lot of them) because it not only allows as you say flexibility for developers how to create packages but actually forces them to think about packaging as a part of the development. But packaging and deployment problems are unrelated to the problems developers solve with their software, so why should they even care? Who decided that developers ought to be able to fiddle with how a language level packaging tool creates a package? The conceptual discrepancy between a pretended choice of implementation and the real world requirements of an easy and simple packaging standard, led developers to opt for relying on cargo culted shims instead of clearly defined metadata standards. Why can't we store the metadata in a file that is machine readable and can be created agnostically with whatever tool you like? Don't get me wrong, @dstufft, I've had this discussion about the best Python packaging pattern a hundred times and always had to reply "it depends". I've just had to iterate over my "solutions" too many times and have contributed to the cargo culting too often. It's a broken system, one that hurts Python. And I'm not willing to keep silent about this now that we're making progress in other parts of the packaging stack. |
@jezdez "Store metadata in a file that is machine readable and can be created agnostically with whatever tool you like" is exactly what PEP426 metadata is and setup.py is a perfectly valid tool for creating that file. If you take the method I suggested and create a Wheel there will be zero setup.py and people installing that file will be getting the metadata from a static source. The same will be true with sdist 2.0. In the future with zero changes on the developer machine besides upgrading to a newer version of setuptools but with no code changes this method (or any method that relies on code in setup.py) will continue to work just fine and will have a static meta-data file inside the actual packages with setup.py becoming similar to The benefits of my system is that most of the metadata is easily introspectable from a REPL, and is available for easy programmatic access without needing to depend on |
@dstufft Sorry but you just don't seem to get what I'm saying. Why do we need a shim around creating the metadata file if the developer of a package can create the file directly next to the package? Why is the standard not proposing to let me write the |
Well that's an option, but I was strongly against making that the requirement. The things you want from a file designed to be parsed by machines to determine the metadata (and figure out how to install a particular package) is different than the things you want from a file designed to be user facing. Just because they contain the same data doesn't mean the same format is appropriate. The To be frank I don't think having humans edit a However the standard does let you write a |
Hey, I just wanted to say that this discussion has been very helpful to me, thanks. If you're curious, after considering the various setup hack options, I'm going for the simple setup: changing the setup.py created by cookiecutter-pypackage to simply Having the ability to generate a I'm still learning how wheel works, but once I figure it out, I can update this if needed. Likewise with any other packaging changes. |
FTR another common work-around here is to use lower-level functions from the imp module to get the info from a |
see this for inspiration http://www.jeffknupp.com/blog/2013/08/16/open-sourcing-a-python-project-the-right-way/ and see this issue for more info: audreyfeldroy/cookiecutter-pypackage#1
Apparently, this can cause issues. Not clear how, but there you are. Here is a mitigation:
https://github.com/jezdez/envdir/blob/master/setup.py#L23-L33
The text was updated successfully, but these errors were encountered: