View Issue Details

IDProjectCategoryView StatusLast Update
0005252ScribusScripterpublic2007-02-03 22:42
ReporterPatMcGee Assigned Tosubik  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
PlatformWinOSXPOS VersionSP2
Product Version1.3.3.7 
Fixed in Version1.3.3.8cvs 
Summary0005252: Scripts run from Script -> Execute Script improperly type some arithmetic expressions
DescriptionA python division binary arithmetic operation between two integers should result in an integer result. When a script is executed using Script -> Execute Script, it results in a float. (When executing the same file from the Script Console, using File -> Open, then Script -> Run, the expression properly results in an integer.)

Steps To Reproduce1. In the file 'boilerplate.py', add the following lines in main immediately before the line containing 'pass':

myVar = ( 3 / 2)
f = open ('testfile', 'a')
f.write('myVar=' + str(myVar) + ' type(myVar)=' + str(type(myVar)) + '\n')
f.close

2. From the Scribus main window, do Script -> Execute Script ..., navigate to the new file, and click OK.

3. Find the file 'testfile' and examine the contents.
My file had:
myVar=1.5 type(myVar)=<type 'float'>

4. From the Scribus main window, do Script -> Show Console.

5. From the Script Console window, do File -> Open. Navigate to the new file and clike Open.

6. Still in the Script Console window, do Script -> Run.

7. Find the file 'testfile' and examine the contents.
My file had:
myVar=1 type(myVar)=<type 'int'>
Additional InformationThis behavior is the same on Windows XP SP2 running Scribus 1.3.3.2 (I forgot to copy the build info before I reinstalled 1.3.3.7), and on Mac OS X 10.4.8, running the Aqua port of Scribus 1.3.3.2 Build C-C-T-F-A-Mac/Aqua.
TagsNo tags attached.
Patch

Activities

PatMcGee

2007-01-26 03:18

reporter   ~0015002

I should have said that I discovered this while debugging a python module that I had written for a different program and attempted to port to Scribus for use with a new script. The program failed in very strange ways, drawing things several inches away from where they should have been. It took me most of a day to track down the problem. I raise the issue because of the portability issues, not because of any impact on new code. For new code, people could use '//' instead of '/' and get the correct result. It's when importing old code where that may be several levels down that tracking down the problem gets really tricky.

subik

2007-01-26 06:54

manager   ~0015004

subzero@powerpuff:~/tmp> python
Python 2.5 (r25:51908, Jan 9 2007, 16:59:32)
[GCC 4.1.2 20061115 (prerelease) (SUSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> myVar = ( 3 / 2)
>>> f = open ('testfile', 'a')
>>> f.write('myVar=' + str(myVar) + ' type(myVar)=' + str(type(myVar)) + '\n')
>>> f.close
<built-in method close of file object at 0xb7c41b18>
>>> f.close()
>>>
subzero@powerpuff:~/tmp> cat testfile
myVar=1 type(myVar)=<type 'int'>
subzero@powerpuff:~/tmp>

subik

2007-01-26 06:56

manager   ~0015005

btw easy workaround: (3.0 / 2) gives you the right result

PatMcGee

2007-01-26 14:45

reporter   ~0015012

I'd agree more with the position that it's a Python issue if Scribus didn't do it two different ways, one place correctly, one place incorrectly. What could it be in Scribus that causes Python to work wrong when called from some places but not others?

And, more worringly, if Scribus has this effect on Python in arithmetic, what other strange things might lurk there?

subik

2007-01-26 15:10

manager   ~0015013

wooha! got it. There is missing a future's import division in one piece of the code.

So 3/2 will return 1.5 in scripts *and* in scribus console after this fix too.

Quick workaround: use "from __future__ import division" in your scripts until the new release/cvs build conquers your desktop.

PatMcGee

2007-01-26 15:28

reporter   ~0015014

Subik, I don't think I understand. From your session on the console in note 15004, it looks like the correct answer should be 1, not 1.5. It looks to me like the Python language reference manual agrees also. So, if you change both Script and Console to return 1.5, I think they'll both be giving the same wrong answer.

subik

2007-01-26 15:43

manager   ~0015015

http://www.python.org/dev/peps/pep-0238/

heh, it's easy to patch too. Lets summarize how it will be:

3/2 = 1 (int)
3.0/2 = 1.5 (float)
float(3)/2 = 1.5 (float)

so it'll be like in standard Python 2.x. (which means all scripts will behave strange in Python 3000 (if it will be released some day ;)))

btw I wonder why is the "true division" switch statement in script-file runtime environment. Ok, 3/2 = 1.5 *is* more logical than 1, but Python handles it this way.

subik

2007-01-26 15:47

manager   ~0015016

Reminder sent to: ringerc

Craig, do you have any clue why is the "from __future__ import division" statement in void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter)?

Maybe it has any meaning. But I cannot see what one.

ringerc

2007-01-26 15:53

reporter   ~0015017

Last edited: 2007-01-26 15:56

Yep - it makes integer division return a real if the result isn't evenly divisible - ie:

   3/2 == 1.5

instead of

   3/2 = 1

As Python 2.5 or 2.6 will make this the default (see the PEP on division) that helps make sure scripts behave consistently into the future with this rather crucial change in behavior. Use // if you want floor division.

[Edit: Actually, it appears that the division change will now not be going into 2.x . I think this has changed, since that was the plan for a while. Given this, removing the division import will improve compatibility, where originally it was put in to help when transitioning to newer Python versions for the same reason]

PatMcGee

2007-01-26 15:58

reporter   ~0015018

Subik, Thanks for the link. Now I understand, and I also have a lot more confidence in everything else in Python under Scribus. I withdraw my question about wondering what other dragons might be lurking.

On a more philosophical note, I believe they did classical division the way they did to value consistency over consistency. That is, they defined a rule that says binary arithmetic on integer operands always returned an integer, no matter what operator. So, they made classical division consistent with this rule.

Some people believe that division operator should always return a float, no matter what the operands. And so, they define things consistent with that definition. In Python 3, it looks like they're changing to be consistent with the second and not with the first. Isn't consistency wonderful?

Issue History

Date Modified Username Field Change
2007-01-26 03:03 PatMcGee New Issue
2007-01-26 03:18 PatMcGee Note Added: 0015002
2007-01-26 06:54 subik Note Added: 0015004
2007-01-26 06:56 subik Note Added: 0015005
2007-01-26 14:45 PatMcGee Note Added: 0015012
2007-01-26 15:07 subik Status new => assigned
2007-01-26 15:07 subik Assigned To => subik
2007-01-26 15:10 subik Note Added: 0015013
2007-01-26 15:28 PatMcGee Note Added: 0015014
2007-01-26 15:43 subik Note Added: 0015015
2007-01-26 15:47 subik Note Added: 0015016
2007-01-26 15:53 ringerc Note Added: 0015017
2007-01-26 15:56 ringerc Note Edited: 0015017
2007-01-26 15:58 PatMcGee Note Added: 0015018
2007-01-26 18:45 subik Status assigned => resolved
2007-01-26 18:45 subik Fixed in Version => 1.3.3.8cvs
2007-01-26 18:45 subik Resolution open => fixed
2007-02-03 22:42 cbradney Status resolved => closed