Reputation: 905
I am getting an error when trying to install a python package with pip.
It is looking in a certain directory for "setup.py" after untaring the package and it can't find it there. The setup.py file is actually one directory down.
It's looking in:
'virtualenvs/pyling/build/nltk/setup.py'
but it's actually in:
virtualenvs/pyling $ ls build/nltk/nltk-2.0b9/
INSTALL.txt javasrc LICENSE.txt nltk PKG-INFO README.txt setup.py
Is there a way to make pip aware of this nested folder structure in the package?
Thanks
Upvotes: 4
Views: 5812
Reputation: 23
I had similar problem and gave up on using the default URL for pip. However, if you just want to install nltk, this works for me:
pip install -E <virtualenv-dir> PyYAML #if you have not done so
pip install -E <virtualenv-dir> --no-index --find-links=http://nltk.googlecode.com/ nltk
Upvotes: 0
Reputation: 79
What I found was that pip runs a python command line script that looks like this:
__file__ = '<path to package>/setup.py'
from setuptools.command import egg_info
def replacement_run(self):
self.mkpath(self.egg_info)
installer = self.distribution.fetch_build_egg
for ep in egg_info.iter_entry_points('egg_info.writers'):
# require=False is the change we're making:
writer = ep.load(require=False)
if writer:
writer(self, ep.name, egg_info.os.path.join(self.egg_info,ep.name))
self.find_sources()
egg_info.egg_info.run = replacement_run
execfile(__file__)
In the package's top level directory, where there was no setup.py, I placed a setup.py that reproduced this behaviour, but chdir'd to the directory that contained the "real" setup.py and executed that at the end instead.
The only other issue was that pip creates a directory "pip-egg-info" which it expects to be populated, requiring a symbolic link to be created to it in the directory with the "real" setup.py.
The new, top level setup.py looks like this:
#! /usr/bin/env python
from os import chdir, symlink, getcwd
from os.path import join, basename, exists
filename = basename(__file__)
chdir("python")
setupdir = getcwd()
egginfo = "pip-egg-info"
if not exists(egginfo) and exists(join("..", egginfo)):
symlink(join("..", egginfo), egginfo)
__file__ = join(setupdir, filename)
from setuptools.command import egg_info
def replacement_run(self):
self.mkpath(self.egg_info)
installer = self.distribution.fetch_build_egg
for ep in egg_info.iter_entry_points('egg_info.writers'):
# require=False is the change we're making:
writer = ep.load(require=False)
if writer:
writer(self, ep.name, egg_info.os.path.join(self.egg_info,ep.name))
self.find_sources()
egg_info.egg_info.run = replacement_run
execfile(__file__)
It's probably brittle, but should continue to work until pip changes the command line python code that it's generating
Upvotes: 1
Reputation: 2938
I already had this problem when calling pip from a directory different from the one the setup.py is in. The solution was adding the following to setup.py:
import os
os.chdir(os.path.dirname(os.path.abspath(__file__
)))
Maybe you call pip from virtualenvs/pyling/build/nltk/ where it should be virtualenvs/pyling/build/nltk/nltk-2.0b9/ ? Then just add what I did.
Upvotes: 0
Reputation: 414745
setup.py
should be in a top directory.or
pip
to a directory with the setup.py
file.Upvotes: 0
Reputation: 905
i added a little function and call it in the property definition for setup_py in the pip/req.py file.
this seems to make it work the way i expect, that is if the setup.py file is only one layer deeper. hopefully nothing gets busted when bundling and freezing...
import os
def get_setup_path(in_path):
print "starting path is %s"%in_path
fileList=os.listdir(in_path)
if fileList.__contains__("setup.py"):
print "setup.py is indeed there"
return in_path
for f in fileList:
f=os.path.join(in_path,f)
if os.path.isdir(f):
contents=os.listdir(f)
if contents.__contains__("setup.py"):
out_path=os.path.join(in_path,f)
return out_path
print "could not find setup.py by looking one level deeper"
return in_path
and then call it here in req.py
(around line 195 in req.py)
@property
def setup_py(self):
self.source_dir= get_setup_path(self.source_dir)
return os.path.join(self.source_dir, 'setup.py')
Upvotes: 0