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 Python 2.6 support #2099

Merged
merged 7 commits into from
Apr 15, 2022
Merged

Drop Python 2.6 support #2099

merged 7 commits into from
Apr 15, 2022

Conversation

hugovk
Copy link
Contributor

@hugovk hugovk commented Apr 15, 2022

Summary

Description

Follow on from #2039, remove a few extra redundant Python 2.6 bits from #1178.

Also bump GitHub Actions to v3 and cache pip.

HISTORY.rst Outdated
@@ -11,6 +11,7 @@ XXXX-XX-XX
``/proc`` pseudo files line by line. This should help having more consistent
results.
- 2057_, [OpenBSD]: add support for `cpu_freq()`_.
- 2039_, 2099_: drop support for Python 2.6, EOL since 2013-10-2.
Copy link
Owner

@giampaolo giampaolo Apr 15, 2022

Choose a reason for hiding this comment

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

please git pull your branch; there is an entry for this a couple of lines earlier:

- 1053_: dropped support for Python 2.6.  (patch by Matthieu Darbois)

Feel free to add your name (also to CREDITS file).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't see this at https://github.com/giampaolo/psutil/blob/master/HISTORY.rst, maybe you need to push it?

Copy link
Owner

Choose a reason for hiding this comment

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

@hugovk sorry you right; I forgot to push indeed hehel. I pushed now.

if PY3:
import unittest
else:
import unittest2 as unittest # requires "pip install unittest2"
Copy link
Owner

@giampaolo giampaolo Apr 15, 2022

Choose a reason for hiding this comment

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

I'm so happy to see this go! All other test files (test_linux.py and others) should stop doing:

from psutil.tests import unittest

...and instead do:

import unittest

Could you please update those files as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file still has a monkey patch of unittest.TestCase for a modified __str__, assertRaisesRegex compat code for 2.7 and handling for multiprocessing.Pool.

Copy link
Owner

@giampaolo giampaolo Apr 15, 2022

Choose a reason for hiding this comment

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

I think the monkey patch should still work because test/__init__.py is imported before other test/*.py files.
When they do import unittest they should automatically inherit the monkey-patched version of unittest.TestCase.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, 4bc28e5 passed on GHA but failed on AppVeyor:

psutil.tests.test_windows.TestSystemAPIs.test_nic_names ... ok
psutil.tests.test_windows.TestSystemAPIs.test_pids ... skipped 'test not relieable on appveyor'
psutil.tests.test_windows.TestSystemAPIs.test_total_phymem ... ok
psutil.tests.test_windows.WindowsTestCase.runTest ... ok
======================================================================
ERROR: psutil.tests.test_process.TestProcess.test_nice
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\projects\psutil\psutil\tests\test_process.py", line 812, in test_nice
    with self.subTest(prio=prio):
AttributeError: 'TestProcess' object has no attribute 'subTest'
----------------------------------------------------------------------
Ran 575 tests in 12.912s
FAILED (errors=1, skipped=263)
FAILED
Command exited with code 1

Copy link
Owner

Choose a reason for hiding this comment

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

I guess unittest2 package provided subTest method on Python 2.7, a unittest method which only appeared later in python 3.X. Not a big deal. I prefer to get rid of unittest2 dependency and fake subTest method existence in our unittest.TestCase subclass. I think something like this should work:

if not PY3:
    @contextlib.contextmanager
    def subTest(self, *args, **kw):
        # fake it for python 2.7
        yield

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That looks better, thanks!

(Another option is dropping 2.7 ;)

Copy link
Owner

@giampaolo giampaolo Apr 15, 2022

Choose a reason for hiding this comment

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

I think 2.7 will stay for a very long time (I'd put a bet to at least one decade).

Copy link
Owner

@giampaolo giampaolo left a comment

Choose a reason for hiding this comment

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

Thanks a lot for this. I added a couple of inline comments.

hugovk added 4 commits April 15, 2022 17:52
Signed-off-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
Signed-off-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
Signed-off-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
Signed-off-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
hugovk added 2 commits April 15, 2022 18:04
Signed-off-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
Signed-off-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
Signed-off-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
@giampaolo giampaolo merged commit 6ab8a54 into giampaolo:master Apr 15, 2022
@hugovk hugovk deleted the rm-2.6 branch April 16, 2022 08:25
giampaolo added a commit that referenced this pull request Dec 20, 2024
About dropping Python 2.7 support, 3 years ago [I stated](#2014 (comment)):

>  [...] not a chance, for many years to come. [Python 2.7] currently represents 7-10% of total downloads, aka around 70k /100k downloads per day

3 years later (and to my surprise) **downloads for Python 2.7 dropped to 0.36%**. These are downloads per month:

```
$ pypinfo --percent psutil pyversion
Served from cache: False
Data processed: 4.65 GiB
Data billed: 4.65 GiB
Estimated cost: $0.03

| python_version | percent | download_count |
| -------------- | ------- | -------------- |
| 3.10           |  23.84% |     26,354,506 |
| 3.8            |  18.87% |     20,862,015 |
| 3.7            |  17.38% |     19,217,960 |
| 3.9            |  17.00% |     18,798,843 |
| 3.11           |  13.63% |     15,066,706 |
| 3.12           |   7.01% |      7,754,751 |
| 3.13           |   1.15% |      1,267,008 |
| 3.6            |   0.73% |        803,189 |
| 2.7            |   0.36% |        402,111 |
| 3.5            |   0.03% |         28,656 |
| Total          |         |    110,555,745 |
```

According to [pypistats.org](https://archive.is/wip/knzql) it's 0.28% of the total, and around 15.000 downloads per day.

Maintaining 2.7 support has become increasingly difficult, but still possible. E.g. we can still run tests by using [old PYPI backports](https://github.com/giampaolo/psutil/blob/fbb6d9ce98f930d3d101b7df5a4f4d0f1d2b35a3/setup.py#L76-L85). GitHub Actions can still be [tweaked](https://github.com/giampaolo/psutil/blob/fbb6d9ce98f930d3d101b7df5a4f4d0f1d2b35a3/.github/workflows/build.yml#L77-L112) to run tests and produce wheels on Linux and macOS. Not Windows though, for which we have to use a separate service (Appveyor). 

Still, the amount of hacks in psutil source code necessary to support Python 2.7 piled up over the years, and became quite big. Some disadvantages that come to mind:

* (high) having to maintain various python compatibility layers (e.g. [psutil/_compat.py](https://github.com/giampaolo/psutil/blob/fbb6d9ce98f930d3d101b7df5a4f4d0f1d2b35a3/psutil/_compat.py#L1)) + all the compromises that come with it (extra imports, extra code, str vs. unicode differences, etc.)
* (medium) having to maintain a C compatibility layer (`#if PY_MAJOR_VERSION <= 3`, etc.)
* (medium) inability to use modern language features, especially f-strings
* (low) inability to freely use `enum`s, which creates a difference on how CONSTANTS are exposed in terms of API
* (medium) having to install a specific version of pip and other (outdated) [deps](https://github.com/giampaolo/psutil/blob/fbb6d9ce98f930d3d101b7df5a4f4d0f1d2b35a3/setup.py#L76-L85)
* (high) relying on third-party Appveyor CI service, just to run tests on python 2.7 and produce wheels, when we could rely on a single CI service instead (GitHub)
  * (high) soon I want to distribute wheels via GitHub instead of manually via `twine`, so that'll be a problem (CC @potiuk)
* (high) gradual lack of support from third-party libraries and services
* (medium) 4 extra CI jobs which are run on every commit (Linux, macOS, Windows 32-bit, Windows 64-bit) 
* (medium) the distribution of 7 wheels specific for Python 2.7. From last release: 
  * psutil-6.1.1-cp27-cp27m-macosx_10_9_x86_64.whl
  * psutil-6.1.1-cp27-none-win32.whl
  * psutil-6.1.1-cp27-none-win_amd64.whl
  * psutil-6.1.1-cp27-cp27m-manylinux2010_i686.whl                                                                          
  * psutil-6.1.1-cp27-cp27m-manylinux2010_x86_64.whl                                                                        
  * psutil-6.1.1-cp27-cp27mu-manylinux2010_i686.whl                                                                         
  * psutil-6.1.1-cp27-cp27mu-manylinux2010_x86_64.whl                                                                       
* etc. 

As such I decided to finally **drop support for Python 2.7**. Current psutil 6.1.1 release will still support Python 2.7, but next 7.0.0 will not. 

We can still make a promise that the 6.1.* line (EDIT: see [python2 branch](https://github.com/giampaolo/psutil/tree/python2)) will keep supporting Python 2.7 and will **receive critical bug-fixes only** (no new features).

In 7.0.0 we can keep the [setup.py](https://github.com/giampaolo/psutil/blob/fbb6d9ce98f930d3d101b7df5a4f4d0f1d2b35a3/setup.py) script compatible with Python 2.7 in terms of syntax, so that it can emit an informative error message on pip install. E.g. the user  will see something like this:

```
$ pip2 install psutil
As of version 7.0.0 psutil no longer supports Python 2.7. 
Latest version supporting Python 2.7 is psutil 6.1.X.  
Install it with: "pip2 install psutil==6.1.*".
```

Related tickets:
* 2017-06: #1053
* 2022-04: #2099
* 2023-04: #2246
* giampaolo/pyftpdlib#635
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.

Drop Python 2.6 support in unit tests and scripts, deprecate it in psutil
2 participants