Skip to content

bpo-32321: Add pure Python fallback for functools.reduce#8548

Merged
vstinner merged 2 commits into
python:masterfrom
madman-bob:fix-issue-32321
Oct 25, 2018
Merged

bpo-32321: Add pure Python fallback for functools.reduce#8548
vstinner merged 2 commits into
python:masterfrom
madman-bob:fix-issue-32321

Conversation

@madman-bob

@madman-bob madman-bob commented Jul 29, 2018

Copy link
Copy Markdown
Contributor

Add a Python fallback for functools.reduce, and enable the appropriate tests to run on py_functools.

https://bugs.python.org/issue32321

https://bugs.python.org/issue32321

@the-knights-who-say-ni

Copy link
Copy Markdown

Hello, and thanks for your contribution!

I'm a bot set up to make sure that the project can legally accept your contribution by verifying you have signed the PSF contributor agreement (CLA).

Unfortunately our records indicate you have not signed the CLA. For legal reasons we need you to sign this before we can look at your contribution. Please follow the steps outlined in the CPython devguide to rectify this issue.

When your account is ready, please add a comment in this pull request
and a Python core developer will remove the CLA not signed label
to make the bot check again.

You can check yourself
to see if the CLA has been received.

Thanks again for your contribution, we look forward to reviewing it!

@serhiy-storchaka serhiy-storchaka left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please test both implementations.

Comment thread Lib/test/test_functools.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This test tests only C implementation of reduce() if it is available. Please make both implementations be tested. See TestPartial and TestCmpToKey for example.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Add a sentence ending period and "Path by yourname."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sorry, what do you mean?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Usually changes from non-core contributors are attributed by adding "Path by contributorname." In your case it will be "Patch by Robert Wright."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, the typo confused me.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Oh, sorry. I just noticed it!

@bedevere-bot

Copy link
Copy Markdown

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@madman-bob

Copy link
Copy Markdown
Contributor Author

I have made the requested changes; please review again

@bedevere-bot

Copy link
Copy Markdown

Thanks for making the requested changes!

@serhiy-storchaka, @zooba: please review the changes made to this pull request.

@rhettinger

Copy link
Copy Markdown
Contributor

Why do you think we might need this? IMO, this just adds unnecessary weight to the code base, resulting in a net degradation of maintainability.

@madman-bob

Copy link
Copy Markdown
Contributor Author

Consistency. If the c_functools module is not available, why should reduce in particular break?

In my opinion, either all of functools should have pure Python fallbacks, or none of them should.

@madman-bob

Copy link
Copy Markdown
Contributor Author

Oh, and the CLA's now been received, so the label can be removed.

Comment thread Lib/functools.py Outdated
try:
value = next(it)
except StopIteration:
raise TypeError("reduce() of empty sequence with no initial value")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Shouldn't this be raised "from None"

Comment thread Lib/functools.py
### reduce() sequence to a single item
################################################################################

_initial_missing = object()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

functools.py already has a sentinel singleton, _NOT_FOUND used by cached_property. Would it be possible to reuse it, instead of adding a second sentinel value?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not sure how I feel about this suggestion. On the one hand, there would be a (slight) overhead reduction by reusing the same sentinel. On the other, semantically, this isn't really a _NOT_FOUND, so much as a "not given".

As these sentinels aren't part of the public interface, we could rename them into an object that semantically makes sense - but I'm loathe to touch another function, if I can help it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ok, keep _initial_missing.

if c_functools:
func = c_functools.reduce

class TestReduce:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you please rename it to BaseTestReduce to make it more obvious that it's not a regular test case?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done this way to be consistent with the other tests.

I have no objection to this suggestion, but as it would also need to be done for TestPartial and TestCmpToKey, I feel it is out of scope for this change.



@unittest.skipUnless(c_functools, 'requires the C _functools module')
class TestReduceC(TestReduce, unittest.TestCase):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nitpick: I suggest to move the C implementation after the Python implementation, since the Python impl is always present, whereas the other one is optional :-)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

As with my other comment, I have no objection to this suggestion, but as it would also need to be done for TestPartial and TestCmpToKey, I feel it is out of scope for this change.

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM.

@vstinner

Copy link
Copy Markdown
Member

Why do you think we might need this? IMO, this just adds unnecessary weight to the code base, resulting in a net degradation of maintainability.

Yes. For me, it helps me to understand more easily the behavior and subtle cases, without having to read C code which is harder to decipher. It's also common that we maintain a Python a C implementation of the same function. It helps other Python implementations to quickly get new features without having to reimplement them in their own "faster language" (like RPython for PyPy or .NET for IronPython). The datetime module has been fully rewritten in Python recently :-)

For this function, it's just 12 lines of Python (if you ignore doc and empty lines). It wouldn't call it a huge maintenance burden :-)

@vstinner vstinner merged commit e25d5fc into python:master Oct 25, 2018
@miss-islington

Copy link
Copy Markdown
Contributor

Thanks @madman-bob for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.7.
🐍🍒⛏🤖

@bedevere-bot

Copy link
Copy Markdown

GH-10092 is a backport of this pull request to the 3.7 branch.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Oct 25, 2018
(cherry picked from commit e25d5fc)

Co-authored-by: madman-bob <madman.bob@hotmail.co.uk>
@vstinner

Copy link
Copy Markdown
Member

@madman-bob: Hi, I merged your PR. You wrote that you care about consistency in the test. I agree that it matters: would you mind to propose a PR to implement my proposed changes?

@madman-bob

Copy link
Copy Markdown
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants