PaddlePaddle/PaddleOCR · error · ValueError
Shear should be a single value or a tuple/list containing tw
Error message
Shear should be a single value or a tuple/list containing two values. Got {} What it means
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.
Source
Thrown at ppocr/data/imaug/abinet_aug.py:133
)
self.shear = [shear]
else:
assert isinstance(shear, (tuple, list)) and (
len(shear) == 2
), "shear should be a list or tuple and it must be of length 2."
self.shear = shear
else:
self.shear = shear
def _get_inverse_affine_matrix(self, center, angle, translate, scale, shear):
# https://github.com/pytorch/vision/blob/v0.4.0/torchvision/transforms/functional.py#L717
from numpy import sin, cos, tan
if isinstance(shear, numbers.Number):
shear = [shear, 0]
if not isinstance(shear, (tuple, list)) and len(shear) == 2:
raise ValueError(
"Shear should be a single value or a tuple/list containing "
+ "two values. Got {}".format(shear)
)
rot = math.radians(angle)
sx, sy = [math.radians(s) for s in shear]
cx, cy = center
tx, ty = translate
# RSS without scaling
a = cos(rot - sy) / cos(sy)
b = -cos(rot - sy) * tan(sx) / cos(sy) - sin(rot)
c = sin(rot - sy) / cos(sy)
d = -sin(rot - sy) * tan(sx) / cos(sy) + cos(rot)
# Inverted rotation matrix with scale and shear
# det([[a, b], [c, d]]) == 1, since det(rotation) = 1 and det(shear) = 1View on GitHub (pinned to 2661c7c0ef)
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 ...`.
Example fix
# before (patched/derived class sets shear directly) aff.shear = [10, 0, 5] # later: ValueError in _get_inverse_affine_matrix # after aff.shear = [10, 0] # exactly two degree values
Defensive patterns
Strategy: type-guard
Validate before calling
import numbers
def normalize_shear(shear):
if isinstance(shear, numbers.Number):
return [shear, 0]
shear = list(shear)
if len(shear) == 1:
return [shear[0], 0]
if len(shear) != 2:
raise ValueError(f'shear must be number or 2-sequence, got {shear!r}')
return shear Type guard
import numbers
def is_normalized_shear(v) -> bool:
return (isinstance(v, (tuple, list)) and len(v) == 2
and all(isinstance(x, numbers.Number) for x in v)) Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- If shear is a single number, it must be positive.
- translation values should be between 0 and 1
- scale values should be positive
- Interpolation types only nearest, linear, cubic, area are su
- factor must be number or list with length 2
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/444cc9d07383eb0e.
Report an issue: GitHub.