{"record":{"id":"444cc9d07383eb0e","repo":"PaddlePaddle/PaddleOCR","slug":"shear-should-be-a-single-value-or-a-tuple-list-con","errorCode":null,"errorMessage":"Shear should be a single value or a tuple/list containing two values. Got {}","messagePattern":"Shear should be a single value or a tuple/list containing two values\\. Got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"ppocr/data/imaug/abinet_aug.py","lineNumber":133,"sourceCode":"                    )\n                self.shear = [shear]\n            else:\n                assert isinstance(shear, (tuple, list)) and (\n                    len(shear) == 2\n                ), \"shear should be a list or tuple and it must be of length 2.\"\n                self.shear = shear\n        else:\n            self.shear = shear\n\n    def _get_inverse_affine_matrix(self, center, angle, translate, scale, shear):\n        # https://github.com/pytorch/vision/blob/v0.4.0/torchvision/transforms/functional.py#L717\n        from numpy import sin, cos, tan\n\n        if isinstance(shear, numbers.Number):\n            shear = [shear, 0]\n\n        if not isinstance(shear, (tuple, list)) and len(shear) == 2:\n            raise ValueError(\n                \"Shear should be a single value or a tuple/list containing \"\n                + \"two values. Got {}\".format(shear)\n            )\n\n        rot = math.radians(angle)\n        sx, sy = [math.radians(s) for s in shear]\n\n        cx, cy = center\n        tx, ty = translate\n\n        # RSS without scaling\n        a = cos(rot - sy) / cos(sy)\n        b = -cos(rot - sy) * tan(sx) / cos(sy) - sin(rot)\n        c = sin(rot - sy) / cos(sy)\n        d = -sin(rot - sy) * tan(sx) / cos(sy) + cos(rot)\n\n        # Inverted rotation matrix with scale and shear\n        # det([[a, b], [c, d]]) == 1, since det(rotation) = 1 and det(shear) = 1","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/ppocr/data/imaug/abinet_aug.py#L115-L151","documentation":"CVRandomAffine._get_inverse_affine_matrix raises ValueError when the shear parameter handed to the matrix computation is neither a number nor a 2-length tuple/list. Note the guard itself has a logic bug — `if not isinstance(shear, (tuple, list)) and len(shear) == 2` — so a number is widened to [shear, 0] first and tuples of length != 2 raise via len() failing or the condition passing; in practice a malformed shear value from construction reaches here.","triggerScenarios":"Calling _get_inverse_affine_matrix (or CVRandomAffine.__call__ which forwards self.shear) with shear as a 3-element list, a string, or a tuple whose length is not 2. Constructing with a properly-validated shear normally avoids this path.","commonSituations":"Subclassing or monkey-patching CVRandomAffine and setting self.shear directly; feeding shear from config without the constructor's validation; passing numpy scalars that fail isinstance checks.","solutions":["Always set shear through the constructor so it is normalized to a list of one or two numbers.","Normalize before use: shear = [shear, 0] if isinstance(shear, numbers.Number) else list(shear); assert len(shear) == 2.","Fix the upstream condition if you control the code: `if not (isinstance(shear, (tuple, list)) and len(shear) == 2): raise ...`."],"exampleFix":"# before (patched/derived class sets shear directly)\naff.shear = [10, 0, 5]  # later: ValueError in _get_inverse_affine_matrix\n# after\naff.shear = [10, 0]     # exactly two degree values","handlingStrategy":"type-guard","validationCode":"import numbers\n\ndef normalize_shear(shear):\n    if isinstance(shear, numbers.Number):\n        return [shear, 0]\n    shear = list(shear)\n    if len(shear) == 1:\n        return [shear[0], 0]\n    if len(shear) != 2:\n        raise ValueError(f'shear must be number or 2-sequence, got {shear!r}')\n    return shear","typeGuard":"import numbers\n\ndef is_normalized_shear(v) -> bool:\n    return (isinstance(v, (tuple, list)) and len(v) == 2\n            and all(isinstance(x, numbers.Number) for x in v))","tryCatchPattern":null,"preventionTips":["Never assign self.shear directly on the transform; go through the constructor","Normalize config shear to a 2-element numeric list before building transforms","Note the upstream condition has a logic bug; do not rely on it to normalize input"],"tags":["data-augmentation","abinet","affine","shear","valueerror","logic-bug"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}