python.lang.correctness.return-in-init.return-in-init

Verifed by r2c
Community Favorite
profile photo of semgrepsemgrep
Author
59,628
Download Count*

return should never appear inside a class init function. This will cause a runtime error.

Run Locally

Run in CI

Defintion

rules:
  - id: return-in-init
    patterns:
      - pattern-inside: |
          class $A(...):
              ...
      - pattern-inside: |
          def __init__(...):
              ...
      - pattern-not-inside: |
          def __init__(...):
              ...
              def $F(...):
                  ...
      - patterns:
          - pattern: return ...
          - pattern-not: return
          - pattern-not: return None
    message: "`return` should never appear inside a class __init__ function. This
      will cause a runtime error."
    languages:
      - python
    severity: ERROR
    metadata:
      category: correctness
      technology:
        - python
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]

Examples

return-in-init.py

class A:
    def __init__(a, b, c):
        # ruleid:return-in-init
        return A(a, b, c)


class B:
    def __init__(a, b, c):
        # ok:return-in-init
        return


class C:
    def __init__(a, b, c):
        # ruleid:yield-in-init
        yield


class D:
    def __init__():
        # ruleid:yield-in-init
        yield 5


def __init__(a, b, c):
    # ok:yield-in-init
    return A(a, b, c)


def __init__(a, b, c):
    # ok:yield-in-init
    yield


def __init__():
    # ok:yield-in-init
    yield 5


class E:
    def func1():
        if not hello:
            # ok:yield-in-init
            yield 5
        # ok:yield-in-init
        yield other


class F:
    def __init__():
        pass

    def func1():
        # ok:return-in-init
        return 5

    def func2():
        # ok:return-in-init
        return


class G:
    def __init__():
        pass

    def func1():
        # ok:yield-in-init
        yield 5

    def func2():
        # ok:yield-in-init
        yield

class H:
    def __init__(self, x):
        # ok:return-in-init
        return None

class Odd:
    def __init__(self, numbers):
        def is_odd(n):
            # ok:return-in-init
            return n % 2 == 1
        self.numbers = filter(is_odd, numbers)

        # todoruleid:return-in-init
        return self.numbers

class Even:
    def __init__(self):
        class EvenNumber:
            def __init__(self, n):
                self.n = n
                # todoruleid:return-in-init
                return n

            def is_even(self):
                # ok:return-in-init
                return self.n % 2 == 0

        self.number = EvenNumber()

    def not_init(self):
        class EvenNumber:
            def __init__(self, n):
                self.n = n
                # ruleid:return-in-init
                return n

            def is_even(self):
                # ok:return-in-init
                return self.n % 2 == 0

        # ok:return-in-init
        return EvenNumber()