zenlc2000 / pyp3

Pyed Piper tool by Toby Rosen at Sony Imageworks converted to Python 3
34 stars 13 forks source link

keep() and lose() filters only work if run with Python2 #7

Open bobpaul opened 7 years ago

bobpaul commented 7 years ago
$ echo -e "This is some input\nignore this line" | python3 pyp3 "keep('some')"
error: can only concatenate list (not "PypStr") to list : keep('some')
error: can only concatenate list (not "PypStr") to list : keep('some')
$ echo -e "This is some input\nignore this line" | python2 pyp3 "keep('some')"
This is some input
bobpaul commented 7 years ago

Problem is here:

    def flatten_list(self, iterables):
        '''
        returns a list of strings from nested lists
        @param iterables: nested list to flatten
        @type iterables: list<str>
        '''
        out = []
        if '__iter__' in dir(iterables) or type(iterables) in [list, PowerPipeList,tuple,PypList]:
            #expand history objects
            if [x for x in iterables if type(x) in [HistoryObject]]:

                expanded_iterables = []
                for iterable in iterables:
                    if type(iterable) in [HistoryObject]:
                        iterable = iterable.wrapped_object()
                    expanded_iterables.append(iterable)
                    iterables = expanded_iterables
            #if [x for x in iterables if type(x) in [str, PypStr,HistoryObject,type,int,float]]:

            if [x for x in iterables if type(x) not in [list,PowerPipeList,tuple,PypList]]: #str,int,etc
                out = out + iterables #add the lists and be done

            else:
                for x in iterables:
                    out = out + self.flatten_list(x)
        else:              #catches non iterables
            out = [iterables] #non-iterables
        return out

In Python2, strings don't have the 'iter' attribute (though they are iterable). In Python3, strings do have the attribute.

So in the above code, if you pass in iterables = "this is some text", the else case runs and you output ['this is some text']. In Python3, the string is flattened. But even in Python2 there's iterables (dicts) that can't be concatenated with lists. There's already a whitelist of expected iterables, I wonder if it's safe to just remove everything before the or.