8000 Spurious unsubscriptable-object error · Issue #3328 · pylint-dev/pylint · GitHub
[go: up one dir, main page]

Skip to content
Spurious unsubscriptable-object error #3328
@fluffy-critter

Description

@fluffy-critter

Possibly related to #2416

Steps to reproduce

I believe this is the minimal amount of code necessary to reproduce the bug.

""" Functions for manipulating images stored within local content """

class LocalImage:
    """ The basic Image class, which knows about the base version and how to
    generate renditions from it """

    def _get_rendition(self, **kwargs):
        """ implements get_rendition and returns tuple of out_rel_path,size,pending """
        _, box = self.get_rendition_size(kwargs)

        if box:
            box = (box[0], box[1], box[2], box[3])


    def get_rendition_size(self, spec):
        """
        Wrapper to determine the overall rendition size and cropping box

        Returns tuple of (size,box)
        """

        width = spec.get('width', 100)
        height = spec.get('height', 100)

        mode = spec.get('resize', 'fit')

        if mode == 'fit':
            return self.get_rendition_fit_size(width, height)

        if mode == 'fill':
   
8008
         return self.get_rendition_fill_size(width, height)

        if mode == 'stretch':
            return self.get_rendition_stretch_size(width, height)

        raise ValueError("Unknown resize mode {}".format(mode))

    @staticmethod
    def get_rendition_fit_size(input_w, input_h):
        """ Determine the scale-crop size given the provided spec """
        return (input_w, input_h), None

    @staticmethod
    def get_rendition_fill_size(input_w, input_h):
        """ Determine the scale-crop size given the provided spec """
        return (input_w, input_h), (0, 0, input_w, input_h)

    @staticmethod
    def get_rendition_stretch_size(input_w, input_h):
        """ Determine the scale-crop size given the provided spec """
        return (input_w, input_h), None

Current behavior

When I run pylint on this, I get errors:

************* Module pylint_repro
pylint_repro.py:14:19: E1136: Value 'box' is unsubscriptable (unsubscriptable-object)
pylint_repro.py:14:37: E1136: Value 'box' is unsubscriptable (unsubscriptable-object)
pylint_repro.py:15:19: E1136: Value 'box' is unsubscriptable (unsubscriptable-object)
pylint_repro.py:15:37: E1136: Value 'box' is unsubscriptable (unsubscriptable-object)

If I split lines 21 and 22 off into a separate function:

    @staticmethod
    def _thunk_adjust_box(crop, box):
        if crop and box:
            box = (box[0] + crop[0], box[1] + crop[1],
                   box[2] + crop[0], box[3] + crop[1])
        elif crop:
            box = (crop[0], crop[1], crop[0] + crop[2], crop[1] + crop[3])

        return box

and replace line 21 with box = self._thunk_adjust_box(crop, box), the error disappears.

If in the method get_rendition_size I remove the lines for if mode == 'fit' the error disappears. However, the error remains if I leave that one present and remove the mode == 'stretch' lines.

Curiously, if I move the mode == 'fit' branch to go after the mode == 'fill' branch, the error also disappears.

This is peculiar since the value of box could be either tuple or NoneType regardless of the order of those branches, and anyway where the linter is throwing the error, box is guaranteed to not be NoneType.

This also still occurs if I change the box check to explicitly check for tuple, absolutely guaranteeing that box is a tuple in that code path:

        if crop and isinstance(box, tuple):
            box = (box[0] + crop[0], box[1] + crop[1],
                   box[2] + crop[0], box[3] + crop[1])

Adding appropriate type hinting has no effect.

Changing the class functions to be module-level functions causes the error to go away, which seems potentially interesting.

Expected behavior

This error should not be emitted, as box is always guaranteed to be a tuple on that code path, and the order of the proxy method branches within get_rendition_size shouldn't matter for that determination anyway.

pylint --version output

pylint 2.4.4
astroid 2.3.3
Python 3.7.4 (default, Sep  7 2019, 18:27:02) 
[Clang 10.0.1 (clang-1001.0.46.4)]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0