New submission from Greg Turner:

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

----------
components: Distutils
files: distutils_accomodate_extension_ducktypes.patch
keywords: patch
messages: 233034
nosy: dstufft, eric.araujo, gmt
priority: normal
severity: normal
status: open
title: distutils: tip-toe around quirks owing to setuptools monkey-patching 
Extension
type: behavior
versions: Python 2.7, Python 3.2, Python 3.3, Python 3.4, Python 3.5, Python 3.6
Added file: 
http://bugs.python.org/file37529/distutils_accomodate_extension_ducktypes.patch

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue23102>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to