PaddlePaddle/PaddleOCR · error · ValueError

If shear is a single number, it must be positive.

Error message

If shear is a single number, it must be positive.

What it means

In CVRandomAffine, when shear is a single number it must be >= 0, otherwise ValueError at construction. (Negative shear is still reachable by passing a 2-element tuple/list, since only the single-number form enforces positivity.) This mirrors torchvision's RandomAffine shear semantics.

Source

Thrown at ppocr/data/imaug/abinet_aug.py:113

            ), "translate should be a list or tuple and it must be of length 2."
            for t in translate:
                if not (0.0 <= t <= 1.0):
                    raise ValueError("translation values should be between 0 and 1")
        self.translate = translate

        if scale is not None:
            assert (
                isinstance(scale, (tuple, list)) and len(scale) == 2
            ), "scale should be a list or tuple and it must be of length 2."
            for s in scale:
                if s <= 0:
                    raise ValueError("scale values should be positive")
        self.scale = scale

        if shear is not None:
            if isinstance(shear, numbers.Number):
                if shear < 0:
                    raise ValueError(
                        "If shear is a single number, it must be positive."
                    )
                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]

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Pass a non-negative single value, e.g. shear=10 (meaning magnitude up to 10 degrees).
  2. Or pass a 2-tuple to get a directional/ranged shear: shear=(-10, 10) — tuples are allowed to contain negatives.
  3. Double-check units: shear is in degrees, not radians.

Example fix

# before
CVRandomAffine(degrees=0, shear=-10)      # ValueError
# after
CVRandomAffine(degrees=0, shear=(-10, 10))  # ranged shear accepts negatives
Defensive patterns

Strategy: validation

Validate before calling

import numbers

def valid_shear(s) -> bool:
    if s is None:
        return True
    if isinstance(s, numbers.Number):
        return s >= 0
    return isinstance(s, (tuple, list)) and len(s) == 2

Type guard

def is_valid_shear(v) -> bool:
    import numbers
    if isinstance(v, numbers.Number):
        return v >= 0
    return isinstance(v, (tuple, list)) and len(v) == 2

Prevention

When it happens

Trigger: CVRandomAffine(degrees=0, shear=-10) — a single negative number; intending a shear range like (-10, 10) but passing only -10.

Common situations: Porting torchvision configs where negative shear ranges are common; sign typos; forgetting that a single number means fixed magnitude, not a symmetric range.

Related errors


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/a070cbf06c2ca56c. Report an issue: GitHub.