_AB='parameters'
_AA='SyntaxError: '
_A9='IndentationError: '
_A8='f-string: '
_A7='error_leaf'
_A6='nonlocal_stmt'
_A5='f-string expression'
_A4='attribute'
_A3='subscript'
_A2='function call'
_A1='await expression'
_A0='conditional expression'
_z='number'
_y='ellipsis'
_x='Ellipsis'
_w='lambda'
_v='comp_for'
_u='exprlist'
_t="can't use starred expression here"
_s='invalid syntax'
_r='annassign'
_q='expr_stmt'
_p='import_from'
_o='expression'
_n='await'
_m='yield_expr'
_l='strings'
_k='yield'
_j='list'
_i='try_stmt'
_h='while_stmt'
_g='expr_list'
_f='error_node'
_e='power'
_d='atom_expr'
_c='string'
_b='comparison'
_a='yield expression'
_Z='keyword'
_Y='tuple'
_X='set display'
_W='dict literal'
_V='dict display'
_U='**'
_T='lambdef'
_S='sync_comp_for'
_R='testlist_star_expr'
_Q='for_stmt'
_P='classdef'
_O='fstring'
_N='star_expr'
_M='trailer'
_L='dictorsetmaker'
_K='name'
_J='funcdef'
_I='literal'
_H='testlist_comp'
_G='operator'
_F='['
_E='atom'
_D='('
_C=False
_B=None
_A=True
import codecs,sys,warnings,re
from contextlib import contextmanager
from parso.normalizer import Normalizer,NormalizerConfig,Issue,Rule
from parso.python.tokenize import _get_token_collection
_BLOCK_STMTS='if_stmt',_h,_Q,_i,'with_stmt'
_STAR_EXPR_PARENTS=_R,_H,_u
_MAX_BLOCK_SIZE=20
_MAX_INDENT_COUNT=100
ALLOWED_FUTURES='nested_scopes','generators','division','absolute_import','with_statement','print_function','unicode_literals','generator_stop'
_COMP_FOR_TYPES=_v,_S
def _get_rhs_name(node,version):
	C=version;B=node;A=B.type
	if A==_T:return _w
	elif A==_E:
		G=_get_comprehension_type(B);D,E=B.children[:2]
		if G is not _B:return G
		elif E.type==_L:
			if C<(3,8):return _I
			elif E.children[1]==':'or E.children[0]==_U:
				if C<(3,10):return _V
				else:return _W
			else:return _X
		elif D==_D and(E==')'or len(B.children)==3 and B.children[1].type==_H):return _Y
		elif D==_D:return _get_rhs_name(_remove_parens(B),version=C)
		elif D==_F:return _j
		elif D=='{'and E=='}':
			if C<(3,10):return _V
			else:return _W
		elif D=='{'and len(B.children)>2:return _X
	elif A==_Z:
		if _k in B.value:return _a
		if C<(3,8):return _Z
		else:return str(B.value)
	elif A==_G and B.value=='...':
		if C<(3,10):return _x
		else:return _y
	elif A==_b:return _b
	elif A in(_c,_z,_l):return _I
	elif A==_m:return _a
	elif A=='test':return _A0
	elif A in(_d,_e):
		if B.children[0]==_n:return _A1
		elif B.children[-1].type==_M:
			F=B.children[-1]
			if F.children[0]==_D:return _A2
			elif F.children[0]==_F:return _A3
			elif F.children[0]=='.':return _A4
	elif'expr'in A and _N not in A or'_test'in A or A in('term','factor'):
		if C<(3,10):return _G
		else:return _o
	elif A==_N:return'starred'
	elif A==_R:return _Y
	elif A==_O:return _A5
	return A
def _iter_stmts(scope):
	'\n    Iterates over all statements and splits up  simple_stmt.\n    '
	for A in scope.children:
		if A.type=='simple_stmt':
			for B in A.children:
				if B.type=='newline'or B==';':continue
				yield B
		else:yield A
def _get_comprehension_type(atom):
	B,A=atom.children[:2]
	if A.type==_H and A.children[1].type in _COMP_FOR_TYPES:
		if B==_F:return'list comprehension'
		else:return'generator expression'
	elif A.type==_L and A.children[-1].type in _COMP_FOR_TYPES:
		if A.children[1]==':':return'dict comprehension'
		else:return'set comprehension'
def _is_future_import(import_from):A=import_from.get_from_names();return[A.value for A in A]==['__future__']
def _remove_parens(atom):
	'\n    Returns the inner part of an expression like `(foo)`. Also removes nested\n    parens.\n    ';A=atom
	try:B=A.children
	except AttributeError:pass
	else:
		if len(B)==3 and B[0]==_D:return _remove_parens(A.children[1])
	return A
def _skip_parens_bottom_up(node):
	'\n    Returns an ancestor node of an expression, skipping all levels of parens\n    bottom-up.\n    ';A=node
	while A.parent is not _B:
		A=A.parent
		if A.type!=_E or A.children[0]!=_D:return A
def _iter_params(parent_node):return(A for A in parent_node.children if A.type=='param'or A.type==_G)
def _is_future_import_first(import_from):
	'\n    Checks if the import is the first statement of a file.\n    ';B=import_from;C=_C
	for A in _iter_stmts(B.get_root_node()):
		if A.type==_c and not C:continue
		C=_A
		if A==B:return _A
		if A.type==_p and _is_future_import(A):continue
		return _C
def _iter_definition_exprs_from_lists(exprlist):
	A=exprlist
	def C(child):
		A=child
		if A.type==_E:
			if A.children[0]==_D:
				B=A.children[1]
				if B.type==_H:yield from _iter_definition_exprs_from_lists(B);return
				else:yield from C(B);return
			elif A.children[0]==_F:yield B;return
		yield A
	if A.type in _STAR_EXPR_PARENTS:
		for B in A.children[::2]:yield from C(B)
	else:yield from C(A)
def _get_expr_stmt_definition_exprs(expr_stmt):
	A=[]
	for B in expr_stmt.children[:-2:2]:
		if B.type in(_R,'testlist'):A+=_iter_definition_exprs_from_lists(B)
		else:A.append(B)
	return A
def _get_for_stmt_definition_exprs(for_stmt):A=for_stmt.children[1];return list(_iter_definition_exprs_from_lists(A))
def _is_argument_comprehension(argument):return argument.children[1].type in _COMP_FOR_TYPES
def _any_fstring_error(version,node):
	A=node
	if version<(3,9)or A is _B:return _C
	if A.type==_f:return any(A.type=='fstring_start'for A in A.children)
	elif A.type==_O:return _A
	else:return A.search_ancestor(_O)
class _Context:
	def __init__(A,node,add_syntax_error,parent_context=_B):A.node=node;A.blocks=[];A.parent_context=parent_context;A._used_name_dict={};A._global_names=[];A._local_params_names=[];A._nonlocal_names=[];A._nonlocal_names_in_subscopes=[];A._add_syntax_error=add_syntax_error
	def is_async_funcdef(A):return A.is_function()and A.node.parent.type in('async_funcdef','async_stmt')
	def is_function(A):return A.node.type==_J
	def add_name(B,name):
		A=name;C=A.parent.type
		if C==_M:return
		if C=='global_stmt':B._global_names.append(A)
		elif C==_A6:B._nonlocal_names.append(A)
		elif C==_J:B._local_params_names.extend([A.name.value for A in A.parent.get_params()])
		else:B._used_name_dict.setdefault(A.value,[]).append(A)
	def finalize(A):
		'\n        Returns a list of nonlocal names that need to be part of that scope.\n        ';A._analyze_names(A._global_names,'global');A._analyze_names(A._nonlocal_names,'nonlocal');E={A.value:A for A in A._global_names}
		for B in A._nonlocal_names:
			try:C=E[B.value]
			except KeyError:continue
			D="name '%s' is nonlocal and global"%C.value
			if C.start_pos<B.start_pos:F=C
			else:F=B
			A._add_syntax_error(F,D)
		G=[]
		for B in A._nonlocal_names_in_subscopes:
			H=B.value
			if H in A._local_params_names:continue
			if H in E or A.parent_context is _B:D="no binding for nonlocal '%s' found"%B.value;A._add_syntax_error(B,D)
			elif not A.is_function()or B.value not in A._used_name_dict:G.append(B)
		return A._nonlocal_names+G
	def _analyze_names(C,globals_or_nonlocals,type_):
		def E(message):C._add_syntax_error(A,message%(A.value,type_))
		G=[]
		if C.node.type==_J:G=C.node.get_params()
		for A in globals_or_nonlocals:
			F=_C
			for B in reversed(C._used_name_dict.get(A.value,[])):
				if B.start_pos>A.start_pos:F=_A
				D=B.parent
				if D.type=='param'and D.name==B:continue
				if B.is_definition():
					if D.type==_q and D.children[1].type==_r:
						if F:A=B
						E("annotated name '%s' can't be %s");break
					else:H="name '%s' is assigned to before %s declaration"
				else:H="name '%s' is used prior to %s declaration"
				if not F:E(H);break
			for I in G:
				if I.name.value==A.value:E("name '%s' is parameter and %s"),
	@contextmanager
	def add_block(self,node):self.blocks.append(node);yield;self.blocks.pop()
	def add_context(A,node):return _Context(node,A._add_syntax_error,parent_context=A)
	def close_child_context(A,child_context):A._nonlocal_names_in_subscopes+=child_context.finalize()
class ErrorFinder(Normalizer):
	'\n    Searches for errors in the syntax tree.\n    '
	def __init__(A,*B,**C):super().__init__(*B,**C);A._error_dict={};A.version=A.grammar.version_info
	def initialize(A,node):
		def C(node):
			B=node
			if B is _B:return
			D=C(B.parent)
			if B.type in(_P,_J,'file_input'):return _Context(B,A._add_syntax_error,D)
			return D
		A.context=C(node)or _Context(node,A._add_syntax_error);A._indentation_count=0
	def visit(B,node):
		A=node
		if A.type==_f:
			with B.visit_node(A):return''
		return super().visit(A)
	@contextmanager
	def visit_node(self,node):
		C='suite';B=node;A=self;A._check_type_rules(B)
		if B.type in _BLOCK_STMTS:
			with A.context.add_block(B):
				if len(A.context.blocks)==_MAX_BLOCK_SIZE:A._add_syntax_error(B,'too many statically nested blocks')
				yield
			return
		elif B.type==C:
			A._indentation_count+=1
			if A._indentation_count==_MAX_INDENT_COUNT:A._add_indentation_error(B.children[1],'too many levels of indentation')
		yield
		if B.type==C:A._indentation_count-=1
		elif B.type in(_P,_J):D=A.context;A.context=D.parent_context;A.context.close_child_context(D)
	def visit_leaf(C,leaf):
		D='INDENT';A=leaf
		if A.type==_A7:
			if A.token_type in(D,'ERROR_DEDENT'):
				G=list(A.get_next_leaf()._split_prefix())[-1]
				if A.token_type==D:B='unexpected indent'
				else:B='unindent does not match any outer indentation level'
				C._add_indentation_error(G,B)
			else:
				if A.value.startswith('\\'):B='unexpected character after line continuation character'
				else:
					E=re.match('\\w{,2}("{1,3}|\'{1,3})',A.value)
					if E is _B:
						B=_s
						if C.version>=(3,9)and A.value in _get_token_collection(C.version).always_break_tokens:B=_A8+B
					elif len(E.group(1))==1:B='EOL while scanning string literal'
					else:B='EOF while scanning triple-quoted string literal'
				C._add_syntax_error(A,B)
			return''
		elif A.value==':':
			F=A.parent
			if F.type in(_P,_J):C.context=C.context.add_context(F)
		return super().visit_leaf(A)
	def _add_indentation_error(A,spacing,message):A.add_issue(spacing,903,_A9+message)
	def _add_syntax_error(A,node,message):A.add_issue(node,901,_AA+message)
	def add_issue(A,node,code,message):B=node.start_pos[0];C=code,message,node;A._error_dict.setdefault(B,C)
	def finalize(A):
		A.context.finalize()
		for(B,C,D)in A._error_dict.values():A.issues.append(Issue(D,B,C))
class IndentationRule(Rule):
	code=903
	def _get_message(B,message,node):A=message;A=super()._get_message(A,node);return _A9+A
@ErrorFinder.register_rule(type=_f)
class _ExpectIndentedBlock(IndentationRule):
	message='expected an indented block'
	def get_node(B,node):A=node.get_next_leaf();return list(A._split_prefix())[-1]
	def is_issue(A,node):return node.children[-1].type=='newline'
class ErrorFinderConfig(NormalizerConfig):normalizer_class=ErrorFinder
class SyntaxRule(Rule):
	code=901
	def _get_message(B,message,node):
		A=message;A=super()._get_message(A,node)
		if'f-string'not in A and _any_fstring_error(B._normalizer.version,node):A=_A8+A
		return _AA+A
@ErrorFinder.register_rule(type=_f)
class _InvalidSyntaxRule(SyntaxRule):
	message=_s;fstring_message='f-string: invalid syntax'
	def get_node(A,node):return node.get_next_leaf()
	def is_issue(A,node):
		B=node;C=B.get_next_leaf().type!=_A7
		if C and _any_fstring_error(A._normalizer.version,B):A.add_issue(B,message=A.fstring_message)
		else:return C
@ErrorFinder.register_rule(value=_n)
class _AwaitOutsideAsync(SyntaxRule):
	message="'await' outside async function"
	def is_issue(A,leaf):return not A._normalizer.context.is_async_funcdef()
	def get_error_node(A,node):return node.parent
@ErrorFinder.register_rule(value='break')
class _BreakOutsideLoop(SyntaxRule):
	message="'break' outside loop"
	def is_issue(B,leaf):
		A=_C
		for C in B._normalizer.context.blocks:
			if C.type in(_Q,_h):A=_A
		return not A
@ErrorFinder.register_rule(value='continue')
class _ContinueChecks(SyntaxRule):
	message="'continue' not properly in loop";message_in_finally="'continue' not supported inside 'finally' clause"
	def is_issue(A,leaf):
		C=_C
		for B in A._normalizer.context.blocks:
			if B.type in(_Q,_h):C=_A
			if B.type==_i:
				D=B.children[-3]
				if D=='finally'and leaf.start_pos>D.start_pos and A._normalizer.version<(3,8):A.add_issue(leaf,message=A.message_in_finally);return _C
		if not C:return _A
@ErrorFinder.register_rule(value='from')
class _YieldFromCheck(SyntaxRule):
	message="'yield from' inside async function"
	def get_node(A,leaf):return leaf.parent.parent
	def is_issue(A,leaf):return leaf.parent.type=='yield_arg'and A._normalizer.context.is_async_funcdef()
@ErrorFinder.register_rule(type=_K)
class _NameChecks(SyntaxRule):
	message='cannot assign to __debug__';message_none='cannot assign to None'
	def is_issue(B,leaf):
		A=leaf;B._normalizer.context.add_name(A)
		if A.value=='__debug__'and A.is_definition():return _A
@ErrorFinder.register_rule(type=_c)
class _StringChecks(SyntaxRule):
	if sys.version_info<(3,10):message='bytes can only contain ASCII literal characters.'
	else:message='bytes can only contain ASCII literal characters'
	def is_issue(E,leaf):
		A=leaf;B=A.string_prefix.lower()
		if'b'in B and any(A for A in A.value if ord(A)>127):return _A
		if'r'not in B:
			C=A._get_payload()
			if'b'in B:C=C.encode('utf-8');F=codecs.escape_decode
			else:F=codecs.unicode_escape_decode
			try:
				with warnings.catch_warnings():warnings.filterwarnings('ignore');F(C)
			except UnicodeDecodeError as D:E.add_issue(A,message='(unicode error) '+str(D))
			except ValueError as D:E.add_issue(A,message='(value error) '+str(D))
@ErrorFinder.register_rule(value='*')
class _StarCheck(SyntaxRule):
	message='named arguments must follow bare *'
	def is_issue(C,leaf):
		A=leaf.parent
		if A.type==_AB and A:B=A.children[A.children.index(leaf)+1:];B=[A for A in B if A not in(',',')')and not A.star_count];return len(B)==0
@ErrorFinder.register_rule(value=_U)
class _StarStarCheck(SyntaxRule):
	message='dict unpacking cannot be used in dict comprehension'
	def is_issue(B,leaf):
		if leaf.parent.type==_L:A=leaf.get_next_sibling().get_next_sibling();return A is not _B and A.type in _COMP_FOR_TYPES
@ErrorFinder.register_rule(value=_k)
@ErrorFinder.register_rule(value='return')
class _ReturnAndYieldChecks(SyntaxRule):
	message="'return' with value in async generator";message_async_yield="'yield' inside async function"
	def get_node(A,leaf):return leaf.parent
	def is_issue(A,leaf):
		B=leaf
		if A._normalizer.context.node.type!=_J:A.add_issue(A.get_node(B),message="'%s' outside function"%B.value)
		elif A._normalizer.context.is_async_funcdef()and any(A._normalizer.context.node.iter_yield_exprs()):
			if B.value=='return'and B.parent.type=='return_stmt':return _A
@ErrorFinder.register_rule(type=_l)
class _BytesAndStringMix(SyntaxRule):
	message='cannot mix bytes and nonbytes literals'
	def _is_bytes_literal(B,string):
		A=string
		if A.type==_O:return _C
		return'b'in A.string_prefix.lower()
	def is_issue(A,node):
		B=node.children[0];C=A._is_bytes_literal(B)
		for D in node.children[1:]:
			if C!=A._is_bytes_literal(D):return _A
@ErrorFinder.register_rule(type='import_as_names')
class _TrailingImportComma(SyntaxRule):
	message='trailing comma not allowed without surrounding parentheses'
	def is_issue(A,node):
		if node.children[-1]==','and node.parent.children[-1]!=')':return _A
@ErrorFinder.register_rule(type=_p)
class _ImportStarInFunction(SyntaxRule):
	message='import * only allowed at module level'
	def is_issue(A,node):return node.is_star_import()and A._normalizer.context.parent_context is not _B
@ErrorFinder.register_rule(type=_p)
class _FutureImportRule(SyntaxRule):
	message='from __future__ imports must occur at the beginning of the file'
	def is_issue(B,node):
		A=node
		if _is_future_import(A):
			if not _is_future_import_first(A):return _A
			for(H,E)in A.get_paths():
				C=E.value;D=list(ALLOWED_FUTURES)
				if B._normalizer.version>=(3,7):D.append('annotations')
				if C=='braces':B.add_issue(A,message='not a chance')
				elif C=='barry_as_FLUFL':F="Seriously I'm not implementing this :) ~ Dave";B.add_issue(A,message=F)
				elif C not in D:G='future feature %s is not defined'%C;B.add_issue(A,message=G)
@ErrorFinder.register_rule(type=_N)
class _StarExprRule(SyntaxRule):
	message_iterable_unpacking='iterable unpacking cannot be used in comprehension'
	def is_issue(B,node):
		A=node
		def D(node):
			A=node
			while A.parent is not _B:
				A=A.parent
				if A.type=='del_stmt':return _A
				if A.type not in(*_STAR_EXPR_PARENTS,_E):return _C
			return _C
		if B._normalizer.version>=(3,9):C=A.parent
		else:C=_skip_parens_bottom_up(A)
		if C.type not in(*_STAR_EXPR_PARENTS,_L)and not(C.type==_E and C.children[0]!=_D):B.add_issue(A,message=_t);return
		if D(A):
			if B._normalizer.version>=(3,9):B.add_issue(A,message='cannot delete starred')
			else:B.add_issue(A,message=_t)
			return
		if A.parent.type==_H:
			if A.parent.children[1].type in _COMP_FOR_TYPES:B.add_issue(A,message=B.message_iterable_unpacking)
@ErrorFinder.register_rule(types=_STAR_EXPR_PARENTS)
class _StarExprParentRule(SyntaxRule):
	def is_issue(C,node):
		D=node
		def E(node,ancestor):
			A=ancestor
			if A is _B:return _C
			B=A.type
			if B==_M:return _C
			if B==_q:return node.start_pos<A.children[-1].start_pos
			return E(node,A.parent)
		if E(D,D.parent):
			F=[A for A in D.children if A!=','];A=[A for A in F if A.type==_N]
			if len(A)>1:
				if C._normalizer.version<(3,9):B='two starred expressions in assignment'
				else:B='multiple starred expressions in assignment'
				C.add_issue(A[1],message=B)
			elif A:
				G=F.index(A[0])
				if G>=256:B='too many expressions in star-unpacking assignment';C.add_issue(A[0],message=B)
@ErrorFinder.register_rule(type=_r)
class _AnnotatorRule(SyntaxRule):
	message='illegal target for annotation'
	def get_node(A,node):return node.parent
	def is_issue(E,node):
		B=_B;A=node.parent.children[0];A=_remove_parens(A)
		try:C=A.children
		except AttributeError:pass
		else:
			if','in C or A.type==_E and C[0]==_D:B=_Y
			elif A.type==_E and C[0]==_F:B=_j
			D=C[-1]
		if B is _B:
			if not(A.type==_K or A.type in(_d,_e)and D.type==_M and D.children[0]!=_D):return _A
		else:F='only single target (not %s) can be annotated';E.add_issue(A.parent,message=F%B)
@ErrorFinder.register_rule(type='argument')
class _ArgumentRule(SyntaxRule):
	def is_issue(A,node):
		E='expression cannot contain assignment, perhaps you meant "=="?';B=node;C=B.children[0]
		if A._normalizer.version<(3,8):C=_remove_parens(C)
		if B.children[1]=='='and C.type!=_K:
			if C.type==_T:
				if A._normalizer.version<(3,8):D='lambda cannot contain assignment'
				else:D=E
			elif A._normalizer.version<(3,8):D="keyword can't be an expression"
			else:D=E
			A.add_issue(C,message=D)
		if _is_argument_comprehension(B)and B.parent.type==_P:A.add_issue(B,message=_s)
@ErrorFinder.register_rule(type=_A6)
class _NonlocalModuleLevelRule(SyntaxRule):
	message='nonlocal declaration not allowed at module level'
	def is_issue(A,node):return A._normalizer.context.parent_context is _B
@ErrorFinder.register_rule(type='arglist')
class _ArglistRule(SyntaxRule):
	@property
	def message(self):
		if self._normalizer.version<(3,7):return'Generator expression must be parenthesized if not sole argument'
		else:return'Generator expression must be parenthesized'
	def is_issue(D,node):
		F=set();G=_C;E=_C
		for B in node.children:
			if B==',':continue
			if B.type=='argument':
				C=B.children[0]
				if _is_argument_comprehension(B)and len(node.children)>=2:return _A
				if C in('*',_U):
					if C=='*':
						if E:A='iterable argument unpacking follows keyword argument unpacking';D.add_issue(B,message=A)
					else:E=_A
				else:
					G=_A
					if C.type==_K:
						if C.value in F:
							A='keyword argument repeated'
							if D._normalizer.version>=(3,9):A+=': {}'.format(C.value)
							D.add_issue(C,message=A)
						else:F.add(C.value)
			elif E:A='positional argument follows keyword argument unpacking';D.add_issue(B,message=A)
			elif G:A='positional argument follows keyword argument';D.add_issue(B,message=A)
@ErrorFinder.register_rule(type=_AB)
@ErrorFinder.register_rule(type=_T)
class _ParameterRule(SyntaxRule):
	message='non-default argument follows default argument'
	def is_issue(E,node):
		D=set();B=_C;C=_C
		for A in _iter_params(node):
			if A.type==_G:
				if A.value=='*':C=_A;B=_C
				continue
			if A.name.value in D:F="duplicate argument '%s' in function definition";E.add_issue(A.name,message=F%A.name.value)
			D.add(A.name.value)
			if not C:
				if A.default is _B and not A.star_count:
					if B:return _A
				elif A.star_count:C=_A;B=_C
				else:B=_A
@ErrorFinder.register_rule(type=_i)
class _TryStmtRule(SyntaxRule):
	message="default 'except:' must be last"
	def is_issue(C,try_stmt):
		A=_B
		for B in try_stmt.children[3::3]:
			if B in('else','finally'):break
			if B=='except':A=B
			elif A is not _B:C.add_issue(A,message=C.message)
@ErrorFinder.register_rule(type=_O)
class _FStringRule(SyntaxRule):
	_fstring_grammar=_B;message_expr='f-string expression part cannot include a backslash';message_nested='f-string: expressions nested too deeply';message_conversion="f-string: invalid conversion character: expected 's', 'r', or 'a'"
	def _check_format_spec(A,format_spec,depth):A._check_fstring_contents(format_spec.children[1:],depth)
	def _check_fstring_expr(A,fstring_expr,depth):
		E=depth;B=fstring_expr
		if E>=2:A.add_issue(B,message=A.message_nested)
		F=B.children[1]
		if'\\'in F.get_code():A.add_issue(F,message=A.message_expr)
		C=B.children[2]
		if C.type==_G and C.value=='=':D=B.children[3]
		else:D=C
		if D.type=='fstring_conversion':
			G=D.children[1]
			if G.value not in('s','r','a'):A.add_issue(G,message=A.message_conversion)
		H=B.children[-2]
		if H.type=='fstring_format_spec':A._check_format_spec(H,E+1)
	def is_issue(A,fstring):A._check_fstring_contents(fstring.children[1:-1])
	def _check_fstring_contents(B,children,depth=0):
		for A in children:
			if A.type=='fstring_expr':B._check_fstring_expr(A,depth)
class _CheckAssignmentRule(SyntaxRule):
	def _check_assignment(B,node,is_deletion=_C,is_namedexpr=_C,is_aug_assign=_C):
		J=is_aug_assign;H=is_deletion;E=is_namedexpr;C=node;A=_B;D=C.type
		if D==_T:A=_w
		elif D==_E:
			I,F=C.children[:2];A=_get_comprehension_type(C)
			if A is _B:
				if F.type==_L:
					if B._normalizer.version<(3,8):A=_I
					elif F.children[1]==':':
						if B._normalizer.version<(3,10):A=_V
						else:A=_W
					else:A=_X
				elif I=='{'and F=='}':
					if B._normalizer.version<(3,8):A=_I
					elif B._normalizer.version<(3,10):A=_V
					else:A=_W
				elif I=='{'and len(C.children)>2:
					if B._normalizer.version<(3,8):A=_I
					else:A=_X
				elif I in(_D,_F):
					if F.type==_m:A=_a
					elif F.type==_H:
						if E:
							if I==_D:A=_Y
							elif I==_F:A=_j
						for M in F.children[::2]:B._check_assignment(M,H,E,J)
					else:B._check_assignment(F,H,E,J)
		elif D==_Z:
			if C.value==_k:A=_a
			elif B._normalizer.version<(3,8):A=_Z
			else:A=str(C.value)
		elif D==_G:
			if C.value=='...':
				if B._normalizer.version<(3,10):A=_x
				else:A=_y
		elif D==_b:A=_b
		elif D in(_c,_z,_l):A=_I
		elif D==_m:G='assignment to yield expression not possible';B.add_issue(C,message=G)
		elif D=='test':A=_A0
		elif D in(_d,_e):
			if C.children[0]==_n:A=_A1
			elif C.children[-2]==_U:
				if B._normalizer.version<(3,10):A=_G
				else:A=_o
			else:
				K=C.children[-1];assert K.type==_M
				if K.children[0]==_D:A=_A2
				elif E and K.children[0]==_F:A=_A3
				elif E and K.children[0]=='.':A=_A4
		elif D==_O:
			if B._normalizer.version<(3,8):A=_I
			else:A=_A5
		elif D in(_R,_u,'testlist'):
			for M in C.children[::2]:B._check_assignment(M,H,E,J)
		elif'expr'in D and D!=_N or'_test'in D or D in('term','factor'):
			if B._normalizer.version<(3,10):A=_G
			else:A=_o
		elif D==_N:
			if H:
				if B._normalizer.version>=(3,9):A='starred'
				else:B.add_issue(C,message=_t)
			else:
				if B._normalizer.version>=(3,9):L=C.parent
				else:L=_skip_parens_bottom_up(C)
				if L.type not in _STAR_EXPR_PARENTS and not J and not(L.type==_E and L.children[0]==_F):G='starred assignment target must be in a list or tuple';B.add_issue(C,message=G)
			B._check_assignment(C.children[1])
		if A is not _B:
			if E:G='cannot use assignment expressions with %s'%A
			else:N="can't"if B._normalizer.version<(3,8)else'cannot';G=' '.join([N,'delete'if H else'assign to',A])
			B.add_issue(C,message=G)
@ErrorFinder.register_rule(type=_S)
class _CompForRule(_CheckAssignmentRule):
	message='asynchronous comprehension outside of an asynchronous function'
	def is_issue(A,node):
		B=node.children[1]
		if B.type!=_g:A._check_assignment(B)
		return node.parent.children[0]=='async'and not A._normalizer.context.is_async_funcdef()
@ErrorFinder.register_rule(type=_q)
class _ExprStmtRule(_CheckAssignmentRule):
	message='illegal expression for augmented assignment';extended_message="'{target}' is an "+message
	def is_issue(A,node):
		B=node;E=B.children[1];D=E!='='and E.type!=_r
		if A._normalizer.version<=(3,8)or not D:
			for F in B.children[:-2:2]:A._check_assignment(F,is_aug_assign=D)
		if D:
			C=_remove_parens(B.children[0])
			if C.type==_K or C.type in(_d,_e)and C.children[1].type==_M and C.children[-1].children[0]!=_D:return _C
			if A._normalizer.version<=(3,8):return _A
			else:A.add_issue(B,message=A.extended_message.format(target=_get_rhs_name(B.children[0],A._normalizer.version)))
@ErrorFinder.register_rule(type='with_item')
class _WithItemRule(_CheckAssignmentRule):
	def is_issue(A,with_item):A._check_assignment(with_item.children[2])
@ErrorFinder.register_rule(type='del_stmt')
class _DelStmtRule(_CheckAssignmentRule):
	def is_issue(B,del_stmt):
		A=del_stmt.children[1]
		if A.type!=_g:B._check_assignment(A,is_deletion=_A)
@ErrorFinder.register_rule(type=_g)
class _ExprListRule(_CheckAssignmentRule):
	def is_issue(A,expr_list):
		for B in expr_list.children[::2]:A._check_assignment(B)
@ErrorFinder.register_rule(type=_Q)
class _ForStmtRule(_CheckAssignmentRule):
	def is_issue(B,for_stmt):
		A=for_stmt.children[1]
		if A.type!=_g:B._check_assignment(A)
@ErrorFinder.register_rule(type='namedexpr_test')
class _NamedExprRule(_CheckAssignmentRule):
	def is_issue(B,namedexpr_test):
		A=namedexpr_test;D=A.children[0]
		def F(node):
			B=node
			while _A:
				A=B.parent
				if A is _B:return A
				if A.type==_S and A.children[3]==B:return A
				B=A
		if F(A):C='assignment expression cannot be used in a comprehension iterable expression';B.add_issue(A,message=C)
		E=list()
		def G(comp_for):
			A=comp_for
			if A.type==_S:B=A
			elif A.type==_v:B=A.children[1]
			E.extend(_get_for_stmt_definition_exprs(B))
		def H(node):
			A=node;B=_C
			while _A:
				A=A.search_ancestor(_H,_L)
				if A is _B:break
				for C in A.children:
					if C.type in _COMP_FOR_TYPES:G(C);B=_A;break
			return B
		I=H(A)
		if I:
			if B._normalizer.context.node.type==_P:C='assignment expression within a comprehension cannot be used in a class body';B.add_issue(A,message=C)
			J=[A.value for A in E if A.type==_K]
			if D.type==_K and D.value in J:C='assignment expression cannot rebind comprehension iteration variable %r'%D.value;B.add_issue(A,message=C)
		B._check_assignment(D,is_namedexpr=_A)