I have a package cclogger
. This directory has a __init__.py
file with some code to load the configuration. When I try to run the file api_main.py
in that directory using the following command...
python -m cclogger.api_main
I get the following erro:-
config loaded
Instantiating DB with: cclogger/test123@localhost:x
Instantiated ParseCentral
Register parser called by : CitiIndia
Registered parser for email: [email protected]
Instantiated SmsParseCentral
Register parser called by : Citi Bank
Registered sms parser for address: lm-citibk
Register parser called by : HDFC Bank
Registered sms parser for address: am-hdfcbk
Traceback (most recent call last):
File "/Users/applegrew/Dropbox/Credit Expense/cclogger/cclogger/api_main.py", line 4, in <module>
from .bottle import run, default_app, debug, get
ValueError: Attempted relative import in non-package
The messages displayed above the error are from modules in the same package which were imported by __init__.py
.
The code in api_main.py is:-
import re
import os
from .bottle import run, default_app, debug, get
from .common_util import date_str_to_datetime, UTCOffset, date_filter
#app = Bottle()
default_app().router.add_filter('date', date_filter)
from . import api, dev
@get('/index')
def index():
return "CCLogger API main live and kicking."
if dev:
debug(True)
run(reloader=True, port=9000)
else:
os.chdir(os.path.dirname(__file__))
application = default_app()
I have python 2.7.1.
What am I doing wrong? You can see the full code at https://github.com/applegrew/cclogger/tree/master/cclogger
Relative imports make use of dot notation to specify location. A single dot means that the module or package referenced is in the same directory as the current location. Two dots mean that it is in the parent directory of the current location—that is, the directory above.
Relative imports use dot(.) notation to specify a location. A single dot specifies that the module is in the current directory, two dots indicate that the module is in its parent directory of the current location and three dots indicate that it is in the grandparent directory and so on.
Note that relative imports are based on the name of the current module. Since the name of the main module is always “main”, modules intended for use as the main module of a Python application must always use absolute imports.
You cannot run a python module directly as a script (I don't really know the reason why).
EDIT : The reason is explained in the PEP338 which is the spec for the "-m"
option.
The release of 2.5b1 showed a surprising (although obvious in retrospect) interaction between this PEP and PEP 328 - explicit relative imports don't work from a main module. This is due to the fact that relative imports rely on
__name__
to determine the current module's position in the package hierarchy. In a main module, the value of__name__
is always__main__
, so explicit relative imports will always fail (as they only work for a module inside a package).For the 2.5 release, the recommendation is to always use absolute imports in any module that is intended to be used as a main module
To test your application, encapsulate api_main in a function and create a top-level main.py file which will run the main loop :
cclogger/api_main.py :
import re
import os
from .bottle import run, default_app, debug, get
from .common_util import date_str_to_datetime, UTCOffset, date_filter
#app = Bottle()
def main():
default_app().router.add_filter('date', date_filter)
from . import api, dev
@get('/index')
def index():
return "CCLogger API main live and kicking."
if dev:
debug(True)
run(reloader=True, port=9000)
else:
os.chdir(os.path.dirname(__file__))
application = default_app()
And /main.py :
from cclogger import api_main
if __name__ == '__main__':
api_main.main()
You can run your application by typing python main.py
, python -m main
or python -c "import cclogger.api_main; api_main.main()"
.
PS : thanks for linking the complete source, it's always much more helpful than the stubs provided with the question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With