Skip to content

Stop working around bug in PyPy < 7.3.18#149

Merged
jaraco merged 5 commits intojaraco:mainfrom
barneygale:rm-text-encoding-workaround
Oct 19, 2025
Merged

Stop working around bug in PyPy < 7.3.18#149
jaraco merged 5 commits intojaraco:mainfrom
barneygale:rm-text-encoding-workaround

Conversation

@barneygale
Copy link
Copy Markdown
Contributor

@barneygale barneygale commented Jul 27, 2025

PyPy used to set the stack level incorrectly when emitting warnings from io.text_encoding(), but this bug is too minor and too obscure to bother working around. Plus it's fixed in recent PyPy.

See pypy/pypy@6ca2f48

PyPy used to set the stack level incorrectly when emitting warnings from
`io.text_encoding()`, but this bug is too minor and too obscure to bother
working around. Plus it's fixed in recent PyPy.
@barneygale barneygale force-pushed the rm-text-encoding-workaround branch from 145b9d5 to 604a614 Compare July 27, 2025 14:38
@barneygale barneygale changed the title Stop working around bug in PyPy < 7.3.19 Stop working around bug in PyPy < 7.3.18 Aug 6, 2025
@barneygale
Copy link
Copy Markdown
Contributor Author

@jaraco would you have a moment to review? thank you!

@barneygale
Copy link
Copy Markdown
Contributor Author

Merging main seems to have fixed the test failures :)

zipp/__init__.py Outdated
return hash((self.root, self.at))

def open(self, mode='r', *args, pwd=None, **kwargs):
def open(self, mode='r', encoding=None, errors=None, newline=None, pwd=None):
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This PR would be an easy merge if it didn't also make these changes to the signature. My objective in using *args and **kwargs was to avoid repetition of the signature of io.TextIOWrapper and make minimal assumptions about it. This new approach causes keyword-based arguments to be transformed to positional ones and will require maintenance if a future Python version adds a new argument.

It took me a moment to realize why this changed. It's basically inlining the logic of _extract_text_encoding into the signatures and parameter handling of the two affected methods. In my opinion, this logic should be encapsulated to capture its essential purpose (apply text_encoding to any encoding parameter).

If only we had something like Annotations as Transforms, we could write it as:

def open(self, mode='r', encoding:apply(text_encoding)=None, ...):

That would succinctly describe the intended effect and independent of the function logic.

Since we don't have parameter transforms, and because decorators are the current best art for implementing this kind of abstraction, I'd like to explore having a decorator to implement the "transform the encoding parameter" behavior.

I may end up deciding that this proposed approach is best.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I tried writing a decorator, but observed it's nearly impossible to reliably extract a possibly positional or possibly keyword argument from the middle of a signature like this one. So I've abandoned that concept.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

In a3a66c5, I've restored the _extract_text_encoding function. This approach is a smaller diff and avoids changing assumptions about encoding parameters.

I'm not sure I love it. There was something elegant about being able to call text_encoding directly and without any stacklevel overrides.

I'm tempted to say let's go with the smaller change for now and we can revisit what to do about _extract_text_encoding later. Maybe we simply revert that commit. Or maybe we keep the "extract" logic and apply the text_encoding to the extracted encoding parameter.

@jaraco
Copy link
Copy Markdown
Owner

jaraco commented Oct 19, 2025

I'm working to create a changelog entry for this change and I'm trying to decide what scope to elect. I don't think this is a bugfix, because it doesn't fix any bugs, so it's a feature or removal. I guess it's a feature if older PyPy are no longer supported or a removal if those versions are still supported. Given those versions are likely still in the wild, I'm leaning removal.

@jaraco jaraco merged commit 624092f into jaraco:main Oct 19, 2025
13 checks passed
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.

2 participants