You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@thrift.apache.org by "Joel Croteau (JIRA)" <ji...@apache.org> on 2018/06/21 23:36:00 UTC

[jira] [Closed] (THRIFT-4588) local variable referenced before assignment in immutable python structs

     [ https://issues.apache.org/jira/browse/THRIFT-4588?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Joel Croteau closed THRIFT-4588.
--------------------------------
       Resolution: Duplicate
    Fix Version/s: 0.12.0

Never mind, I see this was already fixed in THRIFT-4531

> local variable referenced before assignment in immutable python structs
> -----------------------------------------------------------------------
>
>                 Key: THRIFT-4588
>                 URL: https://issues.apache.org/jira/browse/THRIFT-4588
>             Project: Thrift
>          Issue Type: Bug
>          Components: Python - Compiler
>    Affects Versions: 0.11.0
>            Reporter: Joel Croteau
>            Priority: Major
>             Fix For: 0.12.0
>
>
> If an immutable struct has unset optional fields, the Python code generated for it will produce an UnboundLocalError when deserializing it. Consider this struct:
> {code:java}
> struct TestStruct {
>        1: optional i32 value;
> } (python.immutable="",)
> {code}
> Compiling this to Python with Thrift 0.11.0, the ttypes.py has this read method:
> {code:java}
>     @classmethod
>     def read(cls, iprot):
>         if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and cls.thrift_spec is not None:
>             return iprot._fast_decode(None, iprot, [cls, cls.thrift_spec])
>         iprot.readStructBegin()
>         while True:
>             (fname, ftype, fid) = iprot.readFieldBegin()
>             if ftype == TType.STOP:
>                 break
>             if fid == 1:
>                 if ftype == TType.I32:
>                     value = iprot.readI32()
>                 else:
>                     iprot.skip(ftype)
>             else:
>                 iprot.skip(ftype)
>             iprot.readFieldEnd()
>         iprot.readStructEnd()
>         return cls(
>             value=value,
>         )
> {code}
> Since no default is ever set for value, if it is never set while reading the input file, it will attempt to use an unbound variable when creating the class at the end of this method. For a non-immutable struct, the analogous code is:
> {code:java}
>     def __init__(self, value=None,):
>         self.value = value
>     def read(self, iprot):
>         if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
>             iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
>             return
>         iprot.readStructBegin()
>         while True:
>             (fname, ftype, fid) = iprot.readFieldBegin()
>             if ftype == TType.STOP:
>                 break
>             if fid == 1:
>                 if ftype == TType.I32:
>                     self.value = iprot.readI32()
>                 else:
>                     iprot.skip(ftype)
>             else:
>                 iprot.skip(ftype)
>             iprot.readFieldEnd()
>         iprot.readStructEnd()
> {code}
> which works in this case because value is given a default value of None. It would probably make sense to set value to None at the start of this method.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)