From 949c47c97966b22bc3a7a33c08bc8535969e3fa0 Mon Sep 17 00:00:00 2001 From: Jeremy Stanley Date: Fri, 4 Feb 2022 18:36:27 +0000 Subject: Avoid recursive calls into SetupTools entrypoint Add a check in pbr.core.pbr() to make sure it hasn't already run, and return immediately if it has. This replaces the earlier attempt at loop-busting by setting the entrypoint to None in the dist, in order to support PEP 517 builds without setup_requires. Also test that pbr.json is now included in the dist tree, in order to avoid future regressions. Change-Id: I407ae88ab8de4b61f94034b3d79a2ca7f7d79d16 --- pbr/core.py | 23 +++++++++++++++-------- pbr/tests/test_packaging.py | 6 ++++++ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/pbr/core.py b/pbr/core.py index f221299..a801737 100644 --- a/pbr/core.py +++ b/pbr/core.py @@ -61,6 +61,11 @@ else: integer_types = (int, long) # noqa +# We use this canary to detect whether the module has already been called, +# in order to avoid recursion +in_use = False + + def pbr(dist, attr, value): """Implements the actual pbr setup() keyword. @@ -81,6 +86,16 @@ def pbr(dist, attr, value): not work well with distributions that do use a `Distribution` subclass. """ + # Distribution.finalize_options() is what calls this method. That means + # there is potential for recursion here. Recursion seems to be an issue + # particularly when using PEP517 build-system configs without + # setup_requires in setup.py. We can avoid the recursion by setting + # this canary so we don't repeat ourselves. + global in_use + if in_use: + return + in_use = True + if not value: return if isinstance(value, string_type): @@ -130,14 +145,6 @@ def pbr(dist, attr, value): msg = 'Unknown distribution option: %s' % repr(key) warnings.warn(msg) - # Distribution.finalize_options() is what calls this method. That means - # there is potential for recursion here. Recursion seems to be an issue - # particularly when using PEP517 build-system configs without - # setup_requires in setup.py. We can avoid the recursion by setting - # dist.pbr to a None value as the corresponding entrypoint (this function) - # will only be called on a non None value. - setattr(dist, "pbr", None) - # Re-finalize the underlying Distribution try: super(dist.__class__, dist).finalize_options() diff --git a/pbr/tests/test_packaging.py b/pbr/tests/test_packaging.py index 236c5e1..c92ea9b 100644 --- a/pbr/tests/test_packaging.py +++ b/pbr/tests/test_packaging.py @@ -381,6 +381,12 @@ class TestPackagingWheels(base.BaseTestCase): wheel_file.extractall(self.extracted_wheel_dir) wheel_file.close() + def test_metadata_directory_has_pbr_json(self): + # Build the path to the scripts directory + pbr_json = os.path.join( + self.extracted_wheel_dir, 'pbr_testpackage-0.0.dist-info/pbr.json') + self.assertTrue(os.path.exists(pbr_json)) + def test_data_directory_has_wsgi_scripts(self): # Build the path to the scripts directory scripts_dir = os.path.join( -- cgit v1.2.1