@@ -2368,45 +2368,42 @@ def _determine_completion_context(self, line):
23682368 """
23692369 Determine whether the cursor is in an attribute or global completion context.
23702370 """
2371+ # Cursor in string/comment → GLOBAL.
23712372 if self ._is_in_string_or_comment (line ):
23722373 return self ._CompletionContextType .GLOBAL
2373- if line .endswith ("." ):
2374- return self ._CompletionContextType .ATTRIBUTE
2375-
2376- last_token_match = re .search (r"([\w]+)$" , line )
2377- if not last_token_match :
2378- return self ._CompletionContextType .GLOBAL
23792374
2380- prefix = line [: last_token_match .start ()]
2381- chain_match = re .search (r"(.*)\.(\w*)$" , prefix .rstrip ())
2375+ # Match 'anything-dot-word' at end for attribute context.
2376+ # Ex: 'obj.', 'np.random.ran'.
2377+ chain_match = re .search (r"(.+)\.(\w*)$" , line )
23822378 if chain_match :
2379+ prefix = chain_match .group (1 )
2380+ # If prefix is a number → GLOBAL (no attributes).
2381+ # Ex: '3.', '-42.5.'.
2382+ if re .fullmatch (r"[-+]?\d*\.?\d+" , prefix ):
2383+ return self ._CompletionContextType .GLOBAL
23832384 return self ._CompletionContextType .ATTRIBUTE
23842385
2386+ # No attribute pattern → GLOBAL.
2387+ # Ex: 'var', ''.
23852388 return self ._CompletionContextType .GLOBAL
23862389
23872390 def _is_in_string_or_comment (self , text ):
2388- # Check for comments
2389- if "#" in text :
2390- parts = text .split ("#" )
2391- if len (parts ) > 1 :
2392- return True
2393-
23942391 in_single_quote = False
23952392 in_double_quote = False
23962393 in_triple_single = False
23972394 in_triple_double = False
2398- in_fstring = False
2399- in_fstring_expression = False
2395+ in_template_string = False # Covers both f-strings and t-strings
2396+ in_expression = False # For expressions in f/t-strings
24002397 i = 0
24012398
24022399 while i < len (text ):
2403- # Check for f-string start
2400+ # Check for f-string or t-string start
24042401 if (
24052402 i + 1 < len (text )
2406- and text [i ] == "f"
2403+ and text [i ] in ( "f" , "t" )
24072404 and (text [i + 1 ] == '"' or text [i + 1 ] == "'" )
24082405 ):
2409- in_fstring = True
2406+ in_template_string = True
24102407 i += 1
24112408
24122409 # Handle triple quotes
@@ -2433,11 +2430,11 @@ def _is_in_string_or_comment(self, text):
24332430 i += 2
24342431 continue
24352432
2436- # Handle f-string expressions
2437- if in_fstring and text [i ] == "{" :
2438- in_fstring_expression = True
2439- elif in_fstring and text [i ] == "}" :
2440- in_fstring_expression = False
2433+ # Handle expressions in f-strings or t-strings
2434+ if in_template_string and text [i ] == "{" :
2435+ in_expression = True
2436+ elif in_template_string and text [i ] == "}" :
2437+ in_expression = False
24412438
24422439 # Handle quotes
24432440 if (
@@ -2455,10 +2452,22 @@ def _is_in_string_or_comment(self, text):
24552452 ):
24562453 in_single_quote = not in_single_quote
24572454
2455+ # Check for comment
2456+ if text [i ] == "#" and (
2457+ not (
2458+ in_single_quote
2459+ or in_double_quote
2460+ or in_triple_single
2461+ or in_triple_double
2462+ )
2463+ or in_expression
2464+ ):
2465+ return True
2466+
24582467 i += 1
24592468
2460- # If we're in an f-string expression , return False
2461- if in_fstring_expression :
2469+ # If we're in an expression ( f-string or t-string) , return False
2470+ if in_expression :
24622471 return False
24632472
24642473 # Otherwise, return True if we're in any type of string
0 commit comments