1+ import ast
12import importlib
23import sys
4+ from pathlib import Path
35
46import pytest
57import torch
@@ -18,7 +20,7 @@ def fake_find_spec(name, package=None):
1820 monkeypatch .setattr (importlib .util , "find_spec" , fake_find_spec )
1921 module = importlib .import_module ("torch_tensorrt.executorch" )
2022
21- with pytest .raises (ImportError , match = "ExecuTorch.*required " ):
23+ with pytest .raises (ImportError , match = r"torch_tensorrt\[executorch\] " ):
2224 _ = module .TensorRTBackend
2325
2426 sys .modules .pop ("torch_tensorrt.executorch" , None )
@@ -39,7 +41,7 @@ def fake_find_spec(name, package=None):
3941
4042 from torch_tensorrt ._compile import save
4143
42- with pytest .raises (ImportError , match = "Saving in ExecuTorch format requires " ):
44+ with pytest .raises (ImportError , match = r"torch_tensorrt\[executorch\] " ):
4345 save (
4446 torch .nn .Linear (1 , 1 ),
4547 str (tmp_path / "model.pte" ),
@@ -53,3 +55,92 @@ def test_public_api_symbols_present():
5355 assert "get_edge_compile_config" in module .__all__
5456 assert "TensorRTPartitioner" in module .__all__
5557 assert "TensorRTBackend" in module .__all__
58+
59+
60+ _REPO_ROOT = Path (__file__ ).resolve ().parents [4 ]
61+ _SETUP_PY = _REPO_ROOT / "setup.py"
62+
63+
64+ def _setup_tree ():
65+ return ast .parse (_SETUP_PY .read_text (encoding = "utf-8" ))
66+
67+
68+ def _assignment_value (tree , name ):
69+ for node in tree .body :
70+ if isinstance (node , ast .Assign ) and any (
71+ isinstance (target , ast .Name ) and target .id == name
72+ for target in node .targets
73+ ):
74+ return node .value
75+ raise AssertionError (f"Could not find assignment for { name } " )
76+
77+
78+ def _function_def (tree , name ):
79+ for node in tree .body :
80+ if isinstance (node , ast .FunctionDef ) and node .name == name :
81+ return node
82+ raise AssertionError (f"Could not find function { name } " )
83+
84+
85+ @pytest .mark .unit
86+ def test_packaging_declares_executorch_extra ():
87+ tree = _setup_tree ()
88+ extras = _assignment_value (tree , "EXTRAS_REQUIRE" )
89+ assert isinstance (extras , ast .Dict )
90+
91+ extras_by_name = {
92+ key .value : value
93+ for key , value in zip (extras .keys , extras .values )
94+ if isinstance (key , ast .Constant )
95+ }
96+ for extra_name in ("executorch" , "all" ):
97+ assert extra_name in extras_by_name
98+ requirements = extras_by_name [extra_name ]
99+ assert isinstance (requirements , ast .List )
100+ assert any (
101+ isinstance (requirement , ast .Name )
102+ and requirement .id == "EXECUTORCH_REQUIREMENT"
103+ for requirement in requirements .elts
104+ )
105+
106+ setup_call = next (
107+ node
108+ for node in ast .walk (tree )
109+ if isinstance (node , ast .Call )
110+ and isinstance (node .func , ast .Name )
111+ and node .func .id == "setup"
112+ )
113+ extras_keyword = next (
114+ (keyword for keyword in setup_call .keywords if keyword .arg == "extras_require" ),
115+ None ,
116+ )
117+ assert extras_keyword is not None
118+ assert isinstance (extras_keyword .value , ast .Name )
119+ assert extras_keyword .value .id == "EXTRAS_REQUIRE"
120+
121+
122+ @pytest .mark .unit
123+ def test_executorch_is_not_base_install_requirement ():
124+ tree = _setup_tree ()
125+ for function_name in (
126+ "get_jetpack_requirements" ,
127+ "get_sbsa_requirements" ,
128+ "get_x86_64_requirements" ,
129+ "get_requirements" ,
130+ ):
131+ function = _function_def (tree , function_name )
132+ assert not any (
133+ isinstance (node , ast .Name ) and node .id == "EXECUTORCH_REQUIREMENT"
134+ for node in ast .walk (function )
135+ )
136+
137+
138+ @pytest .mark .unit
139+ def test_executorch_headers_are_not_dlfw_gated ():
140+ tree = _setup_tree ()
141+ header_package_data = _assignment_value (tree , "executorch_header_package_data" )
142+ assert isinstance (header_package_data , ast .List )
143+ assert not any (
144+ isinstance (node , ast .Name ) and node .id == "IS_DLFW_CI"
145+ for node in ast .walk (header_package_data )
146+ )
0 commit comments