@@ -127,6 +127,10 @@ def __lt__(self, other: Any) -> bool:
127
127
def __eq__ (self , other : Any ) -> bool :
128
128
return isinstance (other , Error ) and self .cmp () == other .cmp ()
129
129
130
+ def __repr__ (self ) -> str :
131
+ trailer = "" .join (f", { x !r} " for x in self .args )
132
+ return f"<{ self .code } error at { self .line } :{ self .col } { trailer } >"
133
+
130
134
131
135
checkpoint_node_types = (ast .Await , ast .AsyncFor , ast .AsyncWith )
132
136
cancel_scope_names = (
@@ -806,12 +810,13 @@ def iter_guaranteed_once(iterable: ast.expr) -> bool:
806
810
)
807
811
808
812
809
- def is_nursery_call (node : ast .AST , name : str ) -> bool :
813
+ def is_nursery_call (node : ast .AST , name : str ) -> bool : # pragma: no cover
810
814
assert name in ("start" , "start_soon" )
811
815
if isinstance (node , ast .Attribute ):
812
- if not isinstance (node .value , ast .Name ):
813
- return is_nursery_call (node .value , name ) # might be self.nursery.start()
814
- return node .value .id .endswith ("nursery" ) and node .attr == "start"
816
+ if isinstance (node .value , ast .Name ):
817
+ return node .attr == name and node .value .id .endswith ("nursery" )
818
+ if isinstance (node .value , ast .Attribute ):
819
+ return node .attr == name and node .value .attr .endswith ("nursery" )
815
820
return False
816
821
817
822
@@ -827,8 +832,17 @@ def visit(self, node: ast.AST):
827
832
self .node_stack .pop ()
828
833
829
834
def visit_Call (self , node : ast .Call ):
830
- if is_nursery_call (node .func , "start" ) and (
831
- len (self .node_stack ) < 2 or not isinstance (self .node_stack [- 2 ], ast .Await )
835
+ if (
836
+ isinstance (node .func , ast .Attribute )
837
+ and isinstance (node .func .value , ast .Name )
838
+ and (
839
+ (node .func .value .id == "trio" and node .func .attr in trio_async_funcs )
840
+ or is_nursery_call (node .func , "start" )
841
+ )
842
+ and (
843
+ len (self .node_stack ) < 2
844
+ or not isinstance (self .node_stack [- 2 ], ast .Await )
845
+ )
832
846
):
833
847
assert isinstance (node .func , ast .Attribute )
834
848
self .error ("TRIO105" , node , node .func .attr )
@@ -1179,7 +1193,7 @@ def __init__(self, *args: Any, **kwargs: Any):
1179
1193
def visit_AsyncFunctionDef (self , node : ast .AsyncFunctionDef ):
1180
1194
outer = self .aenter
1181
1195
1182
- self .aenter = ( node .name == "__aenter__" and len ( node . args . args ) == 1 ) or any (
1196
+ self .aenter = node .name == "__aenter__" or any (
1183
1197
_get_identifier (d ) == "asynccontextmanager" for d in node .decorator_list
1184
1198
)
1185
1199
0 commit comments