Single version number

What do people use to avoid repeating the version number both in the setup.py as well as in application/library code, when the application/library wants to know its own version number? I've seen several options: 1) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py do from yourpackage import __version__ and pass that to setup() 2) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py execfile(os.path.join(os.path.dirname(__file__), 'src', 'yourpackage', '__init__.py'), d), then use d['__version__'] 3) put a file called version.txt in yourpackage/, have setup.py read it, make sure it's included in MANIFEST.in 4) I don't recall actually ever seeing this one, but it should be possible to use pkg_resources to query the version of yourpackage (downside: if you're running from a source checkout without installing, you won't get the right version number) Marius Gedminas -- In order to get a loan you must first prove you don't need it.

On Jul 10, 2009, at 8:58 AM, Marius Gedminas wrote:
What do people use to avoid repeating the version number both in the setup.py as well as in application/library code, when the application/library wants to know its own version number?
I've seen several options:
1) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py do from yourpackage import __version__ and pass that to setup()
This is generally what I do and it seems to work pretty well for me. I remember talking with Gary Poster about some problems with this, related to our open source lazr packages, but I don't recall the details. -Barry

On Jul 10, 2009, at 9:24 AM, Barry Warsaw wrote:
On Jul 10, 2009, at 8:58 AM, Marius Gedminas wrote:
What do people use to avoid repeating the version number both in the setup.py as well as in application/library code, when the application/library wants to know its own version number?
I've seen several options:
1) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py do from yourpackage import __version__ and pass that to setup()
This is generally what I do and it seems to work pretty well for me. I remember talking with Gary Poster about some problems with this, related to our open source lazr packages, but I don't recall the details.
Basically, this means that your setup.py has to be able to import your package's __init__.py without any of the dependencies. If your __init__.py only has a __version__ then this is fine. However, if you want your __init__ to reexport something to avoid clients having to do foo.foo.Foo-style imports from your package, or if you want to put any other code in your __init__ that might need dependencies, this breaks. Gary

Dear Distutils SIG, I note that easy_install can be used behind a proxy simply by setting the "HTTP_PROXY" environment variable. But what of a proxy which requires authentication? Is there a technique that will allow me to specify some kind of authentication credentials in addition to the address & port of the proxy-server? Thanks! Sal Disclaimer CALYON UK: This email does not create a legal relationship between any member of the Cr=E9dit Agricole group and the recipient or constitute investment advice. The content of this email should not be copied or disclosed (in whole or part) to any other person. It may contain information which is confidential, privileged or otherwise protected from disclosure. If you are not the intended recipient, you should notify us and delete it from your system. Emails may be monitored, are not secure and may be amended, destroyed or contain viruses and in communicating with us such conditions are accepted. Any content which does not relate to business matters is not endorsed by us. Calyon is authorised by the Comit=e9 des Etablissements de Cr=e9dit et des Entreprises d'Investissement (CECEI) and supervised by the Commission Bancaire in France and subject to limited regulation by the Financial Services Authority. Details about the extent of our regulation by the Financial Services Authority are available from us on request. Calyon is incorporated in France with limited liability and registered in England & Wales. Registration number: FC008194. Registered office: Broadwalk House, 5 Appold Street, London, EC2A 2DA. Disclaimer CALYON France: This message and/or any attachments is intended for the sole use of its addressee. If you are not the addressee, please immediately notify the sender and then destroy the message. As this message and/or any attachments may have been altered without our knowledge, its content is not legally binding on CALYON Crédit Agricole CIB. All rights reserved. Ce message et ses pièces jointes est destiné à l'usage exclusif de son destinataire. Si vous recevez ce message par erreur, merci d'en aviser immédiatement l'expéditeur et de le détruire ensuite. Le présent message pouvant être altéré à notre insu, CALYON Crédit Agricole CIB ne peut pas être engagé par son contenu. Tous droits réservés.

One additional fact: I just discovered that the proxy uses NTLM authentication. There's a plugin here: http://code.google.com/p/python-ntlm/ Which allows me to do an NTLM auth on the proxy server - but is there a way to hook this auth-handler into easy_install, but is that even possible? Could this be done as some kind of easy_install plugin? Sal -----Original Message----- From: Salim, Fadhley (CALYON) Sent: 10 July 2009 16:25 To: 'Distutils-SIG@python.org' Subject: easy_install from behind an http proxy which requires authentication Dear Distutils SIG, I note that easy_install can be used behind a proxy simply by setting the "HTTP_PROXY" environment variable. But what of a proxy which requires authentication? Is there a technique that will allow me to specify some kind of authentication credentials in addition to the address & port of the proxy-server? Thanks! Sal Disclaimer CALYON UK: This email does not create a legal relationship between any member of the Cr=E9dit Agricole group and the recipient or constitute investment advice. The content of this email should not be copied or disclosed (in whole or part) to any other person. It may contain information which is confidential, privileged or otherwise protected from disclosure. If you are not the intended recipient, you should notify us and delete it from your system. Emails may be monitored, are not secure and may be amended, destroyed or contain viruses and in communicating with us such conditions are accepted. Any content which does not relate to business matters is not endorsed by us. Calyon is authorised by the Comit=e9 des Etablissements de Cr=e9dit et des Entreprises d'Investissement (CECEI) and supervised by the Commission Bancaire in France and subject to limited regulation by the Financial Services Authority. Details about the extent of our regulation by the Financial Services Authority are available from us on request. Calyon is incorporated in France with limited liability and registered in England & Wales. Registration number: FC008194. Registered office: Broadwalk House, 5 Appold Street, London, EC2A 2DA. Disclaimer CALYON France: This message and/or any attachments is intended for the sole use of its addressee. If you are not the addressee, please immediately notify the sender and then destroy the message. As this message and/or any attachments may have been altered without our knowledge, its content is not legally binding on CALYON Crédit Agricole CIB. All rights reserved. Ce message et ses pièces jointes est destiné à l'usage exclusif de son destinataire. Si vous recevez ce message par erreur, merci d'en aviser immédiatement l'expéditeur et de le détruire ensuite. Le présent message pouvant être altéré à notre insu, CALYON Crédit Agricole CIB ne peut pas être engagé par son contenu. Tous droits réservés.

On Fri, Jul 10, 2009 at 10:19:56AM -0400, Gary Poster wrote:
On Jul 10, 2009, at 9:24 AM, Barry Warsaw wrote:
On Jul 10, 2009, at 8:58 AM, Marius Gedminas wrote:
What do people use to avoid repeating the version number both in the setup.py as well as in application/library code, when the application/library wants to know its own version number?
I've seen several options:
1) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py do from yourpackage import __version__ and pass that to setup()
This is generally what I do and it seems to work pretty well for me. I remember talking with Gary Poster about some problems with this, related to our open source lazr packages, but I don't recall the details.
Basically, this means that your setup.py has to be able to import your package's __init__.py without any of the dependencies.
If your __init__.py only has a __version__ then this is fine. However, if you want your __init__ to reexport something to avoid clients having to do foo.foo.Foo-style imports from your package, or if you want to put any other code in your __init__ that might need dependencies, this breaks.
My __init__.py does "from _version import version as __version__" to solve this problem, setup.py then imports _version. Regards Floris -- Debian GNU/Linux -- The Power of Freedom www.debian.org | www.gnu.org | www.kernel.org

At 09:24 AM 7/10/2009 -0400, Barry Warsaw wrote:
On Jul 10, 2009, at 8:58 AM, Marius Gedminas wrote:
What do people use to avoid repeating the version number both in the setup.py as well as in application/library code, when the application/library wants to know its own version number?
I've seen several options:
1) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py do from yourpackage import __version__ and pass that to setup()
This is generally what I do and it seems to work pretty well for me. I remember talking with Gary Poster about some problems with this, related to our open source lazr packages, but I don't recall the details.
You'll have problems with this in the case where your __init__.py imports any of your dependencies (directly or indirectly), since it will effectively mean your setup.py will need its dependencies installed before it even says what they are. ;-) In such cases, putting a separate version.py or version.txt in the package, and execfile-ing it from setup.py is a better choice. Personally, I don't even bother putting version info in the package code; that's what pkg_resources is for. ;-)

On Jul 10, 2009, at 2:07 PM, P.J. Eby wrote:
At 09:24 AM 7/10/2009 -0400, Barry Warsaw wrote:
On Jul 10, 2009, at 8:58 AM, Marius Gedminas wrote:
What do people use to avoid repeating the version number both in the setup.py as well as in application/library code, when the application/library wants to know its own version number?
I've seen several options:
1) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py do from yourpackage import __version__ and pass that to setup()
This is generally what I do and it seems to work pretty well for me. I remember talking with Gary Poster about some problems with this, related to our open source lazr packages, but I don't recall the details.
You'll have problems with this in the case where your __init__.py imports any of your dependencies (directly or indirectly), since it will effectively mean your setup.py will need its dependencies installed before it even says what they are. ;-)
In such cases, putting a separate version.py or version.txt in the package, and execfile-ing it from setup.py is a better choice.
Personally, I don't even bother putting version info in the package code; that's what pkg_resources is for. ;-)
Gotcha. I generally don't put /anything/ except __version__ in my top level package __init__.py, but this is good to keep in mind. Still, I should probably be using pkg_resources instead. Thanks, -Barry

On Jul 10, 2009, at 7:24 AM, Barry Warsaw wrote:
On Jul 10, 2009, at 8:58 AM, Marius Gedminas wrote:
1) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py do from yourpackage import __version__ and pass that to setup()
This is generally what I do and it seems to work pretty well for me. I remember talking with Gary Poster about some problems with this, related to our open source lazr packages, but I don't recall the details.
This idiom seems to cause problem for building Nevow, when it isn't being built in a fresh process all by itself (i.e. "python ./setup.py build") but is instead being built inside a more complicated setting, such as when it is one of the module being packaged up by py2exe, or when it is the dependency of something which is being built by setuptools: http://divmod.org/trac/ticket/2699 Regards, Zooko

On Fri, 10 Jul 2009 15:58:32 +0300, Marius Gedminas <marius@pov.lt> wrote:
What do people use to avoid repeating the version number both in the setup.py as well as in application/library code, when the application/library wants to know its own version number?
I've seen several options:
1) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py do from yourpackage import __version__ and pass that to setup()
2) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py execfile(os.path.join(os.path.dirname(__file__), 'src', 'yourpackage', '__init__.py'), d), then use d['__version__']
3) put a file called version.txt in yourpackage/, have setup.py read it, make sure it's included in MANIFEST.in
4) I don't recall actually ever seeing this one, but it should be possible to use pkg_resources to query the version of yourpackage (downside: if you're running from a source checkout without installing, you won't get the right version number)
There was some discussion of this here a couple months ago: http://mail.python.org/pipermail/distutils-sig/2009-May/011913.html Jean-Paul

On Fri, Jul 10, 2009 at 09:29:51AM -0400, Jean-Paul Calderone wrote:
On Fri, 10 Jul 2009 15:58:32 +0300, Marius Gedminas <marius@pov.lt> wrote:
What do people use to avoid repeating the version number both in the setup.py as well as in application/library code, when the application/library wants to know its own version number?
I've seen several options:
1) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py do from yourpackage import __version__ and pass that to setup()
2) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py execfile(os.path.join(os.path.dirname(__file__), 'src', 'yourpackage', '__init__.py'), d), then use d['__version__']
3) put a file called version.txt in yourpackage/, have setup.py read it, make sure it's included in MANIFEST.in
4) I don't recall actually ever seeing this one, but it should be possible to use pkg_resources to query the version of yourpackage (downside: if you're running from a source checkout without installing, you won't get the right version number)
There was some discussion of this here a couple months ago:
http://mail.python.org/pipermail/distutils-sig/2009-May/011913.html
Thank you for the link. I shoud've thought to do a search before asking. Marius Gedminas -- If the code and the comments disagree, then both are probably wrong. -- Norm Schryer

On Jul 10, 2009, at 8:58 AM, Marius Gedminas wrote:
What do people use to avoid repeating the version number both in the setup.py as well as in application/library code, when the application/library wants to know its own version number?
...
4) I don't recall actually ever seeing this one, but it should be possible to use pkg_resources to query the version of yourpackage
Yup. I've recommended this to folks in the past.
(downside: if you're running from a source checkout without installing, you won't get the right version number)
I think you do as long as you run setup.py develop. Jim -- Jim Fulton Zope Corporation

Marius Gedminas <marius@pov.lt> writes:
What do people use to avoid repeating the version number both in the setup.py as well as in application/library code, when the application/library wants to know its own version number?
I've seen several options:
1) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py do from yourpackage import __version__ and pass that to setup()
I do a variant on this: ‘mainpackage/version.py’ contains attributes for version string, author details, copyright license, and so on. The ‘mainpackage/__init__.py’ docstring is parsed for the short and long description; it often has the project URL too. Using Bazaar, I can also (with ‘bzr version-info --format=python’) automatically generate an importable module with information about the current VCS head revision; sometimes I use that to put the revision number in the version string, or to get the end-year of a copyright year range, etc. -- \ “Judge: A law student who marks his own papers.” —Henry L. | `\ Mencken | _o__) | Ben Finney

At 03:58 PM 7/10/2009 +0300, Marius Gedminas wrote:
What do people use to avoid repeating the version number both in the setup.py as well as in application/library code, when the application/library wants to know its own version number?
I've seen several options:
1) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py do from yourpackage import __version__ and pass that to setup()
2) put __version__ = '4.2' in yourpackage/__init__.py, have setup.py execfile(os.path.join(os.path.dirname(__file__), 'src', 'yourpackage', '__init__.py'), d), then use d['__version__']
3) put a file called version.txt in yourpackage/, have setup.py read it, make sure it's included in MANIFEST.in
4) I don't recall actually ever seeing this one, but it should be possible to use pkg_resources to query the version of yourpackage (downside: if you're running from a source checkout without installing, you won't get the right version number)
You'll get the right version number if you use "setup.py develop" to add it to your global sys.path, and/or run "setup.py egg_info" to update the version info whenever it changes. The simplest formula for retrieving the version in that case is 'pkg_resources.require("Projectname")[0].version'.

On Jul 10, 2009, at 6:58 AM, Marius Gedminas wrote:
What do people use to avoid repeating the version number both in the setup.py as well as in application/library code, when the application/library wants to know its own version number?
I have a script that reads revision control history and writes out a _version.py file with just "verstr='1.2.3'" in it. Then my setup.py does this: PKG = "zfec" VERSIONFILE = PKG+"/_version.py" verstr = "unknown" try: verstrline = open(VERSIONFILE, "rt").read() except EnvironmentError: pass # Okay, there is no version file. else: VSRE = r"^verstr = ['\"]([^'\"]*)['\"]" mo = re.search(VSRE, verstrline, re.M) if mo: verstr = mo.group(1) else: print "unable to find version in %s" % (VERSIONFILE,) raise RuntimeError("if %s.py exists, it is required to be well-formed" % (VERSIONFILE,)) I packaged up the script that reads revision control history (darcs) and writes out the _version.py file as "darcsver": http:// pypi.python.org/pypi/darcsver . It can be invoked as a command-line tool or a setuptools plugin. I also then extended the darcsver setuptools plugin so that it would do effectively the same thing as the above code, so that I don't have to copy that code into each of my setup.py files. Unfortunately issue20 of setuptools (http://bugs.python.org/setuptools/msg235 ) means that at most one of my packages can use darcsver to do that in the same build, so currently my Tahoe project uses darcsver to set the "version" attribute and doesn't have that code snippet that I pasted above, but my other projects (many of which Tahoe depends on) have that code snippet in the setup.py. Regards, Zooko
participants (10)
-
Barry Warsaw
-
Ben Finney
-
Fadhley Salim
-
Floris Bruynooghe
-
Gary Poster
-
Jean-Paul Calderone
-
Jim Fulton
-
Marius Gedminas
-
P.J. Eby
-
Zooko Wilcox-O'Hearn