tags:

views:

379

answers:

3

I want to use git to allow me to work on several features in a module I'm writing concurrently. I'm currently using SVN, with only one workspace, so I just have the workspace on my PYTHONPATH. I'm realizing this is less than ideal, so I was wondering if anyone could suggest a more 'proper' way of doing this.

Let me elaborate with a hypothetical situation: I say I have a module 'eggs', with sub-modules 'foo' and 'bar'. Components in 'bar' use code in foo, so eggs/bar/a.py may 'import eggs.foo'.

Say that 'eggs' is in a git repository. I want to try out some changes to 'foo', so I copy it. The problem is that 'import eggs.foo' in eggs/bar finds the original repository in the PYTHONPATH, so it ends up using the old 'foo' instead of my modified one.

How do I set myself up such that each copy of the module uses its own associated 'foo'? Thanks.

edit- Thanks for the pointer to relative imports. I've read up on it and I can see how to apply it. One problem I'd have with using it is that I've built up a fairly large codebase, and I haven't been too neat about it so most modules have a quick 'self-test' under if __name__ == '__main__':, which from what I've read does not play with relative imports:

The other solution I've been able to google up is to deliberately manipulate sys.path, which seems like an even worse hack. Are there any other possibilities?

edit - Thanks for the suggestions. I'd originally misunderstood git branches, so as pointed out branches are exactly what I want. Nonetheless, I hadn't heard of relative imports before so thanks for that as well. I've learnt something new and may incorporate its use.

+3  A: 

Relative imports (PEP 328) might help:

eggs/
  __init__.py
  foo.py
  bar.py

# foo.py
from __future__ import absolute_import
from . import bar

See How do you organize Python modules? for other options.

EDIT:

Yet another option is to use S.Lott's and Jim's suggestions i.e, restructure your package to factor out a eggs.foo part used by eggs.bar.a and use git to work on experimental branches (see Git Community Book).

Here's an example:

$ git status
# On branch master
nothing to commit (working directory clean)

[just to make sure that all is good]

$ git checkout -b experimental
Switched to a new branch "experimental"

[work on experimental stuff]

$ git commit -a

[commit to experimental branch]

$ git checkout master
Switched to branch "master"

[work on master branch]

$ git commit -a

To merge changes into master branch:

$ git merge experimental

See chapter Basic Branching and Merging from the above book.

J.F. Sebastian
Thanks for this. I have asked a related follow-up question, if you'd be so kind as to have a look: http://stackoverflow.com/questions/345746/refactoring-python-module-configuration-to-avoid-relative-imports
saffsd
+1  A: 

"say I have a module 'eggs', with sub-modules 'foo' and 'bar'. Components in 'bar' use code in foo, so eggs/bar/a.py may 'import eggs.foo'."

This may not be the best structure. I suggest you have some other modules struggling to get out.

You have eggs.bar.a depending on eggs.foo. I'm guessing other stuff on eggs depends on eggs.foo. Further, I suspect that eggs.foo could be partitioned into eggs.foo and eggs.quux and things might be simpler.

I'd recommend refactoring this to get a better structure. The PYTHONPATH issues are symptomatic of too many things in the wrong places in the module tree.

S.Lott
Refactoring the code-in-common into eggs.quux doesn't solve the problem though. If I'm working on two copies of the module, even if I put both in PYTHONPATH, one will always come first, so the second eggs.bar.a still effectively uses the first's eggs.quux.
saffsd
The point is to avoid 2 copies of the common module. One copy, separated from other things.
S.Lott
+1  A: 

Maybe I'm not understanding correctly, but it seems that git would be the solution here, since git's branches don't need separate paths.

Create a branch for each working version of your eggs module. Then when you checkout that branch, the entire module is changed to a state matching the version of your sub-module. You could then merge what you need back and forth between the branches.

And as S.Lott pointed out, may a little refactoring couldn't hurt either ;)

JimB
I'm new to git so I'm not sure I understand what you're suggesting. The problem is that if I have two branches checked out, submodules from the first will always be found first. Do you have a way around this? I will look at refactoring this.
saffsd
My inexperience with git shows. I'd been branching by simply copying the repository, but you are indeed right. Git branches do do exactly what I want.
saffsd