This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author gmt
Recipients dstufft, eric.araujo, gmt
Date 2014-12-23.06:36:26
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1419316588.75.0.487755278973.issue23102@psf.upfronthosting.co.za>
In-reply-to
Content
Clinical Presentation:
Sometimes a developer consuming distutils will write what seems like a perfectly sensible setup.py, but something inscrutable happens: setup.py bombs out claiming "error: each element of 'ext_modules' option must be an Extension instance or 2-tuple".

Prognosis:
Once she manages to capture this error in pdb (takes some doing), intrepid developer may discover that, bizarrely, it IS an Extension instance, yet, somehow, (not isinstance(that_thing, Extension)) == True.  Sooner or later she'll likely throw up her hands and follow some far-seeing dude's advice on StackOverflow([1]), which will probably work.

If she undertakes a more thorough investigation, she may figure out the true etiology (see below), at which point, various minor tweaks will likely present themselves to her as obvious situation-specific solutions to the problem.

Etiology:
Developer likely employed code early in her module like:

  from distutils.extension import Extension

  .
  . (some other imports)
  .

  setup(..., ext_modules = [
      Extension(...), 
      ...,
  ], ...)

What happened was that setuptools got imported by (presumably) some third-party code, at which point, setuptools monkey-patched distutils.extension.Extension(*), as is setuptools' SOP.

However, in setup.py, a reference to the un-monkey-patched Extension was already saved off as __main__.Extension (along with, in all probability, other un-patched distutils things, as folks tend to consistently use one style or another of import).  So __main__ calls (an un-monkey-patched version of) distutils.core.setup, which ultimately iterates through the list of Extensions, checking isinstance(item, Extension), or so, which, as can now be seen, is not going to be true.

So, the error message is correct, it just fails to mention the possibility that there are multiple things called "Extension" floating around with identical repr's.

Epidemiological Outlook:
Seemingly this is a rare condition, but when a case develops, it can be costly, due to the likelihood of misdiagnosis and/or partial remission and relapse.

One possible vaccine has been developed and is enclosed.  It has not been subjected to clinical trial, nor peer-review (until now).  It is enclosed as a patch which applies to python 2.7-3.5 and seems to do the trick in the particular case that was buggin' me (wish I could say it will do the trick for any non-broken use-case, but I can't, as if I made such a claim, I'd clearly jinx it).

--
* Arguably, this is a bug or misfeature of setuptools, as here setuptools appears to too liberally assume that, if its modules were even casually imported, then it's a good time to monkey-patch distutils.  However, IME, fixing this putative bug, threatens to be a non-trivial undertaking and cause a bunch of regressions and contingent hassles.

Background URLS:

[1] http://stackoverflow.com/questions/21594925/error-each-element-of-ext-modules-option-must-be-an-extension-instance-or-2-t

https://bitbucket.org/pypa/setuptools/issue/309

https://bugs.gentoo.org/show_bug.cgi?id=532708
History
Date User Action Args
2014-12-23 06:36:29gmtsetrecipients: + gmt, eric.araujo, dstufft
2014-12-23 06:36:28gmtsetmessageid: <1419316588.75.0.487755278973.issue23102@psf.upfronthosting.co.za>
2014-12-23 06:36:28gmtlinkissue23102 messages
2014-12-23 06:36:26gmtcreate