Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Another absolute import problem

Tags:

python

I'm having problems with my own modules overriding built in Python ones (specifically the logging module). Here's my project layout:

run.py
package/
        __init__.py
        logging/
                __init__.py
        ...

run.py

from package import main

main()

package/__init__.py

from __future__ import absolute_import
import logging
import logging.config

def main():
    logging.config.fileConfig(...)

package/logging/__init__.py

class Logging(object):
    pass

As it stands right now, the above code works. As soon as I try to import the Logging class from package.logging like so:

from __future__ import absolute_import

import logging
import logging.config
from package.logging import Logging

def main():
    logging.config.fileConfig(...)

I get an error:

AttributeError: 'module' object has no attribute 'config'

I've read the PEP 328 release notes and found absolute imports to be rather straightforward. Unfortunately I haven't been able to figure this one out.

What am I missing here?

like image 892
kierse Avatar asked Aug 11 '09 23:08

kierse


People also ask

What is an absolute import?

An absolute import specifies the resource to be imported using its full path from the project's root folder.

Should you use relative imports Python?

Relative imports are helpful when you are working alone on a Python project, or the module is in the same directory where you are importing the module. While importing the module, be careful with the (.) dot notation.

What is absolute import in react?

Absolute import in React TypescriptIf you're using TypeScript in your project and you created it with command: npx create-react-app bezkoder-react-app --template typescript. You already have the tsconfig. json file inside project root directory. Just open it and add the same baseUrl setting as Javascript.


1 Answers

Relative and absolute imports (PEP 328) are not the problem here.

What happens is that when a module in a package is imported, it is implicitly added to this package's namespace. So

from package.logging import Logging

not only adds 'Logging' to package._dict_, but also adds 'logging' (the newly import local module) to package._dict_. So you first import logging (the top-level module) and it is available as package.logging, and then you overwrite this variable with the local module. This basically means that you cannot have a package.logging to access the top-level module and your local module, as expected.

In this specific case, you probably don't want to "export" the top-level logging module as a public name. Instead do:

from logging import config as _config
def main():
    _config.fileConfig(...)
like image 94
zbyszek Avatar answered Sep 19 '22 12:09

zbyszek