Menu

#1068 <if expr Python error with Dictionary

All
closed-invalid
5
2007-12-11
2007-12-06
Dvboy
No

In Python, these two statements are valid code:
myDict.has_key(key)
key in myDict

the 2nd does not work in stax

Python example:
>>> myDict={}
>>> key='testParentDirPath'
>>> myDict[key] = 'c:\test\subdir'
>>> myDict.has_key(key)
1
>>> key in myDict
1
>>> f1= myDict.has_key(key)
>>> f2= key in myDict
>>> f1
1
>>> f2
1
>>>

In stax the following code will raise an error:
<script>
myDict={}
key='testPath'
myDict[key] = 'c:\test\subdir'
f1 = myDict.has_key(key)
f2 = key in myDict
</script>

Error Message:
2 Error 20071206-11:55:42 STAXPythonEvaluationError signal raised. Terminating job.

===== Element Information =====

<script>myDict={}
key='testPath'
myDict[key] = 'c:\test\subdir'
f1 = myDict.has_key(key)
f2 = key in myDict
</script>

===== Python Error Information =====

com.ibm.staf.service.stax.STAXPythonEvaluationException: Traceback (innermost last):
File "<pyExec string>", line 5, in ?
TypeError: loop over non-sequence

===== Call Stack for STAX Thread 2 =====

[
Sequence: 6/6
Testcase: machine.name.ibm.com
Testcase: machine.name.ibm.com.testGetLAFrameVariablesFromTarget
Try:
Sequence: 7/10
Function: testGetLAFrameVariablesFromTarget
Try:
Sequence: 12/17
]

Discussion

  • Sharon Lucas

    Sharon Lucas - 2007-12-06
    • labels: 357159 --> STAX::Service
    • assigned_to: nobody --> slucas
    • status: open --> closed-invalid
     
  • Sharon Lucas

    Sharon Lucas - 2007-12-06

    Logged In: YES
    user_id=285070
    Originator: NO

    STAX uses Jython 2.1 (not Python) to run code in <script> elements. If you run the same code using Jython 2.1 or Python 2.1, you'll see that it fails (as shown below):

    C:\Jython-2.1>jython
    Jython 2.1 on java1.4.1_02 (JIT: null)
    Type "copyright", "credits" or "license" for more information.
    >>> myDict={}
    >>> key='testParentDirPath'
    >>> myDict[key] = 'c:\test\subdir'
    >>> myDict.has_key(key)
    1
    >>> key in myDict
    Traceback (innermost last):
    File "<console>", line 1, in ?
    TypeError: loop over non-sequence
    >>>

    To get it to work in Jython/Python 2.1, you need to use the keys() method on the Python dictionary which returns a list of the keys. A list is a sequence which can be looped, where a dictionary is not a sequence that can be looped in Jython/Python 2.1.

    >>> key in myDict.keys()
    1
    >>> f2 = key in myDict.keys()
    >>> f2
    1

    There are differences between Jython and Python. You were using a version of Python that is later than 2.1. Jython 2.1 was based on Python 2.1. Support for iterating over a dictionary was provided in Python 2.2. See "Appendix F: Jython and CPython Differences" in the STAX User's Guide. It says:

    "Although in most cases Jython behavior is identical to the C-language implementation of Python (CPython), there are still cases where the two implementations differ. If you are already a CPython programmer, or are hoping to use CPython code under Jython, you need to be aware of these differences. Also, there is a time lag between a new CPython release and the corresponding Jython release. STAX uses Jython 2.1 which is based on Python 2.1. Jython 2.1 cannot execute Python code that uses functions that were provided in later versions of Python, such as Python 2.2."

    Recently in August 2007, Jython 2.2 was made available (it's based on Python 2.2) by the Jython team (http://jython.org). We will be changing STAX to use Jython 2.2 instead of 2.1 next year.

    So, I'm closing this bug. You must use syntax that is valid for Jython 2.1 (as I showed). Thanks.

     
  • Dvboy

    Dvboy - 2007-12-11

    Logged In: YES
    user_id=1923123
    Originator: YES

    I am using:
    Jython 2.2.1 on java1.5.0
    Type "copyright", "credits" or "license" for more information.
    >>>

    Also from the stax user guide:

    if RC == STAFRC.Ok:
    for entryMap in STAFResult:
    # Check if the entry is a file whose size is greater than 500000 bytes
    if entryMap['type'] == 'F' and int(entryMap['lowerSize']) > 500000:
    # Print the name, size, and last Modified Timestamp for the entry:
    msg += 'Name: %s, Size: %s, Timestamp: %s\n' % \
    (entryMap['name'], entryMap['lowerSize'],
    entryMap['lastModifiedTimestamp'])
    else:
    msg = 'FS LIST ENTRY failed with RC=%s Result=%s' % (RC, STAFResult)
    </script>
    <log message="1">msg</log>
    </sequence>
    file:///C|/temp/staxug/staxug.html (23 of 243) [10/2/2007 4:00:12 PM]

    DOC example shows this is allowed.

     
  • Dvboy

    Dvboy - 2007-12-11
    • status: closed-invalid --> open-invalid
     
  • Sharon Lucas

    Sharon Lucas - 2007-12-11

    Logged In: YES
    user_id=285070
    Originator: NO

    The example you showed in the STAX User's Guide does not show that this is allowed. It shows an example of iterating a Python list (STAFResult), not iterating a Python dictionary which you were doing. In this example STAFResult contains a Python list where each entry is a Python dictionary.

    Thus, this is not a bug in STAX. STAX currrently uses Jython 2.1 and Jython 2.1 does not allow you to iterate a Python dictionary (aka map). To iterate a Python dictionary, you can use the keys() method to iterate over the dictionary's keys (which is a list). For example:

    for key in myDict.keys():
    print 'key: %s value: %s' % (key, myDict[key])

    If you have any futher questions, post again.

     
  • Sharon Lucas

    Sharon Lucas - 2007-12-11
    • status: open-invalid --> closed-invalid
     

Log in to post a comment.

MongoDB Logo MongoDB