o
    eiCW                     @   s@  d Z ddlZddlZddlmZmZ ddlmZmZm	Z	 ddl
mZmZmZ ddlmZmZmZmZ ddlmZmZmZmZmZ d	d
lmZmZ d	dlmZ er\ddlmZ ddl m!Z! dZ"G dd deZ#G dd deZ$G dd de$Z%G dd de$Z&G dd de$Z'G dd de$Z(G dd de(Z)G dd de$Z*dS )a  
This module provides iterator-related variable tracking functionality for Dynamo.
It implements variable classes for handling Python iterators and itertools functions
during symbolic execution and tracing.

The module includes:
- Base iterator variable classes for tracking iterator state
- Implementations of built-in iterators (zip, map, filter)
- Support for itertools functions (product, accumulate, combinations, etc.)
- Mutation tracking and reconstruction capabilities for iterator operations

These classes integrate with Dynamo's variable tracking system to enable proper
handling of iterator operations during code transformation and optimization.
    N)CallableSequence)AnyTYPE_CHECKINGUnion   )graph_break_hints	polyfills	variables)create_build_tuplecreate_call_functioncreate_call_function_excreate_instruction)handle_observed_exceptionObservedUserStopIterationraise_observed_exceptionunimplemented	UserError   )ValueMutationNewVariableTracker)ConstantVariable)	PyCodegen)InstructionTranslatori  c                       sh   e Zd Zdededdf fddZdefddZdefd	d
Zddded ddddf fddZ	  Z
S )ItertoolsVariablevaluekwargsreturnNc                       t  jdi | || _d S N )super__init__r   )selfr   r   	__class__r    f/var/www/addictedbytheproject.nl/epg/venv/lib/python3.10/site-packages/torch/_dynamo/variables/iter.pyr"   0      
zItertoolsVariable.__init__c                 C   s   d| j  dS )NzItertoolsVariable()r   r#   r    r    r&   __repr__4   s   zItertoolsVariable.__repr__c                 C      | j S Nr)   r*   r    r    r&   as_python_constant7      z$ItertoolsVariable.as_python_constanttxr   argsr   zdict[str, VariableTracker]c                    s&  j tju r[tdd D r0tdd d  d ddt dh  g tj	d	 dv r;d 
 }nd
}fdd D }dd tj|d|iD }tj|t dS j tju rst dkr d r d
  r d } d
 
 }g }t||D ]}|tt| qtj|t dS j tju rtdd D rtdd d  d ddt dh  g tj	d	 dtdtf fddt d
kr d r d }	ntdd d  d d  d ddgtjd	 dv r"dtdtffdd}
ndtdtffd d}
g }z1tj|	|
d!D ]'\}}|tjtj|rLtj|n|tjt|t dgt d q7W n( ty } ztd"d d  d d#g tj|d$ W Y d }~nd }~ww tj|t dS j tju rt dk rtj d%t iS  t!t"j S j tj#u rtj$ d%t iS j tj%u rt d
kst dkr d
  rst dkr d
 
 }nd }d&d t% d &|D }tj|t dS t' ( S )'Nc                 s       | ]}|d kV  qdS )repeatNr    .0kwr    r    r&   	<genexpr>C       z2ItertoolsVariable.call_function.<locals>.<genexpr>z(Unsupported kwargs for itertools.productcall_function  z#Expected kwargs: 'repeat', but got ,r3   gb_typecontextexplanationhintsr   c                    s   g | ]}|  qS r    )force_unpack_var_sequence)r5   argr0   r    r&   
<listcomp>P   s    z3ItertoolsVariable.call_function.<locals>.<listcomp>c                 S      g | ]	}t t|qS r    r
   TupleVariablelistr5   itemr    r    r&   rD   Q       )mutation_typer   r   c                 s   r2   )keyNr    r4   r    r    r&   r7   k   r8   z(Unsupported kwargs for itertools.groupbyz Expected kwargs: 'key', but got rM   r   c                    s`   t | tjr
|  S |  r|  S tdd d  d dtt|  dg t	j
d d S )Nz*Unsupported key type for itertools.groupbyr9   r:   zCDynamo does not know how to trace itertools.groupby with key type: zJ. We only support grouping keys that are constants (int, float, str, etc.)r<   )
isinstancer
   SymNodeVariableevaluate_expris_python_constantr.   r   strtyper   SUPPORTABLErM   )r1   r   r#   r    r&   retrieve_const_keyt   s   

z;ItertoolsVariable.call_function.<locals>.retrieve_const_keyz+Unsupported arguments for itertools.groupbyz?Dynamo does not know how to trace itertools.groupby with args: z and kwargs: ze. itertools.groupby expects an iterable to group and an optional key function to determine groupings.z9Make sure the arguments to itertools.groupby are correct.xc                    s     d| gi S )NrM   )getcall_functionrW   )r   rV   r0   r    r&   keyfunc   s   z0ItertoolsVariable.call_function.<locals>.keyfuncc                    s    | S r-   r    rZ   )rV   r    r&   r[      s   rU   z7Unexpected failure during itertools.groupby() iterationz6Unexpected failure in invoking function during groupby)r=   r>   r?   r@   from_excrL   c                 S   rE   r    rF   rI   r    r    r&   rD      rK   ))r   	itertoolsproductanyr   joinsetkeysr   
USER_ERRORr.   r
   ListIteratorVariabler   combinationslenhas_unpack_var_sequencerQ   unpack_var_sequenceappendrG   rH   groupbyr   r   rT   r   
is_literalcreate	Exceptionr3   RepeatIteratorVariableinline_user_function_returnbuildr	   countCountIteratorVariablepermutationsrA   r!   rY   )r#   r0   r1   r   rseqsitemsiterablerJ   seqr[   resultkver$   )r1   r   rV   r#   r0   r&   rY   :   s  




*zItertoolsVariable.call_function)__name__
__module____qualname__r   r"   rR   r+   r.   r   rY   __classcell__r    r    r$   r&   r   /   s    r   c                
       s   e Zd Zdeddf fddZdddefdd	Zdddee fd
dZddde	egef ddfddZ
dddefddZdddeddf fddZdddedee deeef def
 fddZ  ZS )IteratorVariabler   r   Nc                    s   t  jdi | d S r   )r!   r"   )r#   r   r$   r    r&   r"      s   zIteratorVariable.__init__r0   r   c                 C   s"   t dd|  ddg tjd d S )NzUnimplemented next() callznext(r(   z(This abstract method must be implementedr<   )r   r   
DYNAMO_BUGr#   r0   r    r    r&   next_variable   s   

zIteratorVariable.next_variablec                 C   s   g }|  ||j |S r-   )force_apply_to_var_sequenceri   )r#   r0   ry   r    r    r&   rA      s   z*IteratorVariable.force_unpack_var_sequencefnc                 C   s4   	 z	||  | W n ty   t| Y d S w qr-   )r   r   r   )r#   r0   r   r    r    r&   r      s   z,IteratorVariable.force_apply_to_var_sequencec                 C      dS NTr    r   r    r    r&   has_force_unpack_var_sequence     z.IteratorVariable.has_force_unpack_var_sequencenamer   c                    s*   |dks|dkrt jdS t ||S )N__iter____next__T)r
   r   rl   r!   call_obj_hasattr)r#   r0   r   r$   r    r&   r     s   z!IteratorVariable.call_obj_hasattrr1   c                    s0   |dkr| S |dkr|  |S t ||||S )Nr   r   )r   r!   call_method)r#   r0   r   r1   r   r$   r    r&   r     s
   
zIteratorVariable.call_method)r}   r~   r   r   r"   r   r   rH   rA   r   r   boolr   rR   r   dictr   r   r    r    r$   r&   r      sD    


r   c                       s@   e Zd ZdZdededdf fddZdd	defd
dZ  ZS )ObjectIteratorVariableaZ  
    VariableTracker for iter(obj) that implements the iterator protocol (i.e.,
    has a `__next__` method).

    We use this class to track the state of the iterator and handle the case
    when the iterator is exhausted:

    Example usage:
        > b = iter(obj)
        > list(b)  # exhaust the iterator
        > list(b)  # empty list
    objr   r   Nc                    s"   t  jdi | || _d| _d S )NFr    )r!   r"   r   generator_exhausted)r#   r   r   r$   r    r&   r"   +  s   
zObjectIteratorVariable.__init__r0   r   c                 C   s6   | j rtt| z| j|W S  ty   d| _  w r   )r   r   StopIterationr   r   r   r   r    r    r&   r   0  s   
z$ObjectIteratorVariable.next_variable)	r}   r~   r   __doc__r   r   r"   r   r   r    r    r$   r&   r     s    r   c                       sF   e Zd Zdededdf fddZdddefd	d
ZdddZ  ZS )rn   rJ   r   r   Nc                    r   r   )r!   r"   rJ   )r#   rJ   r   r$   r    r&   r"   >  r'   zRepeatIteratorVariable.__init__r0   r   c                 C   r,   r-   )rJ   r   r    r    r&   r   C  r/   z$RepeatIteratorVariable.next_variablecodegenr   c                    s0      fdd  | j  tdd d S )Nc                            t dgS )Nr3   extend_outputcreate_load_python_moduler]   create_load_attrr    r   r    r&   <lambda>H  
    z4RepeatIteratorVariable.reconstruct.<locals>.<lambda>r   F)add_push_nullrJ   r   r   r#   r   r    r   r&   reconstructF  s
   

z"RepeatIteratorVariable.reconstructr   r   r   N)	r}   r~   r   r   r   r"   r   r   r   r    r    r$   r&   rn   =  s    rn   c                	       s`   e Zd Z		ddeeef deeef deddf fdd	Zd
ddefddZdddZ	  Z
S )rr   r   r   rJ   stepr   r   Nc                    sJ   t  jdi | t|tst|}t|tst|}|| _|| _d S r   )r!   r"   rN   r   r   rl   rJ   r   )r#   rJ   r   r   r$   r    r&   r"   T  s   




zCountIteratorVariable.__init__r0   r   c                 C   s<   |   sJ | j}|jj|  | j|d| jgi | _|S )N__add__)
is_mutablerJ   outputside_effectsmutationr   r   )r#   r0   old_itemr    r    r&   r   b  s
   z#CountIteratorVariable.next_variabler   r   c                    s:      fdd  | j  | j  tdd d S )Nc                      r   )Nrq   r   r    r   r    r&   r   k  r   z3CountIteratorVariable.reconstruct.<locals>.<lambda>r   F)r   rJ   r   r   r   r   r    r   r&   r   i  s   


z!CountIteratorVariable.reconstruct)r   r   r   )r}   r~   r   r   intr   r   r"   r   r   r   r    r    r$   r&   rr   S  s    

rr   c                	       s   e Zd ZdZddhejZ	ddee dede	ddf fd	d
Z
dee fddZdddefddZddded fddZdddefddZdddZdddZ  ZS )ZipVariablez$
    Represents zip(*iterables)
    indexstrictF	iterablesr   r   Nc                    s6   t  jdi | t|tsJ || _d| _|| _d S Nr   r    )r!   r"   rN   rH   r   r   r   )r#   r   r   r   r$   r    r&   r"     s
   
zZipVariable.__init__c                 C      t S r-   )zipr*   r    r    r&   python_type  r   zZipVariable.python_typer0   r   c                    s   t  fdd| jD S )Nc                 3   s$    | ]}t |tp| V  qd S r-   )rN   rH   rg   )r5   itrC   r    r&   r7     s
    
z6ZipVariable.has_unpack_var_sequence.<locals>.<genexpr>)allr   r   r    rC   r&   rg     s   z#ZipVariable.has_unpack_var_sequencer   c                 C   s~   |  |sJ g }| jD ]}t|tr||| jd   q||| q| jr/d| jini }t|i |}dd |D S )Nr   c                 S   rE   r    rF   )r5   varr    r    r&   rD     s    z3ZipVariable.unpack_var_sequence.<locals>.<listcomp>)	rg   r   rN   rH   ri   r   rh   r   r   )r#   r0   r   r   r   zippedr    r    r&   rh     s   

zZipVariable.unpack_var_sequencec                    s  |   sJ t| jdkrtt | j g }dttt tf dtf fdd}d }zt	| jD ]\}}|
|| q1W n5 tys   | jrr|dkrh| jD ]}z|| W n tyd   t Y qOw  n t ttdd  w jj|  |  jd7  _t|S )Nr   r   r   c                    s2   t | tr t| krtt |   S | S r-   )rN   rH   rf   r   r   r   )r   	old_indexr0   r    r&   get_item  s
   


z+ZipVariable.next_variable.<locals>.get_itemz3zip() has one argument of len differing from othersr   )r   rf   r   r   r   r   r   rH   r   	enumerateri   r   r   r   r   
ValueErrorr   r   r   r
   rG   )r#   r0   r1   r   idxr   r    r   r&   r     sN   



zZipVariable.next_variabler   r   c                 C   sN   | j D ]!}t|tr || jd  }|| |tt| q|| qd S r-   )r   rN   rH   r   foreachappend_outputr   rf   )r#   r   r   remaining_itemsr    r    r&   reconstruct_items  s   



zZipVariable.reconstruct_itemsc                    sh    j  fdddd |    tt| j   d | jt	dddgt
dd	 d S )
Nc                           ddS )Nbuiltinsr   load_import_fromr    r   r    r&   r         z)ZipVariable.reconstruct.<locals>.<lambda>Tcall_function_exr   	BUILD_MAPr   rB   F)r   r   r   r   rf   r   r   create_load_constr   r   r   r   r    r   r&   r     s   


zZipVariable.reconstruct)Fr   )r}   r~   r   r   r   _nonvar_fieldsrH   r   r   r   r"   rS   r   r   rg   rh   r   r   r   r   r    r    r$   r&   r   w  s6    	

1	r   c                       sv   e Zd ZdZdedee deddf fddZdefd	d
Z	ddde
fddZdddef fddZdddZ  ZS )MapVariablez(
    Represents map(fn, *iterables)
    r   r   r   r   Nc                    s   t  j|fi | || _d S r-   )r!   r"   r   )r#   r   r   r   r$   r    r&   r"     s   
zMapVariable.__init__c                 C   r   r-   )mapr*   r    r    r&   r     r   zMapVariable.python_typer0   r   c                 C   r   )NFr    r   r    r    r&   rg     r   z#MapVariable.has_unpack_var_sequencec                    s   t  |}| j||ji S r-   )r!   r   r   rY   rv   )r#   r0   r1   r$   r    r&   r     s   zMapVariable.next_variabler   r   c                    s    j  fdddd  | j |    tt| jd  | jrGtj	dks-J d 
 d | jtd	dd
gtdd d S  
tdd d S )Nc                      r   )Nr   r   r   r    r   r    r&   r   
  r   z)MapVariable.reconstruct.<locals>.<lambda>Tr   r   )      z6Unexpected bug: map(strict=True) requires Python 3.14+r   r   r   F)r   r   r   r   r   rf   r   r   sysversion_infor   r   r   r   r   r    r   r&   r     s&   



	zMapVariable.reconstructr   )r}   r~   r   r   r   rH   r   r"   rS   r   r   rg   r   r   r   r    r    r$   r&   r     s    	r   c                       s   e Zd ZdZdhejZdedee deddf fdd	Z	de
fd
dZdddefddZddded fddZdddefddZdddZdddZ  ZS )FilterVariablez)
    Represents filter(fn, iterable)
    r   r   rw   r   r   Nc                    s(   t  jdi | || _|| _d| _d S r   )r!   r"   r   rw   r   )r#   r   rw   r   r$   r    r&   r"   )  s   
zFilterVariable.__init__c                 C   r   r-   )filterr*   r    r    r&   r   4  r   zFilterVariable.python_typer0   r   c                 C   s   t | jtp| j|S r-   )rN   rw   rH   rg   r   r    r    r&   rg   7  s   z&FilterVariable.has_unpack_var_sequencer   c                 C   sZ   |  |sJ d }t| jtr| j| jd  }n| j|}| j||i }t	|ggS r-   )
rg   rN   rw   rH   r   rh   r   rY   r
   rG   )r#   r0   r   filteredr    r    r&   rh   <  s   z"FilterVariable.unpack_var_sequencec                    sr   dt f fdd}	 | }  jd7  _ j r|}n	 j|gi }ttj|gi }|	 r8|S q)Nr   c                     s@    j } t jtr| t jkrtt  j|  S  jS r-   )r   rN   rw   rH   rf   r   r   r   )r   r   r    r&   _nextI  s   

z+FilterVariable.next_variable.<locals>._nextTr   )
r   r   r   is_constant_nonerY   r
   UserFunctionVariabler	   	predicater.   )r#   r0   r   rJ   respred_resr    r   r&   r   H  s   

zFilterVariable.next_variabler   r   c                 C   sJ   t | jtr| j| jd  }|| |tt| d S || j d S r-   )rN   rw   rH   r   r   r   r   rf   )r#   r   r   r    r    r&   r   `  s
   
z FilterVariable.reconstruct_itemsc                    s:      fdd  | j |    tdd d S )Nc                      r   )Nr   r   r   r    r   r    r&   r   i  r   z,FilterVariable.reconstruct.<locals>.<lambda>r   F)r   r   r   r   r   r   r    r   r&   r   h  s   

zFilterVariable.reconstructr   )r}   r~   r   r   r   r   r   rH   r   r"   rS   r   r   rg   rh   r   r   r   r   r    r    r$   r&   r     s2    

r   )+r   r]   r   collections.abcr   r   typingr   r   r    r   r	   r
   bytecode_transformationr   r   r   r   excr   r   r   r   r   baser   r   constantr   torch._dynamo.codegenr   torch._dynamo.symbolic_convertr   MAX_ITERATOR_LIMITr   r   r   rn   rr   r   r   r   r    r    r    r&   <module>   s.     4; $y/