[PEAK] PATCH for setuptools: local and UTC time mismatch when extracting to PYTHON_EGG_CACHE

Alain Spineux aspineux at gmail.com
Thu Apr 17 10:37:09 EDT 2008


Hi

I wrote a test case below.

The problem: before to import a module, setuptools check if the one
already unzipped in the
cache match the original EGG file ! It compare the size and the date.
At first installation in the cache setuptools use the current timezone
(instead of UTC) to
initiate timestamp, but  if the same module is used when a different
timezone is set, it will try to
install the module again and require the rights to write in $PYTHON_EGG_CACHE.
Now suppose I installed the module once as root and run one
instance of my application per timezone and with different user
credentials ... !
I get the "Permission denied" !!!

Here is the test case and a PATCH at the end

[root at eg01 tmp]# cat setuptools_tz.sh

me=kolab-r
export PYTHON_EGG_CACHE=/tmp/test
rm -rf $PYTHON_EGG_CACHE
mkdir $PYTHON_EGG_CACHE
chown $me.$me $PYTHON_EGG_CACHE

python -c "import MySQLdb" && echo Ok as root
ls -l $PYTHON_EGG_CACHE

su $me -c 'python -c "import MySQLdb"' && echo Ok as $me

export TZ=UTC

su $me -c 'python -c "import MySQLdb"' && echo Ok as $me



[root at eg01 tmp]# sh setuptools_tz.sh
Ok as root
total 8
drwxr-xr-x 2 root root 4096 Apr 17 16:05
MySQL_python-1.2.2-py2.5-linux-i686.egg-tmp
Ok as kolab-r
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/kolab/lib/python/site-packages/PIL/__init__.py", line 19, in <module>

  File "/kolab/lib/python/site-packages/MySQL_python-1.2.2-py2.5-linux-i686.egg/_mysql.py",
line 7, in <module>
  File "/kolab/lib/python/site-packages/MySQL_python-1.2.2-py2.5-linux-i686.egg/_mysql.py",
line 4, in __bootstrap__
  File "pkg_resources.py", line 841, in resource_filename
    self, resource_name
  File "pkg_resources.py", line 1310, in get_resource_filename
    self._extract_resource(manager, self._eager_to_zip(name))
  File "pkg_resources.py", line 1365, in _extract_resource
    manager.extraction_error()  # report a user-friendly error
  File "pkg_resources.py", line 887, in extraction_error
    raise err
pkg_resources.ExtractionError: Can't extract file(s) to egg cache

The following error occurred while trying to extract file(s) to the Python egg
cache:

  [Errno 13] Permission denied:
'/tmp/test/MySQL_python-1.2.2-py2.5-linux-i686.egg-tmp/tmpvIJCos.$extract'

The Python egg cache directory is currently set to:

  /tmp/test

Perhaps your account does not have write access to this directory?  You can
change the cache directory by setting the PYTHON_EGG_CACHE environment
variable to point to an accessible directory.



---- patch start -----
--- setuptools-0.6c8-py2.5.egg/pkg_resources.py.orig    2008-04-17
14:19:03.000000000 +0200
+++ setuptools-0.6c8-py2.5.egg/pkg_resources.py 2008-04-17
16:34:40.000000000 +0200
@@ -1325,7 +1325,20 @@
             (d>>9)+1980, (d>>5)&0xF, d&0x1F,                      # ymd
             (t&0xFFFF)>>11, (t>>5)&0x3F, (t&0x1F) * 2, 0, 0, -1   # hms, etc.
         )
-        timestamp = time.mktime(date_time)
+        # the original buggy code
+        # timestamp = time.mktime(date_time)
+
+        # some helper to convert UTC tuple in UTC sec from the epoch
+        def _d(y, m, d, days=(0,31,59,90,120,151,181,212,243,273,304,334,365)):
+            return (((y - 1901)*1461)/4 + days[m-1] + d +
+             ((m > 2 and not y % 4 and (y % 100 or not y % 400)) and 1))
+
+        def timegm(tm, epoch=_d(1970,1,1)):
+            year, month, day, h, m, s = tm[:6]
+            return (_d(year, month, day) - epoch)*86400 + h*3600 + m*60 + s
+
+        # the good code that return the correct timestamp
+        timestamp = timegm(date_time)

         try:
             real_path = manager.get_cache_path(
@@ -1334,6 +1347,7 @@

             if os.path.isfile(real_path):
                 stat = os.stat(real_path)
+                #print 'ASX', real_path, stat.st_mtime, 'ZIP=',
timestamp, stat.st_mtime-timestamp, zip_stat, date_time
                 if stat.st_size==size and stat.st_mtime==timestamp:
                     # size and stamp match, don't bother extracting
                     return real_path

----- patch end -----

Regards

-- 
Alain Spineux
aspineux gmail com
May the sources be with you



More information about the PEAK mailing list