@klara.inference.inference_transform_wrapper
def infer_abs(node: klara.Call, context=None):
    arg = node.args[0]
    for value in arg.infer(context):
        if value.status and isinstance(value.result, klara.Const):
            yield from klara.inference.const_factory(abs(value.result.value))
        else:
            raise klara.inference.UseInferenceDefault()


def is_abs_call(node: klara.Call):
    return str(node.func) == "abs"


def register():
    klara.MANAGER.register_transform(klara.Call, infer_abs, is_abs_call)


if __name__ == "__main__":
    klara.MANAGER.register_transform(klara.Call, infer_abs, is_abs_call)

    source = """
    s = 1 - 2
    s *= 3
    z = abs(s)
    """
    tree = klara.parse(source)
    print(list(tree.body[-1].value.infer()))
    # [3]
    source = """
        def main(number: int, cm: int, dc: int, wn: int):
            mc = 0
            if wn > 2:
                if number > 2 and number > 2 or number > 2:
                    if number > 0:
                        if wn > 2 or wn > 2:
                            mc = 2
                        else:
                            mc = 5
                    else:
                        mc = 100
            else:
                mc = 1
            pc = number * cm
            if cm <= 4:
                pc_incr = 4
            else:
                pc_incr = cm
            n_pc_incr = pc / pc_incr
            pc_left = dc * pc_incr * (n_pc_incr / 2 + n_pc_incr % 2)
            pc_right = pc - pc_left
            is_rebuf = pc_right
            if is_rebuf:
                cell = Component(pc_right, options=[mc])
            else:
                cell = Component(pc_right)
            return cell
    """
    klara.parse(source)