inability to pass setup.py command line arguments to dependency setups
Consider the case where you want your setup to install third-party software, but you want/need to pass an argument to the command line that runs "python setup.py --argument install" or "python setup.py -- argument bdist_egg" As far as I could research, this feature is unavailable. If there is a graceful way to accomplish this I would really like to know. If there is no way, I offer a workaround to those who require this functionality. Consider a setup.py with the following setup() function call: ________________________________________________________________________________________ setup( name='pylotengine', version='0.1', description='', author='', author_email='', install_requires=[ "SQLAlchemy >= 0.6", "tg.devtools >= 2.0.1", ... ... ) ________________________________________________________________________________________ Now, when SQLAlchemy is to be installed, there is a really nice feature that can be enabled to build it with C extensions for performance, so you want easy_install to run: "python setup.py --with-cextensions bdist_egg" instead of just: "python setup.py bdist_egg" In order to pass the "--with-cextensions" argument, I do the following (again, not a very graceful solution): ________________________________________________________________________________________ # -*- coding: utf-8 -*- try: from setuptools import setup, find_packages except ImportError: from ez_setup import use_setuptools use_setuptools() from setuptools import setup, find_packages #kb: since apparently setuptools has no mechanism to pass # arguments to the dependencies, I am "decorating" the function # that runs the command and adding the arguments myself... from setuptools.command.easy_install import easy_install normal_run_setup_fn = easy_install.run_setup def setup_hook(self, setup_script, setup_base, args): # SQLAlchemy we want to run setup.py --with-cextensions if setup_script.find('/SQLAlchemy') > -1 and setup_script.endswith('setup.py'): args.insert(0,'--with-cextensions') normal_run_setup_fn(self, setup_script, setup_base, args) easy_install.run_setup = setup_hook setup( name='pylotengine', version='0.1', description='', author='', author_email='', #url='', install_requires=[ #kb start "SQLAlchemy >= 0.6", "tg.devtools >= 2.0.1", "psycopg2 >= 2.0.11", ... ...rest of setup() call... ________________________________________________________________________________________ Hope this is helpful to someone...
On May 7, 2010, at 9:09 AM, Kent wrote:
Consider the case where you want your setup to install third-party software, but you want/need to pass an argument to the command line that runs "python setup.py --argument install" or "python setup.py -- argument bdist_egg"
As far as I could research, this feature is unavailable.
And for good reason, I should think. I really hope that nobody ever adds this feature. If you require SQLAlchemy to be installed "--with-cextensions", then what happens when your package is installed in an environment that already has SQLAlchemy installed *without* that flag? Does it stomp on the existing installation? What if the user installed one already with that flag and some other flags as well? What if it's system-installed and you're doing a user-install? Basically, compile-time and install-time options are a configuration nightmare. They should represent only how and where a package is installed, not what features it has. The correct solution to your problem would be to get SQLAlchemy to fix its broken deployment setup and split itself into 2 packages, "SQLAlchemyCExtensions" and "SQLAlchemy", and then have your project depend on both, not to try to cram installer options into the dependency language. For confirmation of this theory, you need look no further than the excruciating user-experience of source-based installation systems with 'variant' support, like gentoo's Portage and *BSD's Ports, versus the relatively non-excruciating experience of packaging systems which express compile-time options as different packages like Yum and Apt.
Just because there are configuration problems associated with adding a feature like the one I needed is absolutely no reason to abandon it when it can bring value to the tool if used correctly and in some circumstances. I considered some of those exact complications "what if it was already installed, etc" and with my company's project, where I am using this useful tool in a circumstance you may overlook (it is perfectly acceptable to have such a feature, *despite* the list of complications you mention), such a feature would have been very valuable. Since it is useful in my case, I understand it would be valuable for others as well. (I don't appreciate the aggressive tone of your reply, though, nor do I see how my good faith efforts to help others warrant this... how did I possibly offend you with my post??) On the other hand, I appreciate your "correct solution" as a good approach and I'll forward this idea to an author of SQLAlchemy for his consideration. On 5/7/2010 1:33 PM, Glyph Lefkowitz wrote:
On May 7, 2010, at 9:09 AM, Kent wrote:
Consider the case where you want your setup to install third-party software, but you want/need to pass an argument to the command line that runs "python setup.py --argument install" or "python setup.py -- argument bdist_egg"
As far as I could research, this feature is unavailable.
And for good reason, I should think. I really hope that nobody ever adds this feature.
If you require SQLAlchemy to be installed "--with-cextensions", then what happens when your package is installed in an environment that already has SQLAlchemy installed *without* that flag? Does it stomp on the existing installation? What if the user installed one already with that flag and some other flags as well? What if it's system-installed and you're doing a user-install?
Basically, compile-time and install-time options are a configuration nightmare. They should represent only how and where a package is installed, not what features it has. The correct solution to your problem would be to get SQLAlchemy to fix its broken deployment setup and split itself into 2 packages, "SQLAlchemyCExtensions" and "SQLAlchemy", and then have your project depend on both, not to try to cram installer options into the dependency language.
For confirmation of this theory, you need look no further than the excruciating user-experience of source-based installation systems with 'variant' support, like gentoo's Portage and *BSD's Ports, versus the relatively non-excruciating experience of packaging systems which express compile-time options as different packages like Yum and Apt.
I'd only mention that Storm has a C extension/non C extension flag as well, and only offers one source distribution on Pypi. You have to modify a variable directly within setup.py. Our setup.py features the same capability (its just our C extension is off by default for 0.6 since it was just written, which is the same case for when Storm first introduced its C extension). On May 7, 2010, at 1:56 PM, Kent Bower wrote:
Just because there are configuration problems associated with adding a feature like the one I needed is absolutely no reason to abandon it when it can bring value to the tool if used correctly and in some circumstances. I considered some of those exact complications "what if it was already installed, etc" and with my company's project, where I am using this useful tool in a circumstance you may overlook (it is perfectly acceptable to have such a feature, *despite* the list of complications you mention), such a feature would have been very valuable.
Since it is useful in my case, I understand it would be valuable for others as well.
(I don't appreciate the aggressive tone of your reply, though, nor do I see how my good faith efforts to help others warrant this... how did I possibly offend you with my post??)
On the other hand, I appreciate your "correct solution" as a good approach and I'll forward this idea to an author of SQLAlchemy for his consideration.
On 5/7/2010 1:33 PM, Glyph Lefkowitz wrote:
On May 7, 2010, at 9:09 AM, Kent wrote:
Consider the case where you want your setup to install third-party software, but you want/need to pass an argument to the command line that runs "python setup.py --argument install" or "python setup.py -- argument bdist_egg"
As far as I could research, this feature is unavailable.
And for good reason, I should think. I really hope that nobody ever adds this feature.
If you require SQLAlchemy to be installed "--with-cextensions", then what happens when your package is installed in an environment that already has SQLAlchemy installed *without* that flag? Does it stomp on the existing installation? What if the user installed one already with that flag and some other flags as well? What if it's system-installed and you're doing a user-install?
Basically, compile-time and install-time options are a configuration nightmare. They should represent only how and where a package is installed, not what features it has. The correct solution to your problem would be to get SQLAlchemy to fix its broken deployment setup and split itself into 2 packages, "SQLAlchemyCExtensions" and "SQLAlchemy", and then have your project depend on both, not to try to cram installer options into the dependency language.
For confirmation of this theory, you need look no further than the excruciating user-experience of source-based installation systems with 'variant' support, like gentoo's Portage and *BSD's Ports, versus the relatively non-excruciating experience of packaging systems which express compile-time options as different packages like Yum and Apt.
-- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
On May 7, 2010, at 2:08 PM, Michael Bayer wrote:
I'd only mention that Storm has a C extension/non C extension flag as well, and only offers one source distribution on Pypi. You have to modify a variable directly within setup.py. Our setup.py features the same capability (its just our C extension is off by default for 0.6 since it was just written, which is the same case for when Storm first introduced its C extension).
It occurs to me that Twisted has a similar problem (except there's no installation flag: it just builds the C extensions if it possibly can). The problem I see here is that the dependencies list of a particular project should be a complete expression of the features that the source code requires to function properly. If a C extension is present for optimization purposes only, then I don't think it ever needs to be mentioned in a dependency listing. Performance tuning is a build and deployment issue, not a dependency-correctness issue. However, if a C extension wraps features necessary for an application to work correctly, without which it will simply traceback and die, then it should be possible for the application to say "I depend on this functionality". After all, it's kind of bogus if I say "I depend on library X", and then library X gets installed, but half of it is missing for some reason. It's bogus if it's missing for any reason at all, really. The "C extension couldn't be compiled" one is common, but there are other configuration and build issues which could prevent a distribution from being fully functional. Is there already a good way to express a dependency on a portion of a source distribution, or "optional" features? A way to list one source distribution on PyPI so that it will be present under multiple names, one for each optional chunk?
On Sat, May 8, 2010 at 07:48, Glyph Lefkowitz
a dependency-correctness issue. However, if a C extension wraps features necessary for an application to work correctly, without which it will simply traceback and die, then it should be possible for the application to say "I depend on this functionality".
I think setuptools can do this, but I've never used it so I'm not sure. Another option would to package the extensions as a separate package, so you get 'MySQL' and 'MySQL-C-extensions'. Problem solved. :) -- Lennart Regebro: Python, Zope, Plone, Grok http://regebro.wordpress.com/ +33 661 58 14 64
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Lennart Regebro wrote:
On Sat, May 8, 2010 at 07:48, Glyph Lefkowitz
wrote: a dependency-correctness issue. However, if a C extension wraps features necessary for an application to work correctly, without which it will simply traceback and die, then it should be possible for the application to say "I depend on this functionality".
I think setuptools can do this, but I've never used it so I'm not sure.
Another option would to package the extensions as a separate package, so you get 'MySQL' and 'MySQL-C-extensions'. Problem solved. :)
That is effectivaly what the "extras" bit in setuptools does[ http://peak.telecommunity.com/DevCenter/setuptools#declaring-extras-optional... Tres. - -- =================================================================== Tres Seaver +1 540-429-0999 tseaver@palladion.com Palladion Software "Excellence by Design" http://palladion.com -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAkvoUd8ACgkQ+gerLs4ltQ6zxQCePHJfWk8mvoQrt7k8n8s4TfOk FmAAnAl3XT1HZK1oeP2Yq1HgLzQQJHTf =HZXH -----END PGP SIGNATURE-----
On Mon, May 10, 2010 at 20:35, Tres Seaver
http://peak.telecommunity.com/DevCenter/setuptools#declaring-extras-optional...
Right, that's what I was thinking of. Clearly in this case, the MySQL package should declare it's C-extensions as an "extra". -- Lennart Regebro: Python, Zope, Plone, Grok http://regebro.wordpress.com/ +33 661 58 14 64
FWIW, it is perfectly possible to package the thing separately as
Glyph seem to suggest, even if the feature is enabled through an
option. For example, Debian does it:
http://packages.debian.org/experimental/python-sqlalchemy-ext
On Fri, May 7, 2010 at 19:56, Kent Bower
Just because there are configuration problems associated with adding a feature like the one I needed is absolutely no reason to abandon it when it can bring value to the tool if used correctly and in some circumstances. I considered some of those exact complications "what if it was already installed, etc" and with my company's project, where I am using this useful tool in a circumstance you may overlook (it is perfectly acceptable to have such a feature, *despite* the list of complications you mention), such a feature would have been very valuable.
Since it is useful in my case, I understand it would be valuable for others as well.
(I don't appreciate the aggressive tone of your reply, though, nor do I see how my good faith efforts to help others warrant this... how did I possibly offend you with my post??)
On the other hand, I appreciate your "correct solution" as a good approach and I'll forward this idea to an author of SQLAlchemy for his consideration.
On 5/7/2010 1:33 PM, Glyph Lefkowitz wrote:
On May 7, 2010, at 9:09 AM, Kent wrote:
Consider the case where you want your setup to install third-party software, but you want/need to pass an argument to the command line that runs "python setup.py --argument install" or "python setup.py -- argument bdist_egg"
As far as I could research, this feature is unavailable.
And for good reason, I should think. I really hope that nobody ever adds this feature.
If you require SQLAlchemy to be installed "--with-cextensions", then what happens when your package is installed in an environment that already has SQLAlchemy installed *without* that flag? Does it stomp on the existing installation? What if the user installed one already with that flag and some other flags as well? What if it's system-installed and you're doing a user-install?
Basically, compile-time and install-time options are a configuration nightmare. They should represent only how and where a package is installed, not what features it has. The correct solution to your problem would be to get SQLAlchemy to fix its broken deployment setup and split itself into 2 packages, "SQLAlchemyCExtensions" and "SQLAlchemy", and then have your project depend on both, not to try to cram installer options into the dependency language.
For confirmation of this theory, you need look no further than the excruciating user-experience of source-based installation systems with 'variant' support, like gentoo's Portage and *BSD's Ports, versus the relatively non-excruciating experience of packaging systems which express compile-time options as different packages like Yum and Apt.
-- Gaëtan de Menten
The build option for C extension or not is taken directly from the setup.py of Genshi, the template language, and as I said was also inspired by what Storm does in this regard. I think once we put the flag on by default there really won't be any controversy anymore - both of those packages build the C extension by default. It seems awkward that a source distribution (emphasis on the word "source") would be broken up into two among configuration options (not to mention it would be totally inconvenient on my side). What if our build had six flags, not two - would I then provide SQLAlchemy as six separate downloads on Pypi ? e.g. the source distro of the Python Imaging Library has a whole set of flags you can set within setup.py to assist in its location of libraries - there's not much getting around those at the level of the source distro - a source distribution only represents the source code, not its particular configuration in a particular environment. You may say these are all broken configurations, but the simple fact is that we talking about a source distribution, not a dpkg or rpm. When you get PIL as a dpkg on your Ubuntu system, its pre-configured for the correct locations of libjpeg and such. Its a problem that is solved by those packaging libraries but is not solved by Python source distros on Pypi. The setuptools analogue to dpkg and rpm, I think, would be an .egg file. If someone wants to distrbute SQLAlchemy in some kind of package oriented system with pre-selected options, outside the realm of well known unix package managers, they can always package it as such. On May 7, 2010, at 2:58 PM, Gaetan de Menten wrote:
FWIW, it is perfectly possible to package the thing separately as Glyph seem to suggest, even if the feature is enabled through an option. For example, Debian does it: http://packages.debian.org/experimental/python-sqlalchemy-ext
On Fri, May 7, 2010 at 19:56, Kent Bower
wrote: Just because there are configuration problems associated with adding a feature like the one I needed is absolutely no reason to abandon it when it can bring value to the tool if used correctly and in some circumstances. I considered some of those exact complications "what if it was already installed, etc" and with my company's project, where I am using this useful tool in a circumstance you may overlook (it is perfectly acceptable to have such a feature, *despite* the list of complications you mention), such a feature would have been very valuable.
Since it is useful in my case, I understand it would be valuable for others as well.
(I don't appreciate the aggressive tone of your reply, though, nor do I see how my good faith efforts to help others warrant this... how did I possibly offend you with my post??)
On the other hand, I appreciate your "correct solution" as a good approach and I'll forward this idea to an author of SQLAlchemy for his consideration.
On 5/7/2010 1:33 PM, Glyph Lefkowitz wrote:
On May 7, 2010, at 9:09 AM, Kent wrote:
Consider the case where you want your setup to install third-party software, but you want/need to pass an argument to the command line that runs "python setup.py --argument install" or "python setup.py -- argument bdist_egg"
As far as I could research, this feature is unavailable.
And for good reason, I should think. I really hope that nobody ever adds this feature.
If you require SQLAlchemy to be installed "--with-cextensions", then what happens when your package is installed in an environment that already has SQLAlchemy installed *without* that flag? Does it stomp on the existing installation? What if the user installed one already with that flag and some other flags as well? What if it's system-installed and you're doing a user-install?
Basically, compile-time and install-time options are a configuration nightmare. They should represent only how and where a package is installed, not what features it has. The correct solution to your problem would be to get SQLAlchemy to fix its broken deployment setup and split itself into 2 packages, "SQLAlchemyCExtensions" and "SQLAlchemy", and then have your project depend on both, not to try to cram installer options into the dependency language.
For confirmation of this theory, you need look no further than the excruciating user-experience of source-based installation systems with 'variant' support, like gentoo's Portage and *BSD's Ports, versus the relatively non-excruciating experience of packaging systems which express compile-time options as different packages like Yum and Apt.
-- Gaëtan de Menten _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org http://mail.python.org/mailman/listinfo/distutils-sig
On May 7, 2010, at 1:56 PM, Kent Bower wrote:
(I don't appreciate the aggressive tone of your reply, though, nor do I see how my good faith efforts to help others warrant this... how did I possibly offend you with my post??)
Let me start here to set the tone: Please note that I am not attacking _you_. I thought that this was pretty clear, but if anything I said (in either my previous message or this one) could be construed as a personal attack, then I sincerely apologize: that was not and is not my intention. If anything, I'm grateful to you for bringing this up, and giving me a clear example to express my views on this issue, so they are recorded for future askers of similar questions. I'm enthusiastically attacking your *proposed feature*, because I think it's a terrible idea that will cause lots of problems if implemented, but I don't believe you suggested it in bad faith or have otherwise malicious intent.
Just because there are configuration problems associated with adding a feature like the one I needed is absolutely no reason to abandon it when it can bring value to the tool if used correctly and in some circumstances.
Here's a somewhat exaggerated example. It may be convenient for some people, in some circumstances, to attach an exposed lawnmower blade to a child's toy. Maybe they're out playing with their kids and want to mow the lawn at the same time: if the toys are also all lawnmowers, it's super convenient. And there's of course no problem if this feature is used correctly, in the right circumstances: by adults, carefully, to mow lawns. However, most toy manufacturers would agree that it is not worth the risk of taking off a child's hands or head to provide someone with that additional convenience. If you want a lawnmower, buy a lawnmower and use it to mow your lawn. Don't go welding exposed blades to every available household object that may be at hand when you're in your yard.
I considered some of those exact complications "what if it was already installed, etc" and with my company's project, where I am using this useful tool in a circumstance you may overlook (it is perfectly acceptable to have such a feature, *despite* the list of complications you mention), such a feature would have been very valuable.
In your particular case, what you're trying to do is deploy an application, not express code dependencies. While I haven't used Buildout personally, my understanding is that this is the sort of thing that Buildout is intended to do: deploy a specific application with specific dependencies in a carefully-controlled environment. I have no idea if Buildout can do precisely what you want, but if not, there are plenty of other tools which do similar things: makefiles, shell scripts, fabric, capistrano... and each of these tools let you encode that consideration that you've done in a dedicated place, rather than injecting it somewhere it doesn't belong (your application logic, your setup.py). The risk here, which I am keen to avoid, is that if you provide the ability to pass command line arguments via setup.py, people will start uploading packages that do that to PyPI. Gradually, half of your dependencies will start wanting to pass conflicting sets of "helpful" options to their dependencies at installation time, and getting your library packages installed will be an even bigger mess than it is right now. For the most part, distutils needs *fewer* knobs that developers and packagers can turn; this is not one of the few places where it needs more. See all the recent work that's gone into statically expressing all dependencies in a data format, without even having a setup.py. This is a manifestation of a social problem in open source projects; rather than fix a problem correctly, there is a temptation to say "just let me pass through my options so it works for me". If you want to depend on C extensions in SQLAlchemy, there should be a proper way to do that so that it works regardless of what other packages you happen to have installed or how they got there. (See "standing up to user pressure", here: http://ometer.com/free-software-ui.html.)
On the other hand, I appreciate your "correct solution" as a good approach and I'll forward this idea to an author of SQLAlchemy for his consideration.
Thanks. Good luck getting that fix in! :)
participants (7)
-
Gaetan de Menten
-
Glyph Lefkowitz
-
Kent
-
Kent Bower
-
Lennart Regebro
-
Michael Bayer
-
Tres Seaver