DEV Community

Yunus Emre Güzel
Yunus Emre Güzel

Posted on Edited on Originally published at blog.emreguzel.ca

PySerial: module ‘serial’ has no attribute ‘Serial’

You install PySerial, write serial.Serial("COM3", 9600), run the script, and Python says:

Traceback (most recent call last):
  File "C:\Users\you\project\main.py", line 3, in <module>
    ser = serial.Serial("COM3", 9600)
          ^^^^^^^^^^^^^
AttributeError: module 'serial' has no attribute 'Serial'
Enter fullscreen mode Exit fullscreen mode

The annoying part: the import worked. Python did find a module called serial. It's just not a working PySerial. There are three possible reasons, and one command tells you which one you have.

What the Error Means

import serial worked, so Python loaded something called serial. The error says that thing has no Serial class. PySerial defines Serial in serial/__init__.py. So either Python loaded a different serial, or it found PySerial's folder with that file missing.

Step 1: Find Out What serial Really Is

Print where Python loaded it from, and list what pip has installed:

python -c "import serial; print(serial.__file__)"
python -m pip list | findstr serial
Enter fullscreen mode Exit fullscreen mode

On macOS and Linux use grep serial instead of findstr serial. Use python -m pip instead of a bare pip, so pip and Python are guaranteed to be the same installation (more on that below). Then match what you see:

What you see What it means Fix
serial.__file__ is None An empty folder named serial, or a damaged PySerial install Cause 3
The path points into your own project Your own file or folder named serial hides the package Cause 1
pip list shows serial, not pyserial The wrong package is installed Cause 2

I reproduced all three in a fresh virtual environment (PySerial 3.5, Python 3.14), so the outputs below are real.

Cause 1: Your Own File Named serial.py

If your project has a file named serial.py, or a folder named serial, Python imports that instead of PySerial, because it looks in your script's folder first. I tried it: a serial.py next to a script gave me the same AttributeError. In that case serial.__file__ points at your own file.

Rename it, for example to serial_reader.py, and delete the __pycache__ folder next to it so Python doesn't keep using the old copy. This is the usual cause when you name your test file after the library.

Cause 2: The Wrong Package

PySerial installs with pip install pyserial, but you import it as serial. There's a different package on PyPI that is literally called serial, and pip install serial gets you that one. I tried it: it installs serial 0.0.97, import serial works, and serial.Serial doesn't exist.

python -m pip uninstall serial
python -m pip install pyserial
Enter fullscreen mode Exit fullscreen mode

If both are installed, remove both first so you get a clean copy:

python -m pip uninstall serial pyserial
python -m pip install pyserial
Enter fullscreen mode Exit fullscreen mode

Cause 3: A Damaged Install (the Confusing One)

This is the sneaky one. pip list still shows pyserial 3.5 and everything looks fine, but serial.__file__ prints None.

On the PC I used for this post, pip said pyserial 3.5, but serial/__init__.py was missing from the install folder, even though pip's own record lists it. Something had deleted it, and I couldn't tell what. Without that file Python treats the serial folder as an empty "namespace package", which is why __file__ is None and Serial doesn't exist.

The fix is to reinstall and force pip to replace the files:

python -m pip install --force-reinstall pyserial
Enter fullscreen mode Exit fullscreen mode

I tested this in a fresh virtual environment: I deleted serial/__init__.py, got the error, ran the command, and serial.Serial worked again.

One Script That Checks All Three

This script prints the path, checks for Serial, shows which of the two packages is installed, and tells you the cause and the fix. Run it with the same Python you use for your project:

# Diagnose: AttributeError: module 'serial' has no attribute 'Serial'
import importlib.metadata as md

import serial


def installed(name):
    try:
        return md.version(name)
    except md.PackageNotFoundError:
        return None


print("serial.__file__  :", serial.__file__)
print("has serial.Serial:", hasattr(serial, "Serial"))
print("installed pyserial:", installed("pyserial") or "no")
print("installed serial  :", installed("serial") or "no")

if serial.__file__ is None:
    print("-> 'serial' is an empty folder or a damaged install. Fix: pip install --force-reinstall pyserial")
elif hasattr(serial, "Serial"):
    print("-> PySerial looks fine.")
elif installed("serial"):
    print("-> The wrong package is installed ('serial', not 'pyserial'). Fix: pip uninstall serial, then pip install pyserial")
else:
    print("-> A file or folder named 'serial' in your project is hiding PySerial (see the path above). Rename it.")
Enter fullscreen mode Exit fullscreen mode

This is the real output on the damaged install described above:

serial.__file__  : None
has serial.Serial: False
installed pyserial: 3.5
installed serial  : no
-> 'serial' is an empty folder or a damaged install. Fix: pip install --force-reinstall pyserial
Enter fullscreen mode Exit fullscreen mode

I ran the script against all four states (healthy, damaged, a serial.py in the way, and the wrong package), and it named the right cause every time.

Check You Are Using the Same Python

Lots of machines have more than one Python: the Microsoft Store one, one from python.org, one inside a virtual environment, and whichever your editor picks. A bare pip can belong to a different Python than the one running your script, so you fix one installation and test another.

Ask the Python that runs your script which one it is, and have the same Python run pip:

python -c "import sys; print(sys.executable)"
python -m pip list
Enter fullscreen mode Exit fullscreen mode

python -m pip always uses the Python you typed. In VS Code, check the interpreter in the bottom-right corner: the Run button uses that one, which isn't necessarily the one in your terminal.

How to Avoid It

Never name your own file serial.py or pyserial.py, and never name a folder serial. Use a name like serial_reader.py or read_port.py. Make one virtual environment per project and install with python -m pip install pyserial, so the package is never mixed up with another project's. And if you ever see serial and pyserial together in pip list, remove both and reinstall pyserial alone.

If You Get a Different Error

The AttributeError is only one PySerial error. If Python says ModuleNotFoundError: No module named 'serial', PySerial is not installed in the Python you are running, which is a different problem: see ModuleNotFoundError After pip install? Here's the Fix. If the import works but opening the port fails with "Access is denied", see PySerial Access Is Denied on a COM Port.

If you are using PySerial to talk to an Arduino, Why delay() Freezes Your Arduino and How to Use millis() Instead covers the other side of the connection, and Architecting Autonomous AI Agents with Hardware Integration shows PySerial inside a bigger project.

The Short Version

module 'serial' has no attribute 'Serial' means Python imported something called serial that isn't a working PySerial. Print serial.__file__ and check pip list. None means a damaged install, a path inside your own project means a file is in the way, and serial in the pip list means the wrong package.

Download the code: the diagnostic script is on GitHub in Python-projects/Troubleshooting/pyserial-no-attribute-serial.


Originally published on my blog. I post new C, Python and AI-agent guides there regularly.

Top comments (0)