Repository: streamlink/streamlink

Issue:
Python 2.7 support
## Issue

- [x] This is not a bug report, feature request, or plugin issue/request.
- [x] I have read the contribution guidelines.

### Description

Hi ! 
This is more of a question and the beginning of a discussion than an issue.

Python 2.7 is not maintained anymore (see: https://github.com/python/devguide/pull/344)

It has been mentioned a few times in the project's issues that Python 2.7 is sometimes problematic.
Last time was only a few days ago (see: https://github.com/streamlink/streamlink/pull/2871#issuecomment-611939149)

I'm really new in this project and I understand that there are historical reasons for a Python 2.7 version of StreamLink but I would like to know if there is a plan on Python 2.7 support.

Maybe some users are still relying on Python 2.7, should they expect an end of support soon?
How many users would be impacted? Is there an easy way to know?
Drop support for EOL Python 2
For #2896.

Minimal version of https://github.com/streamlink/streamlink/pull/2919.

* Don't test or install on Python 2.7
* Remove universal wheel
* Update docs and metadata


Discussion:
It really comes down to resources. If I could wave a magic wand I'd remove 2.7 support today. We're not going to support it, make code changes for it, or do any work to make Streamlink work with 2.7. The only plan around 2.7 is to stop supporting 2.7. If people are still relying on 2.7 they should expect it to go away at any time as 2.7 was already EoL, we just haven't gotten to it yet.

There is no way to know how many users would be impacted, we don't track stats like that at all within the application but even if it impacted 95% of people I'd still push for removing it.
I understand. 
Should we stop testing Python 2.7 then?
see: https://github.com/streamlink/streamlink/blob/master/.github/workflows/main.yml#L23

> we don't track stats like that at all within the application

And I'm grateful for that.
I imagine 99% of the Windows installs are from the installer or a portable version, which use Python 3.5+. 
I would imagine a lot of the Linux installs are Python 2.7, because older distros use Python 2.7 by default, same goes for macOS I guess. 
@brouxco When someone makes the PR to drop 2.7 support they'll stop testing 2.7, until then it needs to be tested. @beardypig I'm running it on 3.6+ on macOS since it's easy to run both with Brew. I don't think it's something worth worrying about as long as we announce it in the release notes.
Fedora and Ubuntu will be switching to python3 as default python interpreter in a couple of days. Apart from that, all available `streamlink` "system-packages" are based on python3.

The only problem with dropping 2.7 are non-system-package installs via pip/setuptools which were done via the system's default python interpreter on distros shipping with python2 as the default one.

These are the current **default** `/usr/bin/python` versions on various Linux distros and macOS:

- **Arch Linux**
  [3.8](https://www.archlinux.org/packages/extra/x86_64/python/)
- **Debian**
  - buster (stable): [2.7](https://packages.debian.org/buster/python)
  - bullseye (testing): [2.7](https://packages.debian.org/bullseye/python) (release date: [next year](https://en.wikipedia.org/wiki/Debian_version_history#Debian_11_(Bullseye)))
  - sid (unstable): [2.7](https://packages.debian.org/sid/python)
  https://www.debian.org/doc/packaging-manuals/python-policy/index.html
  https://wiki.debian.org/Python/2Removal
- **Fedora**
  - fedora 31: [2.7](https://fedoraproject.org/wiki/Changes/Python_means_Python3)
  - fedora 32: [3.8](https://fedoraproject.org/wiki/Releases/32/ChangeSet?rd=Releases/32#Python_3.8) (release date: [2020-04-28](https://www.phoronix.com/scan.php?page=news_item&px=Fedora-32-Release-Bug-Delay))
  https://fedoraproject.org/wiki/Changes/Python_means_Python3#Python_command
- **Gentoo**
  [multiple targets, default is 3.x](https://packages.gentoo.org/packages/dev-lang/python)
- **Linux Mint**
  19.3 Tricia: [based on Ubuntu 18.04](https://en.wikipedia.org/wiki/Linux_Mint_version_history#Release_history)
- **openSUSE**
  tumbleweed: none / [2.7 - via `python`](https://build.opensuse.org/package/view_file/openSUSE:Factory/python/python-base.spec?expand=1)
  leap 15.2: none / [2.7 - via `python`](https://build.opensuse.org/package/view_file/openSUSE:Leap:15.2/python/python-base.spec?expand=1)
- **Solus**
  [2.7](https://dev.getsol.us/source/python/browse/master/package.yml)
- **Ubuntu**
  - 18.04 LTS: [2.7](https://packages.ubuntu.com/bionic/python/python)
  - 19.10: [2.7](https://packages.ubuntu.com/eoan/python/python)
  - 20.04 LTS: none / [3.8 - via `python-is-python3`](https://packages.ubuntu.com/focal/python/python-is-python3) (release date: [2020-04-23](https://en.wikipedia.org/wiki/Ubuntu_version_history#Ubuntu_20.04_LTS_(Focal_Fossa)))
  https://lists.ubuntu.com/archives/ubuntu-devel/2019-October/040834.html
- **Void Linux**
  [2.7](https://github.com/void-linux/void-packages/blob/master/srcpkgs/python/template)
- **macOS**
  - catalina: [2.7](https://developer.apple.com/documentation/macos_release_notes/macos_catalina_10_15_release_notes)
    > Use of Python 2.7 isn’t recommended as this version is included in macOS for compatibility with legacy software. Future versions of macOS won’t include Python 2.7. Instead, it’s recommended that you run python3 from within Terminal.
  - homebrew: [3.7](https://github.com/Homebrew/homebrew-core/blob/master/Formula/python.rb)


https://www.python.org/dev/peps/pep-0394/#history-of-this-pep
Talking about Python: What are the minimal requirements for using version 3, so which version exactly? 
Hopefully it is quite a low version like 3.5 as updating Python on a Linux system, 'overwriting' the included version, is a pain in the ass and nearly never works. 
We should remove support on July 2nd... :|
Should have also posted this site:
https://python3statement.org/

Also, as a small correction to my earlier post, many distros intentionally leave their `python` package (which provides `/usr/bin/python`) on version 2.7. The user is expected to run python3 explicitly via `/usr/bin/python3`. The python2 "drop" is then done by not having the `python` package installed by default, which is already the case on openSUSE for example. On Ubuntu, they are doing that with the  upcoming release and are also providing the `python-is-python3` package, which symlinks `/usr/bin/python` to `/usr/bin/python3`.

----

@malvinas2 
https://github.com/streamlink/streamlink/blob/master/.github/workflows/main.yml#L23

Here's the EOL list of the Python3 branches:
https://devguide.python.org/#status-of-python-branches

----

Why that specific date, @beardypig?
@bastimeyer 
July 2nd... ==> 2.7  (as we already missed 7th of February, hahaha)
Please see PR https://github.com/streamlink/streamlink/pull/2919.
I have installed python 3.5, but streamlink still thinks that I'm using python 2.7
May I ask what should I do?
(I'm using Ubuntu 20.04)
Thank you very much in advance
@wishfulguy depends how you installed `streamlink`, if you used `pip` you might need to use `pip3`. 
@wishfulguy 
or in case you clone the git repository replace python by python**3**: 

```
# Current user
git clone https://github.com/streamlink/streamlink.git
cd streamlink
python3 setup.py install --user

# System wide
git clone https://github.com/streamlink/streamlink.git
cd streamlink
sudo python3 setup.py install
```
@beardypig Do you want to add the python2-removal branch (or whatever you want to call it) to the repo now? We've said that 1.4.0 was the "last" release with p2 support, so we should start removing python2 now. This parallel branch shouldn't live too long though, otherwise we'll have lots of merge conflicts.
I’m on a Mac and I have limited technical knowledge and zero experience with Python. Trying to get streams running with Streamlink 1.4.1 was painful, I just lacked understanding on what it was that needed to be done, and once I did I had no idea how to go about doing it.

I started off by install Python 3 from phython.org (version 3.8.2), and then ran the easy_install command to update to 1.4.1. This this didn’t work, I pointed Twitch GUI at Python 3 (via “which Python3” command) and still got errors. Googling about, I learnt that I needed to get Streamlink installed to Python 3. Then I hit a brick wall as I couldn’t understand anything that I tried to read on how to do it.

The solution is that “easy_install” is a Python program, and that when you run it you are running the system default 2.7 version of it. I had zero clue that this was the case until by chance I saw that there was a file named “easy_install-3.8” in the Python 3 install folder. With this knowledge, I tried running “sudo easy_install-3.8 -U streamlink”, that installed it in the correct place and now I can watch streams again.


I think with the abandonment of 2.7, you should add some clear steps in the documentation for how to handle this on a Mac. It’s simple if you know what you are dealing with, but as someone who was very much on the outside I had a real hard time with it.
@4AM-Campfire Thanks for the feedback. Homebrew is definitely the way to go in this scenario in terms of ease of use. @bastimeyer maybe we should move Homebrew to be the recommended option as the first entry in the list? Or mark Homebrew as the preferred option somehow? Then it's just an install of Homebrew and installing Streamlink will handle all the deps too.
We should remove the `easy_install` suggestion. It's long been deprecated and shouldn't be used at all. It's also questionable if it'll be available on future macOS versions, as they want to remove the system's default python env from what I remember, which includes setuptools, and which therefore includes easy_install.
- https://setuptools.readthedocs.io/en/latest/easy_install.html
- https://packaging.python.org/discussions/pip-vs-easy-install/

To be honest, I didn't notice that we were still mentioning it in the install docs, let alone having it listed as the first entry. In the [Twitch GUI's install wiki](https://github.com/streamlink/streamlink-twitch-gui/wiki/Installation) (which also includes separate Streamlink instructions), I've explicitly never mentioned it.
@bastimeyer I think we should create a version-2 branch, and do all the changes we want for that there, including removal of Python 2.7. We mentioned before the removal of some deprecated options, etc. 

@gravyboat we really should :) We have `easy_install` listed for macOS, but then further down the page we have "Using easy_install is no longer recommended." :) For macOS I'd recommend using homebrew to install Streamlink. 
@beardypig Yeah I only ever user Homebrew on my mac, I've never used easy_install for anything Python related.
It's been another month. We've already announced Streamlink's "last py2" release earlier, so we shouldn't drag this out any further and risk having another 1.x release.

Since nobody has pushed the py2 removal forward so far, I guess we should keep it as simple as possible and not create a secondary branch. It's just too much effort keeping track of the changes which will happen simultaneously on the master branch until this gets merged.

Let's remove py2 from the CI runners now, remove everything related to it from setup.py and afterwards strip out all the compatibility stuff and make the remaining code changes. We already have pull requests for that (#2920, #2921).
# [Codecov](https://codecov.io/gh/streamlink/streamlink/pull/2920?src=pr&el=h1) Report
> Merging [#2920](https://codecov.io/gh/streamlink/streamlink/pull/2920?src=pr&el=desc) into [master](https://codecov.io/gh/streamlink/streamlink/commit/6773c3fb9c41f3793aab78e40e10eb1b1d19546e&el=desc) will **decrease** coverage by `0.33%`.
> The diff coverage is `n/a`.


```diff
@@            Coverage Diff             @@
##           master    #2920      +/-   ##
==========================================
- Coverage   52.66%   52.33%   -0.34%     
==========================================
  Files         250      250              
  Lines       15730    15730              
==========================================
- Hits         8284     8232      -52     
- Misses       7446     7498      +52     
```


Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -7,23 +7,13 @@
 
 import versioneer
 
+
 deps = [
-    # Require backport of concurrent.futures on Python 2
-    'futures;python_version<"3.0"',
-    # Require singledispatch on Python <3.4
-    'singledispatch;python_version<"3.4"',
     "requests>=2.21.0,<3.0",
-    'urllib3[secure]>=1.23;python_version<"3.0"',
     "isodate",
     "websocket-client",
     # Support for SOCKS proxies
     "PySocks!=1.5.7,>=1.5.6",
-    # win-inet-pton is missing a dependency in PySocks, this has been fixed but not released yet
-    # Required due to missing socket.inet_ntop & socket.inet_pton method in Windows Python 2.x
-    'win-inet-pton;python_version<"3.0" and platform_system=="Windows"',
-    # shutil.get_terminal_size and which were added in Python 3.3
-    'backports.shutil_which;python_version<"3.3"',
-    'backports.shutil_get_terminal_size;python_version<"3.3"'
 ]
 
 # for encrypted streams
@@ -76,7 +66,7 @@ def is_wheel_for_windows():
 setup(name="streamlink",
       version=versioneer.get_version(),
       cmdclass=versioneer.get_cmdclass(),
-      description="Streamlink is command-line utility that extracts streams "
+      description="Streamlink is a command-line utility that extracts streams "
                   "from various services and pipes them into a video player of "
                   "choice.",
       long_description=long_description,
@@ -97,7 +87,7 @@ def is_wheel_for_windows():
       entry_points=entry_points,
       install_requires=deps,
       test_suite="tests",
-      python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4",
+      python_requires=">=3.5, <4",
       classifiers=["Development Status :: 5 - Production/Stable",
                    "License :: OSI Approved :: BSD License",
                    "Environment :: Console",
@@ -105,11 +95,13 @@ def is_wheel_for_windows():
                    "Operating System :: POSIX",
                    "Operating System :: Microsoft :: Windows",
                    "Operating System :: MacOS",
-                   "Programming Language :: Python :: 2.7",
+                   "Programming Language :: Python :: 3",
+                   "Programming Language :: Python :: 3 :: Only",
                    "Programming Language :: Python :: 3.5",
                    "Programming Language :: Python :: 3.6",
                    "Programming Language :: Python :: 3.7",
                    "Programming Language :: Python :: 3.8",
+                   "Programming Language :: Python :: 3.9",
                    "Topic :: Internet :: WWW/HTTP",
                    "Topic :: Multimedia :: Sound/Audio",
                    "Topic :: Multimedia :: Video",
diff --git a/src/streamlink/session.py b/src/streamlink/session.py
--- a/src/streamlink/session.py
+++ b/src/streamlink/session.py
@@ -3,7 +3,6 @@
 import pkgutil
 import sys
 import traceback
-import warnings
 
 import requests
 
@@ -52,12 +51,6 @@ class Streamlink(object):
        options and log settings."""
 
     def __init__(self, options=None):
-        if sys.version_info[0] == 2:
-            warnings.warn("Python 2.7 has reached the end of its life.  A future version of streamlink will drop "
-                          "support for Python 2.7. Please upgrade your Python to at least 3.5.",
-                          category=PythonDeprecatedWarning,
-                          stacklevel=2)
-
         self.http = api.HTTPSession()
         self.options = Options({
             "hds-live-edge": 10.0,


Test patch: