Issue1567212

classification
Title: Jython $py.class bytecode doesn't include the .py's mtime
Type: Severity: normal
Components: Core Versions:
Milestone:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: fwierzbicki Nosy List: akuchling, cgroves, fwierzbicki, pekka.klarck, pjenvey
Priority: normal Keywords:

Created on 2006-09-28.18:08:53 by pekka.klarck, last changed 2009-03-06.04:16:51 by fwierzbicki.

Messages
msg1258 (view) Author: Pekka Klärck (pekka.klarck) Date: 2006-09-28.18:08:53
In our project we got some problems when a Jython file
was edited on a remote server using WinSCP and it set
atime and mtime of the file incorrectly one hour into
past. That made Jython to ignore changes because
already existing class file had a newer mtime. The
behaviour of WinSCP is likely to be a bug they've
introduced when trying to have a workaround for a
Windows bug/feature with the daylight saving time [1].
I posted a separate question to WinSCP forums [2] about
the issue but haven't yet got any definitive answers.
I've also sent a mail about this to jython-users
mailing list yesterday but for some reason it hasn't
gone through. 

[1] http://winscp.net/eng/docs/timestamp
[2] http://winscp.net/forum/viewtopic.php?p=12825

I investigated this issue a bit more and noticed that
it is very easy to reproduce the problem in Jython
simply with 'touch'. I also noticed that Python doesn't
have this problem and at that point decided to submit
this issue as a bug.

Example follows. Note that I've renoved some
non-relevant information from 'stat' outputs.

$ uname   
CYGWIN_NT-5.1

$ jython --version
Jython 2.2a1 on java (JIT: null)

$ python -V
Python 2.4.3

$ echo "var = 1" > x.py

$ echo "import x; print x.var" > tester.py

$ python tester.py 
1

$ jython tester.py 
1

$ stat x.py x.pyc x\$py.class 
  File: `x.py'
Access: 2006-09-28 20:36:49.690272200 +0300
Modify: 2006-09-28 20:36:38.537592200 +0300
Change: 2006-09-28 20:36:38.537592200 +0300
  File: `x.pyc'
Access: 2006-09-28 20:36:43.660952200 +0300
Modify: 2006-09-28 20:36:43.660952200 +0300
Change: 2006-09-28 20:36:43.660952200 +0300
  File: `x$py.class'
Access: 2006-09-28 20:36:49.690272200 +0300
Modify: 2006-09-28 20:36:49.690272200 +0300
Change: 2006-09-28 20:36:49.690272200 +0300

$ echo "var = 2" > x.py

$ touch -t 01010101 x.py  

$ python tester.py 
2

$ jython tester.py 
1

$ stat x.py x.pyc x\$py.class 
  File: `x.py'
Access: 2006-09-28 20:38:08.165152200 +0300
Modify: 2006-01-01 01:01:00.000000000 +0200
Change: 2006-09-28 20:38:04.353872200 +0300
  File: `x.pyc'
Access: 2006-09-28 20:38:08.165152200 +0300
Modify: 2006-09-28 20:38:08.165152200 +0300
Change: 2006-09-28 20:38:08.165152200 +0300
  File: `x$py.class'
Access: 2006-09-28 20:38:11.992052200 +0300
Modify: 2006-09-28 20:36:49.690272200 +0300
Change: 2006-09-28 20:36:49.690272200 +0300


Based on the above it seems for me that Jython compares
mtime of 'x.py' file and 'x$py.class' files when
deciding should it recompile the latter. In this case
the class file is thus not recreated even though py
file is newer (which could be seen from ctime). Python,
however, seems to check either both mtime and ctime or
only ctime.

I suppose that checking only the ctime would be ok for
Jython. It can be, AFAIK, updated only by the operating
system itself so no buggy program can reset it. One
problem of ctime is that it's updated also when content
of the file doesn't change, e.g. when only file
permissions are changed, and regenerating the file in
those situations is probably not needed. In my opinion,
however, recompiling the class file sometimes when
there's no need is far less severe problem than not
recompiling it when it really should.

Unfortunately ctime seems to have different semantics
on Windows than on Unix and most of the above is true
only in Unixes. 

PS: See for example [3] if you are not sure what are
the differences between atime, mtime and ctime.

[3] http://www.unix.com/showthread.php?t=20526
msg1259 (view) Author: A.M. Kuchling (akuchling) Date: 2006-11-17.23:04:19
Confirmed; if you look at Python/import.c and getmtime.c, CPython does look at mtime.
msg1260 (view) Author: A.M. Kuchling (akuchling) Date: 2006-11-17.23:16:53
Oops, actually I misread your bug report and am not really confirming it. 

CPython doesn't look at ctime at all; it looks at mtime, but records mtime in the .pyc file and then rebuilds if 
<pyc mtime> != <py mtime>.

For Jython: can we record the original mtime in the .class file through some extension mechanism?  Or, you could add a private attribute to the generated class... but that might mean importing the class in order to check the mtime.

msg1261 (view) Author: Charlie Groves (cgroves) Date: 2006-11-21.03:21:34
We write the API version into the class file as an attribute, and then read it in org/python/core/imp.java.  Since it's the last attribute written, we just read it directly and don't actually need to import it through java. We should be able to do the same thing with the mtime.  
msg3160 (view) Author: Philip Jenvey (pjenvey) Date: 2008-04-17.20:45:51
I can attest to being another unsuspecting victim of this, my example is 
the dupe #1024
msg3737 (view) Author: Frank Wierzbicki (fwierzbicki) Date: 2008-11-03.20:26:52
assigning to myself so I don't lose track of this one.  should be a
relatively quick fix.
msg4178 (view) Author: Frank Wierzbicki (fwierzbicki) Date: 2009-03-06.04:16:51
fixed in r6071
History
Date User Action Args
2009-03-06 04:16:51fwierzbickisetstatus: open -> closed
resolution: fixed
messages: + msg4178
2008-12-15 18:59:51fwierzbickisetcomponents: + Core, - None
2008-11-03 20:26:52fwierzbickisetassignee: fwierzbicki
messages: + msg3737
2008-04-18 23:36:56fwierzbickisetnosy: + fwierzbicki
2008-04-17 20:45:51pjenveysetnosy: + pjenvey
messages: + msg3160
title: ctime, not mtime, should be checked when recompiling class -> Jython $py.class bytecode doesn't include the .py's mtime
2006-09-28 18:08:53pekka.klarckcreate