classification
Title: "PYTHONPATH=" different from no PYTHONPATH at all
Type: Stage: resolved
Components: Interpreter Core Versions: Python 3.4
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Arfrever, arigo, asvetlov, cvrebert, eric.snow, kachayev, pitrou, python-dev, r.david.murray, serhiy.storchaka, tvaughan
Priority: normal Keywords: easy, patch

Created on 2012-10-24 10:37 by arigo, last changed 2013-04-13 08:46 by arigo. This issue is now closed.

Files
File name Uploaded Description Edit
pythonpath.diff arigo, 2012-10-25 09:00 review
pythonpath2.diff arigo, 2012-10-25 15:42 review
issue16309.diff kachayev, 2012-11-03 11:22 review
Messages (18)
msg173665 - (view) Author: Armin Rigo (arigo) * (Python committer) Date: 2012-10-24 10:37
On Posix, it is documented that setting PATH to the empty string is equivalent to not setting PATH at all, which is an exception to the rule that in a string like "/bin::/usr/bin" the empty string in the middle gets interpreted as ".".

PYTHONPATH does not have this exception: an empty PYTHONPATH is interpreted as equivalent to ".".

This difference is not documented.  This is a detail, but a possible source of confusion, so I'm reporting it here.

How to reproduce:

file x/x.py: "import z"
file z.py: "print(42)"

The following two lines behave differently (Bash syntax):

PYTHONPATH= python x/x.py
unset PYTHONPATH && python x/x.py

For comparison, if "./foo" is an executable, the following two lines behave identically (neither finds "./foo"):

PATH= foo
unset PATH && foo
msg173669 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2012-10-24 11:39
Given how confusing it seems, perhaps we should change it to adopt a PATH-like behaviour.
msg173746 - (view) Author: Armin Rigo (arigo) * (Python committer) Date: 2012-10-25 09:00
Attached the diff, in case we want to do that.  The diff is only about non-Windows platforms, given that it follows a Posix use case about PATH.  But do we also need to change PC/getpathp.c?
msg173763 - (view) Author: Armin Rigo (arigo) * (Python committer) Date: 2012-10-25 15:42
Attached another simpler diff (only one "+" line instead of two...).
msg173768 - (view) Author: Eric Snow (eric.snow) * (Python committer) Date: 2012-10-25 16:44
> Given how confusing it seems, perhaps we should change it to
> adopt a PATH-like behaviour.

Wouldn't that introduce a backward-compatibility issue?  FWIW, otherwise I agree that it makes a lot of sense to conform to the same behavior as PATH.
msg173769 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2012-10-25 16:58
LGTM.
msg174048 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2012-10-28 13:42
I would to see some unittest if possible.
msg174605 - (view) Author: Alexey Kachayev (kachayev) * Date: 2012-11-03 11:22
Unit test added. pythonpath2.diff is included into issue16309.diff.
msg174609 - (view) Author: Roundup Robot (python-dev) Date: 2012-11-03 11:53
New changeset 05f8f7544f92 by Andrew Svetlov in branch 'default':
Issue #16309: Make PYTHONPATH= behavior the same as if PYTHONPATH not set at all.
http://hg.python.org/cpython/rev/05f8f7544f92
msg174610 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2012-11-03 11:53
Fixed. Thanks.
msg176141 - (view) Author: Roundup Robot (python-dev) Date: 2012-11-22 23:51
New changeset 803e5a732331 by Ezio Melotti in branch 'default':
#16309: avoid using deprecated method and turn docstring in a comment.
http://hg.python.org/cpython/rev/803e5a732331
msg186638 - (view) Author: Tom Vaughan (tvaughan) Date: 2013-04-12 15:02
PATHONPATH=/tmp: will also be interpreted as "/tmp" and ".". Do the patches also address this case? PYTHONPATH=:/tmp and PYTHONPATH=/foo::/bar are also problematic.
msg186639 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-04-12 15:10
It may be problematic, but it is also consistent with the way the shell works in general.  (Try the same things with PATH.)
msg186640 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-04-12 15:15
Hmm.  Although that argues that the original behavior was in fact correct.  At least, the behavior of bash and zsh for me is that

   PATH= foo

finds foo if it is in the local directory, contradicting the claim made in the original post.
msg186652 - (view) Author: Tom Vaughan (tvaughan) Date: 2013-04-12 16:31
Oh wow. That is not what I remembered/assumed about sh and PATH. Mind. Blown.
msg186666 - (view) Author: Armin Rigo (arigo) * (Python committer) Date: 2013-04-12 18:55
Uh, confusion.  Indeed, "PATH= foo" finds foo in the current directory on bash.  I'm not sure how I ran the original example.  It seems that a default PATH is used, which includes at least "/bin" and ".".

The point I was making in the original post is still valid: "PATH= foo" appears to behave identically to "unset PATH && foo" in all cases I tried so far.  For example, for me both work with some local executable or with "ls" (which is in /bin), and neither works with "which" (which is in /usr/bin).
msg186669 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2013-04-12 19:14
I don't think bin is included:

  > PATH= gzip
  bash: gzip: No such file or directory

But you are right...unset seems to be equivalent to PATH=
I could have sworn it acted different when I tried it, but I just ran it again and it it acted the same, which makes sense.

So given that I agree that the fix is good.  And further fixing is not :).
msg186700 - (view) Author: Armin Rigo (arigo) * (Python committer) Date: 2013-04-13 08:46
Grrr, ok, I have an "alias ls='/bin/ls'".  It seems that both "PATH=" and "unset PATH" are equivalent to "PATH=.".  This is behavior that we cannot add to PYTHONPATH, I fear, because so far "." is not implicitly included if PYTHONPATH is not set.  Or if we do it's a big change, not just an internal fix...
History
Date User Action Args
2013-04-13 08:46:00arigosetmessages: + msg186700
2013-04-12 19:14:58r.david.murraysetmessages: + msg186669
2013-04-12 18:55:27arigosetmessages: + msg186666
2013-04-12 16:31:30tvaughansetmessages: + msg186652
2013-04-12 15:15:44r.david.murraysetmessages: + msg186640
2013-04-12 15:10:26r.david.murraysetnosy: + r.david.murray
messages: + msg186639
2013-04-12 15:02:51tvaughansetnosy: + tvaughan
messages: + msg186638
2012-11-22 23:51:35python-devsetmessages: + msg176141
2012-11-03 11:53:49asvetlovsetstatus: open -> closed
resolution: fixed
messages: + msg174610

stage: commit review -> resolved
2012-11-03 11:53:07python-devsetnosy: + python-dev
messages: + msg174609
2012-11-03 11:22:56kachayevsetfiles: + issue16309.diff
nosy: + kachayev
messages: + msg174605

2012-10-28 13:42:03asvetlovsetmessages: + msg174048
2012-10-28 13:39:31asvetlovsetnosy: + asvetlov
2012-10-26 07:07:59cvrebertsetnosy: + cvrebert
2012-10-25 16:59:27serhiy.storchakasetstage: commit review
2012-10-25 16:58:35serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg173769
2012-10-25 16:44:46eric.snowsetnosy: + eric.snow
messages: + msg173768
2012-10-25 15:42:19arigosetfiles: + pythonpath2.diff

messages: + msg173763
2012-10-25 09:00:37arigosetfiles: + pythonpath.diff
keywords: + patch
messages: + msg173746
2012-10-25 00:55:09Arfreversetnosy: + Arfrever
2012-10-24 11:39:46pitrousetnosy: + pitrou
messages: + msg173669
2012-10-24 10:37:40arigocreate