0
votes

I'm using learn python the hard way 2nd edition to teach myself programming. In exercise 46 were instructed to do a number of things:

$ mkdir -p projects 
$ cd projects/
$ mkdir skeleton
$ cd skeleton
$ mkdir bin NAME tests docs

$ touch NAME/__init__.py
$ touch tests/__init__.py

here are the setup.py contents:

try: from setuptools import setup except ImportError: from distutils.core import setup

config = {
    'description': 'My Project',
    'author': 'My Name',
    'url': 'URL to get it at.',
    'download_url': 'Where to download it.',
    'author_email': 'My email.',
    'version': '0.1',
    'install_requires': ['nose'],
    'packages': ['NAME'],
    'scripts': [],
    'name': 'projectname'
}

setup(**config)

tests/NAME_tests.py:

from nose.tools import *
import NAME

def setup():
    print "SETUP!"

def teardown():
    print "TEAR DOWN!"

def test_basic():
    print "I RAN!"

Then install a number of packages:

  1. pip from http://pypi.python.org/pypi/pip
  2. distribute from http://pypi.python.org/pypi/distribute
  3. nose from http://pypi.python.org/pypi/nose/
  4. virtualenv from http://pypi.python.org/pypi/virtualenv

All of which I did without much fuss (once I switched from Windows to Ubuntu).

Zed (the author of LPTHW) then says you can test if you did everything right by doing this:

 drewverlee@ubuntu:~/projects/skeleton$ nosetests
.
----------------------------------------------------------------------
Ran 1 test in 0.020s

OK
drewverlee@ubuntu:~/projects/skeleton$ 

Wonderful!

But here is the problem. In the udemy class(online tutorial class) he copies skeleton into a test project (cp -r skelton foobar) and he does roughly...

zedscomp/projects/foobar: >>> nosetests

and zed gets a error something like:

ImportError: No module named NAME

so then zed goes ...

grep -r "NAME" .

(which gives him)

./tests/foobar_tests.py:import NAME

Then he explains that "This is the great thing about unit tests because they catch these errors (zeds error apparently being that he didn't rename import NAME to import foobar)

so I didn't get that error when I ran nosetests (even though I hadn't renamed NAME to foobar either) to further complicate it zed said that nosetests should only run from the parent directory i.e skeleton or foobar and not from a child like NAME... but when I run nosetest from name

drewvcomp/project/foobar/name: >>> nosetests 

it runs just fine.

So after reading a lot on nosetests and not really seeing what I was supposed to figure out to solve this I simply deleted my entire project folder using

rm -rf project

and rebuilt it. But no luck, the problem persists.

The suggestion below made me think maybe projects (and everything in it?) was being checked by python. In which case when I ran nosetests in foobar it was ok because it was able to import a module named NAME (which exists inside the original skeleton directory).

So:

import sys sys.path ['', '/usr/local/lib/python2.7/dist-packages', '/usr/local/lib/python2.7/dist-packages/projectname-0.1-py2.7.egg', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/ubuntuone-client', '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', '/usr/lib/python2.7/dist-packages/ubuntuone-couch', '/usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol', '/var/src/Django-1.3.1', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode']

Yikes! I need to clean that up! I don't really need much their other then the original and django (where should I install that?...)

also if you manged to read all this i would love you for ever if you could offer some advice on step 6 in this chapter:

  • install using setup.py and uninstall using pip

and by advice I mean how... because

setup install 

gives me a package.egg-info and I have no idea what that is!

2

2 Answers

0
votes

I think this is what's going on:

He tries to teach 2 things.

  1. A directory with a file caled __init__.py can be imported as a module in python.
  2. Using unit tests warns you of errors and is therefore good practice.
  3. If you do stuff often you might want to create a template structure.

Now in his example he creates a file structure like this:

skeleton/
         bin/
             ..
         NAME/
              __init__.py
              .. 
         tests/
               __init__.py
               .. 
         docs/
               ..

Then he copies this template structure, doing something like:

cp -r skeleton foobar

so you would end up with almost the same:

foobar/
       bin/
           ..
       NAME/
            __init__.py
            .. 
       tests/
             __init__.py
             .. 
       docs/
            ..

Now you still have a dir called NAME with a __init__.py which can be imported in python. So your unittests don't complain.

Now from what you tell i guess, he did not only copy the skeleton, but also renamed NAME to something different, because he wanted to use the cloned skeleton for a new project or something. So he probably had something more like:

foobar/
       bin/
           ..
       someothername/
            __init__.py
            .. 
       tests/
             __init__.py
             .. 
       docs/
            ..

Now his unitests complained, because he hadn't updated his import statement, yet. And so it tried to import NAME, but as you see there is no directory NAME containig a __init__.py.

So i guess, following the live exercise, you missed a step where he renamed NAME to somethingelse and that's why you could not reproduce it later.


Update:

use:

import sys
print sys.path

and

import imp
print imp.find_module("NAME")

to see where your code finds the module "NAME"

0
votes

I think so far the last part of the question has gone unanswered:

also if you manged to read all this i would love you for ever if you could offer some advice on step 6 in this chapter:

install using setup.py and uninstall using pip

There is a related answer in another question on stackoverflow. I think the answer to your question comes at the end. I think by "install using setup.py" he means:

python setup.py sdist

Then, if your module was called NAME, you run:

sudo pip install NAME-0.1.tar.gz   # or a similar filename in the /dist/ directory that is created

To uninstall, run:

sudo pip uninstall NAME