Repository: pypa/virtualenv

Issue:
Creation of a new virtuelenv with Python 3.3 fails
When trying to provision 3.3 RC1 [upd.: and later RC2] for travis-ci.org, I am hitting the following (Chef output):
https://gist.github.com/c47e2107af831c83391b

I am not familiar with the Python ecosystem enough to understand if this qualifies as a virtualenv problem but decided to file this issue. If there are workarounds, I think we can tweak things just for 3.3.



Discussion:
Is that the latest version of virtualenv/pip?

This looks similar to the issues I addressed on OS X for 3.3, which should be fixed in latest virtualenv/pip.

You probably need the virtualenv on the base image to be 1.8.1 - if you need a PPA or whatever for that, then I'm not sure where to look but it should be easy to package.

ISTR It's possible to create a travis vagrant instance from your OSS repos - can you point me at a scriptable reproducer and I can poke more.

I'm going to hop on IRC to see if we can get a quicker turnaround

Full logs: https://gist.github.com/3dd90923365081565e9e

Looks like possibly something odd in the new ubuntu packaging with the minimal package

PKG source  https://launchpad.net/~python-dev/+archive/ppa

```
  Traceback (most recent call last):
    File "setup.py", line 220, in <module>
      scripts = scripts,
    File "/usr/lib/python3.3/distutils/core.py", line 148, in setup
      dist.run_commands()
    File "/usr/lib/python3.3/distutils/dist.py", line 917, in run_commands
      self.run_command(cmd)
    File "/usr/lib/python3.3/distutils/dist.py", line 935, in run_command
      cmd_obj.ensure_finalized()
    File "/usr/lib/python3.3/distutils/cmd.py", line 107, in ensure_finalized
      self.finalize_options()
    File "build/src/setuptools/command/install.py", line 29, in finalize_options
      _install.finalize_options(self)
    File "/usr/lib/python3.3/distutils/command/install.py", line 334, in finalize_options
      (prefix, exec_prefix) = get_config_vars('prefix', 'exec_prefix')
    File "/home/travis/virtualenv/python3.3/lib/python3.3/distutils/__init__.py", line 92, in sysconfig_get_config_vars
      real_vars = old_get_config_vars(*args)
    File "/usr/lib/python3.3/distutils/sysconfig.py", line 505, in get_config_vars
      func()
    File "/usr/lib/python3.3/distutils/sysconfig.py", line 449, in _init_posix
      from _sysconfigdata import build_time_vars
    File "/usr/lib/python3.3/_sysconfigdata.py", line 6, in <module>
      from _sysconfigdata_m import *
  ImportError: No module named '_sysconfigdata_m'
```

The package we use wasn't very heavily tested but the maintainer is very kind and I think we can ask him to rebuild it if we identify what is missing/wrong.

You are hitting virtualenv bug #301 in combination of either http://bugs.python.org/issue15822 (3.3rc1) or http://bugs.python.org/issue15890 (rc2).

Thanks @tpievila for the additional pointers. #301 is an error-reporting/debugging improvement, not something that will cause a failure itself; so if that's correct this is not something we can fix in virtualenv. Fortunately it looks like http://bugs.python.org/issue15822 is fixed in 3.3rc2, and http://bugs.python.org/issue15890 is not hard to work around if needed. Closing for now, unless more information is provided indicating this is a virtualenv bug.

@carljm does it mean that using RC2 will solve the issue? We are not Python experts and working around Python issues is not necessarily something we can do. We would also prefer to not modify virtualenv in any way.

The issue is still present with Python 3.3 RC2. [Log with RC2](https://gist.github.com/07673f094c9bd791e5dc). What our next steps should be? We cannot provide Python 3.3 on travis because of this :( Maybe some Python hackers would be interested in helping us a little bit?

We use a [different PPA](https://launchpad.net/~travis-ci/+archive/python3.3) for 3.3 this time, by the way.

http://bugs.python.org/issue15822 should be fixed in rc2, and on further review it seems unlikely to me that you are hitting http://bugs.python.org/issue15890, since the consensus on that bug seems to be that it's not a regression, so if your umask was set too strictly you'd have seen that problem on earlier Pythons as well (also, not likely that a PPA build would be broken in that way). So it seems likely that @tpievila 's analysis was incorrect.

Reviewing this thread, I don't see confirmation anywhere of the version of virtualenv/pip you are using, @michaelklishin ?

pip 1.2.1, virtualenv 1.8.2.

@michaelklishin I notice in your log that you're running virtualenv over top of an existing virtualenv directory; can you try `rm -rf /home/travis/virtualenv/python3.3` and then rerun the virtualenv-creation? Also, can you run with `-vvv`? Thanks.

(If you're working on this now, I'm also `carljm` on Freenode in the `#pip` IRC channel.)

[Log with -vvv](https://gist.github.com/7839c2059d4e9c949de2)

http://packages.ubuntu.com/quantal/i386/libpython3.3-minimal/filelist

Gives `/usr/lib/python3.3/plat-i386-linux-gnu/_sysconfigdata_m.py` I'm betting that's not in sys.path

https://wiki.ubuntu.com/MultiarchSpec

@pnasrat here's what `sys.path` returns: https://gist.github.com/521958c163fa9626dfed

```
travis@precise32:~$ ls -lh /usr/lib/python3.3/plat-i386-linux-gnu/
total 32K
-rw-r--r-- 1 root root 5.9K Sep 17 14:57 IN.py
drwxr-xr-x 2 root root 4.0K Sep 17 17:31 __pycache__
-rw-r--r-- 1 root root  19K Sep 17 14:58 _sysconfigdata_m.py
```

Note for self/others - http://bazaar.launchpad.net/~doko/python/pkg3.3-debian/files has the patches, etc.

@mezzle suggests there is a patch in Quantal that our package did not include. We are waiting for another build to finish to try it out with supposedly full patch set.

oops fat fingered.

@michaelklishin What is the value of `sys.path` inside the virtualenv? (i.e. `/home/travis/virtualenv/python3.3/bin/python -c "import sys; print(sys.path)"`)

```
travis@precise32:~$ /home/travis/virtualenv/python3.3/bin/python -c "import sys; print(sys.path)"
['', '/home/travis/virtualenv/python3.3/lib/python3.3', '/home/travis/virtualenv/python3.3/lib/python3.3/plat-i386-linux-gnu', '/home/travis/virtualenv/python3.3/lib/python3.3/lib-dynload', '/usr/lib/python3.3', '/home/travis/virtualenv/python3.3/lib/python3.3/site-packages']
```

Yes, @pnasrat 's hunch was correct; we need to add a new special case in virtualenv's `site.py` to check if we're on a system using this multi-arch spec and add the system multi-arch-specific plat dir to `sys.path`. Thanks @michaelklishin for the debugging help.

I'm guessing this is still occuring - @carljm do you have time for this, else I'lll try take  a poke on the weekend

@pnasrat If I have time it won't be until mid-next-week at the earliest; if you have time this weekend that'd be great.

Sure - I should have time then, I'm at conference during the week.

Any progress on this? can someone who is not a virtualenv core contributor submit a fix? travis-ci.org users are already asking for 3.3.

@carljm I think it's more a question of symlinking the plat-$(MULTIARCH) dir when building the virtualenv.
The path is built correctly where I am (from Quantal's python3.3, which travis will get backported in due course), but the directory it refers to doesn't exist. It's part of the platform-dependent sys.path default, which exists before site.py files are read (confirmed with `python3.3 -ESsc 'import sys; print(sys.path)'` inside and outside the virtualenv).


Resolving patch:
diff --git a/virtualenv.py b/virtualenv.py
--- a/virtualenv.py
+++ b/virtualenv.py
@@ -96,6 +96,9 @@
     if minver >= 2:
         REQUIRED_FILES[-1] = 'config-%s' % majver
     if minver == 3:
+        import sysconfig
+        platdir = sysconfig.get_config_var('PLATDIR')
+        REQUIRED_FILES.append(platdir)
         # The whole list of 3.3 modules is reproduced below - the current
         # uncommented ones are required for 3.3 as of now, but more may be
         # added as 3.3 development continues.
@@ -1174,6 +1177,17 @@ def copy_required_modules(dst_prefix):
     finally:
         sys.path = _prev_sys_path
 
+
+def subst_path(prefix_path, prefix, home_dir):
+    prefix_path = os.path.normpath(prefix_path)
+    prefix = os.path.normpath(prefix)
+    home_dir = os.path.normpath(home_dir)
+    if not prefix_path.startswith(prefix):
+        logger.warn('Path not in prefix %r %r', prefix_path, prefix)
+        return
+    return prefix_path.replace(prefix, home_dir, 1)
+
+
 def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
     """Install just the base environment, no distutils patches etc"""
     if sys.executable.startswith(bin_dir):
@@ -1243,6 +1257,16 @@ def install_python(home_dir, lib_dir, inc_dir, bin_dir, site_packages, clear):
     else:
         logger.debug('No include dir %s' % stdinc_dir)
 
+    platinc_dir = distutils.sysconfig.get_python_inc(plat_specific=1)
+    if platinc_dir != stdinc_dir:
+        platinc_dest = distutils.sysconfig.get_python_inc(
+            plat_specific=1, prefix=home_dir)
+        if platinc_dir == platinc_dest:
+            # Do platinc_dest manually due to a CPython bug;
+            # not http://bugs.python.org/issue3386 but a close cousin
+            platinc_dest = subst_path(platinc_dir, prefix, home_dir)
+        copyfile(platinc_dir, platinc_dest)
+
     # pypy never uses exec_prefix, just ignore it
     if sys.exec_prefix != prefix and not is_pypy:
         if is_win:


Test patch: