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.

Title: run_setup() behavior differs from cli invocation of
Type: behavior Stage: resolved
Components: Distutils Versions:
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: eric.araujo Nosy List: eric.araujo, l, steve.dower, tarek
Priority: normal Keywords: patch

Created on 2013-09-08 13:36 by l, last changed 2022-04-11 14:57 by admin. This issue is now closed.

File name Uploaded Description Edit
run_setup-py32-py33-py34.diff l, 2013-09-08 13:36 review
run_setup-py31.diff l, 2013-09-08 13:37 review
run_setup-py27.diff l, 2013-09-08 13:37 review
run_setup-py26.diff l, 2013-09-08 13:38 review
Messages (3)
msg197259 - (view) Author: Lukas Wunner (l) Date: 2013-09-08 13:36
The principle of least surprise suggests that run_setup() should behave equivalently to a command line invocation of However there are currently (at least) two issues preventing this:

(a) When calling exec(), both a globals and a locals dict is passed.

According to the documentation: "If exec gets two separate objects as globals and locals, the code will be executed as if it were embedded in a class definition." [1] Consequence: "The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods". [2]

One example where this is relevant is the "MarkupSafe" PyPI package [3]: Its defines a class BuildFailed which is used in other methods defined in Calling run_setup() with this will therefore fail. Calling from the command line works.

Solution: Only pass a globals dict to exec().

(b) The globals dict does not contain '__name__':'__main__'.

Many scripts use the idiomatic 'conditional script' stanza "if __name__ == '__main__'". An example is the "PyYAML" PyPI package. [4] In these cases, run_setup() will raise a RuntimeError exception ("'distutils.core.setup()' was never called").

Solution: Add '__name__':'__main__' to the globals dict.

Attached are patches to fix these issues in Python 2.6 to 3.4.

msg213225 - (view) Author: Éric Araujo (eric.araujo) * (Python committer) Date: 2014-03-12 09:11
> The principle of least surprise suggests that run_setup() should behave equivalently
> to a command line invocation of

That’s debatable: distutils.core.setup corresponds to a command-line invocation of, but run_setup is documented as something else:

In general, distutils lends itself poorly to programmatic usage.  Can you tell more about your use case for calling run_setup directly?

> Many scripts use the idiomatic 'conditional script' stanza
> "if __name__ == '__main__'".

That’s surprising to me: scripts are not modules-that-also-work-as-scripts, only scripts.
msg386421 - (view) Author: Steve Dower (steve.dower) * (Python committer) Date: 2021-02-03 18:30
Distutils is now deprecated (see PEP 632) and all tagged issues are being closed. From now until removal, only release blocking issues will be considered for distutils.

If this issue does not relate to distutils, please remove the component and reopen it. If you believe it still requires a fix, most likely the issue should be re-reported at
Date User Action Args
2022-04-11 14:57:50adminsetgithub: 63170
2021-02-03 18:30:33steve.dowersetstatus: open -> closed

nosy: + steve.dower
messages: + msg386421

resolution: out of date
stage: resolved
2014-03-12 09:11:02eric.araujosetmessages: + msg213225
versions: - Python 2.6, Python 3.1, Python 2.7, Python 3.2, Python 3.3, Python 3.4
2013-09-08 13:38:06lsetfiles: + run_setup-py26.diff
2013-09-08 13:37:48lsetfiles: + run_setup-py27.diff
2013-09-08 13:37:23lsetfiles: + run_setup-py31.diff
2013-09-08 13:36:31lcreate