Skip to content

Importing a module gives module has no attribute

Python importing a module gives module has no attribute#

An unexpected error was raised when importing a package and trying to use a module inside the imported package.

AttributeError: module 'system_utilities' has no attribute 'events'

This is an error of the standard form:

AttributeError: module 'x' has no attribute 'y'

The strange thing was one expected it work. Here is the code in run.py:

import system_utilities
system_utilities.events.NewEvent()

The folder structure:

run.py
system_utilities/
    __init__.py
    events.py

The strange thing is that compared to a package import like import datetime you can access attributes and methods (or functions) levels down…eg: datetime.datetime.now()

Confusing a Module and a Package#

A module is simply a file. Above, events.py is a module.

A package is a folder (directory) of modules (file). It is a name (a namespace). Python knowns it is a package due to the presence of a __init__.py (package constructor) file inside. Above, system_utilities is a package.

import datatime is importing a module - in the standard library of python that corresponds with a file called datetime.py.

import urllib on the other hand imports a package from the standard library.

Interesting to note that most things are implemented as straight modules in teh python standard library - something to apply to simplify our own code?

Module vs Package#

  • All attributes in a module are imported by default.
  • All modules in a package are not imported by default.

Module:

>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2023, 1, 5, 12, 38, 3, 320737)

package (without automatic import):

>>> import urllib
>>> urllib.request.urlopen('https://example.org')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'urllib' has no attribute 'request'

package (with automatic import):

>>> import unittest
>>> unittest.case.TestCase()
<unittest.case.TestCase testMethod=runTest>

In the above example urlib has an __init__.py that is empty. In this case you must import the modules directly from within the package.

In the case of unittest the __init__.py file does the imports and exposed the string names available with the package is run:

__all__ = ['TestResult', 'TestCase', 'IsolatedAsyncioTestCase', 'TestSuite',
        'TextTestRunner', 'TestLoader', 'FunctionTestCase', 'main',
        'defaultTestLoader', 'SkipTest', 'skip', 'skipIf', 'skipUnless',
        'expectedFailure', 'TextTestResult', 'installHandler',
        'registerResult', 'removeResult', 'removeHandler',
        'addModuleCleanup']

# Expose obsolete functions for backwards compatibility
__all__.extend(['getTestCaseNames', 'makeSuite', 'findTestCases'])

__unittest = True

from .result import TestResult
from .case import (addModuleCleanup, TestCase, FunctionTestCase, SkipTest, skip,
                skipIf, skipUnless, expectedFailure)