From: JinWang An Date: Mon, 27 Mar 2023 08:02:39 +0000 (+0900) Subject: Imported Upstream version 59.3.0 X-Git-Tag: upstream/59.3.0^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a8354a74c67c808a9ef8b93dc82778a073f210c7;p=platform%2Fupstream%2Fpython-setuptools.git Imported Upstream version 59.3.0 --- diff --git a/.bumpversion.cfg b/.bumpversion.cfg index a9d31cd..67dc085 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 59.2.0 +current_version = 59.3.0 commit = True tag = True diff --git a/CHANGES.rst b/CHANGES.rst index 3206647..8fbae4f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,16 @@ +v59.3.0 +------- + + +Changes +^^^^^^^ +* #2902: Merge with pypa/distutils@85db7a41242. + +Misc +^^^^ +* #2906: In ensure_local_distutils, re-use DistutilsMetaFinder to load the module. Avoids race conditions when _distutils_system_mod is employed. + + v59.2.0 ------- diff --git a/_distutils_hack/__init__.py b/_distutils_hack/__init__.py index 5f40996..f707416 100644 --- a/_distutils_hack/__init__.py +++ b/_distutils_hack/__init__.py @@ -48,11 +48,15 @@ def enabled(): def ensure_local_distutils(): clear_distutils() - distutils = importlib.import_module('setuptools._distutils') - distutils.__name__ = 'distutils' - sys.modules['distutils'] = distutils - # sanity check that submodules load as expected + # With the DistutilsMetaFinder in place, + # perform an import to cause distutils to be + # loaded from setuptools._distutils. Ref #2906. + add_shim() + importlib.import_module('distutils') + remove_shim() + + # check that submodules load as expected core = importlib.import_module('distutils.core') assert '_distutils' in core.__file__, core.__file__ diff --git a/setup.cfg b/setup.cfg index 7909ea1..6aabb1a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = setuptools -version = 59.2.0 +version = 59.3.0 author = Python Packaging Authority author_email = distutils-sig@python.org description = Easily download, build, install, upgrade, and uninstall Python packages diff --git a/setuptools/_distutils/core.py b/setuptools/_distutils/core.py index d603d4a..f43888e 100644 --- a/setuptools/_distutils/core.py +++ b/setuptools/_distutils/core.py @@ -8,6 +8,7 @@ really defined in distutils.dist and distutils.cmd. import os import sys +import tokenize from distutils.debug import DEBUG from distutils.errors import * @@ -144,29 +145,41 @@ def setup (**attrs): # And finally, run all the commands found on the command line. if ok: - try: - dist.run_commands() - except KeyboardInterrupt: - raise SystemExit("interrupted") - except OSError as exc: - if DEBUG: - sys.stderr.write("error: %s\n" % (exc,)) - raise - else: - raise SystemExit("error: %s" % (exc,)) - - except (DistutilsError, - CCompilerError) as msg: - if DEBUG: - raise - else: - raise SystemExit("error: " + str(msg)) + return run_commands(dist) return dist # setup () +def run_commands (dist): + """Given a Distribution object run all the commands, + raising ``SystemExit`` errors in the case of failure. + + This function assumes that either ``sys.argv`` or ``dist.script_args`` + is already set accordingly. + """ + try: + dist.run_commands() + except KeyboardInterrupt: + raise SystemExit("interrupted") + except OSError as exc: + if DEBUG: + sys.stderr.write("error: %s\n" % (exc,)) + raise + else: + raise SystemExit("error: %s" % (exc,)) + + except (DistutilsError, + CCompilerError) as msg: + if DEBUG: + raise + else: + raise SystemExit("error: " + str(msg)) + + return dist + + def run_setup (script_name, script_args=None, stop_after="run"): """Run a setup script in a somewhat controlled environment, and return the Distribution instance that drives things. This is useful @@ -205,14 +218,16 @@ def run_setup (script_name, script_args=None, stop_after="run"): _setup_stop_after = stop_after save_argv = sys.argv.copy() - g = {'__file__': script_name} + g = {'__file__': script_name, '__name__': '__main__'} try: try: sys.argv[0] = script_name if script_args is not None: sys.argv[1:] = script_args - with open(script_name, 'rb') as f: - exec(f.read(), g) + # tokenize.open supports automatic encoding detection + with tokenize.open(script_name) as f: + code = f.read().replace(r'\r\n', r'\n') + exec(code, g) finally: sys.argv = save_argv _setup_stop_after = None diff --git a/setuptools/_distutils/tests/test_core.py b/setuptools/_distutils/tests/test_core.py index 666ff4a..d99cfd2 100644 --- a/setuptools/_distutils/tests/test_core.py +++ b/setuptools/_distutils/tests/test_core.py @@ -10,6 +10,7 @@ from . import py38compat as os_helper import unittest from distutils.tests import support from distutils import log +from distutils.dist import Distribution # setup script that uses __file__ setup_using___file__ = """\ @@ -45,6 +46,16 @@ class install(_install): setup(cmdclass={'install': install}) """ +setup_within_if_main = """\ +from distutils.core import setup + +def main(): + return setup(name="setup_within_if_main") + +if __name__ == "__main__": + main() +""" + class CoreTestCase(support.EnvironGuard, unittest.TestCase): def setUp(self): @@ -115,6 +126,20 @@ class CoreTestCase(support.EnvironGuard, unittest.TestCase): output = output[:-1] self.assertEqual(cwd, output) + def test_run_setup_within_if_main(self): + dist = distutils.core.run_setup( + self.write_setup(setup_within_if_main), stop_after="config") + self.assertIsInstance(dist, Distribution) + self.assertEqual(dist.get_name(), "setup_within_if_main") + + def test_run_commands(self): + sys.argv = ['setup.py', 'build'] + dist = distutils.core.run_setup( + self.write_setup(setup_within_if_main), stop_after="commandline") + self.assertNotIn('build', dist.have_run) + distutils.core.run_commands(dist) + self.assertIn('build', dist.have_run) + def test_debug_mode(self): # this covers the code called when DEBUG is set sys.argv = ['setup.py', '--name'] diff --git a/setuptools/tests/test_test.py b/setuptools/tests/test_test.py index 6bce8e2..8b8d9e6 100644 --- a/setuptools/tests/test_test.py +++ b/setuptools/tests/test_test.py @@ -1,7 +1,5 @@ -from distutils import log -import os - import pytest +from jaraco import path from setuptools.command.test import test from setuptools.dist import Distribution @@ -9,100 +7,35 @@ from setuptools.dist import Distribution from .textwrap import DALS -SETUP_PY = DALS( - """ - from setuptools import setup - - setup(name='foo', - packages=['name', 'name.space', 'name.space.tests'], - namespace_packages=['name'], - test_suite='name.space.tests.test_suite', - ) - """ -) - -NS_INIT = DALS( - """ - # -*- coding: Latin-1 -*- - # Söme Arbiträry Ünicode to test Distribute Issüé 310 - try: - __import__('pkg_resources').declare_namespace(__name__) - except ImportError: - from pkgutil import extend_path - __path__ = extend_path(__path__, __name__) - """ -) - -TEST_PY = DALS( - """ - import unittest - - class TestTest(unittest.TestCase): - def test_test(self): - print "Foo" # Should fail under Python 3 - - test_suite = unittest.makeSuite(TestTest) - """ -) - - -@pytest.fixture -def sample_test(tmpdir_cwd): - os.makedirs('name/space/tests') - - # setup.py - with open('setup.py', 'wt') as f: - f.write(SETUP_PY) - - # name/__init__.py - with open('name/__init__.py', 'wb') as f: - f.write(NS_INIT.encode('Latin-1')) - - # name/space/__init__.py - with open('name/space/__init__.py', 'wt') as f: - f.write('#empty\n') - - # name/space/tests/__init__.py - with open('name/space/tests/__init__.py', 'wt') as f: - f.write(TEST_PY) - - -@pytest.fixture -def quiet_log(): - # Running some of the other tests will automatically - # change the log level to info, messing our output. - log.set_verbosity(0) - - -@pytest.mark.usefixtures('tmpdir_cwd', 'quiet_log') +@pytest.mark.usefixtures('tmpdir_cwd') def test_tests_are_run_once(capfd): params = dict( name='foo', packages=['dummy'], ) - with open('setup.py', 'wt') as f: - f.write('from setuptools import setup; setup(\n') - for k, v in sorted(params.items()): - f.write(' %s=%r,\n' % (k, v)) - f.write(')\n') - os.makedirs('dummy') - with open('dummy/__init__.py', 'wt'): - pass - with open('dummy/test_dummy.py', 'wt') as f: - f.write( - DALS( + files = { + 'setup.py': + 'from setuptools import setup; setup(' + + ','.join(f'{name}={params[name]!r}' for name in params) + + ')', + 'dummy': { + '__init__.py': '', + 'test_dummy.py': DALS( + """ + import unittest + class TestTest(unittest.TestCase): + def test_test(self): + print('Foo') """ - import unittest - class TestTest(unittest.TestCase): - def test_test(self): - print('Foo') - """ - ) - ) + ), + }, + } + path.build(files) dist = Distribution(params) dist.script_name = 'setup.py' cmd = test(dist) cmd.ensure_finalized() cmd.run() out, err = capfd.readouterr() - assert out == 'Foo\n' + assert out.endswith('Foo\n') + assert len(out.split('Foo')) == 2