wL i{dZddlmZddlmZmZmZddlmZdZ ddl Z ddl Z ddl Z ddl Z ddlZddlZddlZddlZddlmZmZddlmZGd d Zgd Zd Zd ZdZdZdZdefdefdefgZej?ddfgdZ GddZ!gdZ"GddZ#d!dZ$edddfdZ%eGddeZ&d Z'y)"aIPython extension to reload modules before executing user code. ``autoreload`` reloads modules automatically before entering the execution of code typed at the IPython prompt. This makes for example the following workflow possible: .. sourcecode:: ipython In [1]: %load_ext autoreload In [2]: %autoreload 2 In [3]: from foo import some_function In [4]: some_function() Out[4]: 42 In [5]: # open foo.py in an editor and change some_function to return 43 In [6]: some_function() Out[6]: 43 The module was reloaded without reloading it explicitly, and the object imported with ``from foo import ...`` was also updated. Usage ===== The following magic commands are provided: ``%autoreload``, ``%autoreload now`` Reload all modules (except those excluded by ``%aimport``) automatically now. ``%autoreload 0``, ``%autoreload off`` Disable automatic reloading. ``%autoreload 1``, ``%autoreload explicit`` Reload all modules imported with ``%aimport`` every time before executing the Python code typed. ``%autoreload 2``, ``%autoreload all`` Reload all modules (except those excluded by ``%aimport``) every time before executing the Python code typed. ``%autoreload 3``, ``%autoreload complete`` Same as 2/all, but also adds any new objects in the module. See unit test at IPython/extensions/tests/test_autoreload.py::test_autoload_newly_added_objects Adding ``--print`` or ``-p`` to the ``%autoreload`` line will print autoreload activity to standard out. ``--log`` or ``-l`` will do it to the log at INFO level; both can be used simultaneously. ``%aimport`` List modules which are to be automatically imported or not to be imported. ``%aimport foo`` Import module 'foo' and mark it to be autoreloaded for ``%autoreload 1`` ``%aimport foo, bar`` Import modules 'foo', 'bar' and mark them to be autoreloaded for ``%autoreload 1`` ``%aimport -foo`` Mark module 'foo' to not be autoreloaded. Import Conflict Resolution ========================== In ``%autoreload 3`` mode, the extension tracks ``from X import Y`` style imports and intelligently resolves conflicts when the same name is imported multiple ways. Import tracking occurs after successful code execution, ensuring that only valid imports are tracked. This approach handles edge cases such as: - Importing a name that doesn't initially exist in a module, then adding that name to the module and importing it again - Conflicts between aliased imports (``from X import Y as Z``) and direct imports (``from X import Z``) When conflicts occur: - If you first do ``from X import Y as Z`` then later ``from X import Z``, the extension will switch to reloading ``Z`` instead of ``Y`` under the name ``Z``. - Similarly, if you first do ``from X import Z`` then later ``from X import Y as Z``, the extension will switch to reloading ``Y`` as ``Z`` instead of the original ``Z``. - The most recent successful import always takes precedence in conflict resolution. Caveats ======= Reloading Python modules in a reliable way is in general difficult, and unexpected things may occur. ``%autoreload`` tries to work around common pitfalls by replacing function code objects and parts of classes previously in the module with new versions. This makes the following things to work: - Functions and classes imported via 'from xxx import foo' are upgraded to new versions when 'xxx' is reloaded. - Methods and properties of classes are upgraded on reload, so that calling 'c.foo()' on an object 'c' created before the reload causes the new code for 'foo' to be executed. Some of the known remaining caveats are: - Replacing code objects does not always succeed: changing a @property in a class to an ordinary method or a method to a member variable can cause problems (but in old objects only). - Functions that are removed (eg. via monkey-patching) from a module before it is reloaded are not upgraded. - C extension modules cannot be reloaded, and so cannot be autoreloaded. - While comparing Enum and Flag, the 'is' Identity Operator is used (even in the case '==' has been used (Similar to the 'None' keyword)). - Reloading a module, or importing the same module by a different name, creates new Enums. These may look the same, but are not. )magic_arguments)Magics magics_class line_magic)DeduperReloaderTN) import_modulereload)source_from_cachecLeZdZdZ dZ dZ d dZdZdZdZ dZ d Z d d Z y) ModuleReloaderFTNci|_i|_i|_i|_i|_||_d|_t|_tii|_ |jddd|_ y)NcyNmsgs c/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/IPython/extensions/autoreload.pyz)ModuleReloader.__init__..TF) check_all do_reload) failedmodules skip_modules old_objectsmodules_mtimesshell_reportrdeduper_reloaderImportFromTrackerimport_from_trackercheck hide_errors)selfrs r__init__zModuleReloader.__init__sr    ( !0 1$5R#<  TU 3!rc\ |j|=d|j|<y#t$rYwxYw)z-Skip reloading the named module in the futureTN)rKeyErrorrr% module_names rmark_module_skippedz"ModuleReloader.mark_module_skippeds9  [)*.+&     ++c\ |j|=d|j|<y#t$rYwxYw)z9Reload the named module in the future (if it is imported)TN)rr(rr)s rmark_module_reloadablez%ModuleReloader.mark_module_reloadables9 !!+.%) [!   r,c&tii|_y)z)Clear the persistent import tracker stateN)r!r"r%s rclear_import_trackerz#ModuleReloader.clear_import_trackers#4R#< rc|j|t||jdd}tj|}||fS)zImport a module, and mark it reloadable Returns ------- top_module : module The imported module if it is top-level, or the top-level top_name : module Name of top_module .r)r.rsplitsysr)r%r*top_name top_modules raimport_modulezModuleReloader.aimport_modulesH ##K0k"$$S)!,[[* 8##rcxt|dr |jyt|dddvry|j}tjj |\}}|j dk(r|}n t|} tj|j}||fS#t$rYywxYw#t$rYywxYw)N__file__)NN__name__)N __mp_main____main__z.py) hasattrr:getattrospathsplitextlowerr ValueErrorstatst_mtimeOSError)r%modulefilenamerAext py_filenamepymtimes rfilename_and_mtimez!ModuleReloader.filename_and_mtimesvz*foo.E 6:t ,0Q Q??GG$$X. c 99;% "K "/9  ggk*33GG## "! "   s$/ B;B- B*)B*- B98B9c |js|sy|s |jr(ttjj }n#t|jj }|j jr |j nd}|D]-}tjj|d}||jvr3|j|\}} |J | |j|kr^ |jj|d| k(r| |j|<|s|jd|d |jr)t!|t"|j$|j&|n7|j(j+|rnt!|t"|j$||jvr |j|=0|j(j9y#t$r| |j|<YgwxYw#|j,s>t/dj1|t3j4dtj6| |j|<YxYw)z/Check whether some modules need to be reloaded.Nz Reloading 'z'.)r"z[autoreload of {} failed: {}] )file)enabledrlistr5rkeysr" imports_fromsgetrrMrrr(r autoload_obj superreloadr rrr maybe_reload_moduler$printformat traceback format_excstderrupdate_sources) r%rrexecution_inforr"modnamemrKrLs rr#zModuleReloader.checks||I  3;;++-.G4<<,,./G)-(@(@(N(ND $ $TX 1 7G .A$+++#'#:#:1#= K" d11'::; ;;??;5@+2D   ( {7)2677((#" ,, JJ0C ..BB1E#Avt/?/?@"dkk1 KK 4Q1 7d ,,.K /6##G, 87++;BB ')=)=b)A"%  07DKK ,s G6BG:G76G7:AIr)FTN) r; __module__ __qualname__rQrrVr&r+r.r1r8rMr#rrrr r s>G*IDL=!8.)=$$$4A/rr )__code__ __defaults____doc__ __closure__ __globals____dict__c ttD]} t||t||y#ttf$rY/wxYw)z%Upgrade the code object of a functionN) func_attrssetattrr?AttributeError TypeError)oldnewnames rupdate_functionrrcsB  CwsD1 2 *   s %77ctj|}|D]'}t||ustj |d|)y)zUse garbage collector to find all instances that refer to the old class definition and update their __class__ to point to the new class definition __class__N)gc get_referrerstypeobject __setattr__)rorprefsrefs rupdate_instancesr|lsA   C D6 9    sK 56rc t|jjD]I}t||} t||}||k(dur$ t|r2 t||t||Kt|jjD]@}|t|jjvs) t||t||Bt||y#t$r& t ||n#tt f$rYnwxYwYt$rYwxYw#tt f$rY wxYw#tt f$rYwxYw)zjReplace stuff in the __dict__ of a class, and upgrade method code objects, and add new methods, if anyTN) rRrirSr?rmdelattrrnrDupdate_genericrlr|)rorpkeyold_objnew_objs r update_classrxsXCLL%%'(#s# c3'G7"t+, '7 +   Cgc3/ 018CLL%%'( d3<<,,./ / S'#s"34S#9  S!"I.       *   #I.  s_C#D=D5# D- C:9D:D  D D  DDDD21D25EEct|j|jt|j|jt|j|jy)z+Replace get/set/del functions of a propertyN)rfdelfgetfset)rorps rupdate_propertyrs8388SXX&388SXX&388SXX&rc6t||xr t||Sr) isinstance)abtyps r isinstance2rs a  4*Q"44rc$t||tSr)rrwrrs rrrs+aD)rc8t||tjSr)rtypes FunctionTypers rrrs+aE$6$67rc$t||tSr)rpropertyrs rrrs+aH-rc8t||tjSr)rr MethodTypers rrrsQ5+;+;<rcBt|j|jSr)rr__func__rs rrrsQZZ@rcHtD]\}}|||s|||yy)NTF) UPDATE_RULES)rr type_checkupdates rrrs1* F a  1aL rceZdZdZdZy) StrongRefc||_yrobj)r%rs rr&zStrongRef.__init__s rc|jSrrr0s r__call__zStrongRef.__call__s xxrN)r;rbrcr&rrrrrrs rr)r;rf __package__ __loader____spec__r: __cached__ __builtins__c4eZdZdedefdZdedededdfd Zy) r!rT symbol_mapc,||_i|_|ry|jD]e\}}i|j|<|jD]>\}}t|tr|dd|j||<,|g|j||<@gy|xsi|_yr)rTritemsrrR)r%rTrr*mappings original_nameresolved_namess rr&zImportFromTracker.__init__s* )3)9)9); W% X/1 ,5=^^5EW1M>!.$7FTUVFW 4]CGUFV 4]C W W).BDOrr*r resolved_namereturnNc||jvrg|j|<||jvri|j|<t|j|jD]c\}}||vs ||k7s|j ||r%||j|vr|j|j ||j||=e||j|vr|j|j |||j|vrg|j||<||j||vr"|j||j |yy)zAdd an import, handling conflicts with existing imports. This method is called after successful code execution, so we know the import is valid. N)rTrrRrremoveappend)r%r*rr orig_name res_namess r add_importzImportFromTracker.add_importsT d00 0.0D  { + doo -+-DOOK (%))E)K)K)M$N @ Iy )i=.H  /! D$6$6{$CC**;7>>yI 4Y? @  2 2; ? ?   { + 2 2= A  < <: >} M Lr)r;rbrcdictr&strrrrrr!r!s? /d / /"N"N/2"NCF"N "Nrr!ct|dxr|j|jk(}|r |s |tvry|sy|j|f} |j |gj t j|y#t$rYywxYw)NrbFT) r>rbr; mod_attrs setdefaultrweakrefr{rn)rHdrqrautoload in_modulers r append_objr s\*Ps~~/PITY. ??D !C  S"$$W[[%56     s4A<< BBc|i}t|jjD]W\}}t||||s|j|f} |j |gj tj|Y |jj}|j} |jj| |jd<|d|jd< ||}t|jjD]%\}} |j|f}||vr|r |jnd} |r |j nd} |F|dk(sAt|||| dr2| r1|j| vr#d| |jvr|| |jvr| rT|| j#|jivr6| j#|ji|} | D]}| |j$|<n| |j$|<g}||D])}|}| |j |t'|| +|r|||<#||=(|S#t$rYwxYw#tttf$rY~wxYw#|jjxYw)a2Enhanced version of the builtin reload function. superreload remembers objects previously in the module, and - upgrades the class dictionary of every old class in the module - upgrades the code object of every old function and method - clears the module's namespace before reloading Nr;rEnumT*)rRrirrr;rrrr{rncopyclearrmr(rrTrrUuser_nsr)rHr rrr"rqrrold_dictold_namerrTrrrnew_refsold_refrs rrWrWs &////12 c&+tS9 %   " "3 + 2 27;;s3C D  ??'')??&. #(0(> % foo3356(! g% k !6I#11d !&+tWdK!=8=#AAM&//$BBdjnnV__b&II!+!DT!J%3;M3:EMM-0;'. d#"3' -GiG OOG $ 7G ,  - 'K C Q(!T M    ~x 0   x( s1 4H;A!I %I&; II I#"I#&Jc eZdZfdZeej ej dedddej ddd d d ej d dd d d ej dd d d ej dd d d ddZeddZ dZ dZ deddfdZ xZ S)AutoreloadMagicsct||i|t|j|_d|j_d|j_ttj|_ y)NF) superr&r r _reloaderrrVsetr5rloaded_modules)r%rkwrts rr&zAutoreloadMagics.__init__~sN !"r"' 3#( &+#!#++.rmodenow?ablank or 'now' - Reload all modules (except those excluded by %%aimport) automatically now. '0' or 'off' - Disable automatic reloading. '1' or 'explicit' - Reload only modules imported with %%aimport every time before executing the Python code typed. '2' or 'all' - Reload all modules (except those excluded by %%aimport) every time before executing the Python code typed. '3' or 'complete' - Same as 2/all, but also adds any new objects in the module. By default, a newer autoreload algorithm that diffs the module's source code with the previous version and only reloads changed parts is applied for modes 2 and below. To use the original algorithm, add the `-` suffix to the mode, e.g. '%autoreload 2-', or pass in --full. )rwdefaultnargshelpz-pz--print store_trueFz1Show autoreload activity using `print` statements)actionrrz-lz--logz)Show autoreload activity using the loggerz --hide-errorszHide autoreload errorsz--fullz$Don't ever use new diffing algorithmctj|j|}|jj }|j }|j drd}|dd}||jj_ ttjd}|jfd}|jdur!|jdurd|j_n_|jdur2|jdur||j_n1|j_n|jdur|j_|j |j_|d k(s|d k(r|jj#dy|d k(s|d k(rd|j_ y|d k(s|dk(r4d|j_ d|j_d|j_y|dk(s|dk(r4d|j_ d|j_d|j_y|dk(s|dk(r4d|j_ d|j_d|j_yt)d|d)a* %autoreload => Reload modules automatically %autoreload or %autoreload now Reload all modules (except those excluded by %aimport) automatically now. %autoreload 0 or %autoreload off Disable automatic reloading. %autoreload 1 or %autoreload explicit Reload only modules imported with %aimport every time before executing the Python code typed. %autoreload 2 or %autoreload all Reload all modules (except those excluded by %aimport) every time before executing the Python code typed. %autoreload 3 or %autoreload complete Same as 2/all, but also but also adds any new objects in the module. See unit test at IPython/extensions/tests/test_autoreload.py::test_autoload_newly_added_objects The optional arguments --print and --log control display of autoreload activity. The default is to act silently; --print (or -p) will print out the names of modules that are being reloaded, and --log (or -l) outputs them to the log at INFO level. The optional argument --hide-errors hides any errors that can happen when trying to reload code. Reloading Python modules in a reliable way is in general difficult, and unexpected things may occur. %autoreload tries to work around common pitfalls by replacing function code objects and parts of classes previously in the module with new versions. This makes the following things to work: - Functions and classes imported via 'from xxx import foo' are upgraded to new versions when 'xxx' is reloaded. - Methods and properties of classes are upgraded on reload, so that calling 'c.foo()' on an object 'c' created before the reload causes the new code for 'foo' to be executed. Some of the known remaining caveats are: - Replacing code objects does not always succeed: changing a @property in a class to an ordinary method or a method to a member variable can cause problems (but in old objects only). - Functions that are removed (eg. via monkey-patching) from a module before it is reloaded are not upgraded. - C extension modules cannot be reloaded, and so cannot be autoreloaded. -FN autoreloadc&||yrr)rlps rplz'AutoreloadMagics.autoreload..pls cF cFrcyrrrs rrz-AutoreloadMagics.autoreload..rrTr0off1explicit2all3completezUnrecognized autoreload mode "z".)rparse_argstringrrrCfullendswithrr rQrYlogging getLoggerinfologrr$r#rrVrD) r%lineargsrenable_deduperreloadloggerrrrs @@rrzAutoreloadMagics.autoreloadsX..tEyy #'99} == #( 9D2F''/ ""<0 KK  :: 488u#4%5DNN " ZZ4 xx4)+&)*& XX %&DNN "%)%5%5" 2: NN  & S[DEM%*DNN " S[DJ.%)DNN "',DNN $*/DNN ' S[DEM%)DNN "'+DNN $*/DNN ' S[DJ.%)DNN "'+DNN $*.DNN '=dV2FG GrNc&|}|st|jjj}t|jjj}|t j }|jjr|jdn#|jddj|z|jddj|zy|jdDcgc]}|jc}D]}}|jdr/|ddj}|jj|C|jj|\}} |jj!| |iycc}w) a"%aimport => Import modules for automatic reloading. %aimport List modules to automatically import and not to import. %aimport foo Import module 'foo' and mark it to be autoreloaded for %autoreload explicit %aimport foo, bar Import modules 'foo', 'bar' and mark them to be autoreloaded for %autoreload explicit %aimport -foo, bar Mark module 'foo' to not be autoreloaded for %autoreload explicit, all, or complete, and 'bar' to be autoreloaded for mode explicit. Nz&Modules to reload: all-except-skipped zModules to reload: %s  z Modules to skip: %s ,r)sortedrrrSrr5stdoutrwritejoinr4strip startswithr+r8rpush) r% parameter_sstreamr` to_reloadto_skip__moduler7r6s raimportzAutoreloadMagics.aimport#s4"t~~55::<=IT^^88==?@G~~~'' GH 7#((9:MMN LL3chhw6GG H/6}}S/AB!AGGIB <%%c*%abk//1GNN66w?+/>>+H+H+Q(JJJOOXz$:; <Bs3Fc||_|jjr |jjyy#YyxYwr)_last_execution_inforrQr#)r%rs r pre_run_cellzAutoreloadMagics.pre_run_cellJs;$(! >> ! ! $$& " s;?c(|jjri|jjrSt|drG|jr;|jj r%|j |jj ttj|jz }|D]M}|jjtj|\}}|5||jj|<O|jj|y)zXCache the modification times of any modules imported in this execution and track importsr N)rrQrVr>r transformed_cell_track_imports_from_coderr5rrrMrr)r%newly_loaded_modulesr`r rLs rpost_execute_hookz"AutoreloadMagics.post_execute_hookTs >> ! !dnn&A&A45---->>---->> #3;;/$2E2EE+ AG::3;;w;OPJAw"9@--g6 A ""#78rcoderc tj|}tj|D]}t|tjs|j }|-|j D]Y}|j}|jr |jn |j}|jjj|||[y#ttf$rYywxYw)z*Track import statements from executed codeN)astparsewalkr ImportFromrHnamesrqasnamerr"r SyntaxErrorrD)r%rtreenodemodrqrrs rrz)AutoreloadMagics._track_imports_from_codeks 99T?D dCNN3++C{ $ )- 7;{{  ::EE   (Z(   sAC A9CCC)r)rN)r;rbrcr&rrargumentrrr rrr __classcell__)rts@rrr|s/$_$$&_  2_  @ _  8 _ %  _ 3  gH  3'jgHR$<$r1sAF)??J$   +,g/g/^  6'T'5 *<87I-?   = @   2N2Nj&t4TUzJvJJZFr