Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop support for EOL Python 3.7 #11944

Merged
merged 12 commits into from Feb 18, 2024
Merged

Drop support for EOL Python 3.7 #11944

merged 12 commits into from Feb 18, 2024

Conversation

hugovk
Copy link
Contributor

@hugovk hugovk commented Apr 10, 2023

Fixes #11934.

Or it will be end-of-life on 2023-06-27: https://devguide.python.org/versions/

Which will happen before pip 23.2 is released, sometime before 2023-07-31: https://github.com/pypa/pip/milestone/58

@sbidoul
Copy link
Member

sbidoul commented Apr 10, 2023

Shouldn't we wait until supporting 3.7 is actually a maintenance burden before doing this?

@pfmoore
Copy link
Member

pfmoore commented Apr 10, 2023

I see the attraction of using more modern constructs, but I agree we should be conservative about actively making things incompatible. Let’s just remove it from CI but not change python_requires. We can change the metadata when we actually need a 3.8+ feature. And in case it’s not obvious, this can’t go into 23.1…

@hugovk
Copy link
Contributor Author

hugovk commented Apr 11, 2023

Let’s just remove it from CI but not change python_requires.

I don't recommend that: it would allow installing on 3.7, but we don't know if it still works on 3.7...

For a minimal change, we could remove from CI and change python_requires (plus docs + classifiers) and leave the syntax changes for later. But no rush on any of this.

@pfmoore
Copy link
Member

pfmoore commented Apr 11, 2023

My point is that I'm -1 on actively blocking the use of pip under Python 3.7 without good reason. And "3.7 is EOL" doesn't feel like a good enough reason by itself.

Actually, note our official Python support policy. It's not based on whether the core Python version is EOL, but on usage on PyPI being below 5%. Do we have evidence that this is the case for Python 3.7?

@hugovk
Copy link
Contributor Author

hugovk commented Apr 12, 2023

Nope, it's 28%:

category percent downloads
3.7 27.62% 39,721,366
3.8 20.97% 30,159,714
3.9 14.74% 21,196,566
3.10 11.01% 15,838,291
2.7 9.17% 13,193,218
3.6 7.07% 10,171,164
null 5.10% 7,333,246
3.11 3.55% 5,101,883
3.5 0.62% 885,869
3.4 0.13% 193,820
3.12 0.02% 29,592
3.3 0.00% 1,481
3.2 0.00% 63
2.6 0.00% 4
3.1 0.00% 2
Total 143,826,279

Date range: 2023-03-01 - 2023-03-31

Source: pip install -U pypistats && pypistats python_minor pip --last-month --format markdown, from https://pypistats.org/


Python 3.6 was dropped in November 2021, for pip 22.0, a month and a half before its EOL: #10461 (comment)

At a time when 3.6 was at 24%:

category percent downloads
3.7 24.26% 23,307,514
3.6 23.69% 22,758,024
3.8 18.80% 18,065,071
2.7 12.24% 11,757,369
3.9 12.16% 11,683,512
null 5.06% 4,858,720
3.5 2.28% 2,193,503
"3.10" 1.26% 1,208,242
3.4 0.25% 242,390
3.11 0.00% 4,542
3.3 0.00% 1,074
3.2 0.00% 134
2.6 0.00% 96
3.1 0.00% 1
Total   96,080,192

Date range: 2021-10-01 - 2021-10-31

Source: https://github.com/hugovk/pypi-tools/blob/main/data/pip-2021-10.json, archived from https://pypistats.org/

But that was to ease adopting Rich.


Shall we close this and revisit in another year or two?

@RonnyPfannschmidt
Copy link
Contributor

Maybe pip could start to warn on eol python 3.7 to add extra drive to drop it

Is there any way to distinguish ci usage from downstream usage?

@hugovk
Copy link
Contributor Author

hugovk commented Apr 12, 2023

Maybe pip could start to warn on eol python 3.7 to add extra drive to drop it

This was done for 2.7 (#6147) and 3.5 (#8778), although the 2.7 removal was already planned for EOL+1 year (the 5% policy was only for 3.x), and 3.5 was on track to reach <5% by the target date.

Is there any way to distinguish ci usage from downstream usage?

Not really, although the numbers do exclude mirrors such as bandersnatch and Artifactory.

@uranusjr
Copy link
Member

Since this can not go into 23.1 anyway1, I’d suggest we not worry too much about the detail for now. Things can change a lot in three months.

Footnotes

  1. 3.7 would still be alive at the time of release; 3.6 was allowed to be dropped early because the next release would happen after the EOL.

@lg8080
Copy link

lg8080 commented Apr 19, 2023

At a minimum, please change the support policy if you want to drop 3.7 support before usage drops to 5%.

But I don't see a good reason to change the policy; there may be other Python distributions whose EOL is further out.

@pradyunsg
Copy link
Member

pradyunsg commented Apr 19, 2023

Let's leave this open for now but defer further discussion until we see a need to do this beyond EOL.

Screenshot 2023-04-19 at 12 00 22

We can look at https://pypistats.org/packages/__all__ in 2-3 months to see if the ratios change, and if this blocks something for us that we'd find problematic.

@potiuk
Copy link
Contributor

potiuk commented Apr 21, 2023

My 3 cents. If people really would want to use Python 3.7, they will still be able to use old pip versions. They will not stop working. So there is a nice escape hatch for them.

They will not have new features and some breaking changes will not be enforced for them.

Are we seriously think people will want to upgrade to new pip, when they are not upgrading EOL Pyhon ?

Suggestion: I think it is important (unless it is already done like that) that pip will not warn about new version being available when the future version cannot be installed for 3.7. This would be a little too much because people using last 3.7-compatible version should rather not be warned there is a new version available.

@hugovk hugovk marked this pull request as draft April 21, 2023 20:04
@pfmoore
Copy link
Member

pfmoore commented Apr 21, 2023

If people really would want to use Python 3.7, they will still be able to use old pip versions. They will not stop working. So there is a nice escape hatch for them.

Sadly, that's not realistic. Far too many people just blindly pull in the latest pip in their CI and similar. Saying they shouldn't do that has very little effect, so we have to be conservative - which is why we have the policy that we do.

@potiuk
Copy link
Contributor

potiuk commented Apr 22, 2023

Sadly, that's not realistic. Far too many people just blindly pull in the latest pip in their CI and similar. Saying they shouldn't do that has very little effect, so we have to be conservative - which is why we have the policy that we do.

But if you publish pip in PyPi with > 3.7, then they will continue pulling latest version that will be compatible if they still use Python 3.7 (or am I missing something?). I think the only effect it will have for those CI people is that they will never upgrade (and get-pip could work similarly).

@notatallshaw
Copy link
Contributor

Another category of complaints is when a package requires some new feature of Pip but otherwise would work fine with Python 3.7 and the user is stuck on Python 3.7 (for whatever choices of the organization they are in).

I think this was more of an issue in years past when packages in general didn't have a strong Python version support policy, but it would surprise me if it didn't come up again,

Users still report issues they have on 3.6 (#11959), though this was because of the package support policy not because of lacking a new Pip.

@pfmoore
Copy link
Member

pfmoore commented Jun 25, 2023

3.7 seems to be gradually dropping below 3.8, but not enough that we should be desupporting 3.7 in pip 23.2:

image

@ofek
Copy link
Sponsor Contributor

ofek commented Jun 25, 2023

If people really would want to use Python 3.7, they will still be able to use old pip versions. They will not stop working. So there is a nice escape hatch for them.

Sadly, that's not realistic. Far too many people just blindly pull in the latest pip in their CI and similar. Saying they shouldn't do that has very little effect, so we have to be conservative - which is why we have the policy that we do.

Similar to what the other person said, unless I'm missing something, that will continue to work as expected. Can you please explain what would cause the Python version requirement to not be respected?

@pfmoore
Copy link
Member

pfmoore commented Jun 25, 2023

Can you please explain what would cause the Python version requirement to not be respected?

Sorry, you're right. I withdraw that comment.

What I meant was that I'm -1 on actively preventing people using the latest version of pip under Python 3.7 without good reason. So yes, the version requirement would give 3.7 users a working pip, but not the latest pip. And in any case, our existing policy is based on usage, not Python support lifecycle.

Ultimately, I don't think we gain enough to justify dropping 3.7 support, and our formal criteria for desupport haven't been met yet. It makes no personal difference to me (I haven't used 3.7 in years) but I've been in situations where I've been on old platforms that I can't change and things get desupported, and it sucks. So I'd rather not rush to inflict that pain on our users.

@pradyunsg
Copy link
Member

pradyunsg commented Dec 23, 2023

I didn't realise we hadn't done this yet. I think we should drop Python 3.7 now, even though that's not what the usage numbers suggest.

I've been in situations where I've been on old platforms that I can't change and things get desupported, and it sucks.

I agree it sucks, but I don't want to be subsidising the costs for individuals/organisations staying on EOL Python versions indefinitely in my free time. :)

Quoting past me:

The main beneficiaries of extended post-EoL support for Python versions are organisations/institutions. These have taken on risk by staying on EoL software. One of the risk factors is lack of support in tooling that they don't pay for. The onus is on them to figure out how to keep their lights on. However they do so, it must cost them $$$ -- either by paying maintainers enough to justify their effort spent maintaining that support, by having the developers they have hired maintain the support for them internally, or by paying a redistributor to maintain that support for them.

From curiousefficiency.org/posts/2015/04/stop-supporting-python26.html:

upstream open source developers shouldn't feel obliged to donate their own time to help end users cope with organisations that aren't yet able to upgrade their internal infrastructure in a more timely fashion.

I understand and appreciate that the network effects of pip dropping a Python version exist, but I absolutely do not think that we should be maintaining support for up to 10+ Python versions just because someone with a large server farm keeps downloading stuff from PyPI with EOL Python versions -- a hypothethical situation that we could end up with in a decade if we just followed our own "usage" rule with just download counts blindly, without looking at the actual usage pattern.


As of today, Python 3.7's usage trends are not trending down, if anything, they seem to be actually trending up -- whatever large institutional users are relying on Python 3.7 and PyPI, they're continuing to do so.

Screenshot 2023-12-23 at 09 33 10

We came up with the current "rule" written in our documentation and we can change it if it does not fit our needs. It evidently didn't with Python 3.6, and it certainly doesn't with Python 3.7 either. I'll file a separate PR with a proposal for adding language to limit how long we end up supporting things post-EOL.


All that said, @hugovk could you update this PR? I think it'd be useful to do that eagerly to have smaller conflicts. :)

@pradyunsg
Copy link
Member

Somewhat relatedly, I can no longer fetch the last 30 days of download counts for PyPI, with Python version + pip version + OS information with the monthly free 1 TiB on BigQuery. I can fetch Python version and pip version data but that isn't particularly useful to identify the problem platforms like I've done in the past.

Here's a nice stacked chart and a Google Sheet with the raw data. Shoutout to @pavithraes for helping me figure out how to actually create this neat chart!

The BigQuery SQL query
#standardSQL
SELECT
  details.installer.version,
  REGEXP_EXTRACT(details.python, r"[0-9]+\.[0-9]+") AS python_version,
  COUNT(*) AS num_downloads
FROM
  `bigquery-public-data.pypi.file_downloads`
WHERE
  DATE(timestamp)
    BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 31 DAY)
    AND DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)
  AND details.installer.name = 'pip'
GROUP BY
  details.installer.version,
  python_version
ORDER BY
  num_downloads DESC,
  python_version,
  details.installer.version

@pypa-bot pypa-bot removed the needs rebase or merge PR has conflicts with current master label Dec 23, 2023
@hugovk

This comment was marked as resolved.

@pradyunsg
Copy link
Member

pip==23.3.2

@hugovk Is this of pip 23.3.2, or with pip 23.3.2? i.e. is this project.name / project.version or details.installer.name / details.installer.version?

@hugovk
Copy link
Contributor Author

hugovk commented Dec 24, 2023

Of pip 23.3.2, with anything.

And I think file.project and file.version? https://github.com/ofek/pypinfo/blob/69d912f3e66625910d4d0aac2c18db5e104e9c35/pypinfo/fields.py#L9-L10

@hugovk hugovk marked this pull request as ready for review January 15, 2024 16:35
@hugovk
Copy link
Contributor Author

hugovk commented Jan 15, 2024

The CI is passing after merging from main, setting as ready for review. 👍

@sbidoul
Copy link
Member

sbidoul commented Feb 17, 2024

@hugovk thanks for this. I think the time has now come to drop python 3.7 support.

This PR looks good to me. Would you mind rebasing and handling https://github.com/pypa/pip/pull/11944/files#r1161726499 ?

@pypa/pip-committers shall we update our Python support policy to say we support officialy supported python versions (link?), and may support older versions at the discretion of pip maintainers?

@pfmoore
Copy link
Member

pfmoore commented Feb 17, 2024

@pypa/pip-committers shall we update our Python support policy to say we support officialy supported python versions (link?), and may support older versions at the discretion of pip maintainers?

I'm happy to do that. Our discretion can still be based on download numbers, but we won't have to deal with debates over precise figures if we don't want to 🙂

@hugovk
Copy link
Contributor Author

hugovk commented Feb 17, 2024

Done! I also ran pyupgrade, but let me know if you want to drop that commit. It didn't change much.

@sbidoul
Copy link
Member

sbidoul commented Feb 17, 2024

The proposed updated Python Support Policy is at #12529

Copy link
Member

@sbidoul sbidoul left a comment

Choose a reason for hiding this comment

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

Thanks

Comment on lines 11 to 14
sys.stdout.buffer.write(b"\nThis package prints out UTF-8 stuff like:\n")
sys.stdout.buffer.write("* return type of ‘main’ is not ‘int’\n".encode())
sys.stdout.buffer.write(
"\nThis package prints out UTF-8 stuff like:\n".encode("utf-8")
)
sys.stdout.buffer.write(
"* return type of ‘main’ is not ‘int’\n".encode("utf-8")
)
sys.stdout.buffer.write(
"* Björk Guðmundsdóttir [ˈpjœr̥k ˈkvʏðmʏntsˌtoʊhtɪr]".encode("utf-8")
"* Björk Guðmundsdóttir [ˈpjœr̥k ˈkvʏðmʏntsˌtoʊhtɪr]".encode()
Copy link
Contributor

Choose a reason for hiding this comment

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

btw, why did one of these lines drop the encode and become a binary string, but the others didn't?

Copy link
Member

Choose a reason for hiding this comment

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

I assumed because it's pure ASCII so a bytestring is unambiguous? I'm not a huge fan of tools making changes like this (I tend to feel it's a case where I write it a certain way because it expresses what I want it to better that way) but I'm not going to get up tight about it, frankly.

Copy link
Sponsor Contributor

Choose a reason for hiding this comment

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

The argument is the default which makes it superfluous https://docs.python.org/3/library/stdtypes.html#str.encode

Copy link
Contributor

Choose a reason for hiding this comment

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

The question wasn't about the argument it was about why the first line uses a bytes literal and the next two lines use regular strings + encode.

@pfmoore had the right idea, in fact using non-ASCII characters are illegal for bytes literals: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals

I do find this ugly though, having 3 lines where they made to be bytes in two different ways. But this isn't my codebase so I'll consider this question answered and stop here.

@notatallshaw
Copy link
Contributor

notatallshaw commented Feb 17, 2024

Done! I also ran pyupgrade, but let me know if you want to drop that commit. It didn't change much.

FYI, a lot of the rules from pyupgrade could be automatically enforced via ruff: https://docs.astral.sh/ruff/rules/#pyupgrade-up. I would be happy to raise this as a seperate PR if Pip maintainers are now comfortable to introduce breaking changes to pre-Python 3.8 within the Pip _internal code base.

Otherwise if Pip maintainers are still not comfortable with intentionally breaking Python 3.7 I will point out this commit and all the TYPE_CHECKING changes do that. To avoid it the ruff minimum Python version could be kept at 3.7 and something like this could be implemented for TYPE_CHECKING: #12488

I have no strong opinion, just unsure what the conclusion was from this discussion.

@sbidoul
Copy link
Member

sbidoul commented Feb 18, 2024

@notatallshaw my view is that if we drop Python 3.7 support, we can use Python 3.8 constructs without restraint. I leave this open for a little while, in case this would be controversial.

@pfmoore
Copy link
Member

pfmoore commented Feb 18, 2024

I'm fine with using 3.8 constructs. I'm not sure I'd want to apply pyupgrade-type rules automatically, the way we apply formatting rules - I think they need a manual review, like we did with this.

Copy link
Member

@pfmoore pfmoore left a comment

Choose a reason for hiding this comment

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

One minor fix to the pyupdate stuff, because I prefer consistency. Ignore if you don't agree, it's not a big deal to me.

tests/data/packages/BrokenEmitsUTF8/setup.py Outdated Show resolved Hide resolved
hugovk and others added 2 commits February 18, 2024 17:56
Co-authored-by: Paul Moore <p.f.moore@gmail.com>
@sbidoul sbidoul merged commit 3898741 into pypa:main Feb 18, 2024
24 checks passed
@hugovk hugovk deleted the rm-3.7 branch February 18, 2024 17:30
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Drop support for Python 3.7