bpo-34042: Fix dict.copy() to maintain correct total refcount by 1st1 ยท Pull Request #8119 ยท python/cpython

@1st1

@1st1

@1st1

serhiy-storchaka


for i in range(10):
dct.copy()
first_ref_count = gettotalrefcount()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be in the loop?

'debug build required')
def test_copy_global_refcount(self):
# See issue #34042 for more details.
first_ref_count = second_ref_count = None

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason of this initialization?

vstinner


for i in range(10):
dct.copy()
first_ref_count = gettotalrefcount()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why getting the total for each iteration of the loop?

@1st1

@vstinner @serhiy-storchaka The test is structured in a weird way because that's the only way how I can get it stable on my machine. And yet, here's a CI failure:

2018-07-05T20:27:40.8742568Z test test_dict failed -- Traceback (most recent call last):
2018-07-05T20:27:40.8766139Z   File "/opt/vsts/work/1/s/Lib/test/test_dict.py", line 318, in test_copy_global_refcount
2018-07-05T20:27:40.8783603Z     self.assertEqual(first_ref_count, second_ref_count)
2018-07-05T20:27:40.8798364Z AssertionError: 344832 != 344838

Any suggestions on how I can write a reliable test for sys.gettotalrefcount()? Maybe commit this fix without a test?

@methane

Any suggestions on how I can write a reliable test for sys.gettotalrefcount()? Maybe commit this fix without a test?

Since this is debug feature, I'm OK for this instead of maintain cryptic, fragile test.

methane

@serhiy-storchaka

What about using assertAlmostEqual with a delta much less than the number of loops?

        dct = {'a': 1}
        support.gc_collect()
        first_ref_count = sys.gettotalrefcount()
        for i in range(1000):
            dct.copy()
        support.gc_collect()
        second_ref_count = sys.gettotalrefcount()
        self.assertAlmostEqual(first_ref_count, second_ref_count, delta=10)

@vstinner

Please don't use fragile tests. I already have enough issues with existing fragile tests.

+1 to commit without tests.

@vstinner

What about using assertAlmostEqual with a delta much less than the number of loops?

Honestly, Python internals are too complex to get a reliable total reference count. I'm ok to remove the test.

regrtest usually runs a test 3 times to "warmup caches" before checking for reference leaks, and also use many low-level "cleanup" functions to help to get reliable reference counts.

@1st1

@1st1

Please don't use fragile tests. I already have enough issues with existing fragile tests.

I kind of like Serhiy's idea, but on the other hand Victor is the one who spends so much time herding our buildbots. I'll commit this PR without a test as @vstinner and @methane suggested.

vstinner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@miss-islington

Thanks @1st1 for the PR ๐ŸŒฎ๐ŸŽ‰.. I'm working now to backport this PR to: 3.7.
๐Ÿ๐Ÿ’โ›๐Ÿค–

@1st1 1st1 deleted the fixdict branch

July 6, 2018 16:20

@bedevere-bot

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request

Jul 6, 2018
โ€ฆGH-8119)

(cherry picked from commit 0b75228)

Co-authored-by: Yury Selivanov <yury@magic.io>

miss-islington added a commit that referenced this pull request

Jul 6, 2018
(cherry picked from commit 0b75228)

Co-authored-by: Yury Selivanov <yury@magic.io>