Одно из моих первых разочарований при разработке на Python не имело ничего общего с самим Python, а скорее с излишне изотерическими действиями по развертыванию приложений на Python. Учебные курсы и руководства отлично справляются с задачей обучения студентов запуску Python кода локально, но действительно стоящие приложения не запускают на локальных машинах: они работают на интернет серверах потому что именно в этом и есть их назначение, не так ли? Хотя может быть я высказал сумасшедшую идею.

Ubuntu 20.04 это первая LTS версия Ubuntu в которой отсутствует Python2 и которая поставляется из коробки с установленной версией Python 3.8.5. Но что если написанное вами приложение использующее более новую версию Python? Если вы, как и я, пытались заменить установленную по умолчанию в системе версию, то в процессе сломали вашу ОС. Если до этого вам никто не говорил не делать этого, тогда я возьму на себя эту честь: не делайте этого.

Итак, что же нам делать? Существует нескольок путей как обновить версию Python на Ubuntu, но использование вастроенного в Ubuntu's механизма "alternative install" оптимально по нескольким причинам:

  1. Мы хотим оставить нетронутойси стемную версию Python

  2. По возможности не возиться с Python PATH

  3. Мы можем удобно переключать активную версию Python с использованием CLI

Мы пройдемся по способу легкой и безопасной установки последней версии Python не затрагивая системную версию Python.

Скачивание последней версии Python

Первый шаг должен быть вам знаком: нам необходимо обновить зеркала Ubuntu и установленные пакеты, что бы быть уверенными что мы загружаем последние версии пакетов при установке чего-либо:

Обязательные обновления:
$ sudo apt update && sudo apt upgrade -y

Установка другой версии Python на Ubuntu трубует установки целого ряда зависимых библиотек для Python. Я честно гвооря не уверен что делает половина из этого, и скорее всего это никому из нас никогда не понадобится. Но поверьте, это необходимый шаг:

Установка зависимостей Python:
$ sudo apt-get install build-essential checkinstall
$ sudo apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev \
    libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev libffi-dev zlib1g-dev

Именно здесь многие могут начать установку Python с помощью Ubuntu package manager командой apt-get install python3.X. Мы скачаем и соберем последнюю версию Python из исходные кодов по нескольким причинам. Если версия Python достаточно свежая, некоторые машины под управлением Ubuntu могут не иметь обновленных зеркал что бы получить последнюю версию, но важнее всего то, что этот способ позволяет упростить управление несколькими версиями Python на Ubuntu.

Последнюю версию Python всегда можно найти на официальной странице с релизами на Python.org:

Релизы исходных кодов Python

Первая ссылка на указанной странице должна называться Latest Python 3 Release - Python 3.X. Перейдя по ней необходимо прокрутить вниз страницы до секции «Files» и скопировать URL ссылки Gzipped source tarball.

На вашей Ubuntu машине необходимо теперь скачать эти исходные коды с помощью утилиты «wget». Ниже пример команд для скачивания заархивированной версии Python 3.9.2 в папку /opt и распаковка ее:

Скачивание Python:
$ cd /opt
$ sudo wget https://www.python.org/ftp/python/3.9.2/Python-3.9.2.tgz
$ sudo tar xzf Python-3.9.2.tgz

Теперь последняя версия Python скачана. После этого нам остается ее установить… правильно.

Установка альтернативной версии Python из исходных кодов

Главное разочарование установки Python с использованием команды apt-get install python3.X это что Python будет установлен нормально, но Ubuntu будет по прежнему использовать установленную в системе по умолчанию версию Python. К счастью для нас Ubuntu позволяет устанавливать нам дополнительные (альтернативные) версии Python с использованием команды make altinstall:

Установка из исходных кодов:
$ cd Python-3.9.2
$ sudo ./configure —enable-optimizations
$ sudo make altinstall

Исполнение этих команд может занять некоторое время. После того, как команды будут выполнены вы можете увидеть python3.9 в вашей директории /usr/local/bin/:

Проверка версии Python
$ cd /usr/local/bin/
$ ls

Итак, теперь у нас есть две установленные версии Python: установленная в системе по-умолчанию Python 3.8.5 и добавленная нами новая версия Python 3.9.2. Мы хотим оставить нетронутой установленную в системе версию по-умолчанию, но мы так же хотим запускать написанные нами приложения в версии Python 3.9… итак как мы можем этим управлять?

Linux предусматривает такой сценарий с помощью команды update-alternatives. Мы можем сказать Ubuntu что у нас есть ветка с альтернативной версией на нашей машине, это предоставит нам возможность легко переключаться между ними. Вот как это работает:

Включение альтернативной версии Python
$ update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1
$ update-alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.9 2

Мы запускаем update-alternatives дважды: один раз для Python 3.8, и один раз для Python 3.9. Теперь мы можем использовать команду update-alternatives —list что бы посмотреть все альтернативные версии какого-либо установленного ПО:

Список установленных версий Python
$ update-alternatives --list python3
/usr/bin/python3.6
/usr/local/bin/python3.8

Теперь мы можем переключаться между установленными версиями Python! Запустите следующую команду:

Переключение между версиями
$ update-alternatives --config python3

После выполнения команды вы должны получить подсказку как в приведенном ниже примере. Это будет список всех доступных версий Python в вашей системе. Выберите версию которую хотите использовать введя соответствующий номер версии указанный в колонке Selection:

CLI для переключения активной версии Python

  Selection    Path                       Priority   Status
------------------------------------------------------------
  0            /usr/bin/python3.8          3         auto mode
* 1            /usr/bin/python3.8          3         manual mode
  2            /usr/local/bin/python3.10   2         manual mode

Press <enter> to keep the current choice[*], or type selection number: 

И вы это сделали! Для переключения версии Python все что нужно — это ввести запрошенный номер версии Python указанный в колонке selection.

Это прозвучит абсурдно, но изменить версию Python в Ubuntu ничего не сломав — это впечатляет. Я бы сказал что это в основном вина тех, кто преподаает Python. Если «учат те, кто не может сделать», то было бы логично предположить что Python преподают те, кто не запустил ни одного значимого проекта. Это было жестко, но не бейте меня нисмотря ни на что.

Мы закончили самую трудную часть, но осталось еще немного рутинной работы. Нам все еще нужно установить pip для нашей свежеустановленной версии Python, а так же обновить pip до последней версии.

Установка pip3
$ apt install python3-pip
$ python3.9 -m pip install --upgrade pip

Последний штрих

Вы наверняка заметили что Ubuntu 20.04 (и новее) заставляют нас явно указывать python3 при использовании Python несмотря на отсутствие Python 2 на машине. Это немного раздражает, но так же потенциально может сломать библиотеки которые пытаются использовать Python (NPM, sqlite и node-qyp например)

Возможно вы чувствуетет в себе достаточно сил что бы создать alias, который будет при обращении к python ссылаться на python3, но к сожалению это не будет работать так, как вам бы хотелось. Хорошая новость в том, что есть простое решение:

Скажите Ubuntu что python это python3
$ apt-get install python-is-python3

Да, есть целый пакет для Ubuntu созданный специально для решения этой задачи. Но это работает ¯_(ツ)_/¯.

Комментарии (26)


  1. raamid
    03.09.2022 10:51
    +5

    Контейнеры наше всё. Специально начал изучать контейнеры именно из-за описанного вами случая: среда ОС+ПО перестают нормально работать при необходимости использовать разные версии ПО или когда неудачно установил ПО. Очень рекомендую посмотреть в сторону контейнеров.

    В дополнение к беспроблемной установке вы получаете еще безопасность (как-то не сильно хочется запускать чужой скрипт на родной машинке) и портируемость (чтобы развернуть программную инфраструктуру на другом компьютере достаточно просто взять текстовый файл с настройками контейнера и применить его)


    1. masai
      03.09.2022 11:37
      +3

      Контейнеры хороши, но для каких-то небольших задач такой уровень изоляции не нужен. Можно обойтись и pyenv, который одной командой ставит нужные версии Python (и не удаляет их при обновлении).


      1. masai
        03.09.2022 13:15
        +1

        Минусы меня не смущают, но стало очень интересно, с каким утверждением люди не согласны.


        1. raamid
          03.09.2022 13:54
          +2

          Если что, минусы не мои, но я попробую обосновать свои вышеизложенные аргументы. Преимущество контейнеров в их универсальности. Например, я новичок в Python и понятия не имел про pyenv. Мне проще создать контейнер (дело нескольких секунд) и в нем развернуть новую версию.

          Кроме того, проблемы совместимости могут не ограничиваться возможностями pyenv. Например, это могут быть какие-то разные версии внешней библиотеки, которые использует ваш скрипт.

          Резюмируя: контейнеры позволят одним махом отсекать целые слои потенциальных проблем и не париться и не тратить время на исследования.


          1. masai
            03.09.2022 14:02

            Так я ж не говорю, что контейнеры — это плохо. Мой комментарий как раз и начинается с обратного утверждения. Я на работе постоянно пользуюсь контейнерами (в Kubernetes сложно без этого), и локально частенько веду разработку в контейнере примонтировав данные в отдельный том, так как иногда нужно специфическое окружение. Я просто хотел сказать, что это не единственный способ.

            Насчёт того, что вы не знали про pyenv, так это не проблема. Теперь-то знаете. :)

            А то, что есть ситуации, когда pyenv неудобен (такие, конечно, есть), совершенно не означает, что он неудобен всегда.

            Да, контейнер можно запустить за пару секунд, но pyenv устанавливает интерпретаторы в систему, и тут вообще не нужно ничего устанавливать и запускать, интерпретатор уже есть.

            Это как спор, что лучше: контейнеры или виртуальные окружения. Оба хороши в своих областях и друг другу не мешают. Это ложная дихотомия.


            1. raamid
              03.09.2022 14:21
              +1

              Насчёт того, что вы не знали про pyenv, так это не проблема. Теперь-то знаете. :)

              Однако, я по прежнему не знаю как им пользоваться. Поэтому, в случае любой сомнительной ситуации просто разверну новый контейнер.

              Иными словами, контейнеры помогают, когда что-то не работает и при этом непонятно почему. Довольно частая ситуация, кстати, поскольку когда понятна причина, проблема быстро фиксится и о ней вообще не рассуждают.

              В принципе, поскольку вы уже знакомы с контейнерами, я могу считать свою миссию выполненной :) Почему-то мне подумалось, что кто-то может не знать про такую удобную и мощную технологию.


              1. alepron
                05.09.2022 14:28

                Я не знал ни про контейнеры, ни про pyenv. Теперь знаю. Но по прежнему не умею пользоваться. А вот про update-alternatives знал и умел давно, причем это первое, что пришло в голову. И даже не представляю, как можно "сломать ОС", о чем пишет автор.


      1. datacompboy
        03.09.2022 14:29
        +2

        Но для каких-то небольших задач и изоляция не нужна.

        Надо танцевать с бубном -- возьмём контейнер, где всё просто.

        Надо что-то мелкое для себя -- можем и поправить если что не так.

        А "надо иметь зоопарк версий с гвоздями прибитыми версиями" это всё же пережиток прошлого, когда были либо VM что долго и тяжело либо контейнеры которые совсем не легковесные.


        1. masai
          03.09.2022 14:47
          +1

          Но для каких-то небольших задач и изоляция не нужна.

          Именно это я и написал. :)

          Ну вот, скажем, веду я разработку на маке (да-да, я знаю, что статья про Ubuntu), который выдал мне работодатель. Контейнеры там работают внутри виртуальной машины, стартуют не так уж быстро, работают неповоротливо, а примонтированные тома очень медленные. Это у линукс-бояр контейнер — это изолированный процесс. Так что накладные расходы всё же есть.

          Например, у меня есть проект с бинарным модулем на Python, который в системе собирается за минуты, а в контейнере приходится танцевать с бубном и всё равно сборка на порядок медленнее.

          Так что контейнеры — это не всегда решение для локальной разработки. Хотя иногда, как я уже написал, ими пользуюсь. Тем более, что в VS Code это делать суперлегко и удобно.

          Насчёт прибитых гвоздями версий. Вполне реальна ситуация, когда одном проекте Python 3.8, в другом Python 3.10, а в системе вообще Python 3.9. C pyenv установить интерпретаторы можно в одну строку (хотя это можно сделать и системным пакетным менеджером, я ниже упоминал PPA для Ubuntu). И тут прибитые гвоздями интерпретаторы — это благо, так как виртуальные окружения, в которых я веду разработку, не сломаются от того, что какой-то интерпретатор внезапно удалился по какой-то причине.


          1. datacompboy
            03.09.2022 16:40

            Разные проекты где нельзя обновить систему? Контейнеры.

            Для себя? Поставить одну вёрсию. В конце концов, не 2.6 + 3.5 же держим!


    1. CrocodileRed
      04.09.2022 19:32

      Новичкам только докера не хватает, ага ))

      Устанавливаете нужный питон из исходников (инструкций в инете выше крыши), устанавливаете venv и source ... activate. Среда для hello world готова. Если и это окажется слишком сложно, то я утверждаю, что для соискателя сойдёт любая версия трёшки :))


  1. Tim_86
    03.09.2022 11:09

    Сталкивался с аналогичной проблемой обновления Python в Ubuntu 20.04. Неправильное обновление может сломать систему, нужно быть осторожным вводя команды в консоли.


    1. Yak52
      03.09.2022 14:15

      Еще как сломать. Я как то раз день потратил на то, что бы понять почему новая Убунта после рестарта теряла сеть. Оказалась когда я обновлял версию питона, то за одно со старой версией удалил кучу зависимостей, в том числе netplan, написаный на питоне, который отвечает за конфигурацию сети.


  1. KorP
    03.09.2022 11:11
    +1

    Ну хоть бы для статьи в листингах версии поправили, а то в каждом листинге разные версии фигурируют, что может запутать новичков.


  1. masai
    03.09.2022 11:34
    +12

    Достаточно просто установить pyenv, который одной командой решит все проблемы.

    Как вариант, в убунту можно подключить репозиторий deadsnakes со всеми версиями Python.

    Устанавливать что-то руками с sudo в обход пакетного менеджера как в статье — это, наверное, худший способ.


    1. Vasily_Pechersky
      03.09.2022 12:34

      Ну поэтому автор и пишет — «не делайте этого»


      1. masai
        03.09.2022 13:19

        Как я понял, это относится к другим способам, а описанный он чуть ниже называет оптимальным.


  1. masai
    03.09.2022 13:20
    +2

    К слову, altinstall — это не встроенный в Ubuntu способ, а название правила для make, которое сгенерировал скрипт от авторов Python.


  1. select26
    03.09.2022 14:20
    +1

    Боже мой, какая дичь!

    Неужели автор не слышал про virtual environment?

    Придумал себе проблему и мужественно её решает. А если не Ubuntu? А если не 20 версии? А если не Linux?

    Virtual environment позволяет решить вопрос python окружения везде, где бежит python одной командой без скачивания и компиляции исходных кодов. Документация - наше всё.


    1. Tim_86
      03.09.2022 14:30
      -3

      Дичь пишете вы. Бывает что надо (или просто захотелось) обновить питон в системе. Многие пользователи уже сталкивались с проблемами в случае неправильного обновления питона в Linux. Автор просто указывает что такая проблема есть и показывает как её можно обойти.


      1. select26
        03.09.2022 14:33
        +3

        Поясните причину, по которой "надо просто обновить python в системе"?

        Для чего? Потешить эго? А если уж "просто захотелось", то тогда не нужно рыдать. Но это явно не производственная необходимость.

        Системный python необходим для конкретных системных задач, зачастую привязанных к его версии. Зачем его ломать? Поясните пожалуйста.


        1. Tim_86
          03.09.2022 14:38

          Ну например у меня poetry был установлен в систему и просил Python 3.9.


          1. DustCn
            03.09.2022 23:04
            +2

            И как он туда попал без удовлетворенной зависимости?


      1. masai
        03.09.2022 14:49

        Автор правильно указывает на проблему, но способ, которым он её решает, сомнительный.


    1. un1t
      03.09.2022 19:23
      +3

      venv это про пакеты, а не про версии питона.


  1. AMDmi3
    03.09.2022 15:21

    FYI, существуют пакетные инфраструктуры предоставляющие несколько версий питона, в том числе одновременно. Например, порты FreeBSD. С ними мне ни разу в жизни не приходилось запускать pip или venv.