From d34971a7d5e5184c545531a5ca209e6278e0c248 Mon Sep 17 00:00:00 2001 From: Gabriela Cunha Sampaio Date: Fri, 10 Jan 2025 10:04:37 -0800 Subject: [PATCH] [InferPython] Added unit tests Reviewed By: jvillard Differential Revision: D67049773 fbshipit-source-id: 5f3b0f9247da9e69453f561cb54880e6495eafb8 --- .../python/pulse/async_classes.py | 30 ++++++++++++++++++ .../python/pulse/async_lambda.py | 31 +++++++++++++++++++ .../python/pulse/async_level0.py | 8 +++-- .../python/pulse/async_typing.py | 27 ++++++++++++++++ .../codetoanalyze/python/pulse/issues.exp | 8 +++++ 5 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 infer/tests/codetoanalyze/python/pulse/async_classes.py create mode 100644 infer/tests/codetoanalyze/python/pulse/async_lambda.py create mode 100644 infer/tests/codetoanalyze/python/pulse/async_typing.py diff --git a/infer/tests/codetoanalyze/python/pulse/async_classes.py b/infer/tests/codetoanalyze/python/pulse/async_classes.py new file mode 100644 index 0000000000..4b6b9b68b6 --- /dev/null +++ b/infer/tests/codetoanalyze/python/pulse/async_classes.py @@ -0,0 +1,30 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import asyncio + + +class Car: + def __init__(self, make, model): + self.make = make + self.model = model + + def drive(self): + return 0 + + async def refuel(self): + await asyncio.sleep(2) + + +async def car_instance_ok(): + my_car = Car("Fusca", "1999") + my_car.drive() + await my_car.refuel() + + +async def fn_car_instance_bad(): + my_car = Car("Fusca", "1999") + my_car.drive() + return my_car.refuel() diff --git a/infer/tests/codetoanalyze/python/pulse/async_lambda.py b/infer/tests/codetoanalyze/python/pulse/async_lambda.py new file mode 100644 index 0000000000..32cb5f3e9d --- /dev/null +++ b/infer/tests/codetoanalyze/python/pulse/async_lambda.py @@ -0,0 +1,31 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import asyncio + + +async def foo(): + await asyncio.sleep(1) + + +async def lambda_bad(): + x = lambda: foo() + x() + + +async def lambda_good(): + x = lambda: foo() + await x() + + +async def lambda_param_bad(f): + f() + + +async def lambda_param_bad_call_bad(): + lambda_param_bad(lambda: foo()) + + +lambda_param_bad(lambda: foo()) diff --git a/infer/tests/codetoanalyze/python/pulse/async_level0.py b/infer/tests/codetoanalyze/python/pulse/async_level0.py index ae76e054a2..8da3b410a4 100644 --- a/infer/tests/codetoanalyze/python/pulse/async_level0.py +++ b/infer/tests/codetoanalyze/python/pulse/async_level0.py @@ -4,7 +4,6 @@ # LICENSE file in the root directory of this source tree. import asyncio -import random async def sleep(i): @@ -96,8 +95,13 @@ async def call_fst_bad(i): def main_ok(): asyncio.run(sleep(10)) -main_ok() +async def multi_tasks_ok(): + asyncio.gather(sleep(1), sleep(2)) + + +main_ok() # no FP here asyncio.run(sleep(10)) +asyncio.run(multi_tasks_ok()) diff --git a/infer/tests/codetoanalyze/python/pulse/async_typing.py b/infer/tests/codetoanalyze/python/pulse/async_typing.py new file mode 100644 index 0000000000..768dc08587 --- /dev/null +++ b/infer/tests/codetoanalyze/python/pulse/async_typing.py @@ -0,0 +1,27 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +import asyncio + + +async def fp_await_condition_typing_ok(): + if type(5) == int: + await asyncio.sleep(1) + else: + asyncio.sleep(1) + + +async def await_condition_typing_bad(): + if type(5) == str: + await asyncio.sleep(1) + else: + asyncio.sleep(1) + + +async def await_condition_typing_with_arg_bad(x): + if type(x) == str: + await asyncio.sleep(1) + else: + asyncio.sleep(1) diff --git a/infer/tests/codetoanalyze/python/pulse/issues.exp b/infer/tests/codetoanalyze/python/pulse/issues.exp index 54efdb079d..93728dc3e3 100644 --- a/infer/tests/codetoanalyze/python/pulse/issues.exp +++ b/infer/tests/codetoanalyze/python/pulse/issues.exp @@ -9,6 +9,11 @@ async_import_with_package.py, async_import_with_package.from_class_bad3, 1, PULS async_import_with_package.py, async_import_with_package.bad4, 1, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here] async_import_with_package.py, async_import_with_package.bad5, 1, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here] async_import_with_package.py, async_import_with_package.bad6, 1, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here] +async_lambda.py, async_lambda.lambda_bad, 2, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,when calling `closure:async_lambda:6.call` here,when calling `async_lambda.lambda_bad::_$lambda` here,allocated by async call here,awaitable becomes unreachable here] +async_lambda.py, async_lambda.lambda_param_bad, 1, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,when calling `closure:async_lambda:5.call` here,when calling `async_lambda._$lambda` here,allocated by async call here,awaitable becomes unreachable here] +async_lambda.py, async_lambda.lambda_param_bad, 1, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,when calling `closure:async_lambda:8.call` here,when calling `async_lambda.lambda_param_bad_call_bad::_$lambda` here,allocated by async call here,awaitable becomes unreachable here] +async_lambda.py, async_lambda.lambda_param_bad_call_bad, 1, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here] +async_lambda.py, async_lambda.__module_body__, 30, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here] async_level0.py, async_level0.sleep_bad, 1, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here] async_level0.py, async_level0.call_sleep_bad, 1, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here] async_level0.py, async_level0.call_sleep_with_branchs_bad1, 3, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here] @@ -18,3 +23,6 @@ async_level0.py, async_level0.tuple1_bad, 2, PULSE_UNAWAITED_AWAITABLE, no_bucke async_level0.py, async_level0.with_str_bad, 2, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here] async_level0.py, async_level0.call_fst_bad, 1, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here] async_level1.py, async_level1.D::main, 1, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here] +async_typing.py, async_typing.fp_await_condition_typing_ok, 4, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here] +async_typing.py, async_typing.await_condition_typing_bad, 4, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here] +async_typing.py, async_typing.await_condition_typing_with_arg_bad, 4, PULSE_UNAWAITED_AWAITABLE, no_bucket, ERROR, [allocation part of the trace starts here,allocated by async call here,awaitable becomes unreachable here]