Skip to content

Commit 18a8968

Browse files
Tianhan Lufacebook-github-bot
Tianhan Lu
authored andcommitted
Add test cases for context manager class decorators for higher order call graphs
Reviewed By: arthaud Differential Revision: D71836151 fbshipit-source-id: df00b0bb893d4c0c8aa317b938d399e9d88e0da1
1 parent 1d6d28a commit 18a8968

File tree

1 file changed

+229
-0
lines changed

1 file changed

+229
-0
lines changed

source/interprocedural/test/callGraphFixpointTest.ml

+229
Original file line numberDiff line numberDiff line change
@@ -3456,6 +3456,235 @@ let test_higher_order_call_graph_fixpoint =
34563456
@subclass
34573457
def stub_contextmanager(x):
34583458
print(x)
3459+
|}
3460+
~expected:
3461+
[
3462+
{
3463+
Expected.callable =
3464+
Target.Regular.Function { name = "test.stub_contextmanager"; kind = Decorated }
3465+
|> Target.from_regular;
3466+
call_graph =
3467+
[
3468+
( "9:1-9:9",
3469+
LocationCallees.Singleton
3470+
(ExpressionCallees.from_call
3471+
(CallCallees.create
3472+
~call_targets:
3473+
[
3474+
CallTarget.create_regular
3475+
~implicit_receiver:true
3476+
~implicit_dunder_call:true
3477+
~receiver_class:"test.Subclass"
3478+
(Target.Regular.Method
3479+
{
3480+
class_name = "test.Base";
3481+
method_name = "__call__";
3482+
kind = Normal;
3483+
});
3484+
]
3485+
~higher_order_parameters:
3486+
(HigherOrderParameterMap.from_list
3487+
[
3488+
{
3489+
index = 0;
3490+
call_targets =
3491+
[
3492+
CallTarget.create_regular
3493+
(Target.Regular.Function
3494+
{
3495+
name = "test.stub_contextmanager";
3496+
kind = Normal;
3497+
});
3498+
];
3499+
unresolved = CallGraph.Unresolved.False;
3500+
};
3501+
])
3502+
())) );
3503+
( "10:0-11:10",
3504+
LocationCallees.Singleton
3505+
(ExpressionCallees.from_attribute_access
3506+
(AttributeAccessCallees.create
3507+
~callable_targets:
3508+
[
3509+
CallTarget.create_regular
3510+
(Target.Regular.Function
3511+
{ name = "test.stub_contextmanager"; kind = Normal });
3512+
]
3513+
())) );
3514+
];
3515+
returned_callables = [];
3516+
};
3517+
]
3518+
();
3519+
labeled_test_case __FUNCTION__ __LINE__
3520+
@@ assert_higher_order_call_graph_fixpoint
3521+
~source:
3522+
{|
3523+
class Base:
3524+
def __enter__(self):
3525+
return self
3526+
def __exit__(self, exc_type: object, exc_value: object, traceback: object) -> bool:
3527+
return False
3528+
def __call__(self, func):
3529+
def inner(*args, **kwds):
3530+
func(*args, **kwds)
3531+
return inner
3532+
base = Base()
3533+
@base # Test custom context manager
3534+
def contextmanager(x):
3535+
print(x)
3536+
class Subclass(Base):
3537+
def __init__(self, name):
3538+
self.name = name
3539+
subclass = Subclass("123")
3540+
@subclass # Test subclass and decorator factory
3541+
def contextmanager_subclass(x):
3542+
print(x)
3543+
|}
3544+
~expected:
3545+
[
3546+
{
3547+
Expected.callable =
3548+
Target.Regular.Function { name = "test.contextmanager"; kind = Decorated }
3549+
|> Target.from_regular;
3550+
call_graph =
3551+
[
3552+
( "12:1-12:5",
3553+
LocationCallees.Singleton
3554+
(ExpressionCallees.from_call
3555+
(CallCallees.create
3556+
~call_targets:
3557+
[
3558+
CallTarget.create
3559+
~implicit_receiver:true
3560+
~implicit_dunder_call:true
3561+
~receiver_class:"test.Base"
3562+
(create_parameterized_target
3563+
~regular:
3564+
(Target.Regular.Method
3565+
{
3566+
class_name = "test.Base";
3567+
method_name = "__call__";
3568+
kind = Normal;
3569+
})
3570+
~parameters:
3571+
[
3572+
( create_positional_parameter 1 "func",
3573+
Target.Regular.Function
3574+
{ name = "test.contextmanager"; kind = Normal }
3575+
|> Target.from_regular );
3576+
]);
3577+
]
3578+
())) );
3579+
( "13:0-14:10",
3580+
LocationCallees.Singleton
3581+
(ExpressionCallees.from_attribute_access
3582+
(AttributeAccessCallees.create
3583+
~callable_targets:
3584+
[
3585+
CallTarget.create_regular
3586+
(Target.Regular.Function
3587+
{ name = "test.contextmanager"; kind = Normal });
3588+
]
3589+
())) );
3590+
];
3591+
returned_callables =
3592+
[
3593+
CallTarget.create
3594+
(create_parameterized_target
3595+
~regular:
3596+
(Target.Regular.Function
3597+
{ name = "test.Base.__call__.inner"; kind = Normal })
3598+
~parameters:
3599+
[
3600+
( AccessPath.Root.Variable "$parameter$func",
3601+
Target.Regular.Function
3602+
{ name = "test.contextmanager"; kind = Normal }
3603+
|> Target.from_regular );
3604+
]);
3605+
];
3606+
};
3607+
{
3608+
Expected.callable =
3609+
Target.Regular.Function
3610+
{ name = "test.contextmanager_subclass"; kind = Decorated }
3611+
|> Target.from_regular;
3612+
call_graph =
3613+
[
3614+
( "19:1-19:9",
3615+
LocationCallees.Singleton
3616+
(ExpressionCallees.from_call
3617+
(CallCallees.create
3618+
~call_targets:
3619+
[
3620+
CallTarget.create
3621+
~implicit_receiver:true
3622+
~implicit_dunder_call:true
3623+
~receiver_class:"test.Subclass"
3624+
(create_parameterized_target
3625+
~regular:
3626+
(Target.Regular.Method
3627+
{
3628+
class_name = "test.Base";
3629+
method_name = "__call__";
3630+
kind = Normal;
3631+
})
3632+
~parameters:
3633+
[
3634+
( create_positional_parameter 1 "func",
3635+
Target.Regular.Function
3636+
{
3637+
name = "test.contextmanager_subclass";
3638+
kind = Normal;
3639+
}
3640+
|> Target.from_regular );
3641+
]);
3642+
]
3643+
())) );
3644+
( "20:0-21:10",
3645+
LocationCallees.Singleton
3646+
(ExpressionCallees.from_attribute_access
3647+
(AttributeAccessCallees.create
3648+
~callable_targets:
3649+
[
3650+
CallTarget.create_regular
3651+
(Target.Regular.Function
3652+
{ name = "test.contextmanager_subclass"; kind = Normal });
3653+
]
3654+
())) );
3655+
];
3656+
returned_callables =
3657+
[
3658+
CallTarget.create
3659+
(create_parameterized_target
3660+
~regular:
3661+
(Target.Regular.Function
3662+
{ name = "test.Base.__call__.inner"; kind = Normal })
3663+
~parameters:
3664+
[
3665+
( AccessPath.Root.Variable "$parameter$func",
3666+
Target.Regular.Function
3667+
{ name = "test.contextmanager_subclass"; kind = Normal }
3668+
|> Target.from_regular );
3669+
]);
3670+
];
3671+
};
3672+
]
3673+
();
3674+
labeled_test_case __FUNCTION__ __LINE__
3675+
@@ assert_higher_order_call_graph_fixpoint
3676+
~source:
3677+
{|
3678+
class Base:
3679+
def __call__(self, func):
3680+
... # Test when `__call__` is a stub
3681+
class Subclass(Base):
3682+
def __init__(self, name):
3683+
self.name = name
3684+
subclass = Subclass("123")
3685+
@subclass
3686+
def stub_contextmanager(x):
3687+
print(x)
34593688
|}
34603689
~expected:
34613690
[

0 commit comments

Comments
 (0)