178

I am Debian user, and I want to install python-dev, but when I run the code in the shell as a root:

# aptitude install python-dev

I get the following error:

Traceback (most recent call last):       
  File "/usr/bin/apt-listchanges", line 28, in <module>
    import apt_pkg
ImportError: No module named apt_pkg

What seems to be the problem and how can I resolve it?

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
Belphegor
  • 4,456
  • 11
  • 34
  • 59
  • 1
    looks like your apt ist broken, what happens when you try apt-get install python-dev – Pierre Geier Dec 05 '12 at 06:45
  • When I try with apt-get install python-dev it says that it is already installed: Reading package lists... Done Building dependency tree Reading state information... Done python-dev is already the newest version. 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. Any other suggestions? – Belphegor Dec 05 '12 at 09:14

25 Answers25

252

I met this problem when doing sudo apt-get update. My env is debian8, with python2.7 + 3.4(default) + 3.5.

The following code will only re-create a apt_pkg....so file for python 3.5

sudo apt-get install python3-apt --reinstall

The following code solved my problem:

  1. Go to dist-packages
cd /usr/lib/python3/dist-packages
  1. Locate the appropriate .so file for the python version installed on your system:
ls -l | grep apt_pkg
  1. Create a symbolic link:
sudo ln -s apt_pkg.cpython-{your-version-number}-x86_64-linux-gnu.so apt_pkg.so
  1. Replace {your-version-number} appropriately.

CAUTION, the following will create a symlink from apt_pkg37m to apt_pkg36m. make sure you are linking to the correct, or at least to an existing version by ls apt_pkg.cpython-*, and see which one(s) you have installed.

sudo ln -s apt_pkg.cpython-{35m,34m}-x86_64-linux-gnu.so apt_pkg.so

So, obviously, python3-apt checks the highest python version, instead of the current python version in use.

To understand why this is happening, see this answer further down: https://stackoverflow.com/a/64241654/21539

Intrastellar Explorer
  • 3,005
  • 9
  • 52
  • 119
zhazha
  • 3,114
  • 2
  • 13
  • 7
  • 34
    `sudo ln -s apt_pkg.cpython-{35m,34m}-x86_64-linux-gnu.so` should be changed to `sudo ln -s apt_pkg.cpython-{35m,34m}-x86_64-linux-gnu.so apt_pkg.so` – desaiankitb May 17 '18 at 11:56
  • 41
    You are amazing! For me, it was `sudo ln -s apt_pkg.cpython-{35m,36m}-x86_64-linux-gnu.so` for python3.6, and this horrific bug is now gone. – Alex Gurrola May 19 '18 at 21:38
  • I needed to run `sudo ln -s apt_pkg.cpython-{35m,34m}-x86_64-linux-gnu.so apt` – Philippe C Jun 08 '18 at 12:12
  • 63
    After installing Python 3.7 next to the default 3.6 in Ubuntu 18.04 with `sudo apt install python3.7` I got this apt_pkg error trying to run pip, so I needed to run `cd /usr/lib/python3/dist-packages` then `sudo ln -s apt_pkg.cpython-{36m,37m}-x86_64-linux-gnu.so` then `sudo apt install python3-pip`. – abulka Feb 28 '19 at 11:35
  • 3
    for python 3.6, command will be `sudo ln -s apt_pkg.cpython-{35m,36m}-x86_64-linux-gnu.so` – StatguyUser Mar 11 '19 at 07:46
  • @AlexGurrola Verified in Ubuntu 16.04 on 22Aug2019 – vineeshvs Aug 22 '19 at 09:29
  • 1
    What does the ln command do? I have never seen braces used that way before. Looks like some kind of black magic. – allyourcode May 23 '20 at 04:18
  • 2
    Those braces are not a property of the the ln command. They invoke shell brace expansion, see https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html – Carlos A. Ibarra Aug 24 '20 at 16:03
  • for me no 'm', just the python version number `apt_pkg.cpython-38-x86_64-linux-gnu.so`. – Sylvain Sep 13 '21 at 09:01
  • still relevant for 2023 on ubuntu 20.04 – eran otzap Mar 18 '23 at 14:51
  • It worked for ubuntu 18.04 and python version 3.8 – CVDE Apr 04 '23 at 06:57
183

Solve it by this:

cd /usr/lib/python3/dist-packages
cp apt_pkg.cpython-34m-i386-linux-gnu.so apt_pkg.so

Or:

cd /usr/lib/python3/dist-packages
cp apt_pkg.cpython-35m-x86_64-linux-gnu.so apt_pkg.so

Basically, if you get a No such file or directory just ls to try to get the right name.

Gulzar
  • 23,452
  • 27
  • 113
  • 201
user8178061
  • 1,831
  • 1
  • 8
  • 2
  • 7
    On Ubuntu 18.04, use this $ cd /usr/lib/python3/dist-packages $ sudo cp apt_pkg.cpython-36m-x86_64-linux-gnu.so apt_pkg.so – Naren Yellavula May 13 '19 at 14:31
  • This worked for me as well... I listed all the files on the `/usr/lib/python3/dist-packages`, and I saw that I didn't have of `apt_pkg.cpython-34m-i386-linux-gnu.so` or `apt_pkg.cpython-3m-i386-linux-gnu.so`, but I had `apt_pkg.cpython-36m-i386-linux-gnu.so`... I copied this file to `apt_pkg.so` and worked perfectly! Thanks! – Leonardo Isso Sep 25 '19 at 15:57
  • This worked for me as well. As @LeonardoIsso did I also listed all files to find the proper file name because i am on 32 bit Linux. – w3Develops Nov 21 '19 at 16:08
112

This happened to me on Ubuntu 18.04.2 after I tried to install Python3.7 from the deadsnakes repo.

Solution was this

1) cd /usr/lib/python3/dist-packages/

2) sudo ln -s apt_pkg.cpython-36m-x86_64-linux-gnu.so apt_pkg.so

LoicM
  • 1,786
  • 16
  • 37
Mirror Mirage
  • 1,287
  • 1
  • 8
  • 7
78

Make sure you have a working python-apt package. You could try and remove and install that package again to fix the problem with apt_pkg.so not being located.

apt-get install python-apt
Arnestig
  • 2,285
  • 18
  • 30
  • It is already installed. When I hit: # apt-get install python-apt it gives me Reading package lists... Done Building dependency tree Reading state information... Done python-apt is already the newest version. 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. And when I try again with: # aptitude install python-dev It gives me the same error again. Some other ideas what should I do? – Belphegor Dec 05 '12 at 09:09
  • 20
    remove it using `apt-get remove --purge python-apt` and install it again – Arnestig Dec 05 '12 at 09:20
  • 10
    Be aware of other dependencies. I removed the package (too) quickly in Ubuntu and lots of other dependencies were removed as well (e.g. ubuntu-desktop). It's my fault for not paying attention to the notes in the log, however. – Al R. Jan 29 '13 at 19:21
  • 1
    Not really sure if it was due to python-apt. Look over at http://packages.ubuntu.com/lucid/ubuntu-desktop for dependencies to ubuntu-desktop. – Arnestig Jan 29 '13 at 20:07
  • 5
    @Arnestig REMOVING `python-apt` sounds rather dangerous!! Learnt my lesson once and I shall not try it. – alvas Apr 11 '16 at 01:26
  • 1
    Compiling python worked for me, here is the link https://github.com/pypa/pip/issues/5367#issue-320060428 – Abhimanyu Aug 28 '19 at 11:17
  • 1
    Fixed that error, now I'm getting `ImportError: cannot import name '_gi' from 'gi' (/usr/lib/python3/dist-packages/gi/__init__.py)` :(.. – CpILL Oct 21 '19 at 03:35
  • @Arnestig thank you, `--purge` and then reinstalling seems to have fixed it for me – Boris Verkhovskiy Dec 23 '19 at 16:59
  • 2
    Not working after upgrade from 3.5 to 3.9. – fcm Dec 06 '20 at 10:02
31

This error will often occur when a newer version of python has been installed alongside an older version e.g;

  • Ubuntu 18.04.1 ships with python version 3.6.6
  • Installed ppa:deadsnakes/python3.7.1 or alternative
  • Run a command that uses the apt_pkg module and get an error such as;

        from CommandNotFound.db.db import SqliteDatabase
    File "/usr/lib/python3/dist-packages/CommandNotFound/db/db.py", line 5, in <module>
        import apt_pkg
    

When we install a non-distro python3 version with apt it will set a shared module directory to be that of python3 most usually it will be /usr/lib/python3.

Most of the time this will be ok, but under some circumstances the different versions of python rely on different libraries or shared objects/libraries than the other python version does, so as other answers have pointed out we need to link the .SO to the correct python version. So if we have python3.6 installed on a 64bit system then the apt_pkg .SO link would be

sudo ln -s apt_pkg.cpython-36m-x86_64-linux-gnu.so apt_pkg.so

But the problem lies in the fact that when we install a newer python version the link will update to point to the newest python version, which leads to the error of apt_pkg module not being found. By checking which version of python ships with your distro you can create the link as shown above. Or we use a method to offer the command a choice of python versions to link the .SO such as;

sudo ln -s apt_pkg.cpython-{36m,35m,34m}-x86_64-linux-gnu.so apt_pkg.so

Because python will create this link to the newest installed python version we give the command the option to choose from 3 python versions, of which it will choose the highest version given.

a.t.
  • 2,002
  • 3
  • 26
  • 66
Jamie Lindsey
  • 928
  • 14
  • 26
  • 2
    Running 18.04.2, your first recommendation worked for me and I could finally run the sudo apt-get update with no errors. Your second recommendation return an error saying apt-get.so was not a folder. – CloseISQ Apr 28 '19 at 16:47
29

I see everyone saying how to fix it with strange copying etc, but no one really said why the problem occurs.

So let me explain, for those of you who like me don't want to mess with system files only because someone on SO told them so.


The problem is that:

  • many system scripts have python3 shebang hardcoded into them. You can check it yourself:
~$ grep -R "\#\!/usr/bin/python3" /usr/lib/*

/usr/lib/cnf-update-db:#!/usr/bin/python3
/usr/lib/command-not-found:#!/usr/bin/python3
/usr/lib/cups/filter/pstotiff:#!/usr/bin/python3
/usr/lib/cups/filter/rastertosag-gdi:#!/usr/bin/python3 -u
grep: /usr/lib/cups/backend/cups-brf: Permission denied
/usr/lib/cups/backend/hpfax:#!/usr/bin/python3
/usr/lib/language-selector/ls-dbus-backend:#!/usr/bin/python3
/usr/lib/python3/dist-packages/language_support_pkgs.py:#!/usr/bin/python3
/usr/lib/python3/dist-packages/softwareproperties/MirrorTest.py:#!/usr/bin/python3
/usr/lib/python3/dist-packages/cupshelpers/installdriver.py:#!/usr/bin/python3
/usr/lib/python3/dist-packages/cupshelpers/openprinting.py:#!/usr/bin/python3
/usr/lib/python3/dist-packages/cupshelpers/xmldriverprefs.py:#!/usr/bin/python3
/usr/lib/python3/dist-packages/cupshelpers/smburi.py:#!/usr/bin/python3
/usr/lib/python3/dist-packages/cupshelpers/ppds.py:#!/usr/bin/python3
/usr/lib/python3/dist-packages/cupshelpers/debug.py:#!/usr/bin/python3
/usr/lib/python3/dist-packages/DistUpgrade/dist-upgrade.py:#!/usr/bin/python3
/usr/lib/python3/dist-packages/CommandNotFound/db/creator.py:#!/usr/bin/python3
/usr/lib/python3/dist-packages/CommandNotFound/db/db.py:#!/usr/bin/python3
/usr/lib/python3/dist-packages/Quirks/quirkreader.py:#!/usr/bin/python3
grep: /usr/lib/ssl/private: Permission denied
/usr/lib/system-service/system-service-d:#!/usr/bin/python3
/usr/lib/ubuntu-release-upgrader/check-new-release-gtk:#!/usr/bin/python3
/usr/lib/ubuntu-release-upgrader/do-partial-upgrade:#!/usr/bin/python3
/usr/lib/ubuntu-release-upgrader/check-new-release:#!/usr/bin/python3
/usr/lib/update-notifier/package-data-downloader:#!/usr/bin/python3
/usr/lib/update-notifier/backend_helper.py:#!/usr/bin/python3
/usr/lib/update-notifier/apt_check.py:#!/usr/bin/python3
/usr/lib/update-notifier/apt-check:#!/usr/bin/python3

  • python apt package python-apt/python3-apt is a system package, so it's for default system python

Thus, the scripts will always get the version currently linked to python3, but fail because the apt package is not present.


General solution: NEVER change default python3 link. Ever. This also applies to python link - if an app was written in Python2 with some old syntax elements that don't work in Python3, the app will not work.

[My terminal broke that way because I use Terminator, which is apparently written in Python2.7 not compatible with Python3.]


Solutions presented here either suggest copying/linking the apt package files or changing python3 link.

Let's analyse both:

  1. Copying/linking the apt package

This shouldn't be a problem because from around Python3.4 all python scripts work on newer versions as well.

So far. But it may break in the future - if you keep your system long enough.

  1. Changing python3 link back

This is a great solution because we can get back to "never ever changing the link"


"But I like having to type just python!" - I like it too! That's how I got to this problem in the first place!

  1. In general, you should avoid manually changing system links - use update-alternatives instead to link different versions. This applies to any app with many versions. This will still break those system scripts (because it does change the link), but you can switch back and forth easily, without worrying whether you put link and dest in the right order or made a typo.

  2. Consider using other name than python/python3 for your link or alias.

  3. Or add your own python/python3 link to PATH (just like virtual environments do), without changing system links.

h4z3
  • 5,265
  • 1
  • 15
  • 29
24

This worked for me on after updating python3.7 on ubuntu18.04

cd /usr/lib/python3/dist-packages
sudo cp apt_pkg.cpython-36m-x86_64-linux-gnu.so apt_pkg.so
astha
  • 593
  • 5
  • 15
  • 3
    This worked for me after upgrade **python 3.8** on ubuntu18.04. – Henry Palacios May 21 '20 at 14:30
  • This worked for me with **Python 3.8.5** with **Ubuntu 20.04**; the cause for trouble was having played around with the targets py2/py3 of the symbolic link /bin/usr/python. This confused some programs calling py3 which threw the OP's error. The other answer https://stackoverflow.com/a/64241654/5459638 contains useful information to understand what happened. – XavierStuvw Apr 07 '21 at 20:28
18

The solution of @user8178061 worked well but I did it with some modifications for my version wich is python3.7 with Ubuntu

I replaced the apt_pkg.cpython-3m-i386-linux-gnu.so with apt_pkg.cpython-36m-x86_64-linux-gnu.so

Here the two commands to execute:

cd /usr/lib/python3/dist-packages

sudo cp apt_pkg.cpython-36m-x86_64-linux-gnu.so apt_pkg.so

Hugo Sohm
  • 2,872
  • 4
  • 23
  • 40
  • 1
    This fixed my problem. This solves the problem if it was caused by switching the Python version from 3.6 to 3.7. –  Dec 05 '19 at 18:39
  • 1
    Thanks, had the same issue! Consider using `sudo ln -s apt_pkg.cpython-36m-x86_64-linux-gnu.so apt_pkg.so` so it's clear what `apt_pkg.so` is. – Scipio Dec 17 '19 at 19:56
  • Worked, but I had to change it to `sudo cp apt_pkg.cpython-37m-x86_64-linux-gnu.so apt_pkg.so` for some reason – Daniel Feb 25 '20 at 15:47
16
  1. Check your default Python 3 version:

    python3 --version
    Python 3.7.5
    
  2. cd into /usr/lib/python3/dist-packages and check the apt_pkg.* files. You will find that there is none for your default Python version:

    ll apt_pkg.*
    apt_pkg.cpython-36m-x86_64-linux-gnu.so
    
  3. Create the symlink:

    sudo ln -s apt_pkg.cpython-36m-x86_64-linux-gnu.so apt_pkg.cpython-37m-x86_64-linux-gnu.so 
    
Nico Schlömer
  • 53,797
  • 27
  • 201
  • 249
9

if you're using python 3.7 downgrade it to python 3.6 by updating Alternatives, This worked for me

sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1

sudo update-alternatives --config python3
Viren Patel
  • 91
  • 1
  • 4
8

In my case I ran below command and it fixed the error:

sudo apt install --reinstall python3 python python3-minimal --fix-broken

7

For some reason my install was missing apt_pkg.so in the python3 dist-packages dir. (apt_pkg.cpython-33m-x86_64-linux-gnu.so was there?!) but and I had to make a symlink apt_pkg.so -> apt_pkg.cpython-33m-x86_64-linux-gnu.so in /usr/lib/python3/dist-packages

I'm not sure whether my upgrade was broken or why this was the case. It occured after trying to upgrade (precise->raring->quantal upgrade)

Jamie Pate
  • 1,783
  • 20
  • 18
  • 1
    This was correct fix for me. I caused this problem by using pip3 as root, even though I knew it was a bad idea. I wanted to see how badly I'd get shocked if I put my finger in a light socket. Answer is: pretty bad. Also messing with the /etc/alternatives setup is not for the feint of heart. Not for anybody who is a part time visitor. I think crossing what python link pointed at which python was problem that started me down path to disaster. – pauljohn32 Mar 19 '20 at 23:02
5

A last resort is sudo cp /usr/lib/python3/dist-packages/apt_pkg.cpython-35m-x86_64-linux-gnu.so /usr/lib/python3/dist-packages/apt_pkg.cpython-36m-x86_64-linux-gnu.so if the ln command is too much for you or somehow magically doesn't work.

cp above can also be mv if you are only dedicated to using one Python version.

Tong Niu
  • 91
  • 1
  • 4
4

I'm on Ubuntu 16.04, and upgraded to Python 3.7. Here is the error that I had when trying to add a PPA

    sudo add-apt-repository ppa:ubuntu-toolchain-r/test                                           
Traceback (most recent call last):
  File "/usr/bin/add-apt-repository", line 11, in <module>
    from softwareproperties.SoftwareProperties import SoftwareProperties, shortcut_handler
  File "/usr/lib/python3/dist-packages/softwareproperties/SoftwareProperties.py", line 27, in <module>
    import apt_pkg
ModuleNotFoundError: No module named 'apt_pkg'

I was able to fix this error by making symbolic link with my initial python 3.4 apt_pkg.cpython-34m-x86_64-linux-gnu.so by creating the following symbolic link

sudo ln -s apt_pkg.cpython-34m-x86_64-linux-gnu.so apt_pkg.so
GigaWatts
  • 101
  • 8
  • 2
    It looks like this solution was already proposed in at least 6 another answers to this question (and 3 more just suggested to copy the file instead of symlinking). – Sergey Shubin Jul 07 '20 at 14:50
  • 2
    this simply works for me, thanks! One thing is before that we need to cd /usr/lib/python3/dist-packages – Hao Yellow Jul 14 '20 at 08:07
3

If you're using python 3.5, downgrade to 3.4. That's the safest move to do.

Under /usr/lib/python3/dist-packages you'll see *34m* which python 3.5 can't use. zhazha answer symlink to it.

Pobe
  • 2,693
  • 1
  • 17
  • 24
3

In addition to making a symbolic link for apt_pkg.so, you may want to make apt_inst.so in the same manner of apt_pkg.so.

ln -s apt_inst.cpython-35m-x86_64-linux-gnu.so apt_inst.so 
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
2

I tried to create the link but many other problems happened. So, you can select the old version of python to install things using:

sudo update-alternatives --config python3

And return to the desirable version right after using the same command. Hope it works.

1

Windows 10 WSL v1 (Ubuntu 16.04.6 LTS)

This reddit answer (slightly modified worked for me)

sudo ln -sfn /usr/lib/python3/dist-packages/apt_pkg.cpython-35m-x86_64-linux-gnu.so apt_pkg.so

1

After spending 4 hours I have got this solution which finally worked for me I hope this will help...

It is important to understand that sometimes when you upgrade from an older python version some packages stay in the previous version path, so here is what I did:

cd /usr/lib/python3/dist-packages

Check the existence of a file named apt_pkg.cpython-35m-x86_64-linux-gnu.so or 34m or 36m listing the files and when you find it, delete the current apt_pkg.so file in

/usr/lib/python3/dist-packages

Finally create a link with the correct path using apt_pkg.so like this:

cd /usr/lib/python3/dist-packages
sudo ln -s apt_pkg.cpython-35m-x86_64-linux-gnu.so apt_pkg.so

Now you can try again and It should work.

Hami
  • 704
  • 2
  • 9
  • 27
Aahad
  • 507
  • 4
  • 13
1

This variant work for me.

cd  /usr/lib/python3/dist-packages
ls -la /usr/lib/python3/dist-packages
sudo cp apt_pkg.cpython-38-x86_64-linux-gnu.so apt_pkg.so

If you get an error message saying too many levels of symbolic links as shown below:

cp: failed to access '/usr/lib/python3/dist-packages/apt_pkg.so': Too many levels of symbolic links

Then you need to simply unlink the apt_pkg.so file. Use the following command:

sudo unlink apt_pkg.so

And then use the command

sudo cp apt_pkg.cpython-38-x86_64-linux-gnu.so apt_pkg.so

Good luck!

Original answer: https://askubuntu.com/a/1227625

Andrew Lt
  • 183
  • 1
  • 4
0

None of the answers worked for me (I am using Ubuntu 16.04 and Python 3.6). So I finally solved the issue as following:

1- connect to the FTP of the server

2- go to the folder "/usr/lib/python3/dist-packages/"

3- duplicate the file "apt_pkg.cpython-35m-x86_64-linux-gnu.so"

4- rename this duplicated file to "apt_pkg.cpython-36m-x86_64-linux-gnu.so"

That's it!

Julio S.
  • 944
  • 1
  • 12
  • 26
0

Well, the cleanest solution for me is to rebuild the related library with your new Python version, in its specific space.

I'm doing this right now, switching from Python3.9 to Python3.10.1.

So:

cd /tmp/
apt source python3-apt
cd python-apt-version-ecc
python3-new-version setup.py build
python3-new-version setup.py install

Done this also with dependencies packages (software-properties, python-launchpadlib, and so on), and now add-apt-repository works like a charm.

Which ones to recompile? Simply watch out the complains of running add-apt-repository.

By the way, I'm on Ubuntu 21.04, but the logic is the same on any Debian like system.

-1

Please review the following documentation.

It could help you to solve the problem.

Solve the problem of replacing the python version with ModuleNotFoundError: No module named 'apt_pkg'

Andre Leon Rangel
  • 1,659
  • 1
  • 16
  • 28
Oni
  • 1,093
  • 11
  • 16
-4

Please try to fix this by setting the locale variables:

export LC_ALL="en_US.UTF-8"

export LC_CTYPE="en_US.UTF-8"
Harshith Rai
  • 3,018
  • 7
  • 22
  • 35
rajendra sharma
  • 449
  • 1
  • 5
  • 7
-6

Just in case it helps another, I finally solved this problem, that was apparently caused by python version conflicts, by redirecting the link python3, then redirecting it to the right python version:

sudo rm /usr/bin/python3
sudo ln -s /usr/bin/python3.4

You may need to enter the correct python version, found with:

python3 -V
  • 2
    remove python3 is bad idea :( if you want link to python 3.4 use : ln -s /usr/bin/python3.4 /usr/bin/python3 – Pamungkas Jayuda May 12 '18 at 06:21
  • 2
    It's never a good idea to tell people to remove things from there system unless it is really needed. Luckily /usr/bin/python3 is normally just a symbolic link anyway. I really think you should just delete this answer. – Jamie Lindsey Feb 18 '19 at 09:32
  • at least reinstall is safer... `sudo apt install --reinstall python3` – Andre Leon Rangel Aug 06 '21 at 03:22