Skip to content

Commit 9f04904

Browse files
yangdanny97facebook-github-bot
authored andcommitted
stop control flow after sys.exit()
Summary: We can treat this the same as `raise` since we know what it does. Reviewed By: grievejia Differential Revision: D73125409 fbshipit-source-id: cb75c2264a7227420de96277775ede0a7ef3db8d
1 parent 669cbf1 commit 9f04904

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

Diff for: pyrefly/lib/binding/expr.rs

+9
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,15 @@ impl<'a> BindingsBuilder<'a> {
415415
self.bind_narrow_ops(&narrow_op, *range);
416416
return;
417417
}
418+
Expr::Call(ExprCall {
419+
range: _,
420+
func,
421+
arguments: _,
422+
}) if self.as_special_export(func) == Some(SpecialExport::Exit) => {
423+
// Control flow doesn't proceed after sys.exit()
424+
self.scopes.current_mut().flow.no_next = true;
425+
false
426+
}
418427
Expr::Name(x) => {
419428
let name = Ast::expr_name_identifier(x.clone());
420429
let binding = self.forward_lookup(&name);

Diff for: pyrefly/lib/export/special.rs

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub enum SpecialExport {
3535
Optional,
3636
Cast,
3737
Super,
38+
Exit,
3839
}
3940

4041
#[derive(Debug)]
@@ -70,6 +71,7 @@ impl SpecialExport {
7071
"Optional" => Some(Self::Optional),
7172
"cast" => Some(Self::Cast),
7273
"super" => Some(Self::Super),
74+
"exit" => Some(Self::Exit),
7375
_ => None,
7476
}
7577
}
@@ -94,6 +96,7 @@ impl SpecialExport {
9496
Self::CollectionsNamedTuple => matches!(m.as_str(), "collections"),
9597
Self::Enum | Self::StrEnum | Self::IntEnum => matches!(m.as_str(), "enum"),
9698
Self::Super => matches!(m.as_str(), "builtins"),
99+
Self::Exit => matches!(m.as_str(), "sys"),
97100
}
98101
}
99102

Diff for: pyrefly/lib/test/narrow.rs

+16
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,22 @@ def f(x: str | None):
223223
assert_type(x, str)
224224
else:
225225
assert_type(x, None)
226+
if not x:
227+
assert_type(x, str | None)
228+
else:
229+
assert_type(x, str)
230+
"#,
231+
);
232+
233+
testcase!(
234+
test_exit,
235+
r#"
236+
from typing import assert_type
237+
import sys
238+
def f(x: str | None):
239+
if not x:
240+
sys.exit(1)
241+
assert_type(x, str)
226242
"#,
227243
);
228244

0 commit comments

Comments
 (0)