ExprNodes.py 526 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498
  1. #
  2. # Parse tree nodes for expressions
  3. #
  4. from __future__ import absolute_import
  5. import cython
  6. cython.declare(error=object, warning=object, warn_once=object, InternalError=object,
  7. CompileError=object, UtilityCode=object, TempitaUtilityCode=object,
  8. StringEncoding=object, operator=object, local_errors=object, report_error=object,
  9. Naming=object, Nodes=object, PyrexTypes=object, py_object_type=object,
  10. list_type=object, tuple_type=object, set_type=object, dict_type=object,
  11. unicode_type=object, str_type=object, bytes_type=object, type_type=object,
  12. Builtin=object, Symtab=object, Utils=object, find_coercion_error=object,
  13. debug_disposal_code=object, debug_temp_alloc=object, debug_coercion=object,
  14. bytearray_type=object, slice_type=object, _py_int_types=object,
  15. IS_PYTHON3=cython.bint)
  16. import re
  17. import sys
  18. import copy
  19. import os.path
  20. import operator
  21. from .Errors import (
  22. error, warning, InternalError, CompileError, report_error, local_errors)
  23. from .Code import UtilityCode, TempitaUtilityCode
  24. from . import StringEncoding
  25. from . import Naming
  26. from . import Nodes
  27. from .Nodes import Node, utility_code_for_imports, analyse_type_annotation
  28. from . import PyrexTypes
  29. from .PyrexTypes import py_object_type, c_long_type, typecast, error_type, \
  30. unspecified_type
  31. from . import TypeSlots
  32. from .Builtin import list_type, tuple_type, set_type, dict_type, type_type, \
  33. unicode_type, str_type, bytes_type, bytearray_type, basestring_type, slice_type
  34. from . import Builtin
  35. from . import Symtab
  36. from .. import Utils
  37. from .Annotate import AnnotationItem
  38. from . import Future
  39. from ..Debugging import print_call_chain
  40. from .DebugFlags import debug_disposal_code, debug_temp_alloc, \
  41. debug_coercion
  42. from .Pythran import to_pythran, is_pythran_supported_type, is_pythran_supported_operation_type, \
  43. is_pythran_expr, pythran_func_type, pythran_binop_type, pythran_unaryop_type, has_np_pythran, \
  44. pythran_indexing_code, pythran_indexing_type, is_pythran_supported_node_or_none, pythran_type
  45. from .PyrexTypes import PythranExpr
  46. try:
  47. from __builtin__ import basestring
  48. except ImportError:
  49. # Python 3
  50. basestring = str
  51. any_string_type = (bytes, str)
  52. else:
  53. # Python 2
  54. any_string_type = (bytes, unicode)
  55. if sys.version_info[0] >= 3:
  56. IS_PYTHON3 = True
  57. _py_int_types = int
  58. else:
  59. IS_PYTHON3 = False
  60. _py_int_types = (int, long)
  61. class NotConstant(object):
  62. _obj = None
  63. def __new__(cls):
  64. if NotConstant._obj is None:
  65. NotConstant._obj = super(NotConstant, cls).__new__(cls)
  66. return NotConstant._obj
  67. def __repr__(self):
  68. return "<NOT CONSTANT>"
  69. not_a_constant = NotConstant()
  70. constant_value_not_set = object()
  71. # error messages when coercing from key[0] to key[1]
  72. coercion_error_dict = {
  73. # string related errors
  74. (unicode_type, str_type): ("Cannot convert Unicode string to 'str' implicitly."
  75. " This is not portable and requires explicit encoding."),
  76. (unicode_type, bytes_type): "Cannot convert Unicode string to 'bytes' implicitly, encoding required.",
  77. (unicode_type, PyrexTypes.c_char_ptr_type): "Unicode objects only support coercion to Py_UNICODE*.",
  78. (unicode_type, PyrexTypes.c_const_char_ptr_type): "Unicode objects only support coercion to Py_UNICODE*.",
  79. (unicode_type, PyrexTypes.c_uchar_ptr_type): "Unicode objects only support coercion to Py_UNICODE*.",
  80. (unicode_type, PyrexTypes.c_const_uchar_ptr_type): "Unicode objects only support coercion to Py_UNICODE*.",
  81. (bytes_type, unicode_type): "Cannot convert 'bytes' object to unicode implicitly, decoding required",
  82. (bytes_type, str_type): "Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.",
  83. (bytes_type, basestring_type): ("Cannot convert 'bytes' object to basestring implicitly."
  84. " This is not portable to Py3."),
  85. (bytes_type, PyrexTypes.c_py_unicode_ptr_type): "Cannot convert 'bytes' object to Py_UNICODE*, use 'unicode'.",
  86. (bytes_type, PyrexTypes.c_const_py_unicode_ptr_type): (
  87. "Cannot convert 'bytes' object to Py_UNICODE*, use 'unicode'."),
  88. (basestring_type, bytes_type): "Cannot convert 'basestring' object to bytes implicitly. This is not portable.",
  89. (str_type, unicode_type): ("str objects do not support coercion to unicode,"
  90. " use a unicode string literal instead (u'')"),
  91. (str_type, bytes_type): "Cannot convert 'str' to 'bytes' implicitly. This is not portable.",
  92. (str_type, PyrexTypes.c_char_ptr_type): "'str' objects do not support coercion to C types (use 'bytes'?).",
  93. (str_type, PyrexTypes.c_const_char_ptr_type): "'str' objects do not support coercion to C types (use 'bytes'?).",
  94. (str_type, PyrexTypes.c_uchar_ptr_type): "'str' objects do not support coercion to C types (use 'bytes'?).",
  95. (str_type, PyrexTypes.c_const_uchar_ptr_type): "'str' objects do not support coercion to C types (use 'bytes'?).",
  96. (str_type, PyrexTypes.c_py_unicode_ptr_type): "'str' objects do not support coercion to C types (use 'unicode'?).",
  97. (str_type, PyrexTypes.c_const_py_unicode_ptr_type): (
  98. "'str' objects do not support coercion to C types (use 'unicode'?)."),
  99. (PyrexTypes.c_char_ptr_type, unicode_type): "Cannot convert 'char*' to unicode implicitly, decoding required",
  100. (PyrexTypes.c_const_char_ptr_type, unicode_type): (
  101. "Cannot convert 'char*' to unicode implicitly, decoding required"),
  102. (PyrexTypes.c_uchar_ptr_type, unicode_type): "Cannot convert 'char*' to unicode implicitly, decoding required",
  103. (PyrexTypes.c_const_uchar_ptr_type, unicode_type): (
  104. "Cannot convert 'char*' to unicode implicitly, decoding required"),
  105. }
  106. def find_coercion_error(type_tuple, default, env):
  107. err = coercion_error_dict.get(type_tuple)
  108. if err is None:
  109. return default
  110. elif (env.directives['c_string_encoding'] and
  111. any(t in type_tuple for t in (PyrexTypes.c_char_ptr_type, PyrexTypes.c_uchar_ptr_type,
  112. PyrexTypes.c_const_char_ptr_type, PyrexTypes.c_const_uchar_ptr_type))):
  113. if type_tuple[1].is_pyobject:
  114. return default
  115. elif env.directives['c_string_encoding'] in ('ascii', 'default'):
  116. return default
  117. else:
  118. return "'%s' objects do not support coercion to C types with non-ascii or non-default c_string_encoding" % type_tuple[0].name
  119. else:
  120. return err
  121. def default_str_type(env):
  122. return {
  123. 'bytes': bytes_type,
  124. 'bytearray': bytearray_type,
  125. 'str': str_type,
  126. 'unicode': unicode_type
  127. }.get(env.directives['c_string_type'])
  128. def check_negative_indices(*nodes):
  129. """
  130. Raise a warning on nodes that are known to have negative numeric values.
  131. Used to find (potential) bugs inside of "wraparound=False" sections.
  132. """
  133. for node in nodes:
  134. if node is None or (
  135. not isinstance(node.constant_result, _py_int_types) and
  136. not isinstance(node.constant_result, float)):
  137. continue
  138. if node.constant_result < 0:
  139. warning(node.pos,
  140. "the result of using negative indices inside of "
  141. "code sections marked as 'wraparound=False' is "
  142. "undefined", level=1)
  143. def infer_sequence_item_type(env, seq_node, index_node=None, seq_type=None):
  144. if not seq_node.is_sequence_constructor:
  145. if seq_type is None:
  146. seq_type = seq_node.infer_type(env)
  147. if seq_type is tuple_type:
  148. # tuples are immutable => we can safely follow assignments
  149. if seq_node.cf_state and len(seq_node.cf_state) == 1:
  150. try:
  151. seq_node = seq_node.cf_state[0].rhs
  152. except AttributeError:
  153. pass
  154. if seq_node is not None and seq_node.is_sequence_constructor:
  155. if index_node is not None and index_node.has_constant_result():
  156. try:
  157. item = seq_node.args[index_node.constant_result]
  158. except (ValueError, TypeError, IndexError):
  159. pass
  160. else:
  161. return item.infer_type(env)
  162. # if we're lucky, all items have the same type
  163. item_types = set([item.infer_type(env) for item in seq_node.args])
  164. if len(item_types) == 1:
  165. return item_types.pop()
  166. return None
  167. def get_exception_handler(exception_value):
  168. if exception_value is None:
  169. return "__Pyx_CppExn2PyErr();"
  170. elif exception_value.type.is_pyobject:
  171. return 'try { throw; } catch(const std::exception& exn) { PyErr_SetString(%s, exn.what()); } catch(...) { PyErr_SetNone(%s); }' % (
  172. exception_value.entry.cname,
  173. exception_value.entry.cname)
  174. else:
  175. return '%s(); if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError , "Error converting c++ exception.");' % exception_value.entry.cname
  176. def translate_cpp_exception(code, pos, inside, exception_value, nogil):
  177. raise_py_exception = get_exception_handler(exception_value)
  178. code.putln("try {")
  179. code.putln("%s" % inside)
  180. code.putln("} catch(...) {")
  181. if nogil:
  182. code.put_ensure_gil(declare_gilstate=True)
  183. code.putln(raise_py_exception)
  184. if nogil:
  185. code.put_release_ensured_gil()
  186. code.putln(code.error_goto(pos))
  187. code.putln("}")
  188. # Used to handle the case where an lvalue expression and an overloaded assignment
  189. # both have an exception declaration.
  190. def translate_double_cpp_exception(code, pos, lhs_type, lhs_code, rhs_code,
  191. lhs_exc_val, assign_exc_val, nogil):
  192. handle_lhs_exc = get_exception_handler(lhs_exc_val)
  193. handle_assignment_exc = get_exception_handler(assign_exc_val)
  194. code.putln("try {")
  195. code.putln(lhs_type.declaration_code("__pyx_local_lvalue = %s;" % lhs_code))
  196. code.putln("try {")
  197. code.putln("__pyx_local_lvalue = %s;" % rhs_code)
  198. # Catch any exception from the overloaded assignment.
  199. code.putln("} catch(...) {")
  200. if nogil:
  201. code.put_ensure_gil(declare_gilstate=True)
  202. code.putln(handle_assignment_exc)
  203. if nogil:
  204. code.put_release_ensured_gil()
  205. code.putln(code.error_goto(pos))
  206. code.putln("}")
  207. # Catch any exception from evaluating lhs.
  208. code.putln("} catch(...) {")
  209. if nogil:
  210. code.put_ensure_gil(declare_gilstate=True)
  211. code.putln(handle_lhs_exc)
  212. if nogil:
  213. code.put_release_ensured_gil()
  214. code.putln(code.error_goto(pos))
  215. code.putln('}')
  216. class ExprNode(Node):
  217. # subexprs [string] Class var holding names of subexpr node attrs
  218. # type PyrexType Type of the result
  219. # result_code string Code fragment
  220. # result_ctype string C type of result_code if different from type
  221. # is_temp boolean Result is in a temporary variable
  222. # is_sequence_constructor
  223. # boolean Is a list or tuple constructor expression
  224. # is_starred boolean Is a starred expression (e.g. '*a')
  225. # saved_subexpr_nodes
  226. # [ExprNode or [ExprNode or None] or None]
  227. # Cached result of subexpr_nodes()
  228. # use_managed_ref boolean use ref-counted temps/assignments/etc.
  229. # result_is_used boolean indicates that the result will be dropped and the
  230. # is_numpy_attribute boolean Is a Numpy module attribute
  231. # result_code/temp_result can safely be set to None
  232. # annotation ExprNode or None PEP526 annotation for names or expressions
  233. result_ctype = None
  234. type = None
  235. annotation = None
  236. temp_code = None
  237. old_temp = None # error checker for multiple frees etc.
  238. use_managed_ref = True # can be set by optimisation transforms
  239. result_is_used = True
  240. is_numpy_attribute = False
  241. # The Analyse Expressions phase for expressions is split
  242. # into two sub-phases:
  243. #
  244. # Analyse Types
  245. # Determines the result type of the expression based
  246. # on the types of its sub-expressions, and inserts
  247. # coercion nodes into the expression tree where needed.
  248. # Marks nodes which will need to have temporary variables
  249. # allocated.
  250. #
  251. # Allocate Temps
  252. # Allocates temporary variables where needed, and fills
  253. # in the result_code field of each node.
  254. #
  255. # ExprNode provides some convenience routines which
  256. # perform both of the above phases. These should only
  257. # be called from statement nodes, and only when no
  258. # coercion nodes need to be added around the expression
  259. # being analysed. In that case, the above two phases
  260. # should be invoked separately.
  261. #
  262. # Framework code in ExprNode provides much of the common
  263. # processing for the various phases. It makes use of the
  264. # 'subexprs' class attribute of ExprNodes, which should
  265. # contain a list of the names of attributes which can
  266. # hold sub-nodes or sequences of sub-nodes.
  267. #
  268. # The framework makes use of a number of abstract methods.
  269. # Their responsibilities are as follows.
  270. #
  271. # Declaration Analysis phase
  272. #
  273. # analyse_target_declaration
  274. # Called during the Analyse Declarations phase to analyse
  275. # the LHS of an assignment or argument of a del statement.
  276. # Nodes which cannot be the LHS of an assignment need not
  277. # implement it.
  278. #
  279. # Expression Analysis phase
  280. #
  281. # analyse_types
  282. # - Call analyse_types on all sub-expressions.
  283. # - Check operand types, and wrap coercion nodes around
  284. # sub-expressions where needed.
  285. # - Set the type of this node.
  286. # - If a temporary variable will be required for the
  287. # result, set the is_temp flag of this node.
  288. #
  289. # analyse_target_types
  290. # Called during the Analyse Types phase to analyse
  291. # the LHS of an assignment or argument of a del
  292. # statement. Similar responsibilities to analyse_types.
  293. #
  294. # target_code
  295. # Called by the default implementation of allocate_target_temps.
  296. # Should return a C lvalue for assigning to the node. The default
  297. # implementation calls calculate_result_code.
  298. #
  299. # check_const
  300. # - Check that this node and its subnodes form a
  301. # legal constant expression. If so, do nothing,
  302. # otherwise call not_const.
  303. #
  304. # The default implementation of check_const
  305. # assumes that the expression is not constant.
  306. #
  307. # check_const_addr
  308. # - Same as check_const, except check that the
  309. # expression is a C lvalue whose address is
  310. # constant. Otherwise, call addr_not_const.
  311. #
  312. # The default implementation of calc_const_addr
  313. # assumes that the expression is not a constant
  314. # lvalue.
  315. #
  316. # Code Generation phase
  317. #
  318. # generate_evaluation_code
  319. # - Call generate_evaluation_code for sub-expressions.
  320. # - Perform the functions of generate_result_code
  321. # (see below).
  322. # - If result is temporary, call generate_disposal_code
  323. # on all sub-expressions.
  324. #
  325. # A default implementation of generate_evaluation_code
  326. # is provided which uses the following abstract methods:
  327. #
  328. # generate_result_code
  329. # - Generate any C statements necessary to calculate
  330. # the result of this node from the results of its
  331. # sub-expressions.
  332. #
  333. # calculate_result_code
  334. # - Should return a C code fragment evaluating to the
  335. # result. This is only called when the result is not
  336. # a temporary.
  337. #
  338. # generate_assignment_code
  339. # Called on the LHS of an assignment.
  340. # - Call generate_evaluation_code for sub-expressions.
  341. # - Generate code to perform the assignment.
  342. # - If the assignment absorbed a reference, call
  343. # generate_post_assignment_code on the RHS,
  344. # otherwise call generate_disposal_code on it.
  345. #
  346. # generate_deletion_code
  347. # Called on an argument of a del statement.
  348. # - Call generate_evaluation_code for sub-expressions.
  349. # - Generate code to perform the deletion.
  350. # - Call generate_disposal_code on all sub-expressions.
  351. #
  352. #
  353. is_sequence_constructor = False
  354. is_dict_literal = False
  355. is_set_literal = False
  356. is_string_literal = False
  357. is_attribute = False
  358. is_subscript = False
  359. is_slice = False
  360. is_buffer_access = False
  361. is_memview_index = False
  362. is_memview_slice = False
  363. is_memview_broadcast = False
  364. is_memview_copy_assignment = False
  365. saved_subexpr_nodes = None
  366. is_temp = False
  367. is_target = False
  368. is_starred = False
  369. constant_result = constant_value_not_set
  370. child_attrs = property(fget=operator.attrgetter('subexprs'))
  371. def not_implemented(self, method_name):
  372. print_call_chain(method_name, "not implemented") ###
  373. raise InternalError(
  374. "%s.%s not implemented" %
  375. (self.__class__.__name__, method_name))
  376. def is_lvalue(self):
  377. return 0
  378. def is_addressable(self):
  379. return self.is_lvalue() and not self.type.is_memoryviewslice
  380. def is_ephemeral(self):
  381. # An ephemeral node is one whose result is in
  382. # a Python temporary and we suspect there are no
  383. # other references to it. Certain operations are
  384. # disallowed on such values, since they are
  385. # likely to result in a dangling pointer.
  386. return self.type.is_pyobject and self.is_temp
  387. def subexpr_nodes(self):
  388. # Extract a list of subexpression nodes based
  389. # on the contents of the subexprs class attribute.
  390. nodes = []
  391. for name in self.subexprs:
  392. item = getattr(self, name)
  393. if item is not None:
  394. if type(item) is list:
  395. nodes.extend(item)
  396. else:
  397. nodes.append(item)
  398. return nodes
  399. def result(self):
  400. if self.is_temp:
  401. #if not self.temp_code:
  402. # pos = (os.path.basename(self.pos[0].get_description()),) + self.pos[1:] if self.pos else '(?)'
  403. # raise RuntimeError("temp result name not set in %s at %r" % (
  404. # self.__class__.__name__, pos))
  405. return self.temp_code
  406. else:
  407. return self.calculate_result_code()
  408. def pythran_result(self, type_=None):
  409. if is_pythran_supported_node_or_none(self):
  410. return to_pythran(self)
  411. assert(type_ is not None)
  412. return to_pythran(self, type_)
  413. def is_c_result_required(self):
  414. """
  415. Subtypes may return False here if result temp allocation can be skipped.
  416. """
  417. return True
  418. def result_as(self, type = None):
  419. # Return the result code cast to the specified C type.
  420. if (self.is_temp and self.type.is_pyobject and
  421. type != py_object_type):
  422. # Allocated temporaries are always PyObject *, which may not
  423. # reflect the actual type (e.g. an extension type)
  424. return typecast(type, py_object_type, self.result())
  425. return typecast(type, self.ctype(), self.result())
  426. def py_result(self):
  427. # Return the result code cast to PyObject *.
  428. return self.result_as(py_object_type)
  429. def ctype(self):
  430. # Return the native C type of the result (i.e. the
  431. # C type of the result_code expression).
  432. return self.result_ctype or self.type
  433. def get_constant_c_result_code(self):
  434. # Return the constant value of this node as a result code
  435. # string, or None if the node is not constant. This method
  436. # can be called when the constant result code is required
  437. # before the code generation phase.
  438. #
  439. # The return value is a string that can represent a simple C
  440. # value, a constant C name or a constant C expression. If the
  441. # node type depends on Python code, this must return None.
  442. return None
  443. def calculate_constant_result(self):
  444. # Calculate the constant compile time result value of this
  445. # expression and store it in ``self.constant_result``. Does
  446. # nothing by default, thus leaving ``self.constant_result``
  447. # unknown. If valid, the result can be an arbitrary Python
  448. # value.
  449. #
  450. # This must only be called when it is assured that all
  451. # sub-expressions have a valid constant_result value. The
  452. # ConstantFolding transform will do this.
  453. pass
  454. def has_constant_result(self):
  455. return self.constant_result is not constant_value_not_set and \
  456. self.constant_result is not not_a_constant
  457. def compile_time_value(self, denv):
  458. # Return value of compile-time expression, or report error.
  459. error(self.pos, "Invalid compile-time expression")
  460. def compile_time_value_error(self, e):
  461. error(self.pos, "Error in compile-time expression: %s: %s" % (
  462. e.__class__.__name__, e))
  463. # ------------- Declaration Analysis ----------------
  464. def analyse_target_declaration(self, env):
  465. error(self.pos, "Cannot assign to or delete this")
  466. # ------------- Expression Analysis ----------------
  467. def analyse_const_expression(self, env):
  468. # Called during the analyse_declarations phase of a
  469. # constant expression. Analyses the expression's type,
  470. # checks whether it is a legal const expression,
  471. # and determines its value.
  472. node = self.analyse_types(env)
  473. node.check_const()
  474. return node
  475. def analyse_expressions(self, env):
  476. # Convenience routine performing both the Type
  477. # Analysis and Temp Allocation phases for a whole
  478. # expression.
  479. return self.analyse_types(env)
  480. def analyse_target_expression(self, env, rhs):
  481. # Convenience routine performing both the Type
  482. # Analysis and Temp Allocation phases for the LHS of
  483. # an assignment.
  484. return self.analyse_target_types(env)
  485. def analyse_boolean_expression(self, env):
  486. # Analyse expression and coerce to a boolean.
  487. node = self.analyse_types(env)
  488. bool = node.coerce_to_boolean(env)
  489. return bool
  490. def analyse_temp_boolean_expression(self, env):
  491. # Analyse boolean expression and coerce result into
  492. # a temporary. This is used when a branch is to be
  493. # performed on the result and we won't have an
  494. # opportunity to ensure disposal code is executed
  495. # afterwards. By forcing the result into a temporary,
  496. # we ensure that all disposal has been done by the
  497. # time we get the result.
  498. node = self.analyse_types(env)
  499. return node.coerce_to_boolean(env).coerce_to_simple(env)
  500. # --------------- Type Inference -----------------
  501. def type_dependencies(self, env):
  502. # Returns the list of entries whose types must be determined
  503. # before the type of self can be inferred.
  504. if hasattr(self, 'type') and self.type is not None:
  505. return ()
  506. return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
  507. def infer_type(self, env):
  508. # Attempt to deduce the type of self.
  509. # Differs from analyse_types as it avoids unnecessary
  510. # analysis of subexpressions, but can assume everything
  511. # in self.type_dependencies() has been resolved.
  512. if hasattr(self, 'type') and self.type is not None:
  513. return self.type
  514. elif hasattr(self, 'entry') and self.entry is not None:
  515. return self.entry.type
  516. else:
  517. self.not_implemented("infer_type")
  518. def nonlocally_immutable(self):
  519. # Returns whether this variable is a safe reference, i.e.
  520. # can't be modified as part of globals or closures.
  521. return self.is_literal or self.is_temp or self.type.is_array or self.type.is_cfunction
  522. def inferable_item_node(self, index=0):
  523. """
  524. Return a node that represents the (type) result of an indexing operation,
  525. e.g. for tuple unpacking or iteration.
  526. """
  527. return IndexNode(self.pos, base=self, index=IntNode(
  528. self.pos, value=str(index), constant_result=index, type=PyrexTypes.c_py_ssize_t_type))
  529. # --------------- Type Analysis ------------------
  530. def analyse_as_module(self, env):
  531. # If this node can be interpreted as a reference to a
  532. # cimported module, return its scope, else None.
  533. return None
  534. def analyse_as_type(self, env):
  535. # If this node can be interpreted as a reference to a
  536. # type, return that type, else None.
  537. return None
  538. def analyse_as_extension_type(self, env):
  539. # If this node can be interpreted as a reference to an
  540. # extension type or builtin type, return its type, else None.
  541. return None
  542. def analyse_types(self, env):
  543. self.not_implemented("analyse_types")
  544. def analyse_target_types(self, env):
  545. return self.analyse_types(env)
  546. def nogil_check(self, env):
  547. # By default, any expression based on Python objects is
  548. # prevented in nogil environments. Subtypes must override
  549. # this if they can work without the GIL.
  550. if self.type and self.type.is_pyobject:
  551. self.gil_error()
  552. def gil_assignment_check(self, env):
  553. if env.nogil and self.type.is_pyobject:
  554. error(self.pos, "Assignment of Python object not allowed without gil")
  555. def check_const(self):
  556. self.not_const()
  557. return False
  558. def not_const(self):
  559. error(self.pos, "Not allowed in a constant expression")
  560. def check_const_addr(self):
  561. self.addr_not_const()
  562. return False
  563. def addr_not_const(self):
  564. error(self.pos, "Address is not constant")
  565. # ----------------- Result Allocation -----------------
  566. def result_in_temp(self):
  567. # Return true if result is in a temporary owned by
  568. # this node or one of its subexpressions. Overridden
  569. # by certain nodes which can share the result of
  570. # a subnode.
  571. return self.is_temp
  572. def target_code(self):
  573. # Return code fragment for use as LHS of a C assignment.
  574. return self.calculate_result_code()
  575. def calculate_result_code(self):
  576. self.not_implemented("calculate_result_code")
  577. # def release_target_temp(self, env):
  578. # # Release temporaries used by LHS of an assignment.
  579. # self.release_subexpr_temps(env)
  580. def allocate_temp_result(self, code):
  581. if self.temp_code:
  582. raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
  583. type = self.type
  584. if not type.is_void:
  585. if type.is_pyobject:
  586. type = PyrexTypes.py_object_type
  587. elif not (self.result_is_used or type.is_memoryviewslice or self.is_c_result_required()):
  588. self.temp_code = None
  589. return
  590. self.temp_code = code.funcstate.allocate_temp(
  591. type, manage_ref=self.use_managed_ref)
  592. else:
  593. self.temp_code = None
  594. def release_temp_result(self, code):
  595. if not self.temp_code:
  596. if not self.result_is_used:
  597. # not used anyway, so ignore if not set up
  598. return
  599. pos = (os.path.basename(self.pos[0].get_description()),) + self.pos[1:] if self.pos else '(?)'
  600. if self.old_temp:
  601. raise RuntimeError("temp %s released multiple times in %s at %r" % (
  602. self.old_temp, self.__class__.__name__, pos))
  603. else:
  604. raise RuntimeError("no temp, but release requested in %s at %r" % (
  605. self.__class__.__name__, pos))
  606. code.funcstate.release_temp(self.temp_code)
  607. self.old_temp = self.temp_code
  608. self.temp_code = None
  609. # ---------------- Code Generation -----------------
  610. def make_owned_reference(self, code):
  611. """
  612. If result is a pyobject, make sure we own a reference to it.
  613. If the result is in a temp, it is already a new reference.
  614. """
  615. if self.type.is_pyobject and not self.result_in_temp():
  616. code.put_incref(self.result(), self.ctype())
  617. def make_owned_memoryviewslice(self, code):
  618. """
  619. Make sure we own the reference to this memoryview slice.
  620. """
  621. if not self.result_in_temp():
  622. code.put_incref_memoryviewslice(self.result(),
  623. have_gil=self.in_nogil_context)
  624. def generate_evaluation_code(self, code):
  625. # Generate code to evaluate this node and
  626. # its sub-expressions, and dispose of any
  627. # temporary results of its sub-expressions.
  628. self.generate_subexpr_evaluation_code(code)
  629. code.mark_pos(self.pos)
  630. if self.is_temp:
  631. self.allocate_temp_result(code)
  632. self.generate_result_code(code)
  633. if self.is_temp and not (self.type.is_string or self.type.is_pyunicode_ptr):
  634. # If we are temp we do not need to wait until this node is disposed
  635. # before disposing children.
  636. self.generate_subexpr_disposal_code(code)
  637. self.free_subexpr_temps(code)
  638. def generate_subexpr_evaluation_code(self, code):
  639. for node in self.subexpr_nodes():
  640. node.generate_evaluation_code(code)
  641. def generate_result_code(self, code):
  642. self.not_implemented("generate_result_code")
  643. def generate_disposal_code(self, code):
  644. if self.is_temp:
  645. if self.type.is_string or self.type.is_pyunicode_ptr:
  646. # postponed from self.generate_evaluation_code()
  647. self.generate_subexpr_disposal_code(code)
  648. self.free_subexpr_temps(code)
  649. if self.result():
  650. if self.type.is_pyobject:
  651. code.put_decref_clear(self.result(), self.ctype())
  652. elif self.type.is_memoryviewslice:
  653. code.put_xdecref_memoryviewslice(
  654. self.result(), have_gil=not self.in_nogil_context)
  655. code.putln("%s.memview = NULL;" % self.result())
  656. code.putln("%s.data = NULL;" % self.result())
  657. else:
  658. # Already done if self.is_temp
  659. self.generate_subexpr_disposal_code(code)
  660. def generate_subexpr_disposal_code(self, code):
  661. # Generate code to dispose of temporary results
  662. # of all sub-expressions.
  663. for node in self.subexpr_nodes():
  664. node.generate_disposal_code(code)
  665. def generate_post_assignment_code(self, code):
  666. if self.is_temp:
  667. if self.type.is_string or self.type.is_pyunicode_ptr:
  668. # postponed from self.generate_evaluation_code()
  669. self.generate_subexpr_disposal_code(code)
  670. self.free_subexpr_temps(code)
  671. elif self.type.is_pyobject:
  672. code.putln("%s = 0;" % self.result())
  673. elif self.type.is_memoryviewslice:
  674. code.putln("%s.memview = NULL;" % self.result())
  675. code.putln("%s.data = NULL;" % self.result())
  676. else:
  677. self.generate_subexpr_disposal_code(code)
  678. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  679. exception_check=None, exception_value=None):
  680. # Stub method for nodes which are not legal as
  681. # the LHS of an assignment. An error will have
  682. # been reported earlier.
  683. pass
  684. def generate_deletion_code(self, code, ignore_nonexisting=False):
  685. # Stub method for nodes that are not legal as
  686. # the argument of a del statement. An error
  687. # will have been reported earlier.
  688. pass
  689. def free_temps(self, code):
  690. if self.is_temp:
  691. if not self.type.is_void:
  692. self.release_temp_result(code)
  693. else:
  694. self.free_subexpr_temps(code)
  695. def free_subexpr_temps(self, code):
  696. for sub in self.subexpr_nodes():
  697. sub.free_temps(code)
  698. def generate_function_definitions(self, env, code):
  699. pass
  700. # ---------------- Annotation ---------------------
  701. def annotate(self, code):
  702. for node in self.subexpr_nodes():
  703. node.annotate(code)
  704. # ----------------- Coercion ----------------------
  705. def coerce_to(self, dst_type, env):
  706. # Coerce the result so that it can be assigned to
  707. # something of type dst_type. If processing is necessary,
  708. # wraps this node in a coercion node and returns that.
  709. # Otherwise, returns this node unchanged.
  710. #
  711. # This method is called during the analyse_expressions
  712. # phase of the src_node's processing.
  713. #
  714. # Note that subclasses that override this (especially
  715. # ConstNodes) must not (re-)set their own .type attribute
  716. # here. Since expression nodes may turn up in different
  717. # places in the tree (e.g. inside of CloneNodes in cascaded
  718. # assignments), this method must return a new node instance
  719. # if it changes the type.
  720. #
  721. src = self
  722. src_type = self.type
  723. if self.check_for_coercion_error(dst_type, env):
  724. return self
  725. used_as_reference = dst_type.is_reference
  726. if used_as_reference and not src_type.is_reference:
  727. dst_type = dst_type.ref_base_type
  728. if src_type.is_const:
  729. src_type = src_type.const_base_type
  730. if src_type.is_fused or dst_type.is_fused:
  731. # See if we are coercing a fused function to a pointer to a
  732. # specialized function
  733. if (src_type.is_cfunction and not dst_type.is_fused and
  734. dst_type.is_ptr and dst_type.base_type.is_cfunction):
  735. dst_type = dst_type.base_type
  736. for signature in src_type.get_all_specialized_function_types():
  737. if signature.same_as(dst_type):
  738. src.type = signature
  739. src.entry = src.type.entry
  740. src.entry.used = True
  741. return self
  742. if src_type.is_fused:
  743. error(self.pos, "Type is not specialized")
  744. elif src_type.is_null_ptr and dst_type.is_ptr:
  745. # NULL can be implicitly cast to any pointer type
  746. return self
  747. else:
  748. error(self.pos, "Cannot coerce to a type that is not specialized")
  749. self.type = error_type
  750. return self
  751. if self.coercion_type is not None:
  752. # This is purely for error checking purposes!
  753. node = NameNode(self.pos, name='', type=self.coercion_type)
  754. node.coerce_to(dst_type, env)
  755. if dst_type.is_memoryviewslice:
  756. from . import MemoryView
  757. if not src.type.is_memoryviewslice:
  758. if src.type.is_pyobject:
  759. src = CoerceToMemViewSliceNode(src, dst_type, env)
  760. elif src.type.is_array:
  761. src = CythonArrayNode.from_carray(src, env).coerce_to(dst_type, env)
  762. elif not src_type.is_error:
  763. error(self.pos,
  764. "Cannot convert '%s' to memoryviewslice" % (src_type,))
  765. else:
  766. if src.type.writable_needed:
  767. dst_type.writable_needed = True
  768. if not src.type.conforms_to(dst_type, broadcast=self.is_memview_broadcast,
  769. copying=self.is_memview_copy_assignment):
  770. if src.type.dtype.same_as(dst_type.dtype):
  771. msg = "Memoryview '%s' not conformable to memoryview '%s'."
  772. tup = src.type, dst_type
  773. else:
  774. msg = "Different base types for memoryviews (%s, %s)"
  775. tup = src.type.dtype, dst_type.dtype
  776. error(self.pos, msg % tup)
  777. elif dst_type.is_pyobject:
  778. if not src.type.is_pyobject:
  779. if dst_type is bytes_type and src.type.is_int:
  780. src = CoerceIntToBytesNode(src, env)
  781. else:
  782. src = CoerceToPyTypeNode(src, env, type=dst_type)
  783. if not src.type.subtype_of(dst_type):
  784. if src.constant_result is not None:
  785. src = PyTypeTestNode(src, dst_type, env)
  786. elif is_pythran_expr(dst_type) and is_pythran_supported_type(src.type):
  787. # We let the compiler decide whether this is valid
  788. return src
  789. elif is_pythran_expr(src.type):
  790. if is_pythran_supported_type(dst_type):
  791. # Match the case were a pythran expr is assigned to a value, or vice versa.
  792. # We let the C++ compiler decide whether this is valid or not!
  793. return src
  794. # Else, we need to convert the Pythran expression to a Python object
  795. src = CoerceToPyTypeNode(src, env, type=dst_type)
  796. elif src.type.is_pyobject:
  797. if used_as_reference and dst_type.is_cpp_class:
  798. warning(
  799. self.pos,
  800. "Cannot pass Python object as C++ data structure reference (%s &), will pass by copy." % dst_type)
  801. src = CoerceFromPyTypeNode(dst_type, src, env)
  802. elif (dst_type.is_complex
  803. and src_type != dst_type
  804. and dst_type.assignable_from(src_type)):
  805. src = CoerceToComplexNode(src, dst_type, env)
  806. else: # neither src nor dst are py types
  807. # Added the string comparison, since for c types that
  808. # is enough, but Cython gets confused when the types are
  809. # in different pxi files.
  810. # TODO: Remove this hack and require shared declarations.
  811. if not (src.type == dst_type or str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
  812. self.fail_assignment(dst_type)
  813. return src
  814. def fail_assignment(self, dst_type):
  815. error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
  816. def check_for_coercion_error(self, dst_type, env, fail=False, default=None):
  817. if fail and not default:
  818. default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
  819. message = find_coercion_error((self.type, dst_type), default, env)
  820. if message is not None:
  821. error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
  822. return True
  823. if fail:
  824. self.fail_assignment(dst_type)
  825. return True
  826. return False
  827. def coerce_to_pyobject(self, env):
  828. return self.coerce_to(PyrexTypes.py_object_type, env)
  829. def coerce_to_boolean(self, env):
  830. # Coerce result to something acceptable as
  831. # a boolean value.
  832. # if it's constant, calculate the result now
  833. if self.has_constant_result():
  834. bool_value = bool(self.constant_result)
  835. return BoolNode(self.pos, value=bool_value,
  836. constant_result=bool_value)
  837. type = self.type
  838. if type.is_enum or type.is_error:
  839. return self
  840. elif type.is_pyobject or type.is_int or type.is_ptr or type.is_float:
  841. return CoerceToBooleanNode(self, env)
  842. elif type.is_cpp_class:
  843. return SimpleCallNode(
  844. self.pos,
  845. function=AttributeNode(
  846. self.pos, obj=self, attribute='operator bool'),
  847. args=[]).analyse_types(env)
  848. elif type.is_ctuple:
  849. bool_value = len(type.components) == 0
  850. return BoolNode(self.pos, value=bool_value,
  851. constant_result=bool_value)
  852. else:
  853. error(self.pos, "Type '%s' not acceptable as a boolean" % type)
  854. return self
  855. def coerce_to_integer(self, env):
  856. # If not already some C integer type, coerce to longint.
  857. if self.type.is_int:
  858. return self
  859. else:
  860. return self.coerce_to(PyrexTypes.c_long_type, env)
  861. def coerce_to_temp(self, env):
  862. # Ensure that the result is in a temporary.
  863. if self.result_in_temp():
  864. return self
  865. else:
  866. return CoerceToTempNode(self, env)
  867. def coerce_to_simple(self, env):
  868. # Ensure that the result is simple (see is_simple).
  869. if self.is_simple():
  870. return self
  871. else:
  872. return self.coerce_to_temp(env)
  873. def is_simple(self):
  874. # A node is simple if its result is something that can
  875. # be referred to without performing any operations, e.g.
  876. # a constant, local var, C global var, struct member
  877. # reference, or temporary.
  878. return self.result_in_temp()
  879. def may_be_none(self):
  880. if self.type and not (self.type.is_pyobject or
  881. self.type.is_memoryviewslice):
  882. return False
  883. if self.has_constant_result():
  884. return self.constant_result is not None
  885. return True
  886. def as_cython_attribute(self):
  887. return None
  888. def as_none_safe_node(self, message, error="PyExc_TypeError", format_args=()):
  889. # Wraps the node in a NoneCheckNode if it is not known to be
  890. # not-None (e.g. because it is a Python literal).
  891. if self.may_be_none():
  892. return NoneCheckNode(self, error, message, format_args)
  893. else:
  894. return self
  895. @classmethod
  896. def from_node(cls, node, **kwargs):
  897. """Instantiate this node class from another node, properly
  898. copying over all attributes that one would forget otherwise.
  899. """
  900. attributes = "cf_state cf_maybe_null cf_is_null constant_result".split()
  901. for attr_name in attributes:
  902. if attr_name in kwargs:
  903. continue
  904. try:
  905. value = getattr(node, attr_name)
  906. except AttributeError:
  907. pass
  908. else:
  909. kwargs[attr_name] = value
  910. return cls(node.pos, **kwargs)
  911. class AtomicExprNode(ExprNode):
  912. # Abstract base class for expression nodes which have
  913. # no sub-expressions.
  914. subexprs = []
  915. # Override to optimize -- we know we have no children
  916. def generate_subexpr_evaluation_code(self, code):
  917. pass
  918. def generate_subexpr_disposal_code(self, code):
  919. pass
  920. class PyConstNode(AtomicExprNode):
  921. # Abstract base class for constant Python values.
  922. is_literal = 1
  923. type = py_object_type
  924. def is_simple(self):
  925. return 1
  926. def may_be_none(self):
  927. return False
  928. def analyse_types(self, env):
  929. return self
  930. def calculate_result_code(self):
  931. return self.value
  932. def generate_result_code(self, code):
  933. pass
  934. class NoneNode(PyConstNode):
  935. # The constant value None
  936. is_none = 1
  937. value = "Py_None"
  938. constant_result = None
  939. nogil_check = None
  940. def compile_time_value(self, denv):
  941. return None
  942. def may_be_none(self):
  943. return True
  944. def coerce_to(self, dst_type, env):
  945. if not (dst_type.is_pyobject or dst_type.is_memoryviewslice or dst_type.is_error):
  946. # Catch this error early and loudly.
  947. error(self.pos, "Cannot assign None to %s" % dst_type)
  948. return super(NoneNode, self).coerce_to(dst_type, env)
  949. class EllipsisNode(PyConstNode):
  950. # '...' in a subscript list.
  951. value = "Py_Ellipsis"
  952. constant_result = Ellipsis
  953. def compile_time_value(self, denv):
  954. return Ellipsis
  955. class ConstNode(AtomicExprNode):
  956. # Abstract base type for literal constant nodes.
  957. #
  958. # value string C code fragment
  959. is_literal = 1
  960. nogil_check = None
  961. def is_simple(self):
  962. return 1
  963. def nonlocally_immutable(self):
  964. return 1
  965. def may_be_none(self):
  966. return False
  967. def analyse_types(self, env):
  968. return self # Types are held in class variables
  969. def check_const(self):
  970. return True
  971. def get_constant_c_result_code(self):
  972. return self.calculate_result_code()
  973. def calculate_result_code(self):
  974. return str(self.value)
  975. def generate_result_code(self, code):
  976. pass
  977. class BoolNode(ConstNode):
  978. type = PyrexTypes.c_bint_type
  979. # The constant value True or False
  980. def calculate_constant_result(self):
  981. self.constant_result = self.value
  982. def compile_time_value(self, denv):
  983. return self.value
  984. def calculate_result_code(self):
  985. if self.type.is_pyobject:
  986. return self.value and 'Py_True' or 'Py_False'
  987. else:
  988. return str(int(self.value))
  989. def coerce_to(self, dst_type, env):
  990. if dst_type.is_pyobject and self.type.is_int:
  991. return BoolNode(
  992. self.pos, value=self.value,
  993. constant_result=self.constant_result,
  994. type=Builtin.bool_type)
  995. if dst_type.is_int and self.type.is_pyobject:
  996. return BoolNode(
  997. self.pos, value=self.value,
  998. constant_result=self.constant_result,
  999. type=PyrexTypes.c_bint_type)
  1000. return ConstNode.coerce_to(self, dst_type, env)
  1001. class NullNode(ConstNode):
  1002. type = PyrexTypes.c_null_ptr_type
  1003. value = "NULL"
  1004. constant_result = 0
  1005. def get_constant_c_result_code(self):
  1006. return self.value
  1007. class CharNode(ConstNode):
  1008. type = PyrexTypes.c_char_type
  1009. def calculate_constant_result(self):
  1010. self.constant_result = ord(self.value)
  1011. def compile_time_value(self, denv):
  1012. return ord(self.value)
  1013. def calculate_result_code(self):
  1014. return "'%s'" % StringEncoding.escape_char(self.value)
  1015. class IntNode(ConstNode):
  1016. # unsigned "" or "U"
  1017. # longness "" or "L" or "LL"
  1018. # is_c_literal True/False/None creator considers this a C integer literal
  1019. unsigned = ""
  1020. longness = ""
  1021. is_c_literal = None # unknown
  1022. def __init__(self, pos, **kwds):
  1023. ExprNode.__init__(self, pos, **kwds)
  1024. if 'type' not in kwds:
  1025. self.type = self.find_suitable_type_for_value()
  1026. def find_suitable_type_for_value(self):
  1027. if self.constant_result is constant_value_not_set:
  1028. try:
  1029. self.calculate_constant_result()
  1030. except ValueError:
  1031. pass
  1032. # we ignore 'is_c_literal = True' and instead map signed 32bit
  1033. # integers as C long values
  1034. if self.is_c_literal or \
  1035. not self.has_constant_result() or \
  1036. self.unsigned or self.longness == 'LL':
  1037. # clearly a C literal
  1038. rank = (self.longness == 'LL') and 2 or 1
  1039. suitable_type = PyrexTypes.modifiers_and_name_to_type[not self.unsigned, rank, "int"]
  1040. if self.type:
  1041. suitable_type = PyrexTypes.widest_numeric_type(suitable_type, self.type)
  1042. else:
  1043. # C literal or Python literal - split at 32bit boundary
  1044. if -2**31 <= self.constant_result < 2**31:
  1045. if self.type and self.type.is_int:
  1046. suitable_type = self.type
  1047. else:
  1048. suitable_type = PyrexTypes.c_long_type
  1049. else:
  1050. suitable_type = PyrexTypes.py_object_type
  1051. return suitable_type
  1052. def coerce_to(self, dst_type, env):
  1053. if self.type is dst_type:
  1054. return self
  1055. elif dst_type.is_float:
  1056. if self.has_constant_result():
  1057. return FloatNode(self.pos, value='%d.0' % int(self.constant_result), type=dst_type,
  1058. constant_result=float(self.constant_result))
  1059. else:
  1060. return FloatNode(self.pos, value=self.value, type=dst_type,
  1061. constant_result=not_a_constant)
  1062. if dst_type.is_numeric and not dst_type.is_complex:
  1063. node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
  1064. type=dst_type, is_c_literal=True,
  1065. unsigned=self.unsigned, longness=self.longness)
  1066. return node
  1067. elif dst_type.is_pyobject:
  1068. node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
  1069. type=PyrexTypes.py_object_type, is_c_literal=False,
  1070. unsigned=self.unsigned, longness=self.longness)
  1071. else:
  1072. # FIXME: not setting the type here to keep it working with
  1073. # complex numbers. Should they be special cased?
  1074. node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
  1075. unsigned=self.unsigned, longness=self.longness)
  1076. # We still need to perform normal coerce_to processing on the
  1077. # result, because we might be coercing to an extension type,
  1078. # in which case a type test node will be needed.
  1079. return ConstNode.coerce_to(node, dst_type, env)
  1080. def coerce_to_boolean(self, env):
  1081. return IntNode(
  1082. self.pos, value=self.value,
  1083. constant_result=self.constant_result,
  1084. type=PyrexTypes.c_bint_type,
  1085. unsigned=self.unsigned, longness=self.longness)
  1086. def generate_evaluation_code(self, code):
  1087. if self.type.is_pyobject:
  1088. # pre-allocate a Python version of the number
  1089. plain_integer_string = str(Utils.str_to_number(self.value))
  1090. self.result_code = code.get_py_int(plain_integer_string, self.longness)
  1091. else:
  1092. self.result_code = self.get_constant_c_result_code()
  1093. def get_constant_c_result_code(self):
  1094. unsigned, longness = self.unsigned, self.longness
  1095. literal = self.value_as_c_integer_string()
  1096. if not (unsigned or longness) and self.type.is_int and literal[0] == '-' and literal[1] != '0':
  1097. # negative decimal literal => guess longness from type to prevent wrap-around
  1098. if self.type.rank >= PyrexTypes.c_longlong_type.rank:
  1099. longness = 'LL'
  1100. elif self.type.rank >= PyrexTypes.c_long_type.rank:
  1101. longness = 'L'
  1102. return literal + unsigned + longness
  1103. def value_as_c_integer_string(self):
  1104. value = self.value
  1105. if len(value) <= 2:
  1106. # too short to go wrong (and simplifies code below)
  1107. return value
  1108. neg_sign = ''
  1109. if value[0] == '-':
  1110. neg_sign = '-'
  1111. value = value[1:]
  1112. if value[0] == '0':
  1113. literal_type = value[1] # 0'o' - 0'b' - 0'x'
  1114. # 0x123 hex literals and 0123 octal literals work nicely in C
  1115. # but C-incompatible Py3 oct/bin notations need conversion
  1116. if neg_sign and literal_type in 'oOxX0123456789' and value[2:].isdigit():
  1117. # negative hex/octal literal => prevent C compiler from using
  1118. # unsigned integer types by converting to decimal (see C standard 6.4.4.1)
  1119. value = str(Utils.str_to_number(value))
  1120. elif literal_type in 'oO':
  1121. value = '0' + value[2:] # '0o123' => '0123'
  1122. elif literal_type in 'bB':
  1123. value = str(int(value[2:], 2))
  1124. elif value.isdigit() and not self.unsigned and not self.longness:
  1125. if not neg_sign:
  1126. # C compilers do not consider unsigned types for decimal literals,
  1127. # but they do for hex (see C standard 6.4.4.1)
  1128. value = '0x%X' % int(value)
  1129. return neg_sign + value
  1130. def calculate_result_code(self):
  1131. return self.result_code
  1132. def calculate_constant_result(self):
  1133. self.constant_result = Utils.str_to_number(self.value)
  1134. def compile_time_value(self, denv):
  1135. return Utils.str_to_number(self.value)
  1136. class FloatNode(ConstNode):
  1137. type = PyrexTypes.c_double_type
  1138. def calculate_constant_result(self):
  1139. self.constant_result = float(self.value)
  1140. def compile_time_value(self, denv):
  1141. return float(self.value)
  1142. def coerce_to(self, dst_type, env):
  1143. if dst_type.is_pyobject and self.type.is_float:
  1144. return FloatNode(
  1145. self.pos, value=self.value,
  1146. constant_result=self.constant_result,
  1147. type=Builtin.float_type)
  1148. if dst_type.is_float and self.type.is_pyobject:
  1149. return FloatNode(
  1150. self.pos, value=self.value,
  1151. constant_result=self.constant_result,
  1152. type=dst_type)
  1153. return ConstNode.coerce_to(self, dst_type, env)
  1154. def calculate_result_code(self):
  1155. return self.result_code
  1156. def get_constant_c_result_code(self):
  1157. strval = self.value
  1158. assert isinstance(strval, basestring)
  1159. cmpval = repr(float(strval))
  1160. if cmpval == 'nan':
  1161. return "(Py_HUGE_VAL * 0)"
  1162. elif cmpval == 'inf':
  1163. return "Py_HUGE_VAL"
  1164. elif cmpval == '-inf':
  1165. return "(-Py_HUGE_VAL)"
  1166. else:
  1167. return strval
  1168. def generate_evaluation_code(self, code):
  1169. c_value = self.get_constant_c_result_code()
  1170. if self.type.is_pyobject:
  1171. self.result_code = code.get_py_float(self.value, c_value)
  1172. else:
  1173. self.result_code = c_value
  1174. def _analyse_name_as_type(name, pos, env):
  1175. type = PyrexTypes.parse_basic_type(name)
  1176. if type is not None:
  1177. return type
  1178. global_entry = env.global_scope().lookup_here(name)
  1179. if global_entry and global_entry.type and global_entry.type.is_extension_type:
  1180. return global_entry.type
  1181. from .TreeFragment import TreeFragment
  1182. with local_errors(ignore=True):
  1183. pos = (pos[0], pos[1], pos[2]-7)
  1184. try:
  1185. declaration = TreeFragment(u"sizeof(%s)" % name, name=pos[0].filename, initial_pos=pos)
  1186. except CompileError:
  1187. pass
  1188. else:
  1189. sizeof_node = declaration.root.stats[0].expr
  1190. if isinstance(sizeof_node, SizeofTypeNode):
  1191. sizeof_node = sizeof_node.analyse_types(env)
  1192. if isinstance(sizeof_node, SizeofTypeNode):
  1193. return sizeof_node.arg_type
  1194. return None
  1195. class BytesNode(ConstNode):
  1196. # A char* or bytes literal
  1197. #
  1198. # value BytesLiteral
  1199. is_string_literal = True
  1200. # start off as Python 'bytes' to support len() in O(1)
  1201. type = bytes_type
  1202. def calculate_constant_result(self):
  1203. self.constant_result = self.value
  1204. def as_sliced_node(self, start, stop, step=None):
  1205. value = StringEncoding.bytes_literal(self.value[start:stop:step], self.value.encoding)
  1206. return BytesNode(self.pos, value=value, constant_result=value)
  1207. def compile_time_value(self, denv):
  1208. return self.value.byteencode()
  1209. def analyse_as_type(self, env):
  1210. return _analyse_name_as_type(self.value.decode('ISO8859-1'), self.pos, env)
  1211. def can_coerce_to_char_literal(self):
  1212. return len(self.value) == 1
  1213. def coerce_to_boolean(self, env):
  1214. # This is special because testing a C char* for truth directly
  1215. # would yield the wrong result.
  1216. bool_value = bool(self.value)
  1217. return BoolNode(self.pos, value=bool_value, constant_result=bool_value)
  1218. def coerce_to(self, dst_type, env):
  1219. if self.type == dst_type:
  1220. return self
  1221. if dst_type.is_int:
  1222. if not self.can_coerce_to_char_literal():
  1223. error(self.pos, "Only single-character string literals can be coerced into ints.")
  1224. return self
  1225. if dst_type.is_unicode_char:
  1226. error(self.pos, "Bytes literals cannot coerce to Py_UNICODE/Py_UCS4, use a unicode literal instead.")
  1227. return self
  1228. return CharNode(self.pos, value=self.value,
  1229. constant_result=ord(self.value))
  1230. node = BytesNode(self.pos, value=self.value, constant_result=self.constant_result)
  1231. if dst_type.is_pyobject:
  1232. if dst_type in (py_object_type, Builtin.bytes_type):
  1233. node.type = Builtin.bytes_type
  1234. else:
  1235. self.check_for_coercion_error(dst_type, env, fail=True)
  1236. return node
  1237. elif dst_type in (PyrexTypes.c_char_ptr_type, PyrexTypes.c_const_char_ptr_type):
  1238. node.type = dst_type
  1239. return node
  1240. elif dst_type in (PyrexTypes.c_uchar_ptr_type, PyrexTypes.c_const_uchar_ptr_type, PyrexTypes.c_void_ptr_type):
  1241. node.type = (PyrexTypes.c_const_char_ptr_type if dst_type == PyrexTypes.c_const_uchar_ptr_type
  1242. else PyrexTypes.c_char_ptr_type)
  1243. return CastNode(node, dst_type)
  1244. elif dst_type.assignable_from(PyrexTypes.c_char_ptr_type):
  1245. # Exclude the case of passing a C string literal into a non-const C++ string.
  1246. if not dst_type.is_cpp_class or dst_type.is_const:
  1247. node.type = dst_type
  1248. return node
  1249. # We still need to perform normal coerce_to processing on the
  1250. # result, because we might be coercing to an extension type,
  1251. # in which case a type test node will be needed.
  1252. return ConstNode.coerce_to(node, dst_type, env)
  1253. def generate_evaluation_code(self, code):
  1254. if self.type.is_pyobject:
  1255. result = code.get_py_string_const(self.value)
  1256. elif self.type.is_const:
  1257. result = code.get_string_const(self.value)
  1258. else:
  1259. # not const => use plain C string literal and cast to mutable type
  1260. literal = self.value.as_c_string_literal()
  1261. # C++ may require a cast
  1262. result = typecast(self.type, PyrexTypes.c_void_ptr_type, literal)
  1263. self.result_code = result
  1264. def get_constant_c_result_code(self):
  1265. return None # FIXME
  1266. def calculate_result_code(self):
  1267. return self.result_code
  1268. class UnicodeNode(ConstNode):
  1269. # A Py_UNICODE* or unicode literal
  1270. #
  1271. # value EncodedString
  1272. # bytes_value BytesLiteral the literal parsed as bytes string
  1273. # ('-3' unicode literals only)
  1274. is_string_literal = True
  1275. bytes_value = None
  1276. type = unicode_type
  1277. def calculate_constant_result(self):
  1278. self.constant_result = self.value
  1279. def analyse_as_type(self, env):
  1280. return _analyse_name_as_type(self.value, self.pos, env)
  1281. def as_sliced_node(self, start, stop, step=None):
  1282. if StringEncoding.string_contains_surrogates(self.value[:stop]):
  1283. # this is unsafe as it may give different results
  1284. # in different runtimes
  1285. return None
  1286. value = StringEncoding.EncodedString(self.value[start:stop:step])
  1287. value.encoding = self.value.encoding
  1288. if self.bytes_value is not None:
  1289. bytes_value = StringEncoding.bytes_literal(
  1290. self.bytes_value[start:stop:step], self.bytes_value.encoding)
  1291. else:
  1292. bytes_value = None
  1293. return UnicodeNode(
  1294. self.pos, value=value, bytes_value=bytes_value,
  1295. constant_result=value)
  1296. def coerce_to(self, dst_type, env):
  1297. if dst_type is self.type:
  1298. pass
  1299. elif dst_type.is_unicode_char:
  1300. if not self.can_coerce_to_char_literal():
  1301. error(self.pos,
  1302. "Only single-character Unicode string literals or "
  1303. "surrogate pairs can be coerced into Py_UCS4/Py_UNICODE.")
  1304. return self
  1305. int_value = ord(self.value)
  1306. return IntNode(self.pos, type=dst_type, value=str(int_value),
  1307. constant_result=int_value)
  1308. elif not dst_type.is_pyobject:
  1309. if dst_type.is_string and self.bytes_value is not None:
  1310. # special case: '-3' enforced unicode literal used in a
  1311. # C char* context
  1312. return BytesNode(self.pos, value=self.bytes_value
  1313. ).coerce_to(dst_type, env)
  1314. if dst_type.is_pyunicode_ptr:
  1315. node = UnicodeNode(self.pos, value=self.value)
  1316. node.type = dst_type
  1317. return node
  1318. error(self.pos,
  1319. "Unicode literals do not support coercion to C types other "
  1320. "than Py_UNICODE/Py_UCS4 (for characters) or Py_UNICODE* "
  1321. "(for strings).")
  1322. elif dst_type not in (py_object_type, Builtin.basestring_type):
  1323. self.check_for_coercion_error(dst_type, env, fail=True)
  1324. return self
  1325. def can_coerce_to_char_literal(self):
  1326. return len(self.value) == 1
  1327. ## or (len(self.value) == 2
  1328. ## and (0xD800 <= self.value[0] <= 0xDBFF)
  1329. ## and (0xDC00 <= self.value[1] <= 0xDFFF))
  1330. def coerce_to_boolean(self, env):
  1331. bool_value = bool(self.value)
  1332. return BoolNode(self.pos, value=bool_value, constant_result=bool_value)
  1333. def contains_surrogates(self):
  1334. return StringEncoding.string_contains_surrogates(self.value)
  1335. def generate_evaluation_code(self, code):
  1336. if self.type.is_pyobject:
  1337. if self.contains_surrogates():
  1338. # surrogates are not really portable and cannot be
  1339. # decoded by the UTF-8 codec in Py3.3
  1340. self.result_code = code.get_py_const(py_object_type, 'ustring')
  1341. data_cname = code.get_pyunicode_ptr_const(self.value)
  1342. code = code.get_cached_constants_writer()
  1343. code.mark_pos(self.pos)
  1344. code.putln(
  1345. "%s = PyUnicode_FromUnicode(%s, (sizeof(%s) / sizeof(Py_UNICODE))-1); %s" % (
  1346. self.result_code,
  1347. data_cname,
  1348. data_cname,
  1349. code.error_goto_if_null(self.result_code, self.pos)))
  1350. code.put_error_if_neg(
  1351. self.pos, "__Pyx_PyUnicode_READY(%s)" % self.result_code)
  1352. else:
  1353. self.result_code = code.get_py_string_const(self.value)
  1354. else:
  1355. self.result_code = code.get_pyunicode_ptr_const(self.value)
  1356. def calculate_result_code(self):
  1357. return self.result_code
  1358. def compile_time_value(self, env):
  1359. return self.value
  1360. class StringNode(PyConstNode):
  1361. # A Python str object, i.e. a byte string in Python 2.x and a
  1362. # unicode string in Python 3.x
  1363. #
  1364. # value BytesLiteral (or EncodedString with ASCII content)
  1365. # unicode_value EncodedString or None
  1366. # is_identifier boolean
  1367. type = str_type
  1368. is_string_literal = True
  1369. is_identifier = None
  1370. unicode_value = None
  1371. def calculate_constant_result(self):
  1372. if self.unicode_value is not None:
  1373. # only the Unicode value is portable across Py2/3
  1374. self.constant_result = self.unicode_value
  1375. def analyse_as_type(self, env):
  1376. return _analyse_name_as_type(self.unicode_value or self.value.decode('ISO8859-1'), self.pos, env)
  1377. def as_sliced_node(self, start, stop, step=None):
  1378. value = type(self.value)(self.value[start:stop:step])
  1379. value.encoding = self.value.encoding
  1380. if self.unicode_value is not None:
  1381. if StringEncoding.string_contains_surrogates(self.unicode_value[:stop]):
  1382. # this is unsafe as it may give different results in different runtimes
  1383. return None
  1384. unicode_value = StringEncoding.EncodedString(
  1385. self.unicode_value[start:stop:step])
  1386. else:
  1387. unicode_value = None
  1388. return StringNode(
  1389. self.pos, value=value, unicode_value=unicode_value,
  1390. constant_result=value, is_identifier=self.is_identifier)
  1391. def coerce_to(self, dst_type, env):
  1392. if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
  1393. # if dst_type is Builtin.bytes_type:
  1394. # # special case: bytes = 'str literal'
  1395. # return BytesNode(self.pos, value=self.value)
  1396. if not dst_type.is_pyobject:
  1397. return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
  1398. if dst_type is not Builtin.basestring_type:
  1399. self.check_for_coercion_error(dst_type, env, fail=True)
  1400. return self
  1401. def can_coerce_to_char_literal(self):
  1402. return not self.is_identifier and len(self.value) == 1
  1403. def generate_evaluation_code(self, code):
  1404. self.result_code = code.get_py_string_const(
  1405. self.value, identifier=self.is_identifier, is_str=True,
  1406. unicode_value=self.unicode_value)
  1407. def get_constant_c_result_code(self):
  1408. return None
  1409. def calculate_result_code(self):
  1410. return self.result_code
  1411. def compile_time_value(self, env):
  1412. if self.value.is_unicode:
  1413. return self.value
  1414. if not IS_PYTHON3:
  1415. # use plain str/bytes object in Py2
  1416. return self.value.byteencode()
  1417. # in Py3, always return a Unicode string
  1418. if self.unicode_value is not None:
  1419. return self.unicode_value
  1420. return self.value.decode('iso8859-1')
  1421. class IdentifierStringNode(StringNode):
  1422. # A special str value that represents an identifier (bytes in Py2,
  1423. # unicode in Py3).
  1424. is_identifier = True
  1425. class ImagNode(AtomicExprNode):
  1426. # Imaginary number literal
  1427. #
  1428. # value string imaginary part (float value)
  1429. type = PyrexTypes.c_double_complex_type
  1430. def calculate_constant_result(self):
  1431. self.constant_result = complex(0.0, float(self.value))
  1432. def compile_time_value(self, denv):
  1433. return complex(0.0, float(self.value))
  1434. def analyse_types(self, env):
  1435. self.type.create_declaration_utility_code(env)
  1436. return self
  1437. def may_be_none(self):
  1438. return False
  1439. def coerce_to(self, dst_type, env):
  1440. if self.type is dst_type:
  1441. return self
  1442. node = ImagNode(self.pos, value=self.value)
  1443. if dst_type.is_pyobject:
  1444. node.is_temp = 1
  1445. node.type = Builtin.complex_type
  1446. # We still need to perform normal coerce_to processing on the
  1447. # result, because we might be coercing to an extension type,
  1448. # in which case a type test node will be needed.
  1449. return AtomicExprNode.coerce_to(node, dst_type, env)
  1450. gil_message = "Constructing complex number"
  1451. def calculate_result_code(self):
  1452. if self.type.is_pyobject:
  1453. return self.result()
  1454. else:
  1455. return "%s(0, %r)" % (self.type.from_parts, float(self.value))
  1456. def generate_result_code(self, code):
  1457. if self.type.is_pyobject:
  1458. code.putln(
  1459. "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
  1460. self.result(),
  1461. float(self.value),
  1462. code.error_goto_if_null(self.result(), self.pos)))
  1463. code.put_gotref(self.py_result())
  1464. class NewExprNode(AtomicExprNode):
  1465. # C++ new statement
  1466. #
  1467. # cppclass node c++ class to create
  1468. type = None
  1469. def infer_type(self, env):
  1470. type = self.cppclass.analyse_as_type(env)
  1471. if type is None or not type.is_cpp_class:
  1472. error(self.pos, "new operator can only be applied to a C++ class")
  1473. self.type = error_type
  1474. return
  1475. self.cpp_check(env)
  1476. constructor = type.get_constructor(self.pos)
  1477. self.class_type = type
  1478. self.entry = constructor
  1479. self.type = constructor.type
  1480. return self.type
  1481. def analyse_types(self, env):
  1482. if self.type is None:
  1483. self.infer_type(env)
  1484. return self
  1485. def may_be_none(self):
  1486. return False
  1487. def generate_result_code(self, code):
  1488. pass
  1489. def calculate_result_code(self):
  1490. return "new " + self.class_type.empty_declaration_code()
  1491. class NameNode(AtomicExprNode):
  1492. # Reference to a local or global variable name.
  1493. #
  1494. # name string Python name of the variable
  1495. # entry Entry Symbol table entry
  1496. # type_entry Entry For extension type names, the original type entry
  1497. # cf_is_null boolean Is uninitialized before this node
  1498. # cf_maybe_null boolean Maybe uninitialized before this node
  1499. # allow_null boolean Don't raise UnboundLocalError
  1500. # nogil boolean Whether it is used in a nogil context
  1501. is_name = True
  1502. is_cython_module = False
  1503. cython_attribute = None
  1504. lhs_of_first_assignment = False # TODO: remove me
  1505. is_used_as_rvalue = 0
  1506. entry = None
  1507. type_entry = None
  1508. cf_maybe_null = True
  1509. cf_is_null = False
  1510. allow_null = False
  1511. nogil = False
  1512. inferred_type = None
  1513. def as_cython_attribute(self):
  1514. return self.cython_attribute
  1515. def type_dependencies(self, env):
  1516. if self.entry is None:
  1517. self.entry = env.lookup(self.name)
  1518. if self.entry is not None and self.entry.type.is_unspecified:
  1519. return (self,)
  1520. else:
  1521. return ()
  1522. def infer_type(self, env):
  1523. if self.entry is None:
  1524. self.entry = env.lookup(self.name)
  1525. if self.entry is None or self.entry.type is unspecified_type:
  1526. if self.inferred_type is not None:
  1527. return self.inferred_type
  1528. return py_object_type
  1529. elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
  1530. self.name == self.entry.type.name:
  1531. # Unfortunately the type attribute of type objects
  1532. # is used for the pointer to the type they represent.
  1533. return type_type
  1534. elif self.entry.type.is_cfunction:
  1535. if self.entry.scope.is_builtin_scope:
  1536. # special case: optimised builtin functions must be treated as Python objects
  1537. return py_object_type
  1538. else:
  1539. # special case: referring to a C function must return its pointer
  1540. return PyrexTypes.CPtrType(self.entry.type)
  1541. else:
  1542. # If entry is inferred as pyobject it's safe to use local
  1543. # NameNode's inferred_type.
  1544. if self.entry.type.is_pyobject and self.inferred_type:
  1545. # Overflow may happen if integer
  1546. if not (self.inferred_type.is_int and self.entry.might_overflow):
  1547. return self.inferred_type
  1548. return self.entry.type
  1549. def compile_time_value(self, denv):
  1550. try:
  1551. return denv.lookup(self.name)
  1552. except KeyError:
  1553. error(self.pos, "Compile-time name '%s' not defined" % self.name)
  1554. def get_constant_c_result_code(self):
  1555. if not self.entry or self.entry.type.is_pyobject:
  1556. return None
  1557. return self.entry.cname
  1558. def coerce_to(self, dst_type, env):
  1559. # If coercing to a generic pyobject and this is a builtin
  1560. # C function with a Python equivalent, manufacture a NameNode
  1561. # referring to the Python builtin.
  1562. #print "NameNode.coerce_to:", self.name, dst_type ###
  1563. if dst_type is py_object_type:
  1564. entry = self.entry
  1565. if entry and entry.is_cfunction:
  1566. var_entry = entry.as_variable
  1567. if var_entry:
  1568. if var_entry.is_builtin and var_entry.is_const:
  1569. var_entry = env.declare_builtin(var_entry.name, self.pos)
  1570. node = NameNode(self.pos, name = self.name)
  1571. node.entry = var_entry
  1572. node.analyse_rvalue_entry(env)
  1573. return node
  1574. return super(NameNode, self).coerce_to(dst_type, env)
  1575. def declare_from_annotation(self, env, as_target=False):
  1576. """Implements PEP 526 annotation typing in a fairly relaxed way.
  1577. Annotations are ignored for global variables, Python class attributes and already declared variables.
  1578. String literals are allowed and ignored.
  1579. The ambiguous Python types 'int' and 'long' are ignored and the 'cython.int' form must be used instead.
  1580. """
  1581. if not env.directives['annotation_typing']:
  1582. return
  1583. if env.is_module_scope or env.is_py_class_scope:
  1584. # annotations never create global cdef names and Python classes don't support them anyway
  1585. return
  1586. name = self.name
  1587. if self.entry or env.lookup_here(name) is not None:
  1588. # already declared => ignore annotation
  1589. return
  1590. annotation = self.annotation
  1591. if annotation.is_string_literal:
  1592. # name: "description" => not a type, but still a declared variable or attribute
  1593. atype = None
  1594. else:
  1595. _, atype = analyse_type_annotation(annotation, env)
  1596. if atype is None:
  1597. atype = unspecified_type if as_target and env.directives['infer_types'] != False else py_object_type
  1598. self.entry = env.declare_var(name, atype, self.pos, is_cdef=not as_target)
  1599. self.entry.annotation = annotation
  1600. def analyse_as_module(self, env):
  1601. # Try to interpret this as a reference to a cimported module.
  1602. # Returns the module scope, or None.
  1603. entry = self.entry
  1604. if not entry:
  1605. entry = env.lookup(self.name)
  1606. if entry and entry.as_module:
  1607. return entry.as_module
  1608. return None
  1609. def analyse_as_type(self, env):
  1610. if self.cython_attribute:
  1611. type = PyrexTypes.parse_basic_type(self.cython_attribute)
  1612. else:
  1613. type = PyrexTypes.parse_basic_type(self.name)
  1614. if type:
  1615. return type
  1616. entry = self.entry
  1617. if not entry:
  1618. entry = env.lookup(self.name)
  1619. if entry and entry.is_type:
  1620. return entry.type
  1621. else:
  1622. return None
  1623. def analyse_as_extension_type(self, env):
  1624. # Try to interpret this as a reference to an extension type.
  1625. # Returns the extension type, or None.
  1626. entry = self.entry
  1627. if not entry:
  1628. entry = env.lookup(self.name)
  1629. if entry and entry.is_type:
  1630. if entry.type.is_extension_type or entry.type.is_builtin_type:
  1631. return entry.type
  1632. return None
  1633. def analyse_target_declaration(self, env):
  1634. if not self.entry:
  1635. self.entry = env.lookup_here(self.name)
  1636. if not self.entry and self.annotation is not None:
  1637. # name : type = ...
  1638. self.declare_from_annotation(env, as_target=True)
  1639. if not self.entry:
  1640. if env.directives['warn.undeclared']:
  1641. warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
  1642. if env.directives['infer_types'] != False:
  1643. type = unspecified_type
  1644. else:
  1645. type = py_object_type
  1646. self.entry = env.declare_var(self.name, type, self.pos)
  1647. if self.entry.is_declared_generic:
  1648. self.result_ctype = py_object_type
  1649. if self.entry.as_module:
  1650. # cimported modules namespace can shadow actual variables
  1651. self.entry.is_variable = 1
  1652. def analyse_types(self, env):
  1653. self.initialized_check = env.directives['initializedcheck']
  1654. entry = self.entry
  1655. if entry is None:
  1656. entry = env.lookup(self.name)
  1657. if not entry:
  1658. entry = env.declare_builtin(self.name, self.pos)
  1659. if entry and entry.is_builtin and entry.is_const:
  1660. self.is_literal = True
  1661. if not entry:
  1662. self.type = PyrexTypes.error_type
  1663. return self
  1664. self.entry = entry
  1665. entry.used = 1
  1666. if entry.type.is_buffer:
  1667. from . import Buffer
  1668. Buffer.used_buffer_aux_vars(entry)
  1669. self.analyse_rvalue_entry(env)
  1670. return self
  1671. def analyse_target_types(self, env):
  1672. self.analyse_entry(env, is_target=True)
  1673. entry = self.entry
  1674. if entry.is_cfunction and entry.as_variable:
  1675. # FIXME: unify "is_overridable" flags below
  1676. if (entry.is_overridable or entry.type.is_overridable) or not self.is_lvalue() and entry.fused_cfunction:
  1677. # We need this for assigning to cpdef names and for the fused 'def' TreeFragment
  1678. entry = self.entry = entry.as_variable
  1679. self.type = entry.type
  1680. if self.type.is_const:
  1681. error(self.pos, "Assignment to const '%s'" % self.name)
  1682. if self.type.is_reference:
  1683. error(self.pos, "Assignment to reference '%s'" % self.name)
  1684. if not self.is_lvalue():
  1685. error(self.pos, "Assignment to non-lvalue '%s'" % self.name)
  1686. self.type = PyrexTypes.error_type
  1687. entry.used = 1
  1688. if entry.type.is_buffer:
  1689. from . import Buffer
  1690. Buffer.used_buffer_aux_vars(entry)
  1691. return self
  1692. def analyse_rvalue_entry(self, env):
  1693. #print "NameNode.analyse_rvalue_entry:", self.name ###
  1694. #print "Entry:", self.entry.__dict__ ###
  1695. self.analyse_entry(env)
  1696. entry = self.entry
  1697. if entry.is_declared_generic:
  1698. self.result_ctype = py_object_type
  1699. if entry.is_pyglobal or entry.is_builtin:
  1700. if entry.is_builtin and entry.is_const:
  1701. self.is_temp = 0
  1702. else:
  1703. self.is_temp = 1
  1704. self.is_used_as_rvalue = 1
  1705. elif entry.type.is_memoryviewslice:
  1706. self.is_temp = False
  1707. self.is_used_as_rvalue = True
  1708. self.use_managed_ref = True
  1709. return self
  1710. def nogil_check(self, env):
  1711. self.nogil = True
  1712. if self.is_used_as_rvalue:
  1713. entry = self.entry
  1714. if entry.is_builtin:
  1715. if not entry.is_const: # cached builtins are ok
  1716. self.gil_error()
  1717. elif entry.is_pyglobal:
  1718. self.gil_error()
  1719. gil_message = "Accessing Python global or builtin"
  1720. def analyse_entry(self, env, is_target=False):
  1721. #print "NameNode.analyse_entry:", self.name ###
  1722. self.check_identifier_kind()
  1723. entry = self.entry
  1724. type = entry.type
  1725. if (not is_target and type.is_pyobject and self.inferred_type and
  1726. self.inferred_type.is_builtin_type):
  1727. # assume that type inference is smarter than the static entry
  1728. type = self.inferred_type
  1729. self.type = type
  1730. def check_identifier_kind(self):
  1731. # Check that this is an appropriate kind of name for use in an
  1732. # expression. Also finds the variable entry associated with
  1733. # an extension type.
  1734. entry = self.entry
  1735. if entry.is_type and entry.type.is_extension_type:
  1736. self.type_entry = entry
  1737. if entry.is_type and entry.type.is_enum:
  1738. py_entry = Symtab.Entry(self.name, None, py_object_type)
  1739. py_entry.is_pyglobal = True
  1740. py_entry.scope = self.entry.scope
  1741. self.entry = py_entry
  1742. elif not (entry.is_const or entry.is_variable or
  1743. entry.is_builtin or entry.is_cfunction or
  1744. entry.is_cpp_class):
  1745. if self.entry.as_variable:
  1746. self.entry = self.entry.as_variable
  1747. elif not self.is_cython_module:
  1748. error(self.pos, "'%s' is not a constant, variable or function identifier" % self.name)
  1749. def is_cimported_module_without_shadow(self, env):
  1750. if self.is_cython_module or self.cython_attribute:
  1751. return False
  1752. entry = self.entry or env.lookup(self.name)
  1753. return entry.as_module and not entry.is_variable
  1754. def is_simple(self):
  1755. # If it's not a C variable, it'll be in a temp.
  1756. return 1
  1757. def may_be_none(self):
  1758. if self.cf_state and self.type and (self.type.is_pyobject or
  1759. self.type.is_memoryviewslice):
  1760. # gard against infinite recursion on self-dependencies
  1761. if getattr(self, '_none_checking', False):
  1762. # self-dependency - either this node receives a None
  1763. # value from *another* node, or it can not reference
  1764. # None at this point => safe to assume "not None"
  1765. return False
  1766. self._none_checking = True
  1767. # evaluate control flow state to see if there were any
  1768. # potential None values assigned to the node so far
  1769. may_be_none = False
  1770. for assignment in self.cf_state:
  1771. if assignment.rhs.may_be_none():
  1772. may_be_none = True
  1773. break
  1774. del self._none_checking
  1775. return may_be_none
  1776. return super(NameNode, self).may_be_none()
  1777. def nonlocally_immutable(self):
  1778. if ExprNode.nonlocally_immutable(self):
  1779. return True
  1780. entry = self.entry
  1781. if not entry or entry.in_closure:
  1782. return False
  1783. return entry.is_local or entry.is_arg or entry.is_builtin or entry.is_readonly
  1784. def calculate_target_results(self, env):
  1785. pass
  1786. def check_const(self):
  1787. entry = self.entry
  1788. if entry is not None and not (
  1789. entry.is_const or
  1790. entry.is_cfunction or
  1791. entry.is_builtin or
  1792. entry.type.is_const):
  1793. self.not_const()
  1794. return False
  1795. return True
  1796. def check_const_addr(self):
  1797. entry = self.entry
  1798. if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
  1799. self.addr_not_const()
  1800. return False
  1801. return True
  1802. def is_lvalue(self):
  1803. return (
  1804. self.entry.is_variable and
  1805. not self.entry.is_readonly
  1806. ) or (
  1807. self.entry.is_cfunction and
  1808. self.entry.is_overridable
  1809. )
  1810. def is_addressable(self):
  1811. return self.entry.is_variable and not self.type.is_memoryviewslice
  1812. def is_ephemeral(self):
  1813. # Name nodes are never ephemeral, even if the
  1814. # result is in a temporary.
  1815. return 0
  1816. def calculate_result_code(self):
  1817. entry = self.entry
  1818. if not entry:
  1819. return "<error>" # There was an error earlier
  1820. return entry.cname
  1821. def generate_result_code(self, code):
  1822. assert hasattr(self, 'entry')
  1823. entry = self.entry
  1824. if entry is None:
  1825. return # There was an error earlier
  1826. if entry.is_builtin and entry.is_const:
  1827. return # Lookup already cached
  1828. elif entry.is_pyclass_attr:
  1829. assert entry.type.is_pyobject, "Python global or builtin not a Python object"
  1830. interned_cname = code.intern_identifier(self.entry.name)
  1831. if entry.is_builtin:
  1832. namespace = Naming.builtins_cname
  1833. else: # entry.is_pyglobal
  1834. namespace = entry.scope.namespace_cname
  1835. if not self.cf_is_null:
  1836. code.putln(
  1837. '%s = PyObject_GetItem(%s, %s);' % (
  1838. self.result(),
  1839. namespace,
  1840. interned_cname))
  1841. code.putln('if (unlikely(!%s)) {' % self.result())
  1842. code.putln('PyErr_Clear();')
  1843. code.globalstate.use_utility_code(
  1844. UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c"))
  1845. code.putln(
  1846. '%s = __Pyx_GetModuleGlobalName(%s);' % (
  1847. self.result(),
  1848. interned_cname))
  1849. if not self.cf_is_null:
  1850. code.putln("}")
  1851. code.putln(code.error_goto_if_null(self.result(), self.pos))
  1852. code.put_gotref(self.py_result())
  1853. elif entry.is_builtin and not entry.scope.is_module_scope:
  1854. # known builtin
  1855. assert entry.type.is_pyobject, "Python global or builtin not a Python object"
  1856. interned_cname = code.intern_identifier(self.entry.name)
  1857. code.globalstate.use_utility_code(
  1858. UtilityCode.load_cached("GetBuiltinName", "ObjectHandling.c"))
  1859. code.putln(
  1860. '%s = __Pyx_GetBuiltinName(%s); %s' % (
  1861. self.result(),
  1862. interned_cname,
  1863. code.error_goto_if_null(self.result(), self.pos)))
  1864. code.put_gotref(self.py_result())
  1865. elif entry.is_pyglobal or (entry.is_builtin and entry.scope.is_module_scope):
  1866. # name in class body, global name or unknown builtin
  1867. assert entry.type.is_pyobject, "Python global or builtin not a Python object"
  1868. interned_cname = code.intern_identifier(self.entry.name)
  1869. if entry.scope.is_module_scope:
  1870. code.globalstate.use_utility_code(
  1871. UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c"))
  1872. code.putln(
  1873. '%s = __Pyx_GetModuleGlobalName(%s); %s' % (
  1874. self.result(),
  1875. interned_cname,
  1876. code.error_goto_if_null(self.result(), self.pos)))
  1877. else:
  1878. # FIXME: is_pyglobal is also used for class namespace
  1879. code.globalstate.use_utility_code(
  1880. UtilityCode.load_cached("GetNameInClass", "ObjectHandling.c"))
  1881. code.putln(
  1882. '%s = __Pyx_GetNameInClass(%s, %s); %s' % (
  1883. self.result(),
  1884. entry.scope.namespace_cname,
  1885. interned_cname,
  1886. code.error_goto_if_null(self.result(), self.pos)))
  1887. code.put_gotref(self.py_result())
  1888. elif entry.is_local or entry.in_closure or entry.from_closure or entry.type.is_memoryviewslice:
  1889. # Raise UnboundLocalError for objects and memoryviewslices
  1890. raise_unbound = (
  1891. (self.cf_maybe_null or self.cf_is_null) and not self.allow_null)
  1892. null_code = entry.type.check_for_null_code(entry.cname)
  1893. memslice_check = entry.type.is_memoryviewslice and self.initialized_check
  1894. if null_code and raise_unbound and (entry.type.is_pyobject or memslice_check):
  1895. code.put_error_if_unbound(self.pos, entry, self.in_nogil_context)
  1896. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  1897. exception_check=None, exception_value=None):
  1898. #print "NameNode.generate_assignment_code:", self.name ###
  1899. entry = self.entry
  1900. if entry is None:
  1901. return # There was an error earlier
  1902. if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
  1903. and not self.lhs_of_first_assignment and not rhs.in_module_scope):
  1904. error(self.pos, "Literal list must be assigned to pointer at time of declaration")
  1905. # is_pyglobal seems to be True for module level-globals only.
  1906. # We use this to access class->tp_dict if necessary.
  1907. if entry.is_pyglobal:
  1908. assert entry.type.is_pyobject, "Python global or builtin not a Python object"
  1909. interned_cname = code.intern_identifier(self.entry.name)
  1910. namespace = self.entry.scope.namespace_cname
  1911. if entry.is_member:
  1912. # if the entry is a member we have to cheat: SetAttr does not work
  1913. # on types, so we create a descriptor which is then added to tp_dict
  1914. setter = 'PyDict_SetItem'
  1915. namespace = '%s->tp_dict' % namespace
  1916. elif entry.scope.is_module_scope:
  1917. setter = 'PyDict_SetItem'
  1918. namespace = Naming.moddict_cname
  1919. elif entry.is_pyclass_attr:
  1920. code.globalstate.use_utility_code(UtilityCode.load_cached("SetNameInClass", "ObjectHandling.c"))
  1921. setter = '__Pyx_SetNameInClass'
  1922. else:
  1923. assert False, repr(entry)
  1924. code.put_error_if_neg(
  1925. self.pos,
  1926. '%s(%s, %s, %s)' % (
  1927. setter,
  1928. namespace,
  1929. interned_cname,
  1930. rhs.py_result()))
  1931. if debug_disposal_code:
  1932. print("NameNode.generate_assignment_code:")
  1933. print("...generating disposal code for %s" % rhs)
  1934. rhs.generate_disposal_code(code)
  1935. rhs.free_temps(code)
  1936. if entry.is_member:
  1937. # in Py2.6+, we need to invalidate the method cache
  1938. code.putln("PyType_Modified(%s);" %
  1939. entry.scope.parent_type.typeptr_cname)
  1940. else:
  1941. if self.type.is_memoryviewslice:
  1942. self.generate_acquire_memoryviewslice(rhs, code)
  1943. elif self.type.is_buffer:
  1944. # Generate code for doing the buffer release/acquisition.
  1945. # This might raise an exception in which case the assignment (done
  1946. # below) will not happen.
  1947. #
  1948. # The reason this is not in a typetest-like node is because the
  1949. # variables that the acquired buffer info is stored to is allocated
  1950. # per entry and coupled with it.
  1951. self.generate_acquire_buffer(rhs, code)
  1952. assigned = False
  1953. if self.type.is_pyobject:
  1954. #print "NameNode.generate_assignment_code: to", self.name ###
  1955. #print "...from", rhs ###
  1956. #print "...LHS type", self.type, "ctype", self.ctype() ###
  1957. #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
  1958. if self.use_managed_ref:
  1959. rhs.make_owned_reference(code)
  1960. is_external_ref = entry.is_cglobal or self.entry.in_closure or self.entry.from_closure
  1961. if is_external_ref:
  1962. if not self.cf_is_null:
  1963. if self.cf_maybe_null:
  1964. code.put_xgotref(self.py_result())
  1965. else:
  1966. code.put_gotref(self.py_result())
  1967. assigned = True
  1968. if entry.is_cglobal:
  1969. code.put_decref_set(
  1970. self.result(), rhs.result_as(self.ctype()))
  1971. else:
  1972. if not self.cf_is_null:
  1973. if self.cf_maybe_null:
  1974. code.put_xdecref_set(
  1975. self.result(), rhs.result_as(self.ctype()))
  1976. else:
  1977. code.put_decref_set(
  1978. self.result(), rhs.result_as(self.ctype()))
  1979. else:
  1980. assigned = False
  1981. if is_external_ref:
  1982. code.put_giveref(rhs.py_result())
  1983. if not self.type.is_memoryviewslice:
  1984. if not assigned:
  1985. if overloaded_assignment:
  1986. result = rhs.result()
  1987. if exception_check == '+':
  1988. translate_cpp_exception(code, self.pos, '%s = %s;' % (self.result(), result), exception_value, self.in_nogil_context)
  1989. else:
  1990. code.putln('%s = %s;' % (self.result(), result))
  1991. else:
  1992. result = rhs.result_as(self.ctype())
  1993. if is_pythran_expr(self.type):
  1994. code.putln('new (&%s) decltype(%s){%s};' % (self.result(), self.result(), result))
  1995. else:
  1996. code.putln('%s = %s;' % (self.result(), result))
  1997. if debug_disposal_code:
  1998. print("NameNode.generate_assignment_code:")
  1999. print("...generating post-assignment code for %s" % rhs)
  2000. rhs.generate_post_assignment_code(code)
  2001. elif rhs.result_in_temp():
  2002. rhs.generate_post_assignment_code(code)
  2003. rhs.free_temps(code)
  2004. def generate_acquire_memoryviewslice(self, rhs, code):
  2005. """
  2006. Slices, coercions from objects, return values etc are new references.
  2007. We have a borrowed reference in case of dst = src
  2008. """
  2009. from . import MemoryView
  2010. MemoryView.put_acquire_memoryviewslice(
  2011. lhs_cname=self.result(),
  2012. lhs_type=self.type,
  2013. lhs_pos=self.pos,
  2014. rhs=rhs,
  2015. code=code,
  2016. have_gil=not self.in_nogil_context,
  2017. first_assignment=self.cf_is_null)
  2018. def generate_acquire_buffer(self, rhs, code):
  2019. # rhstmp is only used in case the rhs is a complicated expression leading to
  2020. # the object, to avoid repeating the same C expression for every reference
  2021. # to the rhs. It does NOT hold a reference.
  2022. pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
  2023. if pretty_rhs:
  2024. rhstmp = rhs.result_as(self.ctype())
  2025. else:
  2026. rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
  2027. code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
  2028. from . import Buffer
  2029. Buffer.put_assign_to_buffer(self.result(), rhstmp, self.entry,
  2030. is_initialized=not self.lhs_of_first_assignment,
  2031. pos=self.pos, code=code)
  2032. if not pretty_rhs:
  2033. code.putln("%s = 0;" % rhstmp)
  2034. code.funcstate.release_temp(rhstmp)
  2035. def generate_deletion_code(self, code, ignore_nonexisting=False):
  2036. if self.entry is None:
  2037. return # There was an error earlier
  2038. elif self.entry.is_pyclass_attr:
  2039. namespace = self.entry.scope.namespace_cname
  2040. interned_cname = code.intern_identifier(self.entry.name)
  2041. if ignore_nonexisting:
  2042. key_error_code = 'PyErr_Clear(); else'
  2043. else:
  2044. # minor hack: fake a NameError on KeyError
  2045. key_error_code = (
  2046. '{ PyErr_Clear(); PyErr_Format(PyExc_NameError, "name \'%%s\' is not defined", "%s"); }' %
  2047. self.entry.name)
  2048. code.putln(
  2049. 'if (unlikely(PyObject_DelItem(%s, %s) < 0)) {'
  2050. ' if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) %s'
  2051. ' %s '
  2052. '}' % (namespace, interned_cname,
  2053. key_error_code,
  2054. code.error_goto(self.pos)))
  2055. elif self.entry.is_pyglobal:
  2056. code.globalstate.use_utility_code(
  2057. UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
  2058. interned_cname = code.intern_identifier(self.entry.name)
  2059. del_code = '__Pyx_PyObject_DelAttrStr(%s, %s)' % (
  2060. Naming.module_cname, interned_cname)
  2061. if ignore_nonexisting:
  2062. code.putln(
  2063. 'if (unlikely(%s < 0)) {'
  2064. ' if (likely(PyErr_ExceptionMatches(PyExc_AttributeError))) PyErr_Clear(); else %s '
  2065. '}' % (del_code, code.error_goto(self.pos)))
  2066. else:
  2067. code.put_error_if_neg(self.pos, del_code)
  2068. elif self.entry.type.is_pyobject or self.entry.type.is_memoryviewslice:
  2069. if not self.cf_is_null:
  2070. if self.cf_maybe_null and not ignore_nonexisting:
  2071. code.put_error_if_unbound(self.pos, self.entry)
  2072. if self.entry.type.is_pyobject:
  2073. if self.entry.in_closure:
  2074. # generator
  2075. if ignore_nonexisting and self.cf_maybe_null:
  2076. code.put_xgotref(self.result())
  2077. else:
  2078. code.put_gotref(self.result())
  2079. if ignore_nonexisting and self.cf_maybe_null:
  2080. code.put_xdecref(self.result(), self.ctype())
  2081. else:
  2082. code.put_decref(self.result(), self.ctype())
  2083. code.putln('%s = NULL;' % self.result())
  2084. else:
  2085. code.put_xdecref_memoryviewslice(self.entry.cname,
  2086. have_gil=not self.nogil)
  2087. else:
  2088. error(self.pos, "Deletion of C names not supported")
  2089. def annotate(self, code):
  2090. if hasattr(self, 'is_called') and self.is_called:
  2091. pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
  2092. if self.type.is_pyobject:
  2093. style, text = 'py_call', 'python function (%s)'
  2094. else:
  2095. style, text = 'c_call', 'c function (%s)'
  2096. code.annotate(pos, AnnotationItem(style, text % self.type, size=len(self.name)))
  2097. class BackquoteNode(ExprNode):
  2098. # `expr`
  2099. #
  2100. # arg ExprNode
  2101. type = py_object_type
  2102. subexprs = ['arg']
  2103. def analyse_types(self, env):
  2104. self.arg = self.arg.analyse_types(env)
  2105. self.arg = self.arg.coerce_to_pyobject(env)
  2106. self.is_temp = 1
  2107. return self
  2108. gil_message = "Backquote expression"
  2109. def calculate_constant_result(self):
  2110. self.constant_result = repr(self.arg.constant_result)
  2111. def generate_result_code(self, code):
  2112. code.putln(
  2113. "%s = PyObject_Repr(%s); %s" % (
  2114. self.result(),
  2115. self.arg.py_result(),
  2116. code.error_goto_if_null(self.result(), self.pos)))
  2117. code.put_gotref(self.py_result())
  2118. class ImportNode(ExprNode):
  2119. # Used as part of import statement implementation.
  2120. # Implements result =
  2121. # __import__(module_name, globals(), None, name_list, level)
  2122. #
  2123. # module_name StringNode dotted name of module. Empty module
  2124. # name means importing the parent package according
  2125. # to level
  2126. # name_list ListNode or None list of names to be imported
  2127. # level int relative import level:
  2128. # -1: attempt both relative import and absolute import;
  2129. # 0: absolute import;
  2130. # >0: the number of parent directories to search
  2131. # relative to the current module.
  2132. # None: decide the level according to language level and
  2133. # directives
  2134. type = py_object_type
  2135. subexprs = ['module_name', 'name_list']
  2136. def analyse_types(self, env):
  2137. if self.level is None:
  2138. if (env.directives['py2_import'] or
  2139. Future.absolute_import not in env.global_scope().context.future_directives):
  2140. self.level = -1
  2141. else:
  2142. self.level = 0
  2143. module_name = self.module_name.analyse_types(env)
  2144. self.module_name = module_name.coerce_to_pyobject(env)
  2145. if self.name_list:
  2146. name_list = self.name_list.analyse_types(env)
  2147. self.name_list = name_list.coerce_to_pyobject(env)
  2148. self.is_temp = 1
  2149. return self
  2150. gil_message = "Python import"
  2151. def generate_result_code(self, code):
  2152. if self.name_list:
  2153. name_list_code = self.name_list.py_result()
  2154. else:
  2155. name_list_code = "0"
  2156. code.globalstate.use_utility_code(UtilityCode.load_cached("Import", "ImportExport.c"))
  2157. import_code = "__Pyx_Import(%s, %s, %d)" % (
  2158. self.module_name.py_result(),
  2159. name_list_code,
  2160. self.level)
  2161. if (self.level <= 0 and
  2162. self.module_name.is_string_literal and
  2163. self.module_name.value in utility_code_for_imports):
  2164. helper_func, code_name, code_file = utility_code_for_imports[self.module_name.value]
  2165. code.globalstate.use_utility_code(UtilityCode.load_cached(code_name, code_file))
  2166. import_code = '%s(%s)' % (helper_func, import_code)
  2167. code.putln("%s = %s; %s" % (
  2168. self.result(),
  2169. import_code,
  2170. code.error_goto_if_null(self.result(), self.pos)))
  2171. code.put_gotref(self.py_result())
  2172. class IteratorNode(ExprNode):
  2173. # Used as part of for statement implementation.
  2174. #
  2175. # Implements result = iter(sequence)
  2176. #
  2177. # sequence ExprNode
  2178. type = py_object_type
  2179. iter_func_ptr = None
  2180. counter_cname = None
  2181. cpp_iterator_cname = None
  2182. reversed = False # currently only used for list/tuple types (see Optimize.py)
  2183. is_async = False
  2184. subexprs = ['sequence']
  2185. def analyse_types(self, env):
  2186. self.sequence = self.sequence.analyse_types(env)
  2187. if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
  2188. not self.sequence.type.is_string:
  2189. # C array iteration will be transformed later on
  2190. self.type = self.sequence.type
  2191. elif self.sequence.type.is_cpp_class:
  2192. self.analyse_cpp_types(env)
  2193. else:
  2194. self.sequence = self.sequence.coerce_to_pyobject(env)
  2195. if self.sequence.type in (list_type, tuple_type):
  2196. self.sequence = self.sequence.as_none_safe_node("'NoneType' object is not iterable")
  2197. self.is_temp = 1
  2198. return self
  2199. gil_message = "Iterating over Python object"
  2200. _func_iternext_type = PyrexTypes.CPtrType(PyrexTypes.CFuncType(
  2201. PyrexTypes.py_object_type, [
  2202. PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None),
  2203. ]))
  2204. def type_dependencies(self, env):
  2205. return self.sequence.type_dependencies(env)
  2206. def infer_type(self, env):
  2207. sequence_type = self.sequence.infer_type(env)
  2208. if sequence_type.is_array or sequence_type.is_ptr:
  2209. return sequence_type
  2210. elif sequence_type.is_cpp_class:
  2211. begin = sequence_type.scope.lookup("begin")
  2212. if begin is not None:
  2213. return begin.type.return_type
  2214. elif sequence_type.is_pyobject:
  2215. return sequence_type
  2216. return py_object_type
  2217. def analyse_cpp_types(self, env):
  2218. sequence_type = self.sequence.type
  2219. if sequence_type.is_ptr:
  2220. sequence_type = sequence_type.base_type
  2221. begin = sequence_type.scope.lookup("begin")
  2222. end = sequence_type.scope.lookup("end")
  2223. if (begin is None
  2224. or not begin.type.is_cfunction
  2225. or begin.type.args):
  2226. error(self.pos, "missing begin() on %s" % self.sequence.type)
  2227. self.type = error_type
  2228. return
  2229. if (end is None
  2230. or not end.type.is_cfunction
  2231. or end.type.args):
  2232. error(self.pos, "missing end() on %s" % self.sequence.type)
  2233. self.type = error_type
  2234. return
  2235. iter_type = begin.type.return_type
  2236. if iter_type.is_cpp_class:
  2237. if env.lookup_operator_for_types(
  2238. self.pos,
  2239. "!=",
  2240. [iter_type, end.type.return_type]) is None:
  2241. error(self.pos, "missing operator!= on result of begin() on %s" % self.sequence.type)
  2242. self.type = error_type
  2243. return
  2244. if env.lookup_operator_for_types(self.pos, '++', [iter_type]) is None:
  2245. error(self.pos, "missing operator++ on result of begin() on %s" % self.sequence.type)
  2246. self.type = error_type
  2247. return
  2248. if env.lookup_operator_for_types(self.pos, '*', [iter_type]) is None:
  2249. error(self.pos, "missing operator* on result of begin() on %s" % self.sequence.type)
  2250. self.type = error_type
  2251. return
  2252. self.type = iter_type
  2253. elif iter_type.is_ptr:
  2254. if not (iter_type == end.type.return_type):
  2255. error(self.pos, "incompatible types for begin() and end()")
  2256. self.type = iter_type
  2257. else:
  2258. error(self.pos, "result type of begin() on %s must be a C++ class or pointer" % self.sequence.type)
  2259. self.type = error_type
  2260. return
  2261. def generate_result_code(self, code):
  2262. sequence_type = self.sequence.type
  2263. if sequence_type.is_cpp_class:
  2264. if self.sequence.is_name:
  2265. # safe: C++ won't allow you to reassign to class references
  2266. begin_func = "%s.begin" % self.sequence.result()
  2267. else:
  2268. sequence_type = PyrexTypes.c_ptr_type(sequence_type)
  2269. self.cpp_iterator_cname = code.funcstate.allocate_temp(sequence_type, manage_ref=False)
  2270. code.putln("%s = &%s;" % (self.cpp_iterator_cname, self.sequence.result()))
  2271. begin_func = "%s->begin" % self.cpp_iterator_cname
  2272. # TODO: Limit scope.
  2273. code.putln("%s = %s();" % (self.result(), begin_func))
  2274. return
  2275. if sequence_type.is_array or sequence_type.is_ptr:
  2276. raise InternalError("for in carray slice not transformed")
  2277. is_builtin_sequence = sequence_type in (list_type, tuple_type)
  2278. if not is_builtin_sequence:
  2279. # reversed() not currently optimised (see Optimize.py)
  2280. assert not self.reversed, "internal error: reversed() only implemented for list/tuple objects"
  2281. self.may_be_a_sequence = not sequence_type.is_builtin_type
  2282. if self.may_be_a_sequence:
  2283. code.putln(
  2284. "if (likely(PyList_CheckExact(%s)) || PyTuple_CheckExact(%s)) {" % (
  2285. self.sequence.py_result(),
  2286. self.sequence.py_result()))
  2287. if is_builtin_sequence or self.may_be_a_sequence:
  2288. self.counter_cname = code.funcstate.allocate_temp(
  2289. PyrexTypes.c_py_ssize_t_type, manage_ref=False)
  2290. if self.reversed:
  2291. if sequence_type is list_type:
  2292. init_value = 'PyList_GET_SIZE(%s) - 1' % self.result()
  2293. else:
  2294. init_value = 'PyTuple_GET_SIZE(%s) - 1' % self.result()
  2295. else:
  2296. init_value = '0'
  2297. code.putln("%s = %s; __Pyx_INCREF(%s); %s = %s;" % (
  2298. self.result(),
  2299. self.sequence.py_result(),
  2300. self.result(),
  2301. self.counter_cname,
  2302. init_value))
  2303. if not is_builtin_sequence:
  2304. self.iter_func_ptr = code.funcstate.allocate_temp(self._func_iternext_type, manage_ref=False)
  2305. if self.may_be_a_sequence:
  2306. code.putln("%s = NULL;" % self.iter_func_ptr)
  2307. code.putln("} else {")
  2308. code.put("%s = -1; " % self.counter_cname)
  2309. code.putln("%s = PyObject_GetIter(%s); %s" % (
  2310. self.result(),
  2311. self.sequence.py_result(),
  2312. code.error_goto_if_null(self.result(), self.pos)))
  2313. code.put_gotref(self.py_result())
  2314. # PyObject_GetIter() fails if "tp_iternext" is not set, but the check below
  2315. # makes it visible to the C compiler that the pointer really isn't NULL, so that
  2316. # it can distinguish between the special cases and the generic case
  2317. code.putln("%s = Py_TYPE(%s)->tp_iternext; %s" % (
  2318. self.iter_func_ptr, self.py_result(),
  2319. code.error_goto_if_null(self.iter_func_ptr, self.pos)))
  2320. if self.may_be_a_sequence:
  2321. code.putln("}")
  2322. def generate_next_sequence_item(self, test_name, result_name, code):
  2323. assert self.counter_cname, "internal error: counter_cname temp not prepared"
  2324. final_size = 'Py%s_GET_SIZE(%s)' % (test_name, self.py_result())
  2325. if self.sequence.is_sequence_constructor:
  2326. item_count = len(self.sequence.args)
  2327. if self.sequence.mult_factor is None:
  2328. final_size = item_count
  2329. elif isinstance(self.sequence.mult_factor.constant_result, _py_int_types):
  2330. final_size = item_count * self.sequence.mult_factor.constant_result
  2331. code.putln("if (%s >= %s) break;" % (self.counter_cname, final_size))
  2332. if self.reversed:
  2333. inc_dec = '--'
  2334. else:
  2335. inc_dec = '++'
  2336. code.putln("#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS")
  2337. code.putln(
  2338. "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s%s; %s" % (
  2339. result_name,
  2340. test_name,
  2341. self.py_result(),
  2342. self.counter_cname,
  2343. result_name,
  2344. self.counter_cname,
  2345. inc_dec,
  2346. # use the error label to avoid C compiler warnings if we only use it below
  2347. code.error_goto_if_neg('0', self.pos)
  2348. ))
  2349. code.putln("#else")
  2350. code.putln(
  2351. "%s = PySequence_ITEM(%s, %s); %s%s; %s" % (
  2352. result_name,
  2353. self.py_result(),
  2354. self.counter_cname,
  2355. self.counter_cname,
  2356. inc_dec,
  2357. code.error_goto_if_null(result_name, self.pos)))
  2358. code.put_gotref(result_name)
  2359. code.putln("#endif")
  2360. def generate_iter_next_result_code(self, result_name, code):
  2361. sequence_type = self.sequence.type
  2362. if self.reversed:
  2363. code.putln("if (%s < 0) break;" % self.counter_cname)
  2364. if sequence_type.is_cpp_class:
  2365. if self.cpp_iterator_cname:
  2366. end_func = "%s->end" % self.cpp_iterator_cname
  2367. else:
  2368. end_func = "%s.end" % self.sequence.result()
  2369. # TODO: Cache end() call?
  2370. code.putln("if (!(%s != %s())) break;" % (
  2371. self.result(),
  2372. end_func))
  2373. code.putln("%s = *%s;" % (
  2374. result_name,
  2375. self.result()))
  2376. code.putln("++%s;" % self.result())
  2377. return
  2378. elif sequence_type is list_type:
  2379. self.generate_next_sequence_item('List', result_name, code)
  2380. return
  2381. elif sequence_type is tuple_type:
  2382. self.generate_next_sequence_item('Tuple', result_name, code)
  2383. return
  2384. if self.may_be_a_sequence:
  2385. code.putln("if (likely(!%s)) {" % self.iter_func_ptr)
  2386. code.putln("if (likely(PyList_CheckExact(%s))) {" % self.py_result())
  2387. self.generate_next_sequence_item('List', result_name, code)
  2388. code.putln("} else {")
  2389. self.generate_next_sequence_item('Tuple', result_name, code)
  2390. code.putln("}")
  2391. code.put("} else ")
  2392. code.putln("{")
  2393. code.putln(
  2394. "%s = %s(%s);" % (
  2395. result_name,
  2396. self.iter_func_ptr,
  2397. self.py_result()))
  2398. code.putln("if (unlikely(!%s)) {" % result_name)
  2399. code.putln("PyObject* exc_type = PyErr_Occurred();")
  2400. code.putln("if (exc_type) {")
  2401. code.putln("if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();")
  2402. code.putln("else %s" % code.error_goto(self.pos))
  2403. code.putln("}")
  2404. code.putln("break;")
  2405. code.putln("}")
  2406. code.put_gotref(result_name)
  2407. code.putln("}")
  2408. def free_temps(self, code):
  2409. if self.counter_cname:
  2410. code.funcstate.release_temp(self.counter_cname)
  2411. if self.iter_func_ptr:
  2412. code.funcstate.release_temp(self.iter_func_ptr)
  2413. self.iter_func_ptr = None
  2414. if self.cpp_iterator_cname:
  2415. code.funcstate.release_temp(self.cpp_iterator_cname)
  2416. ExprNode.free_temps(self, code)
  2417. class NextNode(AtomicExprNode):
  2418. # Used as part of for statement implementation.
  2419. # Implements result = next(iterator)
  2420. # Created during analyse_types phase.
  2421. # The iterator is not owned by this node.
  2422. #
  2423. # iterator IteratorNode
  2424. def __init__(self, iterator):
  2425. AtomicExprNode.__init__(self, iterator.pos)
  2426. self.iterator = iterator
  2427. def nogil_check(self, env):
  2428. # ignore - errors (if any) are already handled by IteratorNode
  2429. pass
  2430. def type_dependencies(self, env):
  2431. return self.iterator.type_dependencies(env)
  2432. def infer_type(self, env, iterator_type=None):
  2433. if iterator_type is None:
  2434. iterator_type = self.iterator.infer_type(env)
  2435. if iterator_type.is_ptr or iterator_type.is_array:
  2436. return iterator_type.base_type
  2437. elif iterator_type.is_cpp_class:
  2438. item_type = env.lookup_operator_for_types(self.pos, "*", [iterator_type]).type.return_type
  2439. if item_type.is_reference:
  2440. item_type = item_type.ref_base_type
  2441. if item_type.is_const:
  2442. item_type = item_type.const_base_type
  2443. return item_type
  2444. else:
  2445. # Avoid duplication of complicated logic.
  2446. fake_index_node = IndexNode(
  2447. self.pos,
  2448. base=self.iterator.sequence,
  2449. index=IntNode(self.pos, value='PY_SSIZE_T_MAX',
  2450. type=PyrexTypes.c_py_ssize_t_type))
  2451. return fake_index_node.infer_type(env)
  2452. def analyse_types(self, env):
  2453. self.type = self.infer_type(env, self.iterator.type)
  2454. self.is_temp = 1
  2455. return self
  2456. def generate_result_code(self, code):
  2457. self.iterator.generate_iter_next_result_code(self.result(), code)
  2458. class AsyncIteratorNode(ExprNode):
  2459. # Used as part of 'async for' statement implementation.
  2460. #
  2461. # Implements result = sequence.__aiter__()
  2462. #
  2463. # sequence ExprNode
  2464. subexprs = ['sequence']
  2465. is_async = True
  2466. type = py_object_type
  2467. is_temp = 1
  2468. def infer_type(self, env):
  2469. return py_object_type
  2470. def analyse_types(self, env):
  2471. self.sequence = self.sequence.analyse_types(env)
  2472. if not self.sequence.type.is_pyobject:
  2473. error(self.pos, "async for loops not allowed on C/C++ types")
  2474. self.sequence = self.sequence.coerce_to_pyobject(env)
  2475. return self
  2476. def generate_result_code(self, code):
  2477. code.globalstate.use_utility_code(UtilityCode.load_cached("AsyncIter", "Coroutine.c"))
  2478. code.putln("%s = __Pyx_Coroutine_GetAsyncIter(%s); %s" % (
  2479. self.result(),
  2480. self.sequence.py_result(),
  2481. code.error_goto_if_null(self.result(), self.pos)))
  2482. code.put_gotref(self.result())
  2483. class AsyncNextNode(AtomicExprNode):
  2484. # Used as part of 'async for' statement implementation.
  2485. # Implements result = iterator.__anext__()
  2486. # Created during analyse_types phase.
  2487. # The iterator is not owned by this node.
  2488. #
  2489. # iterator IteratorNode
  2490. type = py_object_type
  2491. is_temp = 1
  2492. def __init__(self, iterator):
  2493. AtomicExprNode.__init__(self, iterator.pos)
  2494. self.iterator = iterator
  2495. def infer_type(self, env):
  2496. return py_object_type
  2497. def analyse_types(self, env):
  2498. return self
  2499. def generate_result_code(self, code):
  2500. code.globalstate.use_utility_code(UtilityCode.load_cached("AsyncIter", "Coroutine.c"))
  2501. code.putln("%s = __Pyx_Coroutine_AsyncIterNext(%s); %s" % (
  2502. self.result(),
  2503. self.iterator.py_result(),
  2504. code.error_goto_if_null(self.result(), self.pos)))
  2505. code.put_gotref(self.result())
  2506. class WithExitCallNode(ExprNode):
  2507. # The __exit__() call of a 'with' statement. Used in both the
  2508. # except and finally clauses.
  2509. # with_stat WithStatNode the surrounding 'with' statement
  2510. # args TupleNode or ResultStatNode the exception info tuple
  2511. # await_expr AwaitExprNode the await expression of an 'async with' statement
  2512. subexprs = ['args', 'await_expr']
  2513. test_if_run = True
  2514. await_expr = None
  2515. def analyse_types(self, env):
  2516. self.args = self.args.analyse_types(env)
  2517. if self.await_expr:
  2518. self.await_expr = self.await_expr.analyse_types(env)
  2519. self.type = PyrexTypes.c_bint_type
  2520. self.is_temp = True
  2521. return self
  2522. def generate_evaluation_code(self, code):
  2523. if self.test_if_run:
  2524. # call only if it was not already called (and decref-cleared)
  2525. code.putln("if (%s) {" % self.with_stat.exit_var)
  2526. self.args.generate_evaluation_code(code)
  2527. result_var = code.funcstate.allocate_temp(py_object_type, manage_ref=False)
  2528. code.mark_pos(self.pos)
  2529. code.globalstate.use_utility_code(UtilityCode.load_cached(
  2530. "PyObjectCall", "ObjectHandling.c"))
  2531. code.putln("%s = __Pyx_PyObject_Call(%s, %s, NULL);" % (
  2532. result_var,
  2533. self.with_stat.exit_var,
  2534. self.args.result()))
  2535. code.put_decref_clear(self.with_stat.exit_var, type=py_object_type)
  2536. self.args.generate_disposal_code(code)
  2537. self.args.free_temps(code)
  2538. code.putln(code.error_goto_if_null(result_var, self.pos))
  2539. code.put_gotref(result_var)
  2540. if self.await_expr:
  2541. # FIXME: result_var temp currently leaks into the closure
  2542. self.await_expr.generate_evaluation_code(code, source_cname=result_var, decref_source=True)
  2543. code.putln("%s = %s;" % (result_var, self.await_expr.py_result()))
  2544. self.await_expr.generate_post_assignment_code(code)
  2545. self.await_expr.free_temps(code)
  2546. if self.result_is_used:
  2547. self.allocate_temp_result(code)
  2548. code.putln("%s = __Pyx_PyObject_IsTrue(%s);" % (self.result(), result_var))
  2549. code.put_decref_clear(result_var, type=py_object_type)
  2550. if self.result_is_used:
  2551. code.put_error_if_neg(self.pos, self.result())
  2552. code.funcstate.release_temp(result_var)
  2553. if self.test_if_run:
  2554. code.putln("}")
  2555. class ExcValueNode(AtomicExprNode):
  2556. # Node created during analyse_types phase
  2557. # of an ExceptClauseNode to fetch the current
  2558. # exception value.
  2559. type = py_object_type
  2560. def __init__(self, pos):
  2561. ExprNode.__init__(self, pos)
  2562. def set_var(self, var):
  2563. self.var = var
  2564. def calculate_result_code(self):
  2565. return self.var
  2566. def generate_result_code(self, code):
  2567. pass
  2568. def analyse_types(self, env):
  2569. return self
  2570. class TempNode(ExprNode):
  2571. # Node created during analyse_types phase
  2572. # of some nodes to hold a temporary value.
  2573. #
  2574. # Note: One must call "allocate" and "release" on
  2575. # the node during code generation to get/release the temp.
  2576. # This is because the temp result is often used outside of
  2577. # the regular cycle.
  2578. subexprs = []
  2579. def __init__(self, pos, type, env=None):
  2580. ExprNode.__init__(self, pos)
  2581. self.type = type
  2582. if type.is_pyobject:
  2583. self.result_ctype = py_object_type
  2584. self.is_temp = 1
  2585. def analyse_types(self, env):
  2586. return self
  2587. def analyse_target_declaration(self, env):
  2588. pass
  2589. def generate_result_code(self, code):
  2590. pass
  2591. def allocate(self, code):
  2592. self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
  2593. def release(self, code):
  2594. code.funcstate.release_temp(self.temp_cname)
  2595. self.temp_cname = None
  2596. def result(self):
  2597. try:
  2598. return self.temp_cname
  2599. except:
  2600. assert False, "Remember to call allocate/release on TempNode"
  2601. raise
  2602. # Do not participate in normal temp alloc/dealloc:
  2603. def allocate_temp_result(self, code):
  2604. pass
  2605. def release_temp_result(self, code):
  2606. pass
  2607. class PyTempNode(TempNode):
  2608. # TempNode holding a Python value.
  2609. def __init__(self, pos, env):
  2610. TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
  2611. class RawCNameExprNode(ExprNode):
  2612. subexprs = []
  2613. def __init__(self, pos, type=None, cname=None):
  2614. ExprNode.__init__(self, pos, type=type)
  2615. if cname is not None:
  2616. self.cname = cname
  2617. def analyse_types(self, env):
  2618. return self
  2619. def set_cname(self, cname):
  2620. self.cname = cname
  2621. def result(self):
  2622. return self.cname
  2623. def generate_result_code(self, code):
  2624. pass
  2625. #-------------------------------------------------------------------
  2626. #
  2627. # F-strings
  2628. #
  2629. #-------------------------------------------------------------------
  2630. class JoinedStrNode(ExprNode):
  2631. # F-strings
  2632. #
  2633. # values [UnicodeNode|FormattedValueNode] Substrings of the f-string
  2634. #
  2635. type = unicode_type
  2636. is_temp = True
  2637. subexprs = ['values']
  2638. def analyse_types(self, env):
  2639. self.values = [v.analyse_types(env).coerce_to_pyobject(env) for v in self.values]
  2640. return self
  2641. def may_be_none(self):
  2642. # PyUnicode_Join() always returns a Unicode string or raises an exception
  2643. return False
  2644. def generate_evaluation_code(self, code):
  2645. code.mark_pos(self.pos)
  2646. num_items = len(self.values)
  2647. list_var = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  2648. ulength_var = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
  2649. max_char_var = code.funcstate.allocate_temp(PyrexTypes.c_py_ucs4_type, manage_ref=False)
  2650. code.putln('%s = PyTuple_New(%s); %s' % (
  2651. list_var,
  2652. num_items,
  2653. code.error_goto_if_null(list_var, self.pos)))
  2654. code.put_gotref(list_var)
  2655. code.putln("%s = 0;" % ulength_var)
  2656. code.putln("%s = 127;" % max_char_var) # at least ASCII character range
  2657. for i, node in enumerate(self.values):
  2658. node.generate_evaluation_code(code)
  2659. node.make_owned_reference(code)
  2660. ulength = "__Pyx_PyUnicode_GET_LENGTH(%s)" % node.py_result()
  2661. max_char_value = "__Pyx_PyUnicode_MAX_CHAR_VALUE(%s)" % node.py_result()
  2662. is_ascii = False
  2663. if isinstance(node, UnicodeNode):
  2664. try:
  2665. # most strings will be ASCII or at least Latin-1
  2666. node.value.encode('iso8859-1')
  2667. max_char_value = '255'
  2668. node.value.encode('us-ascii')
  2669. is_ascii = True
  2670. except UnicodeEncodeError:
  2671. if max_char_value != '255':
  2672. # not ISO8859-1 => check BMP limit
  2673. max_char = max(map(ord, node.value))
  2674. if max_char < 0xD800:
  2675. # BMP-only, no surrogate pairs used
  2676. max_char_value = '65535'
  2677. ulength = str(len(node.value))
  2678. elif max_char >= 65536:
  2679. # cleary outside of BMP, and not on a 16-bit Unicode system
  2680. max_char_value = '1114111'
  2681. ulength = str(len(node.value))
  2682. else:
  2683. # not really worth implementing a check for surrogate pairs here
  2684. # drawback: C code can differ when generating on Py2 with 2-byte Unicode
  2685. pass
  2686. else:
  2687. ulength = str(len(node.value))
  2688. elif isinstance(node, FormattedValueNode) and node.value.type.is_numeric:
  2689. is_ascii = True # formatted C numbers are always ASCII
  2690. if not is_ascii:
  2691. code.putln("%s = (%s > %s) ? %s : %s;" % (
  2692. max_char_var, max_char_value, max_char_var, max_char_value, max_char_var))
  2693. code.putln("%s += %s;" % (ulength_var, ulength))
  2694. code.put_giveref(node.py_result())
  2695. code.putln('PyTuple_SET_ITEM(%s, %s, %s);' % (list_var, i, node.py_result()))
  2696. node.generate_post_assignment_code(code)
  2697. node.free_temps(code)
  2698. code.mark_pos(self.pos)
  2699. self.allocate_temp_result(code)
  2700. code.globalstate.use_utility_code(UtilityCode.load_cached("JoinPyUnicode", "StringTools.c"))
  2701. code.putln('%s = __Pyx_PyUnicode_Join(%s, %d, %s, %s); %s' % (
  2702. self.result(),
  2703. list_var,
  2704. num_items,
  2705. ulength_var,
  2706. max_char_var,
  2707. code.error_goto_if_null(self.py_result(), self.pos)))
  2708. code.put_gotref(self.py_result())
  2709. code.put_decref_clear(list_var, py_object_type)
  2710. code.funcstate.release_temp(list_var)
  2711. code.funcstate.release_temp(ulength_var)
  2712. code.funcstate.release_temp(max_char_var)
  2713. class FormattedValueNode(ExprNode):
  2714. # {}-delimited portions of an f-string
  2715. #
  2716. # value ExprNode The expression itself
  2717. # conversion_char str or None Type conversion (!s, !r, !a, or none)
  2718. # format_spec JoinedStrNode or None Format string passed to __format__
  2719. # c_format_spec str or None If not None, formatting can be done at the C level
  2720. subexprs = ['value', 'format_spec']
  2721. type = unicode_type
  2722. is_temp = True
  2723. c_format_spec = None
  2724. find_conversion_func = {
  2725. 's': 'PyObject_Str',
  2726. 'r': 'PyObject_Repr',
  2727. 'a': 'PyObject_ASCII', # NOTE: mapped to PyObject_Repr() in Py2
  2728. }.get
  2729. def may_be_none(self):
  2730. # PyObject_Format() always returns a Unicode string or raises an exception
  2731. return False
  2732. def analyse_types(self, env):
  2733. self.value = self.value.analyse_types(env)
  2734. if not self.format_spec or self.format_spec.is_string_literal:
  2735. c_format_spec = self.format_spec.value if self.format_spec else self.value.type.default_format_spec
  2736. if self.value.type.can_coerce_to_pystring(env, format_spec=c_format_spec):
  2737. self.c_format_spec = c_format_spec
  2738. if self.format_spec:
  2739. self.format_spec = self.format_spec.analyse_types(env).coerce_to_pyobject(env)
  2740. if self.c_format_spec is None:
  2741. self.value = self.value.coerce_to_pyobject(env)
  2742. if not self.format_spec and (not self.conversion_char or self.conversion_char == 's'):
  2743. if self.value.type is unicode_type and not self.value.may_be_none():
  2744. # value is definitely a unicode string and we don't format it any special
  2745. return self.value
  2746. return self
  2747. def generate_result_code(self, code):
  2748. if self.c_format_spec is not None and not self.value.type.is_pyobject:
  2749. convert_func_call = self.value.type.convert_to_pystring(
  2750. self.value.result(), code, self.c_format_spec)
  2751. code.putln("%s = %s; %s" % (
  2752. self.result(),
  2753. convert_func_call,
  2754. code.error_goto_if_null(self.result(), self.pos)))
  2755. code.put_gotref(self.py_result())
  2756. return
  2757. value_result = self.value.py_result()
  2758. value_is_unicode = self.value.type is unicode_type and not self.value.may_be_none()
  2759. if self.format_spec:
  2760. format_func = '__Pyx_PyObject_Format'
  2761. format_spec = self.format_spec.py_result()
  2762. else:
  2763. # common case: expect simple Unicode pass-through if no format spec
  2764. format_func = '__Pyx_PyObject_FormatSimple'
  2765. # passing a Unicode format string in Py2 forces PyObject_Format() to also return a Unicode string
  2766. format_spec = Naming.empty_unicode
  2767. conversion_char = self.conversion_char
  2768. if conversion_char == 's' and value_is_unicode:
  2769. # no need to pipe unicode strings through str()
  2770. conversion_char = None
  2771. if conversion_char:
  2772. fn = self.find_conversion_func(conversion_char)
  2773. assert fn is not None, "invalid conversion character found: '%s'" % conversion_char
  2774. value_result = '%s(%s)' % (fn, value_result)
  2775. code.globalstate.use_utility_code(
  2776. UtilityCode.load_cached("PyObjectFormatAndDecref", "StringTools.c"))
  2777. format_func += 'AndDecref'
  2778. elif self.format_spec:
  2779. code.globalstate.use_utility_code(
  2780. UtilityCode.load_cached("PyObjectFormat", "StringTools.c"))
  2781. else:
  2782. code.globalstate.use_utility_code(
  2783. UtilityCode.load_cached("PyObjectFormatSimple", "StringTools.c"))
  2784. code.putln("%s = %s(%s, %s); %s" % (
  2785. self.result(),
  2786. format_func,
  2787. value_result,
  2788. format_spec,
  2789. code.error_goto_if_null(self.result(), self.pos)))
  2790. code.put_gotref(self.py_result())
  2791. #-------------------------------------------------------------------
  2792. #
  2793. # Parallel nodes (cython.parallel.thread(savailable|id))
  2794. #
  2795. #-------------------------------------------------------------------
  2796. class ParallelThreadsAvailableNode(AtomicExprNode):
  2797. """
  2798. Note: this is disabled and not a valid directive at this moment
  2799. Implements cython.parallel.threadsavailable(). If we are called from the
  2800. sequential part of the application, we need to call omp_get_max_threads(),
  2801. and in the parallel part we can just call omp_get_num_threads()
  2802. """
  2803. type = PyrexTypes.c_int_type
  2804. def analyse_types(self, env):
  2805. self.is_temp = True
  2806. # env.add_include_file("omp.h")
  2807. return self
  2808. def generate_result_code(self, code):
  2809. code.putln("#ifdef _OPENMP")
  2810. code.putln("if (omp_in_parallel()) %s = omp_get_max_threads();" %
  2811. self.temp_code)
  2812. code.putln("else %s = omp_get_num_threads();" % self.temp_code)
  2813. code.putln("#else")
  2814. code.putln("%s = 1;" % self.temp_code)
  2815. code.putln("#endif")
  2816. def result(self):
  2817. return self.temp_code
  2818. class ParallelThreadIdNode(AtomicExprNode): #, Nodes.ParallelNode):
  2819. """
  2820. Implements cython.parallel.threadid()
  2821. """
  2822. type = PyrexTypes.c_int_type
  2823. def analyse_types(self, env):
  2824. self.is_temp = True
  2825. # env.add_include_file("omp.h")
  2826. return self
  2827. def generate_result_code(self, code):
  2828. code.putln("#ifdef _OPENMP")
  2829. code.putln("%s = omp_get_thread_num();" % self.temp_code)
  2830. code.putln("#else")
  2831. code.putln("%s = 0;" % self.temp_code)
  2832. code.putln("#endif")
  2833. def result(self):
  2834. return self.temp_code
  2835. #-------------------------------------------------------------------
  2836. #
  2837. # Trailer nodes
  2838. #
  2839. #-------------------------------------------------------------------
  2840. class _IndexingBaseNode(ExprNode):
  2841. # Base class for indexing nodes.
  2842. #
  2843. # base ExprNode the value being indexed
  2844. def is_ephemeral(self):
  2845. # in most cases, indexing will return a safe reference to an object in a container,
  2846. # so we consider the result safe if the base object is
  2847. return self.base.is_ephemeral() or self.base.type in (
  2848. basestring_type, str_type, bytes_type, bytearray_type, unicode_type)
  2849. def check_const_addr(self):
  2850. return self.base.check_const_addr() and self.index.check_const()
  2851. def is_lvalue(self):
  2852. # NOTE: references currently have both is_reference and is_ptr
  2853. # set. Since pointers and references have different lvalue
  2854. # rules, we must be careful to separate the two.
  2855. if self.type.is_reference:
  2856. if self.type.ref_base_type.is_array:
  2857. # fixed-sized arrays aren't l-values
  2858. return False
  2859. elif self.type.is_ptr:
  2860. # non-const pointers can always be reassigned
  2861. return True
  2862. # Just about everything else returned by the index operator
  2863. # can be an lvalue.
  2864. return True
  2865. class IndexNode(_IndexingBaseNode):
  2866. # Sequence indexing.
  2867. #
  2868. # base ExprNode
  2869. # index ExprNode
  2870. # type_indices [PyrexType]
  2871. #
  2872. # is_fused_index boolean Whether the index is used to specialize a
  2873. # c(p)def function
  2874. subexprs = ['base', 'index']
  2875. type_indices = None
  2876. is_subscript = True
  2877. is_fused_index = False
  2878. def calculate_constant_result(self):
  2879. self.constant_result = self.base.constant_result[self.index.constant_result]
  2880. def compile_time_value(self, denv):
  2881. base = self.base.compile_time_value(denv)
  2882. index = self.index.compile_time_value(denv)
  2883. try:
  2884. return base[index]
  2885. except Exception as e:
  2886. self.compile_time_value_error(e)
  2887. def is_simple(self):
  2888. base = self.base
  2889. return (base.is_simple() and self.index.is_simple()
  2890. and base.type and (base.type.is_ptr or base.type.is_array))
  2891. def may_be_none(self):
  2892. base_type = self.base.type
  2893. if base_type:
  2894. if base_type.is_string:
  2895. return False
  2896. if isinstance(self.index, SliceNode):
  2897. # slicing!
  2898. if base_type in (bytes_type, bytearray_type, str_type, unicode_type,
  2899. basestring_type, list_type, tuple_type):
  2900. return False
  2901. return ExprNode.may_be_none(self)
  2902. def analyse_target_declaration(self, env):
  2903. pass
  2904. def analyse_as_type(self, env):
  2905. base_type = self.base.analyse_as_type(env)
  2906. if base_type and not base_type.is_pyobject:
  2907. if base_type.is_cpp_class:
  2908. if isinstance(self.index, TupleNode):
  2909. template_values = self.index.args
  2910. else:
  2911. template_values = [self.index]
  2912. type_node = Nodes.TemplatedTypeNode(
  2913. pos=self.pos,
  2914. positional_args=template_values,
  2915. keyword_args=None)
  2916. return type_node.analyse(env, base_type=base_type)
  2917. else:
  2918. index = self.index.compile_time_value(env)
  2919. if index is not None:
  2920. return PyrexTypes.CArrayType(base_type, int(index))
  2921. error(self.pos, "Array size must be a compile time constant")
  2922. return None
  2923. def type_dependencies(self, env):
  2924. return self.base.type_dependencies(env) + self.index.type_dependencies(env)
  2925. def infer_type(self, env):
  2926. base_type = self.base.infer_type(env)
  2927. if self.index.is_slice:
  2928. # slicing!
  2929. if base_type.is_string:
  2930. # sliced C strings must coerce to Python
  2931. return bytes_type
  2932. elif base_type.is_pyunicode_ptr:
  2933. # sliced Py_UNICODE* strings must coerce to Python
  2934. return unicode_type
  2935. elif base_type in (unicode_type, bytes_type, str_type,
  2936. bytearray_type, list_type, tuple_type):
  2937. # slicing these returns the same type
  2938. return base_type
  2939. else:
  2940. # TODO: Handle buffers (hopefully without too much redundancy).
  2941. return py_object_type
  2942. index_type = self.index.infer_type(env)
  2943. if index_type and index_type.is_int or isinstance(self.index, IntNode):
  2944. # indexing!
  2945. if base_type is unicode_type:
  2946. # Py_UCS4 will automatically coerce to a unicode string
  2947. # if required, so this is safe. We only infer Py_UCS4
  2948. # when the index is a C integer type. Otherwise, we may
  2949. # need to use normal Python item access, in which case
  2950. # it's faster to return the one-char unicode string than
  2951. # to receive it, throw it away, and potentially rebuild it
  2952. # on a subsequent PyObject coercion.
  2953. return PyrexTypes.c_py_ucs4_type
  2954. elif base_type is str_type:
  2955. # always returns str - Py2: bytes, Py3: unicode
  2956. return base_type
  2957. elif base_type is bytearray_type:
  2958. return PyrexTypes.c_uchar_type
  2959. elif isinstance(self.base, BytesNode):
  2960. #if env.global_scope().context.language_level >= 3:
  2961. # # inferring 'char' can be made to work in Python 3 mode
  2962. # return PyrexTypes.c_char_type
  2963. # Py2/3 return different types on indexing bytes objects
  2964. return py_object_type
  2965. elif base_type in (tuple_type, list_type):
  2966. # if base is a literal, take a look at its values
  2967. item_type = infer_sequence_item_type(
  2968. env, self.base, self.index, seq_type=base_type)
  2969. if item_type is not None:
  2970. return item_type
  2971. elif base_type.is_ptr or base_type.is_array:
  2972. return base_type.base_type
  2973. elif base_type.is_ctuple and isinstance(self.index, IntNode):
  2974. if self.index.has_constant_result():
  2975. index = self.index.constant_result
  2976. if index < 0:
  2977. index += base_type.size
  2978. if 0 <= index < base_type.size:
  2979. return base_type.components[index]
  2980. if base_type.is_cpp_class:
  2981. class FakeOperand:
  2982. def __init__(self, **kwds):
  2983. self.__dict__.update(kwds)
  2984. operands = [
  2985. FakeOperand(pos=self.pos, type=base_type),
  2986. FakeOperand(pos=self.pos, type=index_type),
  2987. ]
  2988. index_func = env.lookup_operator('[]', operands)
  2989. if index_func is not None:
  2990. return index_func.type.return_type
  2991. if is_pythran_expr(base_type) and is_pythran_expr(index_type):
  2992. index_with_type = (self.index, index_type)
  2993. return PythranExpr(pythran_indexing_type(base_type, [index_with_type]))
  2994. # may be slicing or indexing, we don't know
  2995. if base_type in (unicode_type, str_type):
  2996. # these types always returns their own type on Python indexing/slicing
  2997. return base_type
  2998. else:
  2999. # TODO: Handle buffers (hopefully without too much redundancy).
  3000. return py_object_type
  3001. def analyse_types(self, env):
  3002. return self.analyse_base_and_index_types(env, getting=True)
  3003. def analyse_target_types(self, env):
  3004. node = self.analyse_base_and_index_types(env, setting=True)
  3005. if node.type.is_const:
  3006. error(self.pos, "Assignment to const dereference")
  3007. if node is self and not node.is_lvalue():
  3008. error(self.pos, "Assignment to non-lvalue of type '%s'" % node.type)
  3009. return node
  3010. def analyse_base_and_index_types(self, env, getting=False, setting=False,
  3011. analyse_base=True):
  3012. # Note: This might be cleaned up by having IndexNode
  3013. # parsed in a saner way and only construct the tuple if
  3014. # needed.
  3015. if analyse_base:
  3016. self.base = self.base.analyse_types(env)
  3017. if self.base.type.is_error:
  3018. # Do not visit child tree if base is undeclared to avoid confusing
  3019. # error messages
  3020. self.type = PyrexTypes.error_type
  3021. return self
  3022. is_slice = self.index.is_slice
  3023. if not env.directives['wraparound']:
  3024. if is_slice:
  3025. check_negative_indices(self.index.start, self.index.stop)
  3026. else:
  3027. check_negative_indices(self.index)
  3028. # Potentially overflowing index value.
  3029. if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
  3030. self.index = self.index.coerce_to_pyobject(env)
  3031. is_memslice = self.base.type.is_memoryviewslice
  3032. # Handle the case where base is a literal char* (and we expect a string, not an int)
  3033. if not is_memslice and (isinstance(self.base, BytesNode) or is_slice):
  3034. if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
  3035. self.base = self.base.coerce_to_pyobject(env)
  3036. replacement_node = self.analyse_as_buffer_operation(env, getting)
  3037. if replacement_node is not None:
  3038. return replacement_node
  3039. self.nogil = env.nogil
  3040. base_type = self.base.type
  3041. if not base_type.is_cfunction:
  3042. self.index = self.index.analyse_types(env)
  3043. self.original_index_type = self.index.type
  3044. if base_type.is_unicode_char:
  3045. # we infer Py_UNICODE/Py_UCS4 for unicode strings in some
  3046. # cases, but indexing must still work for them
  3047. if setting:
  3048. warning(self.pos, "cannot assign to Unicode string index", level=1)
  3049. elif self.index.constant_result in (0, -1):
  3050. # uchar[0] => uchar
  3051. return self.base
  3052. self.base = self.base.coerce_to_pyobject(env)
  3053. base_type = self.base.type
  3054. if base_type.is_pyobject:
  3055. return self.analyse_as_pyobject(env, is_slice, getting, setting)
  3056. elif base_type.is_ptr or base_type.is_array:
  3057. return self.analyse_as_c_array(env, is_slice)
  3058. elif base_type.is_cpp_class:
  3059. return self.analyse_as_cpp(env, setting)
  3060. elif base_type.is_cfunction:
  3061. return self.analyse_as_c_function(env)
  3062. elif base_type.is_ctuple:
  3063. return self.analyse_as_c_tuple(env, getting, setting)
  3064. else:
  3065. error(self.pos,
  3066. "Attempting to index non-array type '%s'" %
  3067. base_type)
  3068. self.type = PyrexTypes.error_type
  3069. return self
  3070. def analyse_as_pyobject(self, env, is_slice, getting, setting):
  3071. base_type = self.base.type
  3072. if self.index.type.is_unicode_char and base_type is not dict_type:
  3073. # TODO: eventually fold into case below and remove warning, once people have adapted their code
  3074. warning(self.pos,
  3075. "Item lookup of unicode character codes now always converts to a Unicode string. "
  3076. "Use an explicit C integer cast to get back the previous integer lookup behaviour.", level=1)
  3077. self.index = self.index.coerce_to_pyobject(env)
  3078. self.is_temp = 1
  3079. elif self.index.type.is_int and base_type is not dict_type:
  3080. if (getting
  3081. and (base_type in (list_type, tuple_type, bytearray_type))
  3082. and (not self.index.type.signed
  3083. or not env.directives['wraparound']
  3084. or (isinstance(self.index, IntNode) and
  3085. self.index.has_constant_result() and self.index.constant_result >= 0))
  3086. and not env.directives['boundscheck']):
  3087. self.is_temp = 0
  3088. else:
  3089. self.is_temp = 1
  3090. self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
  3091. self.original_index_type.create_to_py_utility_code(env)
  3092. else:
  3093. self.index = self.index.coerce_to_pyobject(env)
  3094. self.is_temp = 1
  3095. if self.index.type.is_int and base_type is unicode_type:
  3096. # Py_UNICODE/Py_UCS4 will automatically coerce to a unicode string
  3097. # if required, so this is fast and safe
  3098. self.type = PyrexTypes.c_py_ucs4_type
  3099. elif self.index.type.is_int and base_type is bytearray_type:
  3100. if setting:
  3101. self.type = PyrexTypes.c_uchar_type
  3102. else:
  3103. # not using 'uchar' to enable fast and safe error reporting as '-1'
  3104. self.type = PyrexTypes.c_int_type
  3105. elif is_slice and base_type in (bytes_type, bytearray_type, str_type, unicode_type, list_type, tuple_type):
  3106. self.type = base_type
  3107. else:
  3108. item_type = None
  3109. if base_type in (list_type, tuple_type) and self.index.type.is_int:
  3110. item_type = infer_sequence_item_type(
  3111. env, self.base, self.index, seq_type=base_type)
  3112. if item_type is None:
  3113. item_type = py_object_type
  3114. self.type = item_type
  3115. if base_type in (list_type, tuple_type, dict_type):
  3116. # do the None check explicitly (not in a helper) to allow optimising it away
  3117. self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
  3118. self.wrap_in_nonecheck_node(env, getting)
  3119. return self
  3120. def analyse_as_c_array(self, env, is_slice):
  3121. base_type = self.base.type
  3122. self.type = base_type.base_type
  3123. if is_slice:
  3124. self.type = base_type
  3125. elif self.index.type.is_pyobject:
  3126. self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env)
  3127. elif not self.index.type.is_int:
  3128. error(self.pos, "Invalid index type '%s'" % self.index.type)
  3129. return self
  3130. def analyse_as_cpp(self, env, setting):
  3131. base_type = self.base.type
  3132. function = env.lookup_operator("[]", [self.base, self.index])
  3133. if function is None:
  3134. error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
  3135. self.type = PyrexTypes.error_type
  3136. self.result_code = "<error>"
  3137. return self
  3138. func_type = function.type
  3139. if func_type.is_ptr:
  3140. func_type = func_type.base_type
  3141. self.exception_check = func_type.exception_check
  3142. self.exception_value = func_type.exception_value
  3143. if self.exception_check:
  3144. if not setting:
  3145. self.is_temp = True
  3146. if self.exception_value is None:
  3147. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  3148. self.index = self.index.coerce_to(func_type.args[0].type, env)
  3149. self.type = func_type.return_type
  3150. if setting and not func_type.return_type.is_reference:
  3151. error(self.pos, "Can't set non-reference result '%s'" % self.type)
  3152. return self
  3153. def analyse_as_c_function(self, env):
  3154. base_type = self.base.type
  3155. if base_type.is_fused:
  3156. self.parse_indexed_fused_cdef(env)
  3157. else:
  3158. self.type_indices = self.parse_index_as_types(env)
  3159. self.index = None # FIXME: use a dedicated Node class instead of generic IndexNode
  3160. if base_type.templates is None:
  3161. error(self.pos, "Can only parameterize template functions.")
  3162. self.type = error_type
  3163. elif self.type_indices is None:
  3164. # Error recorded earlier.
  3165. self.type = error_type
  3166. elif len(base_type.templates) != len(self.type_indices):
  3167. error(self.pos, "Wrong number of template arguments: expected %s, got %s" % (
  3168. (len(base_type.templates), len(self.type_indices))))
  3169. self.type = error_type
  3170. else:
  3171. self.type = base_type.specialize(dict(zip(base_type.templates, self.type_indices)))
  3172. # FIXME: use a dedicated Node class instead of generic IndexNode
  3173. return self
  3174. def analyse_as_c_tuple(self, env, getting, setting):
  3175. base_type = self.base.type
  3176. if isinstance(self.index, IntNode) and self.index.has_constant_result():
  3177. index = self.index.constant_result
  3178. if -base_type.size <= index < base_type.size:
  3179. if index < 0:
  3180. index += base_type.size
  3181. self.type = base_type.components[index]
  3182. else:
  3183. error(self.pos,
  3184. "Index %s out of bounds for '%s'" %
  3185. (index, base_type))
  3186. self.type = PyrexTypes.error_type
  3187. return self
  3188. else:
  3189. self.base = self.base.coerce_to_pyobject(env)
  3190. return self.analyse_base_and_index_types(env, getting=getting, setting=setting, analyse_base=False)
  3191. def analyse_as_buffer_operation(self, env, getting):
  3192. """
  3193. Analyse buffer indexing and memoryview indexing/slicing
  3194. """
  3195. if isinstance(self.index, TupleNode):
  3196. indices = self.index.args
  3197. else:
  3198. indices = [self.index]
  3199. base = self.base
  3200. base_type = base.type
  3201. replacement_node = None
  3202. if base_type.is_memoryviewslice:
  3203. # memoryviewslice indexing or slicing
  3204. from . import MemoryView
  3205. if base.is_memview_slice:
  3206. # For memory views, "view[i][j]" is the same as "view[i, j]" => use the latter for speed.
  3207. merged_indices = base.merged_indices(indices)
  3208. if merged_indices is not None:
  3209. base = base.base
  3210. base_type = base.type
  3211. indices = merged_indices
  3212. have_slices, indices, newaxes = MemoryView.unellipsify(indices, base_type.ndim)
  3213. if have_slices:
  3214. replacement_node = MemoryViewSliceNode(self.pos, indices=indices, base=base)
  3215. else:
  3216. replacement_node = MemoryViewIndexNode(self.pos, indices=indices, base=base)
  3217. elif base_type.is_buffer or base_type.is_pythran_expr:
  3218. if base_type.is_pythran_expr or len(indices) == base_type.ndim:
  3219. # Buffer indexing
  3220. is_buffer_access = True
  3221. indices = [index.analyse_types(env) for index in indices]
  3222. if base_type.is_pythran_expr:
  3223. do_replacement = all(
  3224. index.type.is_int or index.is_slice or index.type.is_pythran_expr
  3225. for index in indices)
  3226. if do_replacement:
  3227. for i,index in enumerate(indices):
  3228. if index.is_slice:
  3229. index = SliceIntNode(index.pos, start=index.start, stop=index.stop, step=index.step)
  3230. index = index.analyse_types(env)
  3231. indices[i] = index
  3232. else:
  3233. do_replacement = all(index.type.is_int for index in indices)
  3234. if do_replacement:
  3235. replacement_node = BufferIndexNode(self.pos, indices=indices, base=base)
  3236. # On cloning, indices is cloned. Otherwise, unpack index into indices.
  3237. assert not isinstance(self.index, CloneNode)
  3238. if replacement_node is not None:
  3239. replacement_node = replacement_node.analyse_types(env, getting)
  3240. return replacement_node
  3241. def wrap_in_nonecheck_node(self, env, getting):
  3242. if not env.directives['nonecheck'] or not self.base.may_be_none():
  3243. return
  3244. self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
  3245. def parse_index_as_types(self, env, required=True):
  3246. if isinstance(self.index, TupleNode):
  3247. indices = self.index.args
  3248. else:
  3249. indices = [self.index]
  3250. type_indices = []
  3251. for index in indices:
  3252. type_indices.append(index.analyse_as_type(env))
  3253. if type_indices[-1] is None:
  3254. if required:
  3255. error(index.pos, "not parsable as a type")
  3256. return None
  3257. return type_indices
  3258. def parse_indexed_fused_cdef(self, env):
  3259. """
  3260. Interpret fused_cdef_func[specific_type1, ...]
  3261. Note that if this method is called, we are an indexed cdef function
  3262. with fused argument types, and this IndexNode will be replaced by the
  3263. NameNode with specific entry just after analysis of expressions by
  3264. AnalyseExpressionsTransform.
  3265. """
  3266. self.type = PyrexTypes.error_type
  3267. self.is_fused_index = True
  3268. base_type = self.base.type
  3269. positions = []
  3270. if self.index.is_name or self.index.is_attribute:
  3271. positions.append(self.index.pos)
  3272. elif isinstance(self.index, TupleNode):
  3273. for arg in self.index.args:
  3274. positions.append(arg.pos)
  3275. specific_types = self.parse_index_as_types(env, required=False)
  3276. if specific_types is None:
  3277. self.index = self.index.analyse_types(env)
  3278. if not self.base.entry.as_variable:
  3279. error(self.pos, "Can only index fused functions with types")
  3280. else:
  3281. # A cpdef function indexed with Python objects
  3282. self.base.entry = self.entry = self.base.entry.as_variable
  3283. self.base.type = self.type = self.entry.type
  3284. self.base.is_temp = True
  3285. self.is_temp = True
  3286. self.entry.used = True
  3287. self.is_fused_index = False
  3288. return
  3289. for i, type in enumerate(specific_types):
  3290. specific_types[i] = type.specialize_fused(env)
  3291. fused_types = base_type.get_fused_types()
  3292. if len(specific_types) > len(fused_types):
  3293. return error(self.pos, "Too many types specified")
  3294. elif len(specific_types) < len(fused_types):
  3295. t = fused_types[len(specific_types)]
  3296. return error(self.pos, "Not enough types specified to specialize "
  3297. "the function, %s is still fused" % t)
  3298. # See if our index types form valid specializations
  3299. for pos, specific_type, fused_type in zip(positions,
  3300. specific_types,
  3301. fused_types):
  3302. if not any([specific_type.same_as(t) for t in fused_type.types]):
  3303. return error(pos, "Type not in fused type")
  3304. if specific_type is None or specific_type.is_error:
  3305. return
  3306. fused_to_specific = dict(zip(fused_types, specific_types))
  3307. type = base_type.specialize(fused_to_specific)
  3308. if type.is_fused:
  3309. # Only partially specific, this is invalid
  3310. error(self.pos,
  3311. "Index operation makes function only partially specific")
  3312. else:
  3313. # Fully specific, find the signature with the specialized entry
  3314. for signature in self.base.type.get_all_specialized_function_types():
  3315. if type.same_as(signature):
  3316. self.type = signature
  3317. if self.base.is_attribute:
  3318. # Pretend to be a normal attribute, for cdef extension
  3319. # methods
  3320. self.entry = signature.entry
  3321. self.is_attribute = True
  3322. self.obj = self.base.obj
  3323. self.type.entry.used = True
  3324. self.base.type = signature
  3325. self.base.entry = signature.entry
  3326. break
  3327. else:
  3328. # This is a bug
  3329. raise InternalError("Couldn't find the right signature")
  3330. gil_message = "Indexing Python object"
  3331. def calculate_result_code(self):
  3332. if self.base.type in (list_type, tuple_type, bytearray_type):
  3333. if self.base.type is list_type:
  3334. index_code = "PyList_GET_ITEM(%s, %s)"
  3335. elif self.base.type is tuple_type:
  3336. index_code = "PyTuple_GET_ITEM(%s, %s)"
  3337. elif self.base.type is bytearray_type:
  3338. index_code = "((unsigned char)(PyByteArray_AS_STRING(%s)[%s]))"
  3339. else:
  3340. assert False, "unexpected base type in indexing: %s" % self.base.type
  3341. elif self.base.type.is_cfunction:
  3342. return "%s<%s>" % (
  3343. self.base.result(),
  3344. ",".join([param.empty_declaration_code() for param in self.type_indices]))
  3345. elif self.base.type.is_ctuple:
  3346. index = self.index.constant_result
  3347. if index < 0:
  3348. index += self.base.type.size
  3349. return "%s.f%s" % (self.base.result(), index)
  3350. else:
  3351. if (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
  3352. error(self.pos, "Invalid use of pointer slice")
  3353. return
  3354. index_code = "(%s[%s])"
  3355. return index_code % (self.base.result(), self.index.result())
  3356. def extra_index_params(self, code):
  3357. if self.index.type.is_int:
  3358. is_list = self.base.type is list_type
  3359. wraparound = (
  3360. bool(code.globalstate.directives['wraparound']) and
  3361. self.original_index_type.signed and
  3362. not (isinstance(self.index.constant_result, _py_int_types)
  3363. and self.index.constant_result >= 0))
  3364. boundscheck = bool(code.globalstate.directives['boundscheck'])
  3365. return ", %s, %d, %s, %d, %d, %d" % (
  3366. self.original_index_type.empty_declaration_code(),
  3367. self.original_index_type.signed and 1 or 0,
  3368. self.original_index_type.to_py_function,
  3369. is_list, wraparound, boundscheck)
  3370. else:
  3371. return ""
  3372. def generate_result_code(self, code):
  3373. if not self.is_temp:
  3374. # all handled in self.calculate_result_code()
  3375. return
  3376. utility_code = None
  3377. if self.type.is_pyobject:
  3378. error_value = 'NULL'
  3379. if self.index.type.is_int:
  3380. if self.base.type is list_type:
  3381. function = "__Pyx_GetItemInt_List"
  3382. elif self.base.type is tuple_type:
  3383. function = "__Pyx_GetItemInt_Tuple"
  3384. else:
  3385. function = "__Pyx_GetItemInt"
  3386. utility_code = TempitaUtilityCode.load_cached("GetItemInt", "ObjectHandling.c")
  3387. else:
  3388. if self.base.type is dict_type:
  3389. function = "__Pyx_PyDict_GetItem"
  3390. utility_code = UtilityCode.load_cached("DictGetItem", "ObjectHandling.c")
  3391. elif self.base.type is py_object_type and self.index.type in (str_type, unicode_type):
  3392. # obj[str] is probably doing a dict lookup
  3393. function = "__Pyx_PyObject_Dict_GetItem"
  3394. utility_code = UtilityCode.load_cached("DictGetItem", "ObjectHandling.c")
  3395. else:
  3396. function = "__Pyx_PyObject_GetItem"
  3397. code.globalstate.use_utility_code(
  3398. TempitaUtilityCode.load_cached("GetItemInt", "ObjectHandling.c"))
  3399. utility_code = UtilityCode.load_cached("ObjectGetItem", "ObjectHandling.c")
  3400. elif self.type.is_unicode_char and self.base.type is unicode_type:
  3401. assert self.index.type.is_int
  3402. function = "__Pyx_GetItemInt_Unicode"
  3403. error_value = '(Py_UCS4)-1'
  3404. utility_code = UtilityCode.load_cached("GetItemIntUnicode", "StringTools.c")
  3405. elif self.base.type is bytearray_type:
  3406. assert self.index.type.is_int
  3407. assert self.type.is_int
  3408. function = "__Pyx_GetItemInt_ByteArray"
  3409. error_value = '-1'
  3410. utility_code = UtilityCode.load_cached("GetItemIntByteArray", "StringTools.c")
  3411. elif not (self.base.type.is_cpp_class and self.exception_check):
  3412. assert False, "unexpected type %s and base type %s for indexing" % (
  3413. self.type, self.base.type)
  3414. if utility_code is not None:
  3415. code.globalstate.use_utility_code(utility_code)
  3416. if self.index.type.is_int:
  3417. index_code = self.index.result()
  3418. else:
  3419. index_code = self.index.py_result()
  3420. if self.base.type.is_cpp_class and self.exception_check:
  3421. translate_cpp_exception(code, self.pos,
  3422. "%s = %s[%s];" % (self.result(), self.base.result(),
  3423. self.index.result()),
  3424. self.exception_value, self.in_nogil_context)
  3425. else:
  3426. error_check = '!%s' if error_value == 'NULL' else '%%s == %s' % error_value
  3427. code.putln(
  3428. "%s = %s(%s, %s%s); %s" % (
  3429. self.result(),
  3430. function,
  3431. self.base.py_result(),
  3432. index_code,
  3433. self.extra_index_params(code),
  3434. code.error_goto_if(error_check % self.result(), self.pos)))
  3435. if self.type.is_pyobject:
  3436. code.put_gotref(self.py_result())
  3437. def generate_setitem_code(self, value_code, code):
  3438. if self.index.type.is_int:
  3439. if self.base.type is bytearray_type:
  3440. code.globalstate.use_utility_code(
  3441. UtilityCode.load_cached("SetItemIntByteArray", "StringTools.c"))
  3442. function = "__Pyx_SetItemInt_ByteArray"
  3443. else:
  3444. code.globalstate.use_utility_code(
  3445. UtilityCode.load_cached("SetItemInt", "ObjectHandling.c"))
  3446. function = "__Pyx_SetItemInt"
  3447. index_code = self.index.result()
  3448. else:
  3449. index_code = self.index.py_result()
  3450. if self.base.type is dict_type:
  3451. function = "PyDict_SetItem"
  3452. # It would seem that we could specialized lists/tuples, but that
  3453. # shouldn't happen here.
  3454. # Both PyList_SetItem() and PyTuple_SetItem() take a Py_ssize_t as
  3455. # index instead of an object, and bad conversion here would give
  3456. # the wrong exception. Also, tuples are supposed to be immutable,
  3457. # and raise a TypeError when trying to set their entries
  3458. # (PyTuple_SetItem() is for creating new tuples from scratch).
  3459. else:
  3460. function = "PyObject_SetItem"
  3461. code.putln(code.error_goto_if_neg(
  3462. "%s(%s, %s, %s%s)" % (
  3463. function,
  3464. self.base.py_result(),
  3465. index_code,
  3466. value_code,
  3467. self.extra_index_params(code)),
  3468. self.pos))
  3469. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  3470. exception_check=None, exception_value=None):
  3471. self.generate_subexpr_evaluation_code(code)
  3472. if self.type.is_pyobject:
  3473. self.generate_setitem_code(rhs.py_result(), code)
  3474. elif self.base.type is bytearray_type:
  3475. value_code = self._check_byte_value(code, rhs)
  3476. self.generate_setitem_code(value_code, code)
  3477. elif self.base.type.is_cpp_class and self.exception_check and self.exception_check == '+':
  3478. if overloaded_assignment and exception_check and \
  3479. self.exception_value != exception_value:
  3480. # Handle the case that both the index operator and the assignment
  3481. # operator have a c++ exception handler and they are not the same.
  3482. translate_double_cpp_exception(code, self.pos, self.type,
  3483. self.result(), rhs.result(), self.exception_value,
  3484. exception_value, self.in_nogil_context)
  3485. else:
  3486. # Handle the case that only the index operator has a
  3487. # c++ exception handler, or that
  3488. # both exception handlers are the same.
  3489. translate_cpp_exception(code, self.pos,
  3490. "%s = %s;" % (self.result(), rhs.result()),
  3491. self.exception_value, self.in_nogil_context)
  3492. else:
  3493. code.putln(
  3494. "%s = %s;" % (self.result(), rhs.result()))
  3495. self.generate_subexpr_disposal_code(code)
  3496. self.free_subexpr_temps(code)
  3497. rhs.generate_disposal_code(code)
  3498. rhs.free_temps(code)
  3499. def _check_byte_value(self, code, rhs):
  3500. # TODO: should we do this generally on downcasts, or just here?
  3501. assert rhs.type.is_int, repr(rhs.type)
  3502. value_code = rhs.result()
  3503. if rhs.has_constant_result():
  3504. if 0 <= rhs.constant_result < 256:
  3505. return value_code
  3506. needs_cast = True # make at least the C compiler happy
  3507. warning(rhs.pos,
  3508. "value outside of range(0, 256)"
  3509. " when assigning to byte: %s" % rhs.constant_result,
  3510. level=1)
  3511. else:
  3512. needs_cast = rhs.type != PyrexTypes.c_uchar_type
  3513. if not self.nogil:
  3514. conditions = []
  3515. if rhs.is_literal or rhs.type.signed:
  3516. conditions.append('%s < 0' % value_code)
  3517. if (rhs.is_literal or not
  3518. (rhs.is_temp and rhs.type in (
  3519. PyrexTypes.c_uchar_type, PyrexTypes.c_char_type,
  3520. PyrexTypes.c_schar_type))):
  3521. conditions.append('%s > 255' % value_code)
  3522. if conditions:
  3523. code.putln("if (unlikely(%s)) {" % ' || '.join(conditions))
  3524. code.putln(
  3525. 'PyErr_SetString(PyExc_ValueError,'
  3526. ' "byte must be in range(0, 256)"); %s' %
  3527. code.error_goto(self.pos))
  3528. code.putln("}")
  3529. if needs_cast:
  3530. value_code = '((unsigned char)%s)' % value_code
  3531. return value_code
  3532. def generate_deletion_code(self, code, ignore_nonexisting=False):
  3533. self.generate_subexpr_evaluation_code(code)
  3534. #if self.type.is_pyobject:
  3535. if self.index.type.is_int:
  3536. function = "__Pyx_DelItemInt"
  3537. index_code = self.index.result()
  3538. code.globalstate.use_utility_code(
  3539. UtilityCode.load_cached("DelItemInt", "ObjectHandling.c"))
  3540. else:
  3541. index_code = self.index.py_result()
  3542. if self.base.type is dict_type:
  3543. function = "PyDict_DelItem"
  3544. else:
  3545. function = "PyObject_DelItem"
  3546. code.putln(code.error_goto_if_neg(
  3547. "%s(%s, %s%s)" % (
  3548. function,
  3549. self.base.py_result(),
  3550. index_code,
  3551. self.extra_index_params(code)),
  3552. self.pos))
  3553. self.generate_subexpr_disposal_code(code)
  3554. self.free_subexpr_temps(code)
  3555. class BufferIndexNode(_IndexingBaseNode):
  3556. """
  3557. Indexing of buffers and memoryviews. This node is created during type
  3558. analysis from IndexNode and replaces it.
  3559. Attributes:
  3560. base - base node being indexed
  3561. indices - list of indexing expressions
  3562. """
  3563. subexprs = ['base', 'indices']
  3564. is_buffer_access = True
  3565. # Whether we're assigning to a buffer (in that case it needs to be writable)
  3566. writable_needed = False
  3567. def analyse_target_types(self, env):
  3568. self.analyse_types(env, getting=False)
  3569. def analyse_types(self, env, getting=True):
  3570. """
  3571. Analyse types for buffer indexing only. Overridden by memoryview
  3572. indexing and slicing subclasses
  3573. """
  3574. # self.indices are already analyzed
  3575. if not self.base.is_name and not is_pythran_expr(self.base.type):
  3576. error(self.pos, "Can only index buffer variables")
  3577. self.type = error_type
  3578. return self
  3579. if not getting:
  3580. if not self.base.entry.type.writable:
  3581. error(self.pos, "Writing to readonly buffer")
  3582. else:
  3583. self.writable_needed = True
  3584. if self.base.type.is_buffer:
  3585. self.base.entry.buffer_aux.writable_needed = True
  3586. self.none_error_message = "'NoneType' object is not subscriptable"
  3587. self.analyse_buffer_index(env, getting)
  3588. self.wrap_in_nonecheck_node(env)
  3589. return self
  3590. def analyse_buffer_index(self, env, getting):
  3591. if is_pythran_expr(self.base.type):
  3592. index_with_type_list = [(idx, idx.type) for idx in self.indices]
  3593. self.type = PythranExpr(pythran_indexing_type(self.base.type, index_with_type_list))
  3594. else:
  3595. self.base = self.base.coerce_to_simple(env)
  3596. self.type = self.base.type.dtype
  3597. self.buffer_type = self.base.type
  3598. if getting and (self.type.is_pyobject or self.type.is_pythran_expr):
  3599. self.is_temp = True
  3600. def analyse_assignment(self, rhs):
  3601. """
  3602. Called by IndexNode when this node is assigned to,
  3603. with the rhs of the assignment
  3604. """
  3605. def wrap_in_nonecheck_node(self, env):
  3606. if not env.directives['nonecheck'] or not self.base.may_be_none():
  3607. return
  3608. self.base = self.base.as_none_safe_node(self.none_error_message)
  3609. def nogil_check(self, env):
  3610. if self.is_buffer_access or self.is_memview_index:
  3611. if self.type.is_pyobject:
  3612. error(self.pos, "Cannot access buffer with object dtype without gil")
  3613. self.type = error_type
  3614. def calculate_result_code(self):
  3615. return "(*%s)" % self.buffer_ptr_code
  3616. def buffer_entry(self):
  3617. base = self.base
  3618. if self.base.is_nonecheck:
  3619. base = base.arg
  3620. return base.type.get_entry(base)
  3621. def get_index_in_temp(self, code, ivar):
  3622. ret = code.funcstate.allocate_temp(
  3623. PyrexTypes.widest_numeric_type(
  3624. ivar.type,
  3625. PyrexTypes.c_ssize_t_type if ivar.type.signed else PyrexTypes.c_size_t_type),
  3626. manage_ref=False)
  3627. code.putln("%s = %s;" % (ret, ivar.result()))
  3628. return ret
  3629. def buffer_lookup_code(self, code):
  3630. """
  3631. ndarray[1, 2, 3] and memslice[1, 2, 3]
  3632. """
  3633. if self.in_nogil_context:
  3634. if self.is_buffer_access or self.is_memview_index:
  3635. if code.globalstate.directives['boundscheck']:
  3636. warning(self.pos, "Use boundscheck(False) for faster access", level=1)
  3637. # Assign indices to temps of at least (s)size_t to allow further index calculations.
  3638. index_temps = [self.get_index_in_temp(code,ivar) for ivar in self.indices]
  3639. # Generate buffer access code using these temps
  3640. from . import Buffer
  3641. buffer_entry = self.buffer_entry()
  3642. if buffer_entry.type.is_buffer:
  3643. negative_indices = buffer_entry.type.negative_indices
  3644. else:
  3645. negative_indices = Buffer.buffer_defaults['negative_indices']
  3646. return buffer_entry, Buffer.put_buffer_lookup_code(
  3647. entry=buffer_entry,
  3648. index_signeds=[ivar.type.signed for ivar in self.indices],
  3649. index_cnames=index_temps,
  3650. directives=code.globalstate.directives,
  3651. pos=self.pos, code=code,
  3652. negative_indices=negative_indices,
  3653. in_nogil_context=self.in_nogil_context)
  3654. def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
  3655. self.generate_subexpr_evaluation_code(code)
  3656. self.generate_buffer_setitem_code(rhs, code)
  3657. self.generate_subexpr_disposal_code(code)
  3658. self.free_subexpr_temps(code)
  3659. rhs.generate_disposal_code(code)
  3660. rhs.free_temps(code)
  3661. def generate_buffer_setitem_code(self, rhs, code, op=""):
  3662. base_type = self.base.type
  3663. if is_pythran_expr(base_type) and is_pythran_supported_type(rhs.type):
  3664. obj = code.funcstate.allocate_temp(PythranExpr(pythran_type(self.base.type)), manage_ref=False)
  3665. # We have got to do this because we have to declare pythran objects
  3666. # at the beginning of the functions.
  3667. # Indeed, Cython uses "goto" statement for error management, and
  3668. # RAII doesn't work with that kind of construction.
  3669. # Moreover, the way Pythran expressions are made is that they don't
  3670. # support move-assignation easily.
  3671. # This, we explicitly destroy then in-place new objects in this
  3672. # case.
  3673. code.putln("__Pyx_call_destructor(%s);" % obj)
  3674. code.putln("new (&%s) decltype(%s){%s};" % (obj, obj, self.base.pythran_result()))
  3675. code.putln("%s%s %s= %s;" % (
  3676. obj,
  3677. pythran_indexing_code(self.indices),
  3678. op,
  3679. rhs.pythran_result()))
  3680. return
  3681. # Used from generate_assignment_code and InPlaceAssignmentNode
  3682. buffer_entry, ptrexpr = self.buffer_lookup_code(code)
  3683. if self.buffer_type.dtype.is_pyobject:
  3684. # Must manage refcounts. Decref what is already there
  3685. # and incref what we put in.
  3686. ptr = code.funcstate.allocate_temp(buffer_entry.buf_ptr_type,
  3687. manage_ref=False)
  3688. rhs_code = rhs.result()
  3689. code.putln("%s = %s;" % (ptr, ptrexpr))
  3690. code.put_gotref("*%s" % ptr)
  3691. code.putln("__Pyx_INCREF(%s); __Pyx_DECREF(*%s);" % (
  3692. rhs_code, ptr))
  3693. code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
  3694. code.put_giveref("*%s" % ptr)
  3695. code.funcstate.release_temp(ptr)
  3696. else:
  3697. # Simple case
  3698. code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
  3699. def generate_result_code(self, code):
  3700. if is_pythran_expr(self.base.type):
  3701. res = self.result()
  3702. code.putln("__Pyx_call_destructor(%s);" % res)
  3703. code.putln("new (&%s) decltype(%s){%s%s};" % (
  3704. res,
  3705. res,
  3706. self.base.pythran_result(),
  3707. pythran_indexing_code(self.indices)))
  3708. return
  3709. buffer_entry, self.buffer_ptr_code = self.buffer_lookup_code(code)
  3710. if self.type.is_pyobject:
  3711. # is_temp is True, so must pull out value and incref it.
  3712. # NOTE: object temporary results for nodes are declared
  3713. # as PyObject *, so we need a cast
  3714. code.putln("%s = (PyObject *) *%s;" % (self.result(), self.buffer_ptr_code))
  3715. code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
  3716. class MemoryViewIndexNode(BufferIndexNode):
  3717. is_memview_index = True
  3718. is_buffer_access = False
  3719. warned_untyped_idx = False
  3720. def analyse_types(self, env, getting=True):
  3721. # memoryviewslice indexing or slicing
  3722. from . import MemoryView
  3723. self.is_pythran_mode = has_np_pythran(env)
  3724. indices = self.indices
  3725. have_slices, indices, newaxes = MemoryView.unellipsify(indices, self.base.type.ndim)
  3726. if not getting:
  3727. self.writable_needed = True
  3728. if self.base.is_name or self.base.is_attribute:
  3729. self.base.entry.type.writable_needed = True
  3730. self.memslice_index = (not newaxes and len(indices) == self.base.type.ndim)
  3731. axes = []
  3732. index_type = PyrexTypes.c_py_ssize_t_type
  3733. new_indices = []
  3734. if len(indices) - len(newaxes) > self.base.type.ndim:
  3735. self.type = error_type
  3736. error(indices[self.base.type.ndim].pos,
  3737. "Too many indices specified for type %s" % self.base.type)
  3738. return self
  3739. axis_idx = 0
  3740. for i, index in enumerate(indices[:]):
  3741. index = index.analyse_types(env)
  3742. if index.is_none:
  3743. self.is_memview_slice = True
  3744. new_indices.append(index)
  3745. axes.append(('direct', 'strided'))
  3746. continue
  3747. access, packing = self.base.type.axes[axis_idx]
  3748. axis_idx += 1
  3749. if index.is_slice:
  3750. self.is_memview_slice = True
  3751. if index.step.is_none:
  3752. axes.append((access, packing))
  3753. else:
  3754. axes.append((access, 'strided'))
  3755. # Coerce start, stop and step to temps of the right type
  3756. for attr in ('start', 'stop', 'step'):
  3757. value = getattr(index, attr)
  3758. if not value.is_none:
  3759. value = value.coerce_to(index_type, env)
  3760. #value = value.coerce_to_temp(env)
  3761. setattr(index, attr, value)
  3762. new_indices.append(value)
  3763. elif index.type.is_int or index.type.is_pyobject:
  3764. if index.type.is_pyobject and not self.warned_untyped_idx:
  3765. warning(index.pos, "Index should be typed for more efficient access", level=2)
  3766. MemoryViewIndexNode.warned_untyped_idx = True
  3767. self.is_memview_index = True
  3768. index = index.coerce_to(index_type, env)
  3769. indices[i] = index
  3770. new_indices.append(index)
  3771. else:
  3772. self.type = error_type
  3773. error(index.pos, "Invalid index for memoryview specified, type %s" % index.type)
  3774. return self
  3775. ### FIXME: replace by MemoryViewSliceNode if is_memview_slice ?
  3776. self.is_memview_index = self.is_memview_index and not self.is_memview_slice
  3777. self.indices = new_indices
  3778. # All indices with all start/stop/step for slices.
  3779. # We need to keep this around.
  3780. self.original_indices = indices
  3781. self.nogil = env.nogil
  3782. self.analyse_operation(env, getting, axes)
  3783. self.wrap_in_nonecheck_node(env)
  3784. return self
  3785. def analyse_operation(self, env, getting, axes):
  3786. self.none_error_message = "Cannot index None memoryview slice"
  3787. self.analyse_buffer_index(env, getting)
  3788. def analyse_broadcast_operation(self, rhs):
  3789. """
  3790. Support broadcasting for slice assignment.
  3791. E.g.
  3792. m_2d[...] = m_1d # or,
  3793. m_1d[...] = m_2d # if the leading dimension has extent 1
  3794. """
  3795. if self.type.is_memoryviewslice:
  3796. lhs = self
  3797. if lhs.is_memview_broadcast or rhs.is_memview_broadcast:
  3798. lhs.is_memview_broadcast = True
  3799. rhs.is_memview_broadcast = True
  3800. def analyse_as_memview_scalar_assignment(self, rhs):
  3801. lhs = self.analyse_assignment(rhs)
  3802. if lhs:
  3803. rhs.is_memview_copy_assignment = lhs.is_memview_copy_assignment
  3804. return lhs
  3805. return self
  3806. class MemoryViewSliceNode(MemoryViewIndexNode):
  3807. is_memview_slice = True
  3808. # No-op slicing operation, this node will be replaced
  3809. is_ellipsis_noop = False
  3810. is_memview_scalar_assignment = False
  3811. is_memview_index = False
  3812. is_memview_broadcast = False
  3813. def analyse_ellipsis_noop(self, env, getting):
  3814. """Slicing operations needing no evaluation, i.e. m[...] or m[:, :]"""
  3815. ### FIXME: replace directly
  3816. self.is_ellipsis_noop = all(
  3817. index.is_slice and index.start.is_none and index.stop.is_none and index.step.is_none
  3818. for index in self.indices)
  3819. if self.is_ellipsis_noop:
  3820. self.type = self.base.type
  3821. def analyse_operation(self, env, getting, axes):
  3822. from . import MemoryView
  3823. if not getting:
  3824. self.is_memview_broadcast = True
  3825. self.none_error_message = "Cannot assign to None memoryview slice"
  3826. else:
  3827. self.none_error_message = "Cannot slice None memoryview slice"
  3828. self.analyse_ellipsis_noop(env, getting)
  3829. if self.is_ellipsis_noop:
  3830. return
  3831. self.index = None
  3832. self.is_temp = True
  3833. self.use_managed_ref = True
  3834. if not MemoryView.validate_axes(self.pos, axes):
  3835. self.type = error_type
  3836. return
  3837. self.type = PyrexTypes.MemoryViewSliceType(self.base.type.dtype, axes)
  3838. if not (self.base.is_simple() or self.base.result_in_temp()):
  3839. self.base = self.base.coerce_to_temp(env)
  3840. def analyse_assignment(self, rhs):
  3841. if not rhs.type.is_memoryviewslice and (
  3842. self.type.dtype.assignable_from(rhs.type) or
  3843. rhs.type.is_pyobject):
  3844. # scalar assignment
  3845. return MemoryCopyScalar(self.pos, self)
  3846. else:
  3847. return MemoryCopySlice(self.pos, self)
  3848. def merged_indices(self, indices):
  3849. """Return a new list of indices/slices with 'indices' merged into the current ones
  3850. according to slicing rules.
  3851. Is used to implement "view[i][j]" => "view[i, j]".
  3852. Return None if the indices cannot (easily) be merged at compile time.
  3853. """
  3854. if not indices:
  3855. return None
  3856. # NOTE: Need to evaluate "self.original_indices" here as they might differ from "self.indices".
  3857. new_indices = self.original_indices[:]
  3858. indices = indices[:]
  3859. for i, s in enumerate(self.original_indices):
  3860. if s.is_slice:
  3861. if s.start.is_none and s.stop.is_none and s.step.is_none:
  3862. # Full slice found, replace by index.
  3863. new_indices[i] = indices[0]
  3864. indices.pop(0)
  3865. if not indices:
  3866. return new_indices
  3867. else:
  3868. # Found something non-trivial, e.g. a partial slice.
  3869. return None
  3870. elif not s.type.is_int:
  3871. # Not a slice, not an integer index => could be anything...
  3872. return None
  3873. if indices:
  3874. if len(new_indices) + len(indices) > self.base.type.ndim:
  3875. return None
  3876. new_indices += indices
  3877. return new_indices
  3878. def is_simple(self):
  3879. if self.is_ellipsis_noop:
  3880. # TODO: fix SimpleCallNode.is_simple()
  3881. return self.base.is_simple() or self.base.result_in_temp()
  3882. return self.result_in_temp()
  3883. def calculate_result_code(self):
  3884. """This is called in case this is a no-op slicing node"""
  3885. return self.base.result()
  3886. def generate_result_code(self, code):
  3887. if self.is_ellipsis_noop:
  3888. return ### FIXME: remove
  3889. buffer_entry = self.buffer_entry()
  3890. have_gil = not self.in_nogil_context
  3891. # TODO Mark: this is insane, do it better
  3892. have_slices = False
  3893. it = iter(self.indices)
  3894. for index in self.original_indices:
  3895. if index.is_slice:
  3896. have_slices = True
  3897. if not index.start.is_none:
  3898. index.start = next(it)
  3899. if not index.stop.is_none:
  3900. index.stop = next(it)
  3901. if not index.step.is_none:
  3902. index.step = next(it)
  3903. else:
  3904. next(it)
  3905. assert not list(it)
  3906. buffer_entry.generate_buffer_slice_code(
  3907. code, self.original_indices, self.result(),
  3908. have_gil=have_gil, have_slices=have_slices,
  3909. directives=code.globalstate.directives)
  3910. def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
  3911. if self.is_ellipsis_noop:
  3912. self.generate_subexpr_evaluation_code(code)
  3913. else:
  3914. self.generate_evaluation_code(code)
  3915. if self.is_memview_scalar_assignment:
  3916. self.generate_memoryviewslice_assign_scalar_code(rhs, code)
  3917. else:
  3918. self.generate_memoryviewslice_setslice_code(rhs, code)
  3919. if self.is_ellipsis_noop:
  3920. self.generate_subexpr_disposal_code(code)
  3921. else:
  3922. self.generate_disposal_code(code)
  3923. rhs.generate_disposal_code(code)
  3924. rhs.free_temps(code)
  3925. class MemoryCopyNode(ExprNode):
  3926. """
  3927. Wraps a memoryview slice for slice assignment.
  3928. dst: destination mememoryview slice
  3929. """
  3930. subexprs = ['dst']
  3931. def __init__(self, pos, dst):
  3932. super(MemoryCopyNode, self).__init__(pos)
  3933. self.dst = dst
  3934. self.type = dst.type
  3935. def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
  3936. self.dst.generate_evaluation_code(code)
  3937. self._generate_assignment_code(rhs, code)
  3938. self.dst.generate_disposal_code(code)
  3939. rhs.generate_disposal_code(code)
  3940. rhs.free_temps(code)
  3941. class MemoryCopySlice(MemoryCopyNode):
  3942. """
  3943. Copy the contents of slice src to slice dst. Does not support indirect
  3944. slices.
  3945. memslice1[...] = memslice2
  3946. memslice1[:] = memslice2
  3947. """
  3948. is_memview_copy_assignment = True
  3949. copy_slice_cname = "__pyx_memoryview_copy_contents"
  3950. def _generate_assignment_code(self, src, code):
  3951. dst = self.dst
  3952. src.type.assert_direct_dims(src.pos)
  3953. dst.type.assert_direct_dims(dst.pos)
  3954. code.putln(code.error_goto_if_neg(
  3955. "%s(%s, %s, %d, %d, %d)" % (self.copy_slice_cname,
  3956. src.result(), dst.result(),
  3957. src.type.ndim, dst.type.ndim,
  3958. dst.type.dtype.is_pyobject),
  3959. dst.pos))
  3960. class MemoryCopyScalar(MemoryCopyNode):
  3961. """
  3962. Assign a scalar to a slice. dst must be simple, scalar will be assigned
  3963. to a correct type and not just something assignable.
  3964. memslice1[...] = 0.0
  3965. memslice1[:] = 0.0
  3966. """
  3967. def __init__(self, pos, dst):
  3968. super(MemoryCopyScalar, self).__init__(pos, dst)
  3969. self.type = dst.type.dtype
  3970. def _generate_assignment_code(self, scalar, code):
  3971. from . import MemoryView
  3972. self.dst.type.assert_direct_dims(self.dst.pos)
  3973. dtype = self.dst.type.dtype
  3974. type_decl = dtype.declaration_code("")
  3975. slice_decl = self.dst.type.declaration_code("")
  3976. code.begin_block()
  3977. code.putln("%s __pyx_temp_scalar = %s;" % (type_decl, scalar.result()))
  3978. if self.dst.result_in_temp() or self.dst.is_simple():
  3979. dst_temp = self.dst.result()
  3980. else:
  3981. code.putln("%s __pyx_temp_slice = %s;" % (slice_decl, self.dst.result()))
  3982. dst_temp = "__pyx_temp_slice"
  3983. slice_iter_obj = MemoryView.slice_iter(self.dst.type, dst_temp,
  3984. self.dst.type.ndim, code)
  3985. p = slice_iter_obj.start_loops()
  3986. if dtype.is_pyobject:
  3987. code.putln("Py_DECREF(*(PyObject **) %s);" % p)
  3988. code.putln("*((%s *) %s) = __pyx_temp_scalar;" % (type_decl, p))
  3989. if dtype.is_pyobject:
  3990. code.putln("Py_INCREF(__pyx_temp_scalar);")
  3991. slice_iter_obj.end_loops()
  3992. code.end_block()
  3993. class SliceIndexNode(ExprNode):
  3994. # 2-element slice indexing
  3995. #
  3996. # base ExprNode
  3997. # start ExprNode or None
  3998. # stop ExprNode or None
  3999. # slice ExprNode or None constant slice object
  4000. subexprs = ['base', 'start', 'stop', 'slice']
  4001. slice = None
  4002. def infer_type(self, env):
  4003. base_type = self.base.infer_type(env)
  4004. if base_type.is_string or base_type.is_cpp_class:
  4005. return bytes_type
  4006. elif base_type.is_pyunicode_ptr:
  4007. return unicode_type
  4008. elif base_type in (bytes_type, bytearray_type, str_type, unicode_type,
  4009. basestring_type, list_type, tuple_type):
  4010. return base_type
  4011. elif base_type.is_ptr or base_type.is_array:
  4012. return PyrexTypes.c_array_type(base_type.base_type, None)
  4013. return py_object_type
  4014. def inferable_item_node(self, index=0):
  4015. # slicing shouldn't change the result type of the base, but the index might
  4016. if index is not not_a_constant and self.start:
  4017. if self.start.has_constant_result():
  4018. index += self.start.constant_result
  4019. else:
  4020. index = not_a_constant
  4021. return self.base.inferable_item_node(index)
  4022. def may_be_none(self):
  4023. base_type = self.base.type
  4024. if base_type:
  4025. if base_type.is_string:
  4026. return False
  4027. if base_type in (bytes_type, str_type, unicode_type,
  4028. basestring_type, list_type, tuple_type):
  4029. return False
  4030. return ExprNode.may_be_none(self)
  4031. def calculate_constant_result(self):
  4032. if self.start is None:
  4033. start = None
  4034. else:
  4035. start = self.start.constant_result
  4036. if self.stop is None:
  4037. stop = None
  4038. else:
  4039. stop = self.stop.constant_result
  4040. self.constant_result = self.base.constant_result[start:stop]
  4041. def compile_time_value(self, denv):
  4042. base = self.base.compile_time_value(denv)
  4043. if self.start is None:
  4044. start = 0
  4045. else:
  4046. start = self.start.compile_time_value(denv)
  4047. if self.stop is None:
  4048. stop = None
  4049. else:
  4050. stop = self.stop.compile_time_value(denv)
  4051. try:
  4052. return base[start:stop]
  4053. except Exception as e:
  4054. self.compile_time_value_error(e)
  4055. def analyse_target_declaration(self, env):
  4056. pass
  4057. def analyse_target_types(self, env):
  4058. node = self.analyse_types(env, getting=False)
  4059. # when assigning, we must accept any Python type
  4060. if node.type.is_pyobject:
  4061. node.type = py_object_type
  4062. return node
  4063. def analyse_types(self, env, getting=True):
  4064. self.base = self.base.analyse_types(env)
  4065. if self.base.type.is_buffer or self.base.type.is_pythran_expr or self.base.type.is_memoryviewslice:
  4066. none_node = NoneNode(self.pos)
  4067. index = SliceNode(self.pos,
  4068. start=self.start or none_node,
  4069. stop=self.stop or none_node,
  4070. step=none_node)
  4071. index_node = IndexNode(self.pos, index=index, base=self.base)
  4072. return index_node.analyse_base_and_index_types(
  4073. env, getting=getting, setting=not getting,
  4074. analyse_base=False)
  4075. if self.start:
  4076. self.start = self.start.analyse_types(env)
  4077. if self.stop:
  4078. self.stop = self.stop.analyse_types(env)
  4079. if not env.directives['wraparound']:
  4080. check_negative_indices(self.start, self.stop)
  4081. base_type = self.base.type
  4082. if base_type.is_array and not getting:
  4083. # cannot assign directly to C array => try to assign by making a copy
  4084. if not self.start and not self.stop:
  4085. self.type = base_type
  4086. else:
  4087. self.type = PyrexTypes.CPtrType(base_type.base_type)
  4088. elif base_type.is_string or base_type.is_cpp_string:
  4089. self.type = default_str_type(env)
  4090. elif base_type.is_pyunicode_ptr:
  4091. self.type = unicode_type
  4092. elif base_type.is_ptr:
  4093. self.type = base_type
  4094. elif base_type.is_array:
  4095. # we need a ptr type here instead of an array type, as
  4096. # array types can result in invalid type casts in the C
  4097. # code
  4098. self.type = PyrexTypes.CPtrType(base_type.base_type)
  4099. else:
  4100. self.base = self.base.coerce_to_pyobject(env)
  4101. self.type = py_object_type
  4102. if base_type.is_builtin_type:
  4103. # slicing builtin types returns something of the same type
  4104. self.type = base_type
  4105. self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
  4106. if self.type is py_object_type:
  4107. if (not self.start or self.start.is_literal) and \
  4108. (not self.stop or self.stop.is_literal):
  4109. # cache the constant slice object, in case we need it
  4110. none_node = NoneNode(self.pos)
  4111. self.slice = SliceNode(
  4112. self.pos,
  4113. start=copy.deepcopy(self.start or none_node),
  4114. stop=copy.deepcopy(self.stop or none_node),
  4115. step=none_node
  4116. ).analyse_types(env)
  4117. else:
  4118. c_int = PyrexTypes.c_py_ssize_t_type
  4119. if self.start:
  4120. self.start = self.start.coerce_to(c_int, env)
  4121. if self.stop:
  4122. self.stop = self.stop.coerce_to(c_int, env)
  4123. self.is_temp = 1
  4124. return self
  4125. nogil_check = Node.gil_error
  4126. gil_message = "Slicing Python object"
  4127. get_slice_utility_code = TempitaUtilityCode.load(
  4128. "SliceObject", "ObjectHandling.c", context={'access': 'Get'})
  4129. set_slice_utility_code = TempitaUtilityCode.load(
  4130. "SliceObject", "ObjectHandling.c", context={'access': 'Set'})
  4131. def coerce_to(self, dst_type, env):
  4132. if ((self.base.type.is_string or self.base.type.is_cpp_string)
  4133. and dst_type in (bytes_type, bytearray_type, str_type, unicode_type)):
  4134. if (dst_type not in (bytes_type, bytearray_type)
  4135. and not env.directives['c_string_encoding']):
  4136. error(self.pos,
  4137. "default encoding required for conversion from '%s' to '%s'" %
  4138. (self.base.type, dst_type))
  4139. self.type = dst_type
  4140. if dst_type.is_array and self.base.type.is_array:
  4141. if not self.start and not self.stop:
  4142. # redundant slice building, copy C arrays directly
  4143. return self.base.coerce_to(dst_type, env)
  4144. # else: check array size if possible
  4145. return super(SliceIndexNode, self).coerce_to(dst_type, env)
  4146. def generate_result_code(self, code):
  4147. if not self.type.is_pyobject:
  4148. error(self.pos,
  4149. "Slicing is not currently supported for '%s'." % self.type)
  4150. return
  4151. base_result = self.base.result()
  4152. result = self.result()
  4153. start_code = self.start_code()
  4154. stop_code = self.stop_code()
  4155. if self.base.type.is_string:
  4156. base_result = self.base.result()
  4157. if self.base.type not in (PyrexTypes.c_char_ptr_type, PyrexTypes.c_const_char_ptr_type):
  4158. base_result = '((const char*)%s)' % base_result
  4159. if self.type is bytearray_type:
  4160. type_name = 'ByteArray'
  4161. else:
  4162. type_name = self.type.name.title()
  4163. if self.stop is None:
  4164. code.putln(
  4165. "%s = __Pyx_Py%s_FromString(%s + %s); %s" % (
  4166. result,
  4167. type_name,
  4168. base_result,
  4169. start_code,
  4170. code.error_goto_if_null(result, self.pos)))
  4171. else:
  4172. code.putln(
  4173. "%s = __Pyx_Py%s_FromStringAndSize(%s + %s, %s - %s); %s" % (
  4174. result,
  4175. type_name,
  4176. base_result,
  4177. start_code,
  4178. stop_code,
  4179. start_code,
  4180. code.error_goto_if_null(result, self.pos)))
  4181. elif self.base.type.is_pyunicode_ptr:
  4182. base_result = self.base.result()
  4183. if self.base.type != PyrexTypes.c_py_unicode_ptr_type:
  4184. base_result = '((const Py_UNICODE*)%s)' % base_result
  4185. if self.stop is None:
  4186. code.putln(
  4187. "%s = __Pyx_PyUnicode_FromUnicode(%s + %s); %s" % (
  4188. result,
  4189. base_result,
  4190. start_code,
  4191. code.error_goto_if_null(result, self.pos)))
  4192. else:
  4193. code.putln(
  4194. "%s = __Pyx_PyUnicode_FromUnicodeAndLength(%s + %s, %s - %s); %s" % (
  4195. result,
  4196. base_result,
  4197. start_code,
  4198. stop_code,
  4199. start_code,
  4200. code.error_goto_if_null(result, self.pos)))
  4201. elif self.base.type is unicode_type:
  4202. code.globalstate.use_utility_code(
  4203. UtilityCode.load_cached("PyUnicode_Substring", "StringTools.c"))
  4204. code.putln(
  4205. "%s = __Pyx_PyUnicode_Substring(%s, %s, %s); %s" % (
  4206. result,
  4207. base_result,
  4208. start_code,
  4209. stop_code,
  4210. code.error_goto_if_null(result, self.pos)))
  4211. elif self.type is py_object_type:
  4212. code.globalstate.use_utility_code(self.get_slice_utility_code)
  4213. (has_c_start, has_c_stop, c_start, c_stop,
  4214. py_start, py_stop, py_slice) = self.get_slice_config()
  4215. code.putln(
  4216. "%s = __Pyx_PyObject_GetSlice(%s, %s, %s, %s, %s, %s, %d, %d, %d); %s" % (
  4217. result,
  4218. self.base.py_result(),
  4219. c_start, c_stop,
  4220. py_start, py_stop, py_slice,
  4221. has_c_start, has_c_stop,
  4222. bool(code.globalstate.directives['wraparound']),
  4223. code.error_goto_if_null(result, self.pos)))
  4224. else:
  4225. if self.base.type is list_type:
  4226. code.globalstate.use_utility_code(
  4227. TempitaUtilityCode.load_cached("SliceTupleAndList", "ObjectHandling.c"))
  4228. cfunc = '__Pyx_PyList_GetSlice'
  4229. elif self.base.type is tuple_type:
  4230. code.globalstate.use_utility_code(
  4231. TempitaUtilityCode.load_cached("SliceTupleAndList", "ObjectHandling.c"))
  4232. cfunc = '__Pyx_PyTuple_GetSlice'
  4233. else:
  4234. cfunc = 'PySequence_GetSlice'
  4235. code.putln(
  4236. "%s = %s(%s, %s, %s); %s" % (
  4237. result,
  4238. cfunc,
  4239. self.base.py_result(),
  4240. start_code,
  4241. stop_code,
  4242. code.error_goto_if_null(result, self.pos)))
  4243. code.put_gotref(self.py_result())
  4244. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  4245. exception_check=None, exception_value=None):
  4246. self.generate_subexpr_evaluation_code(code)
  4247. if self.type.is_pyobject:
  4248. code.globalstate.use_utility_code(self.set_slice_utility_code)
  4249. (has_c_start, has_c_stop, c_start, c_stop,
  4250. py_start, py_stop, py_slice) = self.get_slice_config()
  4251. code.put_error_if_neg(self.pos,
  4252. "__Pyx_PyObject_SetSlice(%s, %s, %s, %s, %s, %s, %s, %d, %d, %d)" % (
  4253. self.base.py_result(),
  4254. rhs.py_result(),
  4255. c_start, c_stop,
  4256. py_start, py_stop, py_slice,
  4257. has_c_start, has_c_stop,
  4258. bool(code.globalstate.directives['wraparound'])))
  4259. else:
  4260. start_offset = self.start_code() if self.start else '0'
  4261. if rhs.type.is_array:
  4262. array_length = rhs.type.size
  4263. self.generate_slice_guard_code(code, array_length)
  4264. else:
  4265. array_length = '%s - %s' % (self.stop_code(), start_offset)
  4266. code.globalstate.use_utility_code(UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
  4267. code.putln("memcpy(&(%s[%s]), %s, sizeof(%s[0]) * (%s));" % (
  4268. self.base.result(), start_offset,
  4269. rhs.result(),
  4270. self.base.result(), array_length
  4271. ))
  4272. self.generate_subexpr_disposal_code(code)
  4273. self.free_subexpr_temps(code)
  4274. rhs.generate_disposal_code(code)
  4275. rhs.free_temps(code)
  4276. def generate_deletion_code(self, code, ignore_nonexisting=False):
  4277. if not self.base.type.is_pyobject:
  4278. error(self.pos,
  4279. "Deleting slices is only supported for Python types, not '%s'." % self.type)
  4280. return
  4281. self.generate_subexpr_evaluation_code(code)
  4282. code.globalstate.use_utility_code(self.set_slice_utility_code)
  4283. (has_c_start, has_c_stop, c_start, c_stop,
  4284. py_start, py_stop, py_slice) = self.get_slice_config()
  4285. code.put_error_if_neg(self.pos,
  4286. "__Pyx_PyObject_DelSlice(%s, %s, %s, %s, %s, %s, %d, %d, %d)" % (
  4287. self.base.py_result(),
  4288. c_start, c_stop,
  4289. py_start, py_stop, py_slice,
  4290. has_c_start, has_c_stop,
  4291. bool(code.globalstate.directives['wraparound'])))
  4292. self.generate_subexpr_disposal_code(code)
  4293. self.free_subexpr_temps(code)
  4294. def get_slice_config(self):
  4295. has_c_start, c_start, py_start = False, '0', 'NULL'
  4296. if self.start:
  4297. has_c_start = not self.start.type.is_pyobject
  4298. if has_c_start:
  4299. c_start = self.start.result()
  4300. else:
  4301. py_start = '&%s' % self.start.py_result()
  4302. has_c_stop, c_stop, py_stop = False, '0', 'NULL'
  4303. if self.stop:
  4304. has_c_stop = not self.stop.type.is_pyobject
  4305. if has_c_stop:
  4306. c_stop = self.stop.result()
  4307. else:
  4308. py_stop = '&%s' % self.stop.py_result()
  4309. py_slice = self.slice and '&%s' % self.slice.py_result() or 'NULL'
  4310. return (has_c_start, has_c_stop, c_start, c_stop,
  4311. py_start, py_stop, py_slice)
  4312. def generate_slice_guard_code(self, code, target_size):
  4313. if not self.base.type.is_array:
  4314. return
  4315. slice_size = self.base.type.size
  4316. try:
  4317. total_length = slice_size = int(slice_size)
  4318. except ValueError:
  4319. total_length = None
  4320. start = stop = None
  4321. if self.stop:
  4322. stop = self.stop.result()
  4323. try:
  4324. stop = int(stop)
  4325. if stop < 0:
  4326. if total_length is None:
  4327. slice_size = '%s + %d' % (slice_size, stop)
  4328. else:
  4329. slice_size += stop
  4330. else:
  4331. slice_size = stop
  4332. stop = None
  4333. except ValueError:
  4334. pass
  4335. if self.start:
  4336. start = self.start.result()
  4337. try:
  4338. start = int(start)
  4339. if start < 0:
  4340. if total_length is None:
  4341. start = '%s + %d' % (self.base.type.size, start)
  4342. else:
  4343. start += total_length
  4344. if isinstance(slice_size, _py_int_types):
  4345. slice_size -= start
  4346. else:
  4347. slice_size = '%s - (%s)' % (slice_size, start)
  4348. start = None
  4349. except ValueError:
  4350. pass
  4351. runtime_check = None
  4352. compile_time_check = False
  4353. try:
  4354. int_target_size = int(target_size)
  4355. except ValueError:
  4356. int_target_size = None
  4357. else:
  4358. compile_time_check = isinstance(slice_size, _py_int_types)
  4359. if compile_time_check and slice_size < 0:
  4360. if int_target_size > 0:
  4361. error(self.pos, "Assignment to empty slice.")
  4362. elif compile_time_check and start is None and stop is None:
  4363. # we know the exact slice length
  4364. if int_target_size != slice_size:
  4365. error(self.pos, "Assignment to slice of wrong length, expected %s, got %s" % (
  4366. slice_size, target_size))
  4367. elif start is not None:
  4368. if stop is None:
  4369. stop = slice_size
  4370. runtime_check = "(%s)-(%s)" % (stop, start)
  4371. elif stop is not None:
  4372. runtime_check = stop
  4373. else:
  4374. runtime_check = slice_size
  4375. if runtime_check:
  4376. code.putln("if (unlikely((%s) != (%s))) {" % (runtime_check, target_size))
  4377. code.putln(
  4378. 'PyErr_Format(PyExc_ValueError, "Assignment to slice of wrong length,'
  4379. ' expected %%" CYTHON_FORMAT_SSIZE_T "d, got %%" CYTHON_FORMAT_SSIZE_T "d",'
  4380. ' (Py_ssize_t)(%s), (Py_ssize_t)(%s));' % (
  4381. target_size, runtime_check))
  4382. code.putln(code.error_goto(self.pos))
  4383. code.putln("}")
  4384. def start_code(self):
  4385. if self.start:
  4386. return self.start.result()
  4387. else:
  4388. return "0"
  4389. def stop_code(self):
  4390. if self.stop:
  4391. return self.stop.result()
  4392. elif self.base.type.is_array:
  4393. return self.base.type.size
  4394. else:
  4395. return "PY_SSIZE_T_MAX"
  4396. def calculate_result_code(self):
  4397. # self.result() is not used, but this method must exist
  4398. return "<unused>"
  4399. class SliceNode(ExprNode):
  4400. # start:stop:step in subscript list
  4401. #
  4402. # start ExprNode
  4403. # stop ExprNode
  4404. # step ExprNode
  4405. subexprs = ['start', 'stop', 'step']
  4406. is_slice = True
  4407. type = slice_type
  4408. is_temp = 1
  4409. def calculate_constant_result(self):
  4410. self.constant_result = slice(
  4411. self.start.constant_result,
  4412. self.stop.constant_result,
  4413. self.step.constant_result)
  4414. def compile_time_value(self, denv):
  4415. start = self.start.compile_time_value(denv)
  4416. stop = self.stop.compile_time_value(denv)
  4417. step = self.step.compile_time_value(denv)
  4418. try:
  4419. return slice(start, stop, step)
  4420. except Exception as e:
  4421. self.compile_time_value_error(e)
  4422. def may_be_none(self):
  4423. return False
  4424. def analyse_types(self, env):
  4425. start = self.start.analyse_types(env)
  4426. stop = self.stop.analyse_types(env)
  4427. step = self.step.analyse_types(env)
  4428. self.start = start.coerce_to_pyobject(env)
  4429. self.stop = stop.coerce_to_pyobject(env)
  4430. self.step = step.coerce_to_pyobject(env)
  4431. if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
  4432. self.is_literal = True
  4433. self.is_temp = False
  4434. return self
  4435. gil_message = "Constructing Python slice object"
  4436. def calculate_result_code(self):
  4437. return self.result_code
  4438. def generate_result_code(self, code):
  4439. if self.is_literal:
  4440. self.result_code = code.get_py_const(py_object_type, 'slice', cleanup_level=2)
  4441. code = code.get_cached_constants_writer()
  4442. code.mark_pos(self.pos)
  4443. code.putln(
  4444. "%s = PySlice_New(%s, %s, %s); %s" % (
  4445. self.result(),
  4446. self.start.py_result(),
  4447. self.stop.py_result(),
  4448. self.step.py_result(),
  4449. code.error_goto_if_null(self.result(), self.pos)))
  4450. code.put_gotref(self.py_result())
  4451. if self.is_literal:
  4452. code.put_giveref(self.py_result())
  4453. class SliceIntNode(SliceNode):
  4454. # start:stop:step in subscript list
  4455. # This is just a node to hold start,stop and step nodes that can be
  4456. # converted to integers. This does not generate a slice python object.
  4457. #
  4458. # start ExprNode
  4459. # stop ExprNode
  4460. # step ExprNode
  4461. is_temp = 0
  4462. def calculate_constant_result(self):
  4463. self.constant_result = slice(
  4464. self.start.constant_result,
  4465. self.stop.constant_result,
  4466. self.step.constant_result)
  4467. def compile_time_value(self, denv):
  4468. start = self.start.compile_time_value(denv)
  4469. stop = self.stop.compile_time_value(denv)
  4470. step = self.step.compile_time_value(denv)
  4471. try:
  4472. return slice(start, stop, step)
  4473. except Exception as e:
  4474. self.compile_time_value_error(e)
  4475. def may_be_none(self):
  4476. return False
  4477. def analyse_types(self, env):
  4478. self.start = self.start.analyse_types(env)
  4479. self.stop = self.stop.analyse_types(env)
  4480. self.step = self.step.analyse_types(env)
  4481. if not self.start.is_none:
  4482. self.start = self.start.coerce_to_integer(env)
  4483. if not self.stop.is_none:
  4484. self.stop = self.stop.coerce_to_integer(env)
  4485. if not self.step.is_none:
  4486. self.step = self.step.coerce_to_integer(env)
  4487. if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
  4488. self.is_literal = True
  4489. self.is_temp = False
  4490. return self
  4491. def calculate_result_code(self):
  4492. pass
  4493. def generate_result_code(self, code):
  4494. for a in self.start,self.stop,self.step:
  4495. if isinstance(a, CloneNode):
  4496. a.arg.result()
  4497. class CallNode(ExprNode):
  4498. # allow overriding the default 'may_be_none' behaviour
  4499. may_return_none = None
  4500. def infer_type(self, env):
  4501. # TODO(robertwb): Reduce redundancy with analyse_types.
  4502. function = self.function
  4503. func_type = function.infer_type(env)
  4504. if isinstance(function, NewExprNode):
  4505. # note: needs call to infer_type() above
  4506. return PyrexTypes.CPtrType(function.class_type)
  4507. if func_type is py_object_type:
  4508. # function might have lied for safety => try to find better type
  4509. entry = getattr(function, 'entry', None)
  4510. if entry is not None:
  4511. func_type = entry.type or func_type
  4512. if func_type.is_ptr:
  4513. func_type = func_type.base_type
  4514. if func_type.is_cfunction:
  4515. if getattr(self.function, 'entry', None) and hasattr(self, 'args'):
  4516. alternatives = self.function.entry.all_alternatives()
  4517. arg_types = [arg.infer_type(env) for arg in self.args]
  4518. func_entry = PyrexTypes.best_match(arg_types, alternatives)
  4519. if func_entry:
  4520. func_type = func_entry.type
  4521. if func_type.is_ptr:
  4522. func_type = func_type.base_type
  4523. return func_type.return_type
  4524. return func_type.return_type
  4525. elif func_type is type_type:
  4526. if function.is_name and function.entry and function.entry.type:
  4527. result_type = function.entry.type
  4528. if result_type.is_extension_type:
  4529. return result_type
  4530. elif result_type.is_builtin_type:
  4531. if function.entry.name == 'float':
  4532. return PyrexTypes.c_double_type
  4533. elif function.entry.name in Builtin.types_that_construct_their_instance:
  4534. return result_type
  4535. return py_object_type
  4536. def type_dependencies(self, env):
  4537. # TODO: Update when Danilo's C++ code merged in to handle the
  4538. # the case of function overloading.
  4539. return self.function.type_dependencies(env)
  4540. def is_simple(self):
  4541. # C function calls could be considered simple, but they may
  4542. # have side-effects that may hit when multiple operations must
  4543. # be effected in order, e.g. when constructing the argument
  4544. # sequence for a function call or comparing values.
  4545. return False
  4546. def may_be_none(self):
  4547. if self.may_return_none is not None:
  4548. return self.may_return_none
  4549. func_type = self.function.type
  4550. if func_type is type_type and self.function.is_name:
  4551. entry = self.function.entry
  4552. if entry.type.is_extension_type:
  4553. return False
  4554. if (entry.type.is_builtin_type and
  4555. entry.name in Builtin.types_that_construct_their_instance):
  4556. return False
  4557. return ExprNode.may_be_none(self)
  4558. def set_py_result_type(self, function, func_type=None):
  4559. if func_type is None:
  4560. func_type = function.type
  4561. if func_type is Builtin.type_type and (
  4562. function.is_name and
  4563. function.entry and
  4564. function.entry.is_builtin and
  4565. function.entry.name in Builtin.types_that_construct_their_instance):
  4566. # calling a builtin type that returns a specific object type
  4567. if function.entry.name == 'float':
  4568. # the following will come true later on in a transform
  4569. self.type = PyrexTypes.c_double_type
  4570. self.result_ctype = PyrexTypes.c_double_type
  4571. else:
  4572. self.type = Builtin.builtin_types[function.entry.name]
  4573. self.result_ctype = py_object_type
  4574. self.may_return_none = False
  4575. elif function.is_name and function.type_entry:
  4576. # We are calling an extension type constructor. As long as we do not
  4577. # support __new__(), the result type is clear
  4578. self.type = function.type_entry.type
  4579. self.result_ctype = py_object_type
  4580. self.may_return_none = False
  4581. else:
  4582. self.type = py_object_type
  4583. def analyse_as_type_constructor(self, env):
  4584. type = self.function.analyse_as_type(env)
  4585. if type and type.is_struct_or_union:
  4586. args, kwds = self.explicit_args_kwds()
  4587. items = []
  4588. for arg, member in zip(args, type.scope.var_entries):
  4589. items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
  4590. if kwds:
  4591. items += kwds.key_value_pairs
  4592. self.key_value_pairs = items
  4593. self.__class__ = DictNode
  4594. self.analyse_types(env) # FIXME
  4595. self.coerce_to(type, env)
  4596. return True
  4597. elif type and type.is_cpp_class:
  4598. self.args = [ arg.analyse_types(env) for arg in self.args ]
  4599. constructor = type.scope.lookup("<init>")
  4600. if not constructor:
  4601. error(self.function.pos, "no constructor found for C++ type '%s'" % self.function.name)
  4602. self.type = error_type
  4603. return self
  4604. self.function = RawCNameExprNode(self.function.pos, constructor.type)
  4605. self.function.entry = constructor
  4606. self.function.set_cname(type.empty_declaration_code())
  4607. self.analyse_c_function_call(env)
  4608. self.type = type
  4609. return True
  4610. def is_lvalue(self):
  4611. return self.type.is_reference
  4612. def nogil_check(self, env):
  4613. func_type = self.function_type()
  4614. if func_type.is_pyobject:
  4615. self.gil_error()
  4616. elif not getattr(func_type, 'nogil', False):
  4617. self.gil_error()
  4618. gil_message = "Calling gil-requiring function"
  4619. class SimpleCallNode(CallNode):
  4620. # Function call without keyword, * or ** args.
  4621. #
  4622. # function ExprNode
  4623. # args [ExprNode]
  4624. # arg_tuple ExprNode or None used internally
  4625. # self ExprNode or None used internally
  4626. # coerced_self ExprNode or None used internally
  4627. # wrapper_call bool used internally
  4628. # has_optional_args bool used internally
  4629. # nogil bool used internally
  4630. subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
  4631. self = None
  4632. coerced_self = None
  4633. arg_tuple = None
  4634. wrapper_call = False
  4635. has_optional_args = False
  4636. nogil = False
  4637. analysed = False
  4638. overflowcheck = False
  4639. def compile_time_value(self, denv):
  4640. function = self.function.compile_time_value(denv)
  4641. args = [arg.compile_time_value(denv) for arg in self.args]
  4642. try:
  4643. return function(*args)
  4644. except Exception as e:
  4645. self.compile_time_value_error(e)
  4646. def analyse_as_type(self, env):
  4647. attr = self.function.as_cython_attribute()
  4648. if attr == 'pointer':
  4649. if len(self.args) != 1:
  4650. error(self.args.pos, "only one type allowed.")
  4651. else:
  4652. type = self.args[0].analyse_as_type(env)
  4653. if not type:
  4654. error(self.args[0].pos, "Unknown type")
  4655. else:
  4656. return PyrexTypes.CPtrType(type)
  4657. elif attr == 'typeof':
  4658. if len(self.args) != 1:
  4659. error(self.args.pos, "only one type allowed.")
  4660. operand = self.args[0].analyse_types(env)
  4661. return operand.type
  4662. def explicit_args_kwds(self):
  4663. return self.args, None
  4664. def analyse_types(self, env):
  4665. if self.analyse_as_type_constructor(env):
  4666. return self
  4667. if self.analysed:
  4668. return self
  4669. self.analysed = True
  4670. self.function.is_called = 1
  4671. self.function = self.function.analyse_types(env)
  4672. function = self.function
  4673. if function.is_attribute and function.entry and function.entry.is_cmethod:
  4674. # Take ownership of the object from which the attribute
  4675. # was obtained, because we need to pass it as 'self'.
  4676. self.self = function.obj
  4677. function.obj = CloneNode(self.self)
  4678. func_type = self.function_type()
  4679. self.is_numpy_call_with_exprs = False
  4680. if has_np_pythran(env) and self.function.is_numpy_attribute:
  4681. has_pythran_args = True
  4682. self.arg_tuple = TupleNode(self.pos, args = self.args)
  4683. self.arg_tuple = self.arg_tuple.analyse_types(env)
  4684. for arg in self.arg_tuple.args:
  4685. has_pythran_args &= is_pythran_supported_node_or_none(arg)
  4686. self.is_numpy_call_with_exprs = bool(has_pythran_args)
  4687. if self.is_numpy_call_with_exprs:
  4688. env.add_include_file("pythonic/numpy/%s.hpp" % self.function.attribute)
  4689. return NumPyMethodCallNode.from_node(
  4690. self,
  4691. function=self.function,
  4692. arg_tuple=self.arg_tuple,
  4693. type=PythranExpr(pythran_func_type(self.function.attribute, self.arg_tuple.args)),
  4694. )
  4695. elif func_type.is_pyobject:
  4696. self.arg_tuple = TupleNode(self.pos, args = self.args)
  4697. self.arg_tuple = self.arg_tuple.analyse_types(env).coerce_to_pyobject(env)
  4698. self.args = None
  4699. self.set_py_result_type(function, func_type)
  4700. self.is_temp = 1
  4701. else:
  4702. self.args = [ arg.analyse_types(env) for arg in self.args ]
  4703. self.analyse_c_function_call(env)
  4704. if func_type.exception_check == '+':
  4705. self.is_temp = True
  4706. return self
  4707. def function_type(self):
  4708. # Return the type of the function being called, coercing a function
  4709. # pointer to a function if necessary. If the function has fused
  4710. # arguments, return the specific type.
  4711. func_type = self.function.type
  4712. if func_type.is_ptr:
  4713. func_type = func_type.base_type
  4714. return func_type
  4715. def analyse_c_function_call(self, env):
  4716. func_type = self.function.type
  4717. if func_type is error_type:
  4718. self.type = error_type
  4719. return
  4720. if func_type.is_cfunction and func_type.is_static_method:
  4721. if self.self and self.self.type.is_extension_type:
  4722. # To support this we'd need to pass self to determine whether
  4723. # it was overloaded in Python space (possibly via a Cython
  4724. # superclass turning a cdef method into a cpdef one).
  4725. error(self.pos, "Cannot call a static method on an instance variable.")
  4726. args = self.args
  4727. elif self.self:
  4728. args = [self.self] + self.args
  4729. else:
  4730. args = self.args
  4731. if func_type.is_cpp_class:
  4732. overloaded_entry = self.function.type.scope.lookup("operator()")
  4733. if overloaded_entry is None:
  4734. self.type = PyrexTypes.error_type
  4735. self.result_code = "<error>"
  4736. return
  4737. elif hasattr(self.function, 'entry'):
  4738. overloaded_entry = self.function.entry
  4739. elif self.function.is_subscript and self.function.is_fused_index:
  4740. overloaded_entry = self.function.type.entry
  4741. else:
  4742. overloaded_entry = None
  4743. if overloaded_entry:
  4744. if self.function.type.is_fused:
  4745. functypes = self.function.type.get_all_specialized_function_types()
  4746. alternatives = [f.entry for f in functypes]
  4747. else:
  4748. alternatives = overloaded_entry.all_alternatives()
  4749. entry = PyrexTypes.best_match(
  4750. [arg.type for arg in args], alternatives, self.pos, env, args)
  4751. if not entry:
  4752. self.type = PyrexTypes.error_type
  4753. self.result_code = "<error>"
  4754. return
  4755. entry.used = True
  4756. if not func_type.is_cpp_class:
  4757. self.function.entry = entry
  4758. self.function.type = entry.type
  4759. func_type = self.function_type()
  4760. else:
  4761. entry = None
  4762. func_type = self.function_type()
  4763. if not func_type.is_cfunction:
  4764. error(self.pos, "Calling non-function type '%s'" % func_type)
  4765. self.type = PyrexTypes.error_type
  4766. self.result_code = "<error>"
  4767. return
  4768. # Check no. of args
  4769. max_nargs = len(func_type.args)
  4770. expected_nargs = max_nargs - func_type.optional_arg_count
  4771. actual_nargs = len(args)
  4772. if func_type.optional_arg_count and expected_nargs != actual_nargs:
  4773. self.has_optional_args = 1
  4774. self.is_temp = 1
  4775. # check 'self' argument
  4776. if entry and entry.is_cmethod and func_type.args and not func_type.is_static_method:
  4777. formal_arg = func_type.args[0]
  4778. arg = args[0]
  4779. if formal_arg.not_none:
  4780. if self.self:
  4781. self.self = self.self.as_none_safe_node(
  4782. "'NoneType' object has no attribute '%{0}s'".format('.30' if len(entry.name) <= 30 else ''),
  4783. error='PyExc_AttributeError',
  4784. format_args=[entry.name])
  4785. else:
  4786. # unbound method
  4787. arg = arg.as_none_safe_node(
  4788. "descriptor '%s' requires a '%s' object but received a 'NoneType'",
  4789. format_args=[entry.name, formal_arg.type.name])
  4790. if self.self:
  4791. if formal_arg.accept_builtin_subtypes:
  4792. arg = CMethodSelfCloneNode(self.self)
  4793. else:
  4794. arg = CloneNode(self.self)
  4795. arg = self.coerced_self = arg.coerce_to(formal_arg.type, env)
  4796. elif formal_arg.type.is_builtin_type:
  4797. # special case: unbound methods of builtins accept subtypes
  4798. arg = arg.coerce_to(formal_arg.type, env)
  4799. if arg.type.is_builtin_type and isinstance(arg, PyTypeTestNode):
  4800. arg.exact_builtin_type = False
  4801. args[0] = arg
  4802. # Coerce arguments
  4803. some_args_in_temps = False
  4804. for i in range(min(max_nargs, actual_nargs)):
  4805. formal_arg = func_type.args[i]
  4806. formal_type = formal_arg.type
  4807. arg = args[i].coerce_to(formal_type, env)
  4808. if formal_arg.not_none:
  4809. # C methods must do the None checks at *call* time
  4810. arg = arg.as_none_safe_node(
  4811. "cannot pass None into a C function argument that is declared 'not None'")
  4812. if arg.is_temp:
  4813. if i > 0:
  4814. # first argument in temp doesn't impact subsequent arguments
  4815. some_args_in_temps = True
  4816. elif arg.type.is_pyobject and not env.nogil:
  4817. if i == 0 and self.self is not None:
  4818. # a method's cloned "self" argument is ok
  4819. pass
  4820. elif arg.nonlocally_immutable():
  4821. # plain local variables are ok
  4822. pass
  4823. else:
  4824. # we do not safely own the argument's reference,
  4825. # but we must make sure it cannot be collected
  4826. # before we return from the function, so we create
  4827. # an owned temp reference to it
  4828. if i > 0: # first argument doesn't matter
  4829. some_args_in_temps = True
  4830. arg = arg.coerce_to_temp(env)
  4831. args[i] = arg
  4832. # handle additional varargs parameters
  4833. for i in range(max_nargs, actual_nargs):
  4834. arg = args[i]
  4835. if arg.type.is_pyobject:
  4836. if arg.type is str_type:
  4837. arg_ctype = PyrexTypes.c_char_ptr_type
  4838. else:
  4839. arg_ctype = arg.type.default_coerced_ctype()
  4840. if arg_ctype is None:
  4841. error(self.args[i].pos,
  4842. "Python object cannot be passed as a varargs parameter")
  4843. else:
  4844. args[i] = arg = arg.coerce_to(arg_ctype, env)
  4845. if arg.is_temp and i > 0:
  4846. some_args_in_temps = True
  4847. if some_args_in_temps:
  4848. # if some args are temps and others are not, they may get
  4849. # constructed in the wrong order (temps first) => make
  4850. # sure they are either all temps or all not temps (except
  4851. # for the last argument, which is evaluated last in any
  4852. # case)
  4853. for i in range(actual_nargs-1):
  4854. if i == 0 and self.self is not None:
  4855. continue # self is ok
  4856. arg = args[i]
  4857. if arg.nonlocally_immutable():
  4858. # locals, C functions, unassignable types are safe.
  4859. pass
  4860. elif arg.type.is_cpp_class:
  4861. # Assignment has side effects, avoid.
  4862. pass
  4863. elif env.nogil and arg.type.is_pyobject:
  4864. # can't copy a Python reference into a temp in nogil
  4865. # env (this is safe: a construction would fail in
  4866. # nogil anyway)
  4867. pass
  4868. else:
  4869. #self.args[i] = arg.coerce_to_temp(env)
  4870. # instead: issue a warning
  4871. if i > 0 or i == 1 and self.self is not None: # skip first arg
  4872. warning(arg.pos, "Argument evaluation order in C function call is undefined and may not be as expected", 0)
  4873. break
  4874. self.args[:] = args
  4875. # Calc result type and code fragment
  4876. if isinstance(self.function, NewExprNode):
  4877. self.type = PyrexTypes.CPtrType(self.function.class_type)
  4878. else:
  4879. self.type = func_type.return_type
  4880. if self.function.is_name or self.function.is_attribute:
  4881. func_entry = self.function.entry
  4882. if func_entry and (func_entry.utility_code or func_entry.utility_code_definition):
  4883. self.is_temp = 1 # currently doesn't work for self.calculate_result_code()
  4884. if self.type.is_pyobject:
  4885. self.result_ctype = py_object_type
  4886. self.is_temp = 1
  4887. elif func_type.exception_value is not None or func_type.exception_check:
  4888. self.is_temp = 1
  4889. elif self.type.is_memoryviewslice:
  4890. self.is_temp = 1
  4891. # func_type.exception_check = True
  4892. if self.is_temp and self.type.is_reference:
  4893. self.type = PyrexTypes.CFakeReferenceType(self.type.ref_base_type)
  4894. # Called in 'nogil' context?
  4895. self.nogil = env.nogil
  4896. if (self.nogil and
  4897. func_type.exception_check and
  4898. func_type.exception_check != '+'):
  4899. env.use_utility_code(pyerr_occurred_withgil_utility_code)
  4900. # C++ exception handler
  4901. if func_type.exception_check == '+':
  4902. if func_type.exception_value is None:
  4903. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  4904. self.overflowcheck = env.directives['overflowcheck']
  4905. def calculate_result_code(self):
  4906. return self.c_call_code()
  4907. def c_call_code(self):
  4908. func_type = self.function_type()
  4909. if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
  4910. return "<error>"
  4911. formal_args = func_type.args
  4912. arg_list_code = []
  4913. args = list(zip(formal_args, self.args))
  4914. max_nargs = len(func_type.args)
  4915. expected_nargs = max_nargs - func_type.optional_arg_count
  4916. actual_nargs = len(self.args)
  4917. for formal_arg, actual_arg in args[:expected_nargs]:
  4918. arg_code = actual_arg.result_as(formal_arg.type)
  4919. arg_list_code.append(arg_code)
  4920. if func_type.is_overridable:
  4921. arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
  4922. if func_type.optional_arg_count:
  4923. if expected_nargs == actual_nargs:
  4924. optional_args = 'NULL'
  4925. else:
  4926. optional_args = "&%s" % self.opt_arg_struct
  4927. arg_list_code.append(optional_args)
  4928. for actual_arg in self.args[len(formal_args):]:
  4929. arg_list_code.append(actual_arg.result())
  4930. result = "%s(%s)" % (self.function.result(), ', '.join(arg_list_code))
  4931. return result
  4932. def is_c_result_required(self):
  4933. func_type = self.function_type()
  4934. if not func_type.exception_value or func_type.exception_check == '+':
  4935. return False # skip allocation of unused result temp
  4936. return True
  4937. def generate_evaluation_code(self, code):
  4938. function = self.function
  4939. if function.is_name or function.is_attribute:
  4940. code.globalstate.use_entry_utility_code(function.entry)
  4941. if not function.type.is_pyobject or len(self.arg_tuple.args) > 1 or (
  4942. self.arg_tuple.args and self.arg_tuple.is_literal):
  4943. super(SimpleCallNode, self).generate_evaluation_code(code)
  4944. return
  4945. # Special case 0-args and try to avoid explicit tuple creation for Python calls with 1 arg.
  4946. arg = self.arg_tuple.args[0] if self.arg_tuple.args else None
  4947. subexprs = (self.self, self.coerced_self, function, arg)
  4948. for subexpr in subexprs:
  4949. if subexpr is not None:
  4950. subexpr.generate_evaluation_code(code)
  4951. code.mark_pos(self.pos)
  4952. assert self.is_temp
  4953. self.allocate_temp_result(code)
  4954. if arg is None:
  4955. code.globalstate.use_utility_code(UtilityCode.load_cached(
  4956. "PyObjectCallNoArg", "ObjectHandling.c"))
  4957. code.putln(
  4958. "%s = __Pyx_PyObject_CallNoArg(%s); %s" % (
  4959. self.result(),
  4960. function.py_result(),
  4961. code.error_goto_if_null(self.result(), self.pos)))
  4962. else:
  4963. code.globalstate.use_utility_code(UtilityCode.load_cached(
  4964. "PyObjectCallOneArg", "ObjectHandling.c"))
  4965. code.putln(
  4966. "%s = __Pyx_PyObject_CallOneArg(%s, %s); %s" % (
  4967. self.result(),
  4968. function.py_result(),
  4969. arg.py_result(),
  4970. code.error_goto_if_null(self.result(), self.pos)))
  4971. code.put_gotref(self.py_result())
  4972. for subexpr in subexprs:
  4973. if subexpr is not None:
  4974. subexpr.generate_disposal_code(code)
  4975. subexpr.free_temps(code)
  4976. def generate_result_code(self, code):
  4977. func_type = self.function_type()
  4978. if func_type.is_pyobject:
  4979. arg_code = self.arg_tuple.py_result()
  4980. code.globalstate.use_utility_code(UtilityCode.load_cached(
  4981. "PyObjectCall", "ObjectHandling.c"))
  4982. code.putln(
  4983. "%s = __Pyx_PyObject_Call(%s, %s, NULL); %s" % (
  4984. self.result(),
  4985. self.function.py_result(),
  4986. arg_code,
  4987. code.error_goto_if_null(self.result(), self.pos)))
  4988. code.put_gotref(self.py_result())
  4989. elif func_type.is_cfunction:
  4990. if self.has_optional_args:
  4991. actual_nargs = len(self.args)
  4992. expected_nargs = len(func_type.args) - func_type.optional_arg_count
  4993. self.opt_arg_struct = code.funcstate.allocate_temp(
  4994. func_type.op_arg_struct.base_type, manage_ref=True)
  4995. code.putln("%s.%s = %s;" % (
  4996. self.opt_arg_struct,
  4997. Naming.pyrex_prefix + "n",
  4998. len(self.args) - expected_nargs))
  4999. args = list(zip(func_type.args, self.args))
  5000. for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
  5001. code.putln("%s.%s = %s;" % (
  5002. self.opt_arg_struct,
  5003. func_type.opt_arg_cname(formal_arg.name),
  5004. actual_arg.result_as(formal_arg.type)))
  5005. exc_checks = []
  5006. if self.type.is_pyobject and self.is_temp:
  5007. exc_checks.append("!%s" % self.result())
  5008. elif self.type.is_memoryviewslice:
  5009. assert self.is_temp
  5010. exc_checks.append(self.type.error_condition(self.result()))
  5011. else:
  5012. exc_val = func_type.exception_value
  5013. exc_check = func_type.exception_check
  5014. if exc_val is not None:
  5015. exc_checks.append("%s == %s" % (self.result(), func_type.return_type.cast_code(exc_val)))
  5016. if exc_check:
  5017. if self.nogil:
  5018. exc_checks.append("__Pyx_ErrOccurredWithGIL()")
  5019. else:
  5020. exc_checks.append("PyErr_Occurred()")
  5021. if self.is_temp or exc_checks:
  5022. rhs = self.c_call_code()
  5023. if self.result():
  5024. lhs = "%s = " % self.result()
  5025. if self.is_temp and self.type.is_pyobject:
  5026. #return_type = self.type # func_type.return_type
  5027. #print "SimpleCallNode.generate_result_code: casting", rhs, \
  5028. # "from", return_type, "to pyobject" ###
  5029. rhs = typecast(py_object_type, self.type, rhs)
  5030. else:
  5031. lhs = ""
  5032. if func_type.exception_check == '+':
  5033. translate_cpp_exception(code, self.pos, '%s%s;' % (lhs, rhs),
  5034. func_type.exception_value, self.nogil)
  5035. else:
  5036. if (self.overflowcheck
  5037. and self.type.is_int
  5038. and self.type.signed
  5039. and self.function.result() in ('abs', 'labs', '__Pyx_abs_longlong')):
  5040. goto_error = 'if (unlikely(%s < 0)) { PyErr_SetString(PyExc_OverflowError, "value too large"); %s; }' % (self.result(), code.error_goto(self.pos))
  5041. elif exc_checks:
  5042. goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
  5043. else:
  5044. goto_error = ""
  5045. code.putln("%s%s; %s" % (lhs, rhs, goto_error))
  5046. if self.type.is_pyobject and self.result():
  5047. code.put_gotref(self.py_result())
  5048. if self.has_optional_args:
  5049. code.funcstate.release_temp(self.opt_arg_struct)
  5050. class NumPyMethodCallNode(SimpleCallNode):
  5051. # Pythran call to a NumPy function or method.
  5052. #
  5053. # function ExprNode the function/method to call
  5054. # arg_tuple TupleNode the arguments as an args tuple
  5055. subexprs = ['function', 'arg_tuple']
  5056. is_temp = True
  5057. may_return_none = True
  5058. def generate_evaluation_code(self, code):
  5059. code.mark_pos(self.pos)
  5060. self.allocate_temp_result(code)
  5061. self.function.generate_evaluation_code(code)
  5062. assert self.arg_tuple.mult_factor is None
  5063. args = self.arg_tuple.args
  5064. for arg in args:
  5065. arg.generate_evaluation_code(code)
  5066. code.putln("// function evaluation code for numpy function")
  5067. code.putln("__Pyx_call_destructor(%s);" % self.result())
  5068. code.putln("new (&%s) decltype(%s){pythonic::numpy::functor::%s{}(%s)};" % (
  5069. self.result(),
  5070. self.result(),
  5071. self.function.attribute,
  5072. ", ".join(a.pythran_result() for a in args)))
  5073. class PyMethodCallNode(SimpleCallNode):
  5074. # Specialised call to a (potential) PyMethodObject with non-constant argument tuple.
  5075. # Allows the self argument to be injected directly instead of repacking a tuple for it.
  5076. #
  5077. # function ExprNode the function/method object to call
  5078. # arg_tuple TupleNode the arguments for the args tuple
  5079. subexprs = ['function', 'arg_tuple']
  5080. is_temp = True
  5081. def generate_evaluation_code(self, code):
  5082. code.mark_pos(self.pos)
  5083. self.allocate_temp_result(code)
  5084. self.function.generate_evaluation_code(code)
  5085. assert self.arg_tuple.mult_factor is None
  5086. args = self.arg_tuple.args
  5087. for arg in args:
  5088. arg.generate_evaluation_code(code)
  5089. # make sure function is in temp so that we can replace the reference below if it's a method
  5090. reuse_function_temp = self.function.is_temp
  5091. if reuse_function_temp:
  5092. function = self.function.result()
  5093. else:
  5094. function = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  5095. self.function.make_owned_reference(code)
  5096. code.put("%s = %s; " % (function, self.function.py_result()))
  5097. self.function.generate_disposal_code(code)
  5098. self.function.free_temps(code)
  5099. self_arg = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  5100. code.putln("%s = NULL;" % self_arg)
  5101. arg_offset_cname = None
  5102. if len(args) > 1:
  5103. arg_offset_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
  5104. code.putln("%s = 0;" % arg_offset_cname)
  5105. def attribute_is_likely_method(attr):
  5106. obj = attr.obj
  5107. if obj.is_name and obj.entry.is_pyglobal:
  5108. return False # more likely to be a function
  5109. return True
  5110. if self.function.is_attribute:
  5111. likely_method = 'likely' if attribute_is_likely_method(self.function) else 'unlikely'
  5112. elif self.function.is_name and self.function.cf_state:
  5113. # not an attribute itself, but might have been assigned from one (e.g. bound method)
  5114. for assignment in self.function.cf_state:
  5115. value = assignment.rhs
  5116. if value and value.is_attribute and value.obj.type.is_pyobject:
  5117. if attribute_is_likely_method(value):
  5118. likely_method = 'likely'
  5119. break
  5120. else:
  5121. likely_method = 'unlikely'
  5122. else:
  5123. likely_method = 'unlikely'
  5124. code.putln("if (CYTHON_UNPACK_METHODS && %s(PyMethod_Check(%s))) {" % (likely_method, function))
  5125. code.putln("%s = PyMethod_GET_SELF(%s);" % (self_arg, function))
  5126. # the following is always true in Py3 (kept only for safety),
  5127. # but is false for unbound methods in Py2
  5128. code.putln("if (likely(%s)) {" % self_arg)
  5129. code.putln("PyObject* function = PyMethod_GET_FUNCTION(%s);" % function)
  5130. code.put_incref(self_arg, py_object_type)
  5131. code.put_incref("function", py_object_type)
  5132. # free method object as early to possible to enable reuse from CPython's freelist
  5133. code.put_decref_set(function, "function")
  5134. if len(args) > 1:
  5135. code.putln("%s = 1;" % arg_offset_cname)
  5136. code.putln("}")
  5137. code.putln("}")
  5138. if not args:
  5139. # fastest special case: try to avoid tuple creation
  5140. code.putln("if (%s) {" % self_arg)
  5141. code.globalstate.use_utility_code(
  5142. UtilityCode.load_cached("PyObjectCallOneArg", "ObjectHandling.c"))
  5143. code.putln(
  5144. "%s = __Pyx_PyObject_CallOneArg(%s, %s); %s" % (
  5145. self.result(),
  5146. function, self_arg,
  5147. code.error_goto_if_null(self.result(), self.pos)))
  5148. code.put_decref_clear(self_arg, py_object_type)
  5149. code.funcstate.release_temp(self_arg)
  5150. code.putln("} else {")
  5151. code.globalstate.use_utility_code(
  5152. UtilityCode.load_cached("PyObjectCallNoArg", "ObjectHandling.c"))
  5153. code.putln(
  5154. "%s = __Pyx_PyObject_CallNoArg(%s); %s" % (
  5155. self.result(),
  5156. function,
  5157. code.error_goto_if_null(self.result(), self.pos)))
  5158. code.putln("}")
  5159. code.put_gotref(self.py_result())
  5160. else:
  5161. if len(args) == 1:
  5162. code.putln("if (!%s) {" % self_arg)
  5163. code.globalstate.use_utility_code(
  5164. UtilityCode.load_cached("PyObjectCallOneArg", "ObjectHandling.c"))
  5165. arg = args[0]
  5166. code.putln(
  5167. "%s = __Pyx_PyObject_CallOneArg(%s, %s); %s" % (
  5168. self.result(),
  5169. function, arg.py_result(),
  5170. code.error_goto_if_null(self.result(), self.pos)))
  5171. arg.generate_disposal_code(code)
  5172. code.put_gotref(self.py_result())
  5173. code.putln("} else {")
  5174. arg_offset = 1
  5175. else:
  5176. arg_offset = arg_offset_cname
  5177. code.globalstate.use_utility_code(
  5178. UtilityCode.load_cached("PyFunctionFastCall", "ObjectHandling.c"))
  5179. code.globalstate.use_utility_code(
  5180. UtilityCode.load_cached("PyCFunctionFastCall", "ObjectHandling.c"))
  5181. for test_func, call_prefix in [('PyFunction_Check', 'Py'), ('__Pyx_PyFastCFunction_Check', 'PyC')]:
  5182. code.putln("#if CYTHON_FAST_%sCALL" % call_prefix.upper())
  5183. code.putln("if (%s(%s)) {" % (test_func, function))
  5184. code.putln("PyObject *%s[%d] = {%s, %s};" % (
  5185. Naming.quick_temp_cname,
  5186. len(args)+1,
  5187. self_arg,
  5188. ', '.join(arg.py_result() for arg in args)))
  5189. code.putln("%s = __Pyx_%sFunction_FastCall(%s, %s+1-%s, %d+%s); %s" % (
  5190. self.result(),
  5191. call_prefix,
  5192. function,
  5193. Naming.quick_temp_cname,
  5194. arg_offset,
  5195. len(args),
  5196. arg_offset,
  5197. code.error_goto_if_null(self.result(), self.pos)))
  5198. code.put_xdecref_clear(self_arg, py_object_type)
  5199. code.put_gotref(self.py_result())
  5200. for arg in args:
  5201. arg.generate_disposal_code(code)
  5202. code.putln("} else")
  5203. code.putln("#endif")
  5204. code.putln("{")
  5205. args_tuple = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  5206. code.putln("%s = PyTuple_New(%d+%s); %s" % (
  5207. args_tuple, len(args), arg_offset,
  5208. code.error_goto_if_null(args_tuple, self.pos)))
  5209. code.put_gotref(args_tuple)
  5210. if len(args) > 1:
  5211. code.putln("if (%s) {" % self_arg)
  5212. code.putln("__Pyx_GIVEREF(%s); PyTuple_SET_ITEM(%s, 0, %s); %s = NULL;" % (
  5213. self_arg, args_tuple, self_arg, self_arg)) # stealing owned ref in this case
  5214. code.funcstate.release_temp(self_arg)
  5215. if len(args) > 1:
  5216. code.putln("}")
  5217. for i, arg in enumerate(args):
  5218. arg.make_owned_reference(code)
  5219. code.put_giveref(arg.py_result())
  5220. code.putln("PyTuple_SET_ITEM(%s, %d+%s, %s);" % (
  5221. args_tuple, i, arg_offset, arg.py_result()))
  5222. if len(args) > 1:
  5223. code.funcstate.release_temp(arg_offset_cname)
  5224. for arg in args:
  5225. arg.generate_post_assignment_code(code)
  5226. arg.free_temps(code)
  5227. code.globalstate.use_utility_code(
  5228. UtilityCode.load_cached("PyObjectCall", "ObjectHandling.c"))
  5229. code.putln(
  5230. "%s = __Pyx_PyObject_Call(%s, %s, NULL); %s" % (
  5231. self.result(),
  5232. function, args_tuple,
  5233. code.error_goto_if_null(self.result(), self.pos)))
  5234. code.put_gotref(self.py_result())
  5235. code.put_decref_clear(args_tuple, py_object_type)
  5236. code.funcstate.release_temp(args_tuple)
  5237. if len(args) == 1:
  5238. code.putln("}")
  5239. code.putln("}") # !CYTHON_FAST_PYCALL
  5240. if reuse_function_temp:
  5241. self.function.generate_disposal_code(code)
  5242. self.function.free_temps(code)
  5243. else:
  5244. code.put_decref_clear(function, py_object_type)
  5245. code.funcstate.release_temp(function)
  5246. class InlinedDefNodeCallNode(CallNode):
  5247. # Inline call to defnode
  5248. #
  5249. # function PyCFunctionNode
  5250. # function_name NameNode
  5251. # args [ExprNode]
  5252. subexprs = ['args', 'function_name']
  5253. is_temp = 1
  5254. type = py_object_type
  5255. function = None
  5256. function_name = None
  5257. def can_be_inlined(self):
  5258. func_type= self.function.def_node
  5259. if func_type.star_arg or func_type.starstar_arg:
  5260. return False
  5261. if len(func_type.args) != len(self.args):
  5262. return False
  5263. if func_type.num_kwonly_args:
  5264. return False # actually wrong number of arguments
  5265. return True
  5266. def analyse_types(self, env):
  5267. self.function_name = self.function_name.analyse_types(env)
  5268. self.args = [ arg.analyse_types(env) for arg in self.args ]
  5269. func_type = self.function.def_node
  5270. actual_nargs = len(self.args)
  5271. # Coerce arguments
  5272. some_args_in_temps = False
  5273. for i in range(actual_nargs):
  5274. formal_type = func_type.args[i].type
  5275. arg = self.args[i].coerce_to(formal_type, env)
  5276. if arg.is_temp:
  5277. if i > 0:
  5278. # first argument in temp doesn't impact subsequent arguments
  5279. some_args_in_temps = True
  5280. elif arg.type.is_pyobject and not env.nogil:
  5281. if arg.nonlocally_immutable():
  5282. # plain local variables are ok
  5283. pass
  5284. else:
  5285. # we do not safely own the argument's reference,
  5286. # but we must make sure it cannot be collected
  5287. # before we return from the function, so we create
  5288. # an owned temp reference to it
  5289. if i > 0: # first argument doesn't matter
  5290. some_args_in_temps = True
  5291. arg = arg.coerce_to_temp(env)
  5292. self.args[i] = arg
  5293. if some_args_in_temps:
  5294. # if some args are temps and others are not, they may get
  5295. # constructed in the wrong order (temps first) => make
  5296. # sure they are either all temps or all not temps (except
  5297. # for the last argument, which is evaluated last in any
  5298. # case)
  5299. for i in range(actual_nargs-1):
  5300. arg = self.args[i]
  5301. if arg.nonlocally_immutable():
  5302. # locals, C functions, unassignable types are safe.
  5303. pass
  5304. elif arg.type.is_cpp_class:
  5305. # Assignment has side effects, avoid.
  5306. pass
  5307. elif env.nogil and arg.type.is_pyobject:
  5308. # can't copy a Python reference into a temp in nogil
  5309. # env (this is safe: a construction would fail in
  5310. # nogil anyway)
  5311. pass
  5312. else:
  5313. #self.args[i] = arg.coerce_to_temp(env)
  5314. # instead: issue a warning
  5315. if i > 0:
  5316. warning(arg.pos, "Argument evaluation order in C function call is undefined and may not be as expected", 0)
  5317. break
  5318. return self
  5319. def generate_result_code(self, code):
  5320. arg_code = [self.function_name.py_result()]
  5321. func_type = self.function.def_node
  5322. for arg, proto_arg in zip(self.args, func_type.args):
  5323. if arg.type.is_pyobject:
  5324. arg_code.append(arg.result_as(proto_arg.type))
  5325. else:
  5326. arg_code.append(arg.result())
  5327. arg_code = ', '.join(arg_code)
  5328. code.putln(
  5329. "%s = %s(%s); %s" % (
  5330. self.result(),
  5331. self.function.def_node.entry.pyfunc_cname,
  5332. arg_code,
  5333. code.error_goto_if_null(self.result(), self.pos)))
  5334. code.put_gotref(self.py_result())
  5335. class PythonCapiFunctionNode(ExprNode):
  5336. subexprs = []
  5337. def __init__(self, pos, py_name, cname, func_type, utility_code = None):
  5338. ExprNode.__init__(self, pos, name=py_name, cname=cname,
  5339. type=func_type, utility_code=utility_code)
  5340. def analyse_types(self, env):
  5341. return self
  5342. def generate_result_code(self, code):
  5343. if self.utility_code:
  5344. code.globalstate.use_utility_code(self.utility_code)
  5345. def calculate_result_code(self):
  5346. return self.cname
  5347. class PythonCapiCallNode(SimpleCallNode):
  5348. # Python C-API Function call (only created in transforms)
  5349. # By default, we assume that the call never returns None, as this
  5350. # is true for most C-API functions in CPython. If this does not
  5351. # apply to a call, set the following to True (or None to inherit
  5352. # the default behaviour).
  5353. may_return_none = False
  5354. def __init__(self, pos, function_name, func_type,
  5355. utility_code = None, py_name=None, **kwargs):
  5356. self.type = func_type.return_type
  5357. self.result_ctype = self.type
  5358. self.function = PythonCapiFunctionNode(
  5359. pos, py_name, function_name, func_type,
  5360. utility_code = utility_code)
  5361. # call this last so that we can override the constructed
  5362. # attributes above with explicit keyword arguments if required
  5363. SimpleCallNode.__init__(self, pos, **kwargs)
  5364. class CachedBuiltinMethodCallNode(CallNode):
  5365. # Python call to a method of a known Python builtin (only created in transforms)
  5366. subexprs = ['obj', 'args']
  5367. is_temp = True
  5368. def __init__(self, call_node, obj, method_name, args):
  5369. super(CachedBuiltinMethodCallNode, self).__init__(
  5370. call_node.pos,
  5371. obj=obj, method_name=method_name, args=args,
  5372. may_return_none=call_node.may_return_none,
  5373. type=call_node.type)
  5374. def may_be_none(self):
  5375. if self.may_return_none is not None:
  5376. return self.may_return_none
  5377. return ExprNode.may_be_none(self)
  5378. def generate_result_code(self, code):
  5379. type_cname = self.obj.type.cname
  5380. obj_cname = self.obj.py_result()
  5381. args = [arg.py_result() for arg in self.args]
  5382. call_code = code.globalstate.cached_unbound_method_call_code(
  5383. obj_cname, type_cname, self.method_name, args)
  5384. code.putln("%s = %s; %s" % (
  5385. self.result(), call_code,
  5386. code.error_goto_if_null(self.result(), self.pos)
  5387. ))
  5388. code.put_gotref(self.result())
  5389. class GeneralCallNode(CallNode):
  5390. # General Python function call, including keyword,
  5391. # * and ** arguments.
  5392. #
  5393. # function ExprNode
  5394. # positional_args ExprNode Tuple of positional arguments
  5395. # keyword_args ExprNode or None Dict of keyword arguments
  5396. type = py_object_type
  5397. subexprs = ['function', 'positional_args', 'keyword_args']
  5398. nogil_check = Node.gil_error
  5399. def compile_time_value(self, denv):
  5400. function = self.function.compile_time_value(denv)
  5401. positional_args = self.positional_args.compile_time_value(denv)
  5402. keyword_args = self.keyword_args.compile_time_value(denv)
  5403. try:
  5404. return function(*positional_args, **keyword_args)
  5405. except Exception as e:
  5406. self.compile_time_value_error(e)
  5407. def explicit_args_kwds(self):
  5408. if (self.keyword_args and not self.keyword_args.is_dict_literal or
  5409. not self.positional_args.is_sequence_constructor):
  5410. raise CompileError(self.pos,
  5411. 'Compile-time keyword arguments must be explicit.')
  5412. return self.positional_args.args, self.keyword_args
  5413. def analyse_types(self, env):
  5414. if self.analyse_as_type_constructor(env):
  5415. return self
  5416. self.function = self.function.analyse_types(env)
  5417. if not self.function.type.is_pyobject:
  5418. if self.function.type.is_error:
  5419. self.type = error_type
  5420. return self
  5421. if hasattr(self.function, 'entry'):
  5422. node = self.map_to_simple_call_node()
  5423. if node is not None and node is not self:
  5424. return node.analyse_types(env)
  5425. elif self.function.entry.as_variable:
  5426. self.function = self.function.coerce_to_pyobject(env)
  5427. elif node is self:
  5428. error(self.pos,
  5429. "Non-trivial keyword arguments and starred "
  5430. "arguments not allowed in cdef functions.")
  5431. else:
  5432. # error was already reported
  5433. pass
  5434. else:
  5435. self.function = self.function.coerce_to_pyobject(env)
  5436. if self.keyword_args:
  5437. self.keyword_args = self.keyword_args.analyse_types(env)
  5438. self.positional_args = self.positional_args.analyse_types(env)
  5439. self.positional_args = \
  5440. self.positional_args.coerce_to_pyobject(env)
  5441. self.set_py_result_type(self.function)
  5442. self.is_temp = 1
  5443. return self
  5444. def map_to_simple_call_node(self):
  5445. """
  5446. Tries to map keyword arguments to declared positional arguments.
  5447. Returns self to try a Python call, None to report an error
  5448. or a SimpleCallNode if the mapping succeeds.
  5449. """
  5450. if not isinstance(self.positional_args, TupleNode):
  5451. # has starred argument
  5452. return self
  5453. if not self.keyword_args.is_dict_literal:
  5454. # keywords come from arbitrary expression => nothing to do here
  5455. return self
  5456. function = self.function
  5457. entry = getattr(function, 'entry', None)
  5458. if not entry:
  5459. return self
  5460. function_type = entry.type
  5461. if function_type.is_ptr:
  5462. function_type = function_type.base_type
  5463. if not function_type.is_cfunction:
  5464. return self
  5465. pos_args = self.positional_args.args
  5466. kwargs = self.keyword_args
  5467. declared_args = function_type.args
  5468. if entry.is_cmethod:
  5469. declared_args = declared_args[1:] # skip 'self'
  5470. if len(pos_args) > len(declared_args):
  5471. error(self.pos, "function call got too many positional arguments, "
  5472. "expected %d, got %s" % (len(declared_args),
  5473. len(pos_args)))
  5474. return None
  5475. matched_args = set([ arg.name for arg in declared_args[:len(pos_args)]
  5476. if arg.name ])
  5477. unmatched_args = declared_args[len(pos_args):]
  5478. matched_kwargs_count = 0
  5479. args = list(pos_args)
  5480. # check for duplicate keywords
  5481. seen = set(matched_args)
  5482. has_errors = False
  5483. for arg in kwargs.key_value_pairs:
  5484. name = arg.key.value
  5485. if name in seen:
  5486. error(arg.pos, "argument '%s' passed twice" % name)
  5487. has_errors = True
  5488. # continue to report more errors if there are any
  5489. seen.add(name)
  5490. # match keywords that are passed in order
  5491. for decl_arg, arg in zip(unmatched_args, kwargs.key_value_pairs):
  5492. name = arg.key.value
  5493. if decl_arg.name == name:
  5494. matched_args.add(name)
  5495. matched_kwargs_count += 1
  5496. args.append(arg.value)
  5497. else:
  5498. break
  5499. # match keyword arguments that are passed out-of-order, but keep
  5500. # the evaluation of non-simple arguments in order by moving them
  5501. # into temps
  5502. from .UtilNodes import EvalWithTempExprNode, LetRefNode
  5503. temps = []
  5504. if len(kwargs.key_value_pairs) > matched_kwargs_count:
  5505. unmatched_args = declared_args[len(args):]
  5506. keywords = dict([ (arg.key.value, (i+len(pos_args), arg))
  5507. for i, arg in enumerate(kwargs.key_value_pairs) ])
  5508. first_missing_keyword = None
  5509. for decl_arg in unmatched_args:
  5510. name = decl_arg.name
  5511. if name not in keywords:
  5512. # missing keyword argument => either done or error
  5513. if not first_missing_keyword:
  5514. first_missing_keyword = name
  5515. continue
  5516. elif first_missing_keyword:
  5517. if entry.as_variable:
  5518. # we might be able to convert the function to a Python
  5519. # object, which then allows full calling semantics
  5520. # with default values in gaps - currently, we only
  5521. # support optional arguments at the end
  5522. return self
  5523. # wasn't the last keyword => gaps are not supported
  5524. error(self.pos, "C function call is missing "
  5525. "argument '%s'" % first_missing_keyword)
  5526. return None
  5527. pos, arg = keywords[name]
  5528. matched_args.add(name)
  5529. matched_kwargs_count += 1
  5530. if arg.value.is_simple():
  5531. args.append(arg.value)
  5532. else:
  5533. temp = LetRefNode(arg.value)
  5534. assert temp.is_simple()
  5535. args.append(temp)
  5536. temps.append((pos, temp))
  5537. if temps:
  5538. # may have to move preceding non-simple args into temps
  5539. final_args = []
  5540. new_temps = []
  5541. first_temp_arg = temps[0][-1]
  5542. for arg_value in args:
  5543. if arg_value is first_temp_arg:
  5544. break # done
  5545. if arg_value.is_simple():
  5546. final_args.append(arg_value)
  5547. else:
  5548. temp = LetRefNode(arg_value)
  5549. new_temps.append(temp)
  5550. final_args.append(temp)
  5551. if new_temps:
  5552. args = final_args
  5553. temps = new_temps + [ arg for i,arg in sorted(temps) ]
  5554. # check for unexpected keywords
  5555. for arg in kwargs.key_value_pairs:
  5556. name = arg.key.value
  5557. if name not in matched_args:
  5558. has_errors = True
  5559. error(arg.pos,
  5560. "C function got unexpected keyword argument '%s'" %
  5561. name)
  5562. if has_errors:
  5563. # error was reported already
  5564. return None
  5565. # all keywords mapped to positional arguments
  5566. # if we are missing arguments, SimpleCallNode will figure it out
  5567. node = SimpleCallNode(self.pos, function=function, args=args)
  5568. for temp in temps[::-1]:
  5569. node = EvalWithTempExprNode(temp, node)
  5570. return node
  5571. def generate_result_code(self, code):
  5572. if self.type.is_error: return
  5573. if self.keyword_args:
  5574. kwargs = self.keyword_args.py_result()
  5575. else:
  5576. kwargs = 'NULL'
  5577. code.globalstate.use_utility_code(UtilityCode.load_cached(
  5578. "PyObjectCall", "ObjectHandling.c"))
  5579. code.putln(
  5580. "%s = __Pyx_PyObject_Call(%s, %s, %s); %s" % (
  5581. self.result(),
  5582. self.function.py_result(),
  5583. self.positional_args.py_result(),
  5584. kwargs,
  5585. code.error_goto_if_null(self.result(), self.pos)))
  5586. code.put_gotref(self.py_result())
  5587. class AsTupleNode(ExprNode):
  5588. # Convert argument to tuple. Used for normalising
  5589. # the * argument of a function call.
  5590. #
  5591. # arg ExprNode
  5592. subexprs = ['arg']
  5593. is_temp = 1
  5594. def calculate_constant_result(self):
  5595. self.constant_result = tuple(self.arg.constant_result)
  5596. def compile_time_value(self, denv):
  5597. arg = self.arg.compile_time_value(denv)
  5598. try:
  5599. return tuple(arg)
  5600. except Exception as e:
  5601. self.compile_time_value_error(e)
  5602. def analyse_types(self, env):
  5603. self.arg = self.arg.analyse_types(env).coerce_to_pyobject(env)
  5604. if self.arg.type is tuple_type:
  5605. return self.arg.as_none_safe_node("'NoneType' object is not iterable")
  5606. self.type = tuple_type
  5607. return self
  5608. def may_be_none(self):
  5609. return False
  5610. nogil_check = Node.gil_error
  5611. gil_message = "Constructing Python tuple"
  5612. def generate_result_code(self, code):
  5613. cfunc = "__Pyx_PySequence_Tuple" if self.arg.type in (py_object_type, tuple_type) else "PySequence_Tuple"
  5614. code.putln(
  5615. "%s = %s(%s); %s" % (
  5616. self.result(),
  5617. cfunc, self.arg.py_result(),
  5618. code.error_goto_if_null(self.result(), self.pos)))
  5619. code.put_gotref(self.py_result())
  5620. class MergedDictNode(ExprNode):
  5621. # Helper class for keyword arguments and other merged dicts.
  5622. #
  5623. # keyword_args [DictNode or other ExprNode]
  5624. subexprs = ['keyword_args']
  5625. is_temp = 1
  5626. type = dict_type
  5627. reject_duplicates = True
  5628. def calculate_constant_result(self):
  5629. result = {}
  5630. reject_duplicates = self.reject_duplicates
  5631. for item in self.keyword_args:
  5632. if item.is_dict_literal:
  5633. # process items in order
  5634. items = ((key.constant_result, value.constant_result)
  5635. for key, value in item.key_value_pairs)
  5636. else:
  5637. items = item.constant_result.iteritems()
  5638. for key, value in items:
  5639. if reject_duplicates and key in result:
  5640. raise ValueError("duplicate keyword argument found: %s" % key)
  5641. result[key] = value
  5642. self.constant_result = result
  5643. def compile_time_value(self, denv):
  5644. result = {}
  5645. reject_duplicates = self.reject_duplicates
  5646. for item in self.keyword_args:
  5647. if item.is_dict_literal:
  5648. # process items in order
  5649. items = [(key.compile_time_value(denv), value.compile_time_value(denv))
  5650. for key, value in item.key_value_pairs]
  5651. else:
  5652. items = item.compile_time_value(denv).iteritems()
  5653. try:
  5654. for key, value in items:
  5655. if reject_duplicates and key in result:
  5656. raise ValueError("duplicate keyword argument found: %s" % key)
  5657. result[key] = value
  5658. except Exception as e:
  5659. self.compile_time_value_error(e)
  5660. return result
  5661. def type_dependencies(self, env):
  5662. return ()
  5663. def infer_type(self, env):
  5664. return dict_type
  5665. def analyse_types(self, env):
  5666. args = [
  5667. arg.analyse_types(env).coerce_to_pyobject(env).as_none_safe_node(
  5668. # FIXME: CPython's error message starts with the runtime function name
  5669. 'argument after ** must be a mapping, not NoneType')
  5670. for arg in self.keyword_args
  5671. ]
  5672. if len(args) == 1 and args[0].type is dict_type:
  5673. # strip this intermediate node and use the bare dict
  5674. arg = args[0]
  5675. if arg.is_name and arg.entry.is_arg and len(arg.entry.cf_assignments) == 1:
  5676. # passing **kwargs through to function call => allow NULL
  5677. arg.allow_null = True
  5678. return arg
  5679. self.keyword_args = args
  5680. return self
  5681. def may_be_none(self):
  5682. return False
  5683. gil_message = "Constructing Python dict"
  5684. def generate_evaluation_code(self, code):
  5685. code.mark_pos(self.pos)
  5686. self.allocate_temp_result(code)
  5687. args = iter(self.keyword_args)
  5688. item = next(args)
  5689. item.generate_evaluation_code(code)
  5690. if item.type is not dict_type:
  5691. # CPython supports calling functions with non-dicts, so do we
  5692. code.putln('if (likely(PyDict_CheckExact(%s))) {' %
  5693. item.py_result())
  5694. if item.is_dict_literal:
  5695. item.make_owned_reference(code)
  5696. code.putln("%s = %s;" % (self.result(), item.py_result()))
  5697. item.generate_post_assignment_code(code)
  5698. else:
  5699. code.putln("%s = PyDict_Copy(%s); %s" % (
  5700. self.result(),
  5701. item.py_result(),
  5702. code.error_goto_if_null(self.result(), item.pos)))
  5703. code.put_gotref(self.result())
  5704. item.generate_disposal_code(code)
  5705. if item.type is not dict_type:
  5706. code.putln('} else {')
  5707. code.putln("%s = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, %s, NULL); %s" % (
  5708. self.result(),
  5709. item.py_result(),
  5710. code.error_goto_if_null(self.result(), self.pos)))
  5711. code.put_gotref(self.py_result())
  5712. item.generate_disposal_code(code)
  5713. code.putln('}')
  5714. item.free_temps(code)
  5715. helpers = set()
  5716. for item in args:
  5717. if item.is_dict_literal:
  5718. # inline update instead of creating an intermediate dict
  5719. for arg in item.key_value_pairs:
  5720. arg.generate_evaluation_code(code)
  5721. if self.reject_duplicates:
  5722. code.putln("if (unlikely(PyDict_Contains(%s, %s))) {" % (
  5723. self.result(),
  5724. arg.key.py_result()))
  5725. helpers.add("RaiseDoubleKeywords")
  5726. # FIXME: find out function name at runtime!
  5727. code.putln('__Pyx_RaiseDoubleKeywordsError("function", %s); %s' % (
  5728. arg.key.py_result(),
  5729. code.error_goto(self.pos)))
  5730. code.putln("}")
  5731. code.put_error_if_neg(arg.key.pos, "PyDict_SetItem(%s, %s, %s)" % (
  5732. self.result(),
  5733. arg.key.py_result(),
  5734. arg.value.py_result()))
  5735. arg.generate_disposal_code(code)
  5736. arg.free_temps(code)
  5737. else:
  5738. item.generate_evaluation_code(code)
  5739. if self.reject_duplicates:
  5740. # merge mapping into kwdict one by one as we need to check for duplicates
  5741. helpers.add("MergeKeywords")
  5742. code.put_error_if_neg(item.pos, "__Pyx_MergeKeywords(%s, %s)" % (
  5743. self.result(), item.py_result()))
  5744. else:
  5745. # simple case, just add all entries
  5746. helpers.add("RaiseMappingExpected")
  5747. code.putln("if (unlikely(PyDict_Update(%s, %s) < 0)) {" % (
  5748. self.result(), item.py_result()))
  5749. code.putln("if (PyErr_ExceptionMatches(PyExc_AttributeError)) "
  5750. "__Pyx_RaiseMappingExpectedError(%s);" % item.py_result())
  5751. code.putln(code.error_goto(item.pos))
  5752. code.putln("}")
  5753. item.generate_disposal_code(code)
  5754. item.free_temps(code)
  5755. for helper in sorted(helpers):
  5756. code.globalstate.use_utility_code(UtilityCode.load_cached(helper, "FunctionArguments.c"))
  5757. def annotate(self, code):
  5758. for item in self.keyword_args:
  5759. item.annotate(code)
  5760. class AttributeNode(ExprNode):
  5761. # obj.attribute
  5762. #
  5763. # obj ExprNode
  5764. # attribute string
  5765. # needs_none_check boolean Used if obj is an extension type.
  5766. # If set to True, it is known that the type is not None.
  5767. #
  5768. # Used internally:
  5769. #
  5770. # is_py_attr boolean Is a Python getattr operation
  5771. # member string C name of struct member
  5772. # is_called boolean Function call is being done on result
  5773. # entry Entry Symbol table entry of attribute
  5774. is_attribute = 1
  5775. subexprs = ['obj']
  5776. type = PyrexTypes.error_type
  5777. entry = None
  5778. is_called = 0
  5779. needs_none_check = True
  5780. is_memslice_transpose = False
  5781. is_special_lookup = False
  5782. is_py_attr = 0
  5783. def as_cython_attribute(self):
  5784. if (isinstance(self.obj, NameNode) and
  5785. self.obj.is_cython_module and not
  5786. self.attribute == u"parallel"):
  5787. return self.attribute
  5788. cy = self.obj.as_cython_attribute()
  5789. if cy:
  5790. return "%s.%s" % (cy, self.attribute)
  5791. return None
  5792. def coerce_to(self, dst_type, env):
  5793. # If coercing to a generic pyobject and this is a cpdef function
  5794. # we can create the corresponding attribute
  5795. if dst_type is py_object_type:
  5796. entry = self.entry
  5797. if entry and entry.is_cfunction and entry.as_variable:
  5798. # must be a cpdef function
  5799. self.is_temp = 1
  5800. self.entry = entry.as_variable
  5801. self.analyse_as_python_attribute(env)
  5802. return self
  5803. return ExprNode.coerce_to(self, dst_type, env)
  5804. def calculate_constant_result(self):
  5805. attr = self.attribute
  5806. if attr.startswith("__") and attr.endswith("__"):
  5807. return
  5808. self.constant_result = getattr(self.obj.constant_result, attr)
  5809. def compile_time_value(self, denv):
  5810. attr = self.attribute
  5811. if attr.startswith("__") and attr.endswith("__"):
  5812. error(self.pos,
  5813. "Invalid attribute name '%s' in compile-time expression" % attr)
  5814. return None
  5815. obj = self.obj.compile_time_value(denv)
  5816. try:
  5817. return getattr(obj, attr)
  5818. except Exception as e:
  5819. self.compile_time_value_error(e)
  5820. def type_dependencies(self, env):
  5821. return self.obj.type_dependencies(env)
  5822. def infer_type(self, env):
  5823. # FIXME: this is way too redundant with analyse_types()
  5824. node = self.analyse_as_cimported_attribute_node(env, target=False)
  5825. if node is not None:
  5826. return node.entry.type
  5827. node = self.analyse_as_type_attribute(env)
  5828. if node is not None:
  5829. return node.entry.type
  5830. obj_type = self.obj.infer_type(env)
  5831. self.analyse_attribute(env, obj_type=obj_type)
  5832. if obj_type.is_builtin_type and self.type.is_cfunction:
  5833. # special case: C-API replacements for C methods of
  5834. # builtin types cannot be inferred as C functions as
  5835. # that would prevent their use as bound methods
  5836. return py_object_type
  5837. elif self.entry and self.entry.is_cmethod:
  5838. # special case: bound methods should not be inferred
  5839. # as their unbound method types
  5840. return py_object_type
  5841. return self.type
  5842. def analyse_target_declaration(self, env):
  5843. pass
  5844. def analyse_target_types(self, env):
  5845. node = self.analyse_types(env, target = 1)
  5846. if node.type.is_const:
  5847. error(self.pos, "Assignment to const attribute '%s'" % self.attribute)
  5848. if not node.is_lvalue():
  5849. error(self.pos, "Assignment to non-lvalue of type '%s'" % self.type)
  5850. return node
  5851. def analyse_types(self, env, target = 0):
  5852. self.initialized_check = env.directives['initializedcheck']
  5853. node = self.analyse_as_cimported_attribute_node(env, target)
  5854. if node is None and not target:
  5855. node = self.analyse_as_type_attribute(env)
  5856. if node is None:
  5857. node = self.analyse_as_ordinary_attribute_node(env, target)
  5858. assert node is not None
  5859. if node.entry:
  5860. node.entry.used = True
  5861. if node.is_attribute:
  5862. node.wrap_obj_in_nonecheck(env)
  5863. return node
  5864. def analyse_as_cimported_attribute_node(self, env, target):
  5865. # Try to interpret this as a reference to an imported
  5866. # C const, type, var or function. If successful, mutates
  5867. # this node into a NameNode and returns 1, otherwise
  5868. # returns 0.
  5869. module_scope = self.obj.analyse_as_module(env)
  5870. if module_scope:
  5871. entry = module_scope.lookup_here(self.attribute)
  5872. if entry and (
  5873. entry.is_cglobal or entry.is_cfunction
  5874. or entry.is_type or entry.is_const):
  5875. return self.as_name_node(env, entry, target)
  5876. if self.is_cimported_module_without_shadow(env):
  5877. error(self.pos, "cimported module has no attribute '%s'" % self.attribute)
  5878. return self
  5879. return None
  5880. def analyse_as_type_attribute(self, env):
  5881. # Try to interpret this as a reference to an unbound
  5882. # C method of an extension type or builtin type. If successful,
  5883. # creates a corresponding NameNode and returns it, otherwise
  5884. # returns None.
  5885. if self.obj.is_string_literal:
  5886. return
  5887. type = self.obj.analyse_as_type(env)
  5888. if type:
  5889. if type.is_extension_type or type.is_builtin_type or type.is_cpp_class:
  5890. entry = type.scope.lookup_here(self.attribute)
  5891. if entry and (entry.is_cmethod or type.is_cpp_class and entry.type.is_cfunction):
  5892. if type.is_builtin_type:
  5893. if not self.is_called:
  5894. # must handle this as Python object
  5895. return None
  5896. ubcm_entry = entry
  5897. else:
  5898. # Create a temporary entry describing the C method
  5899. # as an ordinary function.
  5900. if entry.func_cname and not hasattr(entry.type, 'op_arg_struct'):
  5901. cname = entry.func_cname
  5902. if entry.type.is_static_method or (
  5903. env.parent_scope and env.parent_scope.is_cpp_class_scope):
  5904. ctype = entry.type
  5905. elif type.is_cpp_class:
  5906. error(self.pos, "%s not a static member of %s" % (entry.name, type))
  5907. ctype = PyrexTypes.error_type
  5908. else:
  5909. # Fix self type.
  5910. ctype = copy.copy(entry.type)
  5911. ctype.args = ctype.args[:]
  5912. ctype.args[0] = PyrexTypes.CFuncTypeArg('self', type, 'self', None)
  5913. else:
  5914. cname = "%s->%s" % (type.vtabptr_cname, entry.cname)
  5915. ctype = entry.type
  5916. ubcm_entry = Symtab.Entry(entry.name, cname, ctype)
  5917. ubcm_entry.is_cfunction = 1
  5918. ubcm_entry.func_cname = entry.func_cname
  5919. ubcm_entry.is_unbound_cmethod = 1
  5920. ubcm_entry.scope = entry.scope
  5921. return self.as_name_node(env, ubcm_entry, target=False)
  5922. elif type.is_enum:
  5923. if self.attribute in type.values:
  5924. for entry in type.entry.enum_values:
  5925. if entry.name == self.attribute:
  5926. return self.as_name_node(env, entry, target=False)
  5927. else:
  5928. error(self.pos, "%s not a known value of %s" % (self.attribute, type))
  5929. else:
  5930. error(self.pos, "%s not a known value of %s" % (self.attribute, type))
  5931. return None
  5932. def analyse_as_type(self, env):
  5933. module_scope = self.obj.analyse_as_module(env)
  5934. if module_scope:
  5935. return module_scope.lookup_type(self.attribute)
  5936. if not self.obj.is_string_literal:
  5937. base_type = self.obj.analyse_as_type(env)
  5938. if base_type and hasattr(base_type, 'scope') and base_type.scope is not None:
  5939. return base_type.scope.lookup_type(self.attribute)
  5940. return None
  5941. def analyse_as_extension_type(self, env):
  5942. # Try to interpret this as a reference to an extension type
  5943. # in a cimported module. Returns the extension type, or None.
  5944. module_scope = self.obj.analyse_as_module(env)
  5945. if module_scope:
  5946. entry = module_scope.lookup_here(self.attribute)
  5947. if entry and entry.is_type:
  5948. if entry.type.is_extension_type or entry.type.is_builtin_type:
  5949. return entry.type
  5950. return None
  5951. def analyse_as_module(self, env):
  5952. # Try to interpret this as a reference to a cimported module
  5953. # in another cimported module. Returns the module scope, or None.
  5954. module_scope = self.obj.analyse_as_module(env)
  5955. if module_scope:
  5956. entry = module_scope.lookup_here(self.attribute)
  5957. if entry and entry.as_module:
  5958. return entry.as_module
  5959. return None
  5960. def as_name_node(self, env, entry, target):
  5961. # Create a corresponding NameNode from this node and complete the
  5962. # analyse_types phase.
  5963. node = NameNode.from_node(self, name=self.attribute, entry=entry)
  5964. if target:
  5965. node = node.analyse_target_types(env)
  5966. else:
  5967. node = node.analyse_rvalue_entry(env)
  5968. node.entry.used = 1
  5969. return node
  5970. def analyse_as_ordinary_attribute_node(self, env, target):
  5971. self.obj = self.obj.analyse_types(env)
  5972. self.analyse_attribute(env)
  5973. if self.entry and self.entry.is_cmethod and not self.is_called:
  5974. # error(self.pos, "C method can only be called")
  5975. pass
  5976. ## Reference to C array turns into pointer to first element.
  5977. #while self.type.is_array:
  5978. # self.type = self.type.element_ptr_type()
  5979. if self.is_py_attr:
  5980. if not target:
  5981. self.is_temp = 1
  5982. self.result_ctype = py_object_type
  5983. elif target and self.obj.type.is_builtin_type:
  5984. error(self.pos, "Assignment to an immutable object field")
  5985. #elif self.type.is_memoryviewslice and not target:
  5986. # self.is_temp = True
  5987. return self
  5988. def analyse_attribute(self, env, obj_type = None):
  5989. # Look up attribute and set self.type and self.member.
  5990. immutable_obj = obj_type is not None # used during type inference
  5991. self.is_py_attr = 0
  5992. self.member = self.attribute
  5993. if obj_type is None:
  5994. if self.obj.type.is_string or self.obj.type.is_pyunicode_ptr:
  5995. self.obj = self.obj.coerce_to_pyobject(env)
  5996. obj_type = self.obj.type
  5997. else:
  5998. if obj_type.is_string or obj_type.is_pyunicode_ptr:
  5999. obj_type = py_object_type
  6000. if obj_type.is_ptr or obj_type.is_array:
  6001. obj_type = obj_type.base_type
  6002. self.op = "->"
  6003. elif obj_type.is_extension_type or obj_type.is_builtin_type:
  6004. self.op = "->"
  6005. elif obj_type.is_reference and obj_type.is_fake_reference:
  6006. self.op = "->"
  6007. else:
  6008. self.op = "."
  6009. if obj_type.has_attributes:
  6010. if obj_type.attributes_known():
  6011. entry = obj_type.scope.lookup_here(self.attribute)
  6012. if obj_type.is_memoryviewslice and not entry:
  6013. if self.attribute == 'T':
  6014. self.is_memslice_transpose = True
  6015. self.is_temp = True
  6016. self.use_managed_ref = True
  6017. self.type = self.obj.type.transpose(self.pos)
  6018. return
  6019. else:
  6020. obj_type.declare_attribute(self.attribute, env, self.pos)
  6021. entry = obj_type.scope.lookup_here(self.attribute)
  6022. if entry and entry.is_member:
  6023. entry = None
  6024. else:
  6025. error(self.pos,
  6026. "Cannot select attribute of incomplete type '%s'"
  6027. % obj_type)
  6028. self.type = PyrexTypes.error_type
  6029. return
  6030. self.entry = entry
  6031. if entry:
  6032. if obj_type.is_extension_type and entry.name == "__weakref__":
  6033. error(self.pos, "Illegal use of special attribute __weakref__")
  6034. # def methods need the normal attribute lookup
  6035. # because they do not have struct entries
  6036. # fused function go through assignment synthesis
  6037. # (foo = pycfunction(foo_func_obj)) and need to go through
  6038. # regular Python lookup as well
  6039. if (entry.is_variable and not entry.fused_cfunction) or entry.is_cmethod:
  6040. self.type = entry.type
  6041. self.member = entry.cname
  6042. return
  6043. else:
  6044. # If it's not a variable or C method, it must be a Python
  6045. # method of an extension type, so we treat it like a Python
  6046. # attribute.
  6047. pass
  6048. # If we get here, the base object is not a struct/union/extension
  6049. # type, or it is an extension type and the attribute is either not
  6050. # declared or is declared as a Python method. Treat it as a Python
  6051. # attribute reference.
  6052. self.analyse_as_python_attribute(env, obj_type, immutable_obj)
  6053. def analyse_as_python_attribute(self, env, obj_type=None, immutable_obj=False):
  6054. if obj_type is None:
  6055. obj_type = self.obj.type
  6056. # mangle private '__*' Python attributes used inside of a class
  6057. self.attribute = env.mangle_class_private_name(self.attribute)
  6058. self.member = self.attribute
  6059. self.type = py_object_type
  6060. self.is_py_attr = 1
  6061. if not obj_type.is_pyobject and not obj_type.is_error:
  6062. # Expose python methods for immutable objects.
  6063. if (obj_type.is_string or obj_type.is_cpp_string
  6064. or obj_type.is_buffer or obj_type.is_memoryviewslice
  6065. or obj_type.is_numeric
  6066. or (obj_type.is_ctuple and obj_type.can_coerce_to_pyobject(env))
  6067. or (obj_type.is_struct and obj_type.can_coerce_to_pyobject(env))):
  6068. if not immutable_obj:
  6069. self.obj = self.obj.coerce_to_pyobject(env)
  6070. elif (obj_type.is_cfunction and (self.obj.is_name or self.obj.is_attribute)
  6071. and self.obj.entry.as_variable
  6072. and self.obj.entry.as_variable.type.is_pyobject):
  6073. # might be an optimised builtin function => unpack it
  6074. if not immutable_obj:
  6075. self.obj = self.obj.coerce_to_pyobject(env)
  6076. else:
  6077. error(self.pos,
  6078. "Object of type '%s' has no attribute '%s'" %
  6079. (obj_type, self.attribute))
  6080. def wrap_obj_in_nonecheck(self, env):
  6081. if not env.directives['nonecheck']:
  6082. return
  6083. msg = None
  6084. format_args = ()
  6085. if (self.obj.type.is_extension_type and self.needs_none_check and not
  6086. self.is_py_attr):
  6087. msg = "'NoneType' object has no attribute '%{0}s'".format('.30' if len(self.attribute) <= 30 else '')
  6088. format_args = (self.attribute,)
  6089. elif self.obj.type.is_memoryviewslice:
  6090. if self.is_memslice_transpose:
  6091. msg = "Cannot transpose None memoryview slice"
  6092. else:
  6093. entry = self.obj.type.scope.lookup_here(self.attribute)
  6094. if entry:
  6095. # copy/is_c_contig/shape/strides etc
  6096. msg = "Cannot access '%s' attribute of None memoryview slice"
  6097. format_args = (entry.name,)
  6098. if msg:
  6099. self.obj = self.obj.as_none_safe_node(msg, 'PyExc_AttributeError',
  6100. format_args=format_args)
  6101. def nogil_check(self, env):
  6102. if self.is_py_attr:
  6103. self.gil_error()
  6104. gil_message = "Accessing Python attribute"
  6105. def is_cimported_module_without_shadow(self, env):
  6106. return self.obj.is_cimported_module_without_shadow(env)
  6107. def is_simple(self):
  6108. if self.obj:
  6109. return self.result_in_temp() or self.obj.is_simple()
  6110. else:
  6111. return NameNode.is_simple(self)
  6112. def is_lvalue(self):
  6113. if self.obj:
  6114. return True
  6115. else:
  6116. return NameNode.is_lvalue(self)
  6117. def is_ephemeral(self):
  6118. if self.obj:
  6119. return self.obj.is_ephemeral()
  6120. else:
  6121. return NameNode.is_ephemeral(self)
  6122. def calculate_result_code(self):
  6123. #print "AttributeNode.calculate_result_code:", self.member ###
  6124. #print "...obj node =", self.obj, "code", self.obj.result() ###
  6125. #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
  6126. obj = self.obj
  6127. obj_code = obj.result_as(obj.type)
  6128. #print "...obj_code =", obj_code ###
  6129. if self.entry and self.entry.is_cmethod:
  6130. if obj.type.is_extension_type and not self.entry.is_builtin_cmethod:
  6131. if self.entry.final_func_cname:
  6132. return self.entry.final_func_cname
  6133. if self.type.from_fused:
  6134. # If the attribute was specialized through indexing, make
  6135. # sure to get the right fused name, as our entry was
  6136. # replaced by our parent index node
  6137. # (AnalyseExpressionsTransform)
  6138. self.member = self.entry.cname
  6139. return "((struct %s *)%s%s%s)->%s" % (
  6140. obj.type.vtabstruct_cname, obj_code, self.op,
  6141. obj.type.vtabslot_cname, self.member)
  6142. elif self.result_is_used:
  6143. return self.member
  6144. # Generating no code at all for unused access to optimised builtin
  6145. # methods fixes the problem that some optimisations only exist as
  6146. # macros, i.e. there is no function pointer to them, so we would
  6147. # generate invalid C code here.
  6148. return
  6149. elif obj.type.is_complex:
  6150. return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
  6151. else:
  6152. if obj.type.is_builtin_type and self.entry and self.entry.is_variable:
  6153. # accessing a field of a builtin type, need to cast better than result_as() does
  6154. obj_code = obj.type.cast_code(obj.result(), to_object_struct = True)
  6155. return "%s%s%s" % (obj_code, self.op, self.member)
  6156. def generate_result_code(self, code):
  6157. if self.is_py_attr:
  6158. if self.is_special_lookup:
  6159. code.globalstate.use_utility_code(
  6160. UtilityCode.load_cached("PyObjectLookupSpecial", "ObjectHandling.c"))
  6161. lookup_func_name = '__Pyx_PyObject_LookupSpecial'
  6162. else:
  6163. code.globalstate.use_utility_code(
  6164. UtilityCode.load_cached("PyObjectGetAttrStr", "ObjectHandling.c"))
  6165. lookup_func_name = '__Pyx_PyObject_GetAttrStr'
  6166. code.putln(
  6167. '%s = %s(%s, %s); %s' % (
  6168. self.result(),
  6169. lookup_func_name,
  6170. self.obj.py_result(),
  6171. code.intern_identifier(self.attribute),
  6172. code.error_goto_if_null(self.result(), self.pos)))
  6173. code.put_gotref(self.py_result())
  6174. elif self.type.is_memoryviewslice:
  6175. if self.is_memslice_transpose:
  6176. # transpose the slice
  6177. for access, packing in self.type.axes:
  6178. if access == 'ptr':
  6179. error(self.pos, "Transposing not supported for slices "
  6180. "with indirect dimensions")
  6181. return
  6182. code.putln("%s = %s;" % (self.result(), self.obj.result()))
  6183. code.put_incref_memoryviewslice(self.result(), have_gil=True)
  6184. T = "__pyx_memslice_transpose(&%s) == 0"
  6185. code.putln(code.error_goto_if(T % self.result(), self.pos))
  6186. elif self.initialized_check:
  6187. code.putln(
  6188. 'if (unlikely(!%s.memview)) {'
  6189. 'PyErr_SetString(PyExc_AttributeError,'
  6190. '"Memoryview is not initialized");'
  6191. '%s'
  6192. '}' % (self.result(), code.error_goto(self.pos)))
  6193. else:
  6194. # result_code contains what is needed, but we may need to insert
  6195. # a check and raise an exception
  6196. if self.obj.type and self.obj.type.is_extension_type:
  6197. pass
  6198. elif self.entry and self.entry.is_cmethod:
  6199. # C method implemented as function call with utility code
  6200. code.globalstate.use_entry_utility_code(self.entry)
  6201. def generate_disposal_code(self, code):
  6202. if self.is_temp and self.type.is_memoryviewslice and self.is_memslice_transpose:
  6203. # mirror condition for putting the memview incref here:
  6204. code.put_xdecref_memoryviewslice(
  6205. self.result(), have_gil=True)
  6206. code.putln("%s.memview = NULL;" % self.result())
  6207. code.putln("%s.data = NULL;" % self.result())
  6208. else:
  6209. ExprNode.generate_disposal_code(self, code)
  6210. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  6211. exception_check=None, exception_value=None):
  6212. self.obj.generate_evaluation_code(code)
  6213. if self.is_py_attr:
  6214. code.globalstate.use_utility_code(
  6215. UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
  6216. code.put_error_if_neg(self.pos,
  6217. '__Pyx_PyObject_SetAttrStr(%s, %s, %s)' % (
  6218. self.obj.py_result(),
  6219. code.intern_identifier(self.attribute),
  6220. rhs.py_result()))
  6221. rhs.generate_disposal_code(code)
  6222. rhs.free_temps(code)
  6223. elif self.obj.type.is_complex:
  6224. code.putln("__Pyx_SET_C%s(%s, %s);" % (
  6225. self.member.upper(),
  6226. self.obj.result_as(self.obj.type),
  6227. rhs.result_as(self.ctype())))
  6228. else:
  6229. select_code = self.result()
  6230. if self.type.is_pyobject and self.use_managed_ref:
  6231. rhs.make_owned_reference(code)
  6232. code.put_giveref(rhs.py_result())
  6233. code.put_gotref(select_code)
  6234. code.put_decref(select_code, self.ctype())
  6235. elif self.type.is_memoryviewslice:
  6236. from . import MemoryView
  6237. MemoryView.put_assign_to_memviewslice(
  6238. select_code, rhs, rhs.result(), self.type, code)
  6239. if not self.type.is_memoryviewslice:
  6240. code.putln(
  6241. "%s = %s;" % (
  6242. select_code,
  6243. rhs.result_as(self.ctype())))
  6244. #rhs.result()))
  6245. rhs.generate_post_assignment_code(code)
  6246. rhs.free_temps(code)
  6247. self.obj.generate_disposal_code(code)
  6248. self.obj.free_temps(code)
  6249. def generate_deletion_code(self, code, ignore_nonexisting=False):
  6250. self.obj.generate_evaluation_code(code)
  6251. if self.is_py_attr or (self.entry.scope.is_property_scope
  6252. and u'__del__' in self.entry.scope.entries):
  6253. code.globalstate.use_utility_code(
  6254. UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
  6255. code.put_error_if_neg(self.pos,
  6256. '__Pyx_PyObject_DelAttrStr(%s, %s)' % (
  6257. self.obj.py_result(),
  6258. code.intern_identifier(self.attribute)))
  6259. else:
  6260. error(self.pos, "Cannot delete C attribute of extension type")
  6261. self.obj.generate_disposal_code(code)
  6262. self.obj.free_temps(code)
  6263. def annotate(self, code):
  6264. if self.is_py_attr:
  6265. style, text = 'py_attr', 'python attribute (%s)'
  6266. else:
  6267. style, text = 'c_attr', 'c attribute (%s)'
  6268. code.annotate(self.pos, AnnotationItem(style, text % self.type, size=len(self.attribute)))
  6269. #-------------------------------------------------------------------
  6270. #
  6271. # Constructor nodes
  6272. #
  6273. #-------------------------------------------------------------------
  6274. class StarredUnpackingNode(ExprNode):
  6275. # A starred expression like "*a"
  6276. #
  6277. # This is only allowed in sequence assignment or construction such as
  6278. #
  6279. # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
  6280. #
  6281. # and will be special cased during type analysis (or generate an error
  6282. # if it's found at unexpected places).
  6283. #
  6284. # target ExprNode
  6285. subexprs = ['target']
  6286. is_starred = 1
  6287. type = py_object_type
  6288. is_temp = 1
  6289. starred_expr_allowed_here = False
  6290. def __init__(self, pos, target):
  6291. ExprNode.__init__(self, pos, target=target)
  6292. def analyse_declarations(self, env):
  6293. if not self.starred_expr_allowed_here:
  6294. error(self.pos, "starred expression is not allowed here")
  6295. self.target.analyse_declarations(env)
  6296. def infer_type(self, env):
  6297. return self.target.infer_type(env)
  6298. def analyse_types(self, env):
  6299. if not self.starred_expr_allowed_here:
  6300. error(self.pos, "starred expression is not allowed here")
  6301. self.target = self.target.analyse_types(env)
  6302. self.type = self.target.type
  6303. return self
  6304. def analyse_target_declaration(self, env):
  6305. self.target.analyse_target_declaration(env)
  6306. def analyse_target_types(self, env):
  6307. self.target = self.target.analyse_target_types(env)
  6308. self.type = self.target.type
  6309. return self
  6310. def calculate_result_code(self):
  6311. return ""
  6312. def generate_result_code(self, code):
  6313. pass
  6314. class SequenceNode(ExprNode):
  6315. # Base class for list and tuple constructor nodes.
  6316. # Contains common code for performing sequence unpacking.
  6317. #
  6318. # args [ExprNode]
  6319. # unpacked_items [ExprNode] or None
  6320. # coerced_unpacked_items [ExprNode] or None
  6321. # mult_factor ExprNode the integer number of content repetitions ([1,2]*3)
  6322. subexprs = ['args', 'mult_factor']
  6323. is_sequence_constructor = 1
  6324. unpacked_items = None
  6325. mult_factor = None
  6326. slow = False # trade speed for code size (e.g. use PyTuple_Pack())
  6327. def compile_time_value_list(self, denv):
  6328. return [arg.compile_time_value(denv) for arg in self.args]
  6329. def replace_starred_target_node(self):
  6330. # replace a starred node in the targets by the contained expression
  6331. self.starred_assignment = False
  6332. args = []
  6333. for arg in self.args:
  6334. if arg.is_starred:
  6335. if self.starred_assignment:
  6336. error(arg.pos, "more than 1 starred expression in assignment")
  6337. self.starred_assignment = True
  6338. arg = arg.target
  6339. arg.is_starred = True
  6340. args.append(arg)
  6341. self.args = args
  6342. def analyse_target_declaration(self, env):
  6343. self.replace_starred_target_node()
  6344. for arg in self.args:
  6345. arg.analyse_target_declaration(env)
  6346. def analyse_types(self, env, skip_children=False):
  6347. for i, arg in enumerate(self.args):
  6348. if not skip_children:
  6349. arg = arg.analyse_types(env)
  6350. self.args[i] = arg.coerce_to_pyobject(env)
  6351. if self.mult_factor:
  6352. self.mult_factor = self.mult_factor.analyse_types(env)
  6353. if not self.mult_factor.type.is_int:
  6354. self.mult_factor = self.mult_factor.coerce_to_pyobject(env)
  6355. self.is_temp = 1
  6356. # not setting self.type here, subtypes do this
  6357. return self
  6358. def coerce_to_ctuple(self, dst_type, env):
  6359. if self.type == dst_type:
  6360. return self
  6361. assert not self.mult_factor
  6362. if len(self.args) != dst_type.size:
  6363. error(self.pos, "trying to coerce sequence to ctuple of wrong length, expected %d, got %d" % (
  6364. dst_type.size, len(self.args)))
  6365. coerced_args = [arg.coerce_to(type, env) for arg, type in zip(self.args, dst_type.components)]
  6366. return TupleNode(self.pos, args=coerced_args, type=dst_type, is_temp=True)
  6367. def _create_merge_node_if_necessary(self, env):
  6368. self._flatten_starred_args()
  6369. if not any(arg.is_starred for arg in self.args):
  6370. return self
  6371. # convert into MergedSequenceNode by building partial sequences
  6372. args = []
  6373. values = []
  6374. for arg in self.args:
  6375. if arg.is_starred:
  6376. if values:
  6377. args.append(TupleNode(values[0].pos, args=values).analyse_types(env, skip_children=True))
  6378. values = []
  6379. args.append(arg.target)
  6380. else:
  6381. values.append(arg)
  6382. if values:
  6383. args.append(TupleNode(values[0].pos, args=values).analyse_types(env, skip_children=True))
  6384. node = MergedSequenceNode(self.pos, args, self.type)
  6385. if self.mult_factor:
  6386. node = binop_node(
  6387. self.pos, '*', node, self.mult_factor.coerce_to_pyobject(env),
  6388. inplace=True, type=self.type, is_temp=True)
  6389. return node
  6390. def _flatten_starred_args(self):
  6391. args = []
  6392. for arg in self.args:
  6393. if arg.is_starred and arg.target.is_sequence_constructor and not arg.target.mult_factor:
  6394. args.extend(arg.target.args)
  6395. else:
  6396. args.append(arg)
  6397. self.args[:] = args
  6398. def may_be_none(self):
  6399. return False
  6400. def analyse_target_types(self, env):
  6401. if self.mult_factor:
  6402. error(self.pos, "can't assign to multiplied sequence")
  6403. self.unpacked_items = []
  6404. self.coerced_unpacked_items = []
  6405. self.any_coerced_items = False
  6406. for i, arg in enumerate(self.args):
  6407. arg = self.args[i] = arg.analyse_target_types(env)
  6408. if arg.is_starred:
  6409. if not arg.type.assignable_from(list_type):
  6410. error(arg.pos,
  6411. "starred target must have Python object (list) type")
  6412. if arg.type is py_object_type:
  6413. arg.type = list_type
  6414. unpacked_item = PyTempNode(self.pos, env)
  6415. coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
  6416. if unpacked_item is not coerced_unpacked_item:
  6417. self.any_coerced_items = True
  6418. self.unpacked_items.append(unpacked_item)
  6419. self.coerced_unpacked_items.append(coerced_unpacked_item)
  6420. self.type = py_object_type
  6421. return self
  6422. def generate_result_code(self, code):
  6423. self.generate_operation_code(code)
  6424. def generate_sequence_packing_code(self, code, target=None, plain=False):
  6425. if target is None:
  6426. target = self.result()
  6427. size_factor = c_mult = ''
  6428. mult_factor = None
  6429. if self.mult_factor and not plain:
  6430. mult_factor = self.mult_factor
  6431. if mult_factor.type.is_int:
  6432. c_mult = mult_factor.result()
  6433. if (isinstance(mult_factor.constant_result, _py_int_types) and
  6434. mult_factor.constant_result > 0):
  6435. size_factor = ' * %s' % mult_factor.constant_result
  6436. elif mult_factor.type.signed:
  6437. size_factor = ' * ((%s<0) ? 0:%s)' % (c_mult, c_mult)
  6438. else:
  6439. size_factor = ' * (%s)' % (c_mult,)
  6440. if self.type is tuple_type and (self.is_literal or self.slow) and not c_mult:
  6441. # use PyTuple_Pack() to avoid generating huge amounts of one-time code
  6442. code.putln('%s = PyTuple_Pack(%d, %s); %s' % (
  6443. target,
  6444. len(self.args),
  6445. ', '.join(arg.py_result() for arg in self.args),
  6446. code.error_goto_if_null(target, self.pos)))
  6447. code.put_gotref(target)
  6448. elif self.type.is_ctuple:
  6449. for i, arg in enumerate(self.args):
  6450. code.putln("%s.f%s = %s;" % (
  6451. target, i, arg.result()))
  6452. else:
  6453. # build the tuple/list step by step, potentially multiplying it as we go
  6454. if self.type is list_type:
  6455. create_func, set_item_func = 'PyList_New', 'PyList_SET_ITEM'
  6456. elif self.type is tuple_type:
  6457. create_func, set_item_func = 'PyTuple_New', 'PyTuple_SET_ITEM'
  6458. else:
  6459. raise InternalError("sequence packing for unexpected type %s" % self.type)
  6460. arg_count = len(self.args)
  6461. code.putln("%s = %s(%s%s); %s" % (
  6462. target, create_func, arg_count, size_factor,
  6463. code.error_goto_if_null(target, self.pos)))
  6464. code.put_gotref(target)
  6465. if c_mult:
  6466. # FIXME: can't use a temp variable here as the code may
  6467. # end up in the constant building function. Temps
  6468. # currently don't work there.
  6469. #counter = code.funcstate.allocate_temp(mult_factor.type, manage_ref=False)
  6470. counter = Naming.quick_temp_cname
  6471. code.putln('{ Py_ssize_t %s;' % counter)
  6472. if arg_count == 1:
  6473. offset = counter
  6474. else:
  6475. offset = '%s * %s' % (counter, arg_count)
  6476. code.putln('for (%s=0; %s < %s; %s++) {' % (
  6477. counter, counter, c_mult, counter
  6478. ))
  6479. else:
  6480. offset = ''
  6481. for i in range(arg_count):
  6482. arg = self.args[i]
  6483. if c_mult or not arg.result_in_temp():
  6484. code.put_incref(arg.result(), arg.ctype())
  6485. code.put_giveref(arg.py_result())
  6486. code.putln("%s(%s, %s, %s);" % (
  6487. set_item_func,
  6488. target,
  6489. (offset and i) and ('%s + %s' % (offset, i)) or (offset or i),
  6490. arg.py_result()))
  6491. if c_mult:
  6492. code.putln('}')
  6493. #code.funcstate.release_temp(counter)
  6494. code.putln('}')
  6495. if mult_factor is not None and mult_factor.type.is_pyobject:
  6496. code.putln('{ PyObject* %s = PyNumber_InPlaceMultiply(%s, %s); %s' % (
  6497. Naming.quick_temp_cname, target, mult_factor.py_result(),
  6498. code.error_goto_if_null(Naming.quick_temp_cname, self.pos)
  6499. ))
  6500. code.put_gotref(Naming.quick_temp_cname)
  6501. code.put_decref(target, py_object_type)
  6502. code.putln('%s = %s;' % (target, Naming.quick_temp_cname))
  6503. code.putln('}')
  6504. def generate_subexpr_disposal_code(self, code):
  6505. if self.mult_factor and self.mult_factor.type.is_int:
  6506. super(SequenceNode, self).generate_subexpr_disposal_code(code)
  6507. elif self.type is tuple_type and (self.is_literal or self.slow):
  6508. super(SequenceNode, self).generate_subexpr_disposal_code(code)
  6509. else:
  6510. # We call generate_post_assignment_code here instead
  6511. # of generate_disposal_code, because values were stored
  6512. # in the tuple using a reference-stealing operation.
  6513. for arg in self.args:
  6514. arg.generate_post_assignment_code(code)
  6515. # Should NOT call free_temps -- this is invoked by the default
  6516. # generate_evaluation_code which will do that.
  6517. if self.mult_factor:
  6518. self.mult_factor.generate_disposal_code(code)
  6519. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  6520. exception_check=None, exception_value=None):
  6521. if self.starred_assignment:
  6522. self.generate_starred_assignment_code(rhs, code)
  6523. else:
  6524. self.generate_parallel_assignment_code(rhs, code)
  6525. for item in self.unpacked_items:
  6526. item.release(code)
  6527. rhs.free_temps(code)
  6528. _func_iternext_type = PyrexTypes.CPtrType(PyrexTypes.CFuncType(
  6529. PyrexTypes.py_object_type, [
  6530. PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None),
  6531. ]))
  6532. def generate_parallel_assignment_code(self, rhs, code):
  6533. # Need to work around the fact that generate_evaluation_code
  6534. # allocates the temps in a rather hacky way -- the assignment
  6535. # is evaluated twice, within each if-block.
  6536. for item in self.unpacked_items:
  6537. item.allocate(code)
  6538. special_unpack = (rhs.type is py_object_type
  6539. or rhs.type in (tuple_type, list_type)
  6540. or not rhs.type.is_builtin_type)
  6541. long_enough_for_a_loop = len(self.unpacked_items) > 3
  6542. if special_unpack:
  6543. self.generate_special_parallel_unpacking_code(
  6544. code, rhs, use_loop=long_enough_for_a_loop)
  6545. else:
  6546. code.putln("{")
  6547. self.generate_generic_parallel_unpacking_code(
  6548. code, rhs, self.unpacked_items, use_loop=long_enough_for_a_loop)
  6549. code.putln("}")
  6550. for value_node in self.coerced_unpacked_items:
  6551. value_node.generate_evaluation_code(code)
  6552. for i in range(len(self.args)):
  6553. self.args[i].generate_assignment_code(
  6554. self.coerced_unpacked_items[i], code)
  6555. def generate_special_parallel_unpacking_code(self, code, rhs, use_loop):
  6556. sequence_type_test = '1'
  6557. none_check = "likely(%s != Py_None)" % rhs.py_result()
  6558. if rhs.type is list_type:
  6559. sequence_types = ['List']
  6560. if rhs.may_be_none():
  6561. sequence_type_test = none_check
  6562. elif rhs.type is tuple_type:
  6563. sequence_types = ['Tuple']
  6564. if rhs.may_be_none():
  6565. sequence_type_test = none_check
  6566. else:
  6567. sequence_types = ['Tuple', 'List']
  6568. tuple_check = 'likely(PyTuple_CheckExact(%s))' % rhs.py_result()
  6569. list_check = 'PyList_CheckExact(%s)' % rhs.py_result()
  6570. sequence_type_test = "(%s) || (%s)" % (tuple_check, list_check)
  6571. code.putln("if (%s) {" % sequence_type_test)
  6572. code.putln("PyObject* sequence = %s;" % rhs.py_result())
  6573. # list/tuple => check size
  6574. code.putln("Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);")
  6575. code.putln("if (unlikely(size != %d)) {" % len(self.args))
  6576. code.globalstate.use_utility_code(raise_too_many_values_to_unpack)
  6577. code.putln("if (size > %d) __Pyx_RaiseTooManyValuesError(%d);" % (
  6578. len(self.args), len(self.args)))
  6579. code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
  6580. code.putln("else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);")
  6581. # < 0 => exception
  6582. code.putln(code.error_goto(self.pos))
  6583. code.putln("}")
  6584. code.putln("#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS")
  6585. # unpack items from list/tuple in unrolled loop (can't fail)
  6586. if len(sequence_types) == 2:
  6587. code.putln("if (likely(Py%s_CheckExact(sequence))) {" % sequence_types[0])
  6588. for i, item in enumerate(self.unpacked_items):
  6589. code.putln("%s = Py%s_GET_ITEM(sequence, %d); " % (
  6590. item.result(), sequence_types[0], i))
  6591. if len(sequence_types) == 2:
  6592. code.putln("} else {")
  6593. for i, item in enumerate(self.unpacked_items):
  6594. code.putln("%s = Py%s_GET_ITEM(sequence, %d); " % (
  6595. item.result(), sequence_types[1], i))
  6596. code.putln("}")
  6597. for item in self.unpacked_items:
  6598. code.put_incref(item.result(), item.ctype())
  6599. code.putln("#else")
  6600. # in non-CPython, use the PySequence protocol (which can fail)
  6601. if not use_loop:
  6602. for i, item in enumerate(self.unpacked_items):
  6603. code.putln("%s = PySequence_ITEM(sequence, %d); %s" % (
  6604. item.result(), i,
  6605. code.error_goto_if_null(item.result(), self.pos)))
  6606. code.put_gotref(item.result())
  6607. else:
  6608. code.putln("{")
  6609. code.putln("Py_ssize_t i;")
  6610. code.putln("PyObject** temps[%s] = {%s};" % (
  6611. len(self.unpacked_items),
  6612. ','.join(['&%s' % item.result() for item in self.unpacked_items])))
  6613. code.putln("for (i=0; i < %s; i++) {" % len(self.unpacked_items))
  6614. code.putln("PyObject* item = PySequence_ITEM(sequence, i); %s" % (
  6615. code.error_goto_if_null('item', self.pos)))
  6616. code.put_gotref('item')
  6617. code.putln("*(temps[i]) = item;")
  6618. code.putln("}")
  6619. code.putln("}")
  6620. code.putln("#endif")
  6621. rhs.generate_disposal_code(code)
  6622. if sequence_type_test == '1':
  6623. code.putln("}") # all done
  6624. elif sequence_type_test == none_check:
  6625. # either tuple/list or None => save some code by generating the error directly
  6626. code.putln("} else {")
  6627. code.globalstate.use_utility_code(
  6628. UtilityCode.load_cached("RaiseNoneIterError", "ObjectHandling.c"))
  6629. code.putln("__Pyx_RaiseNoneNotIterableError(); %s" % code.error_goto(self.pos))
  6630. code.putln("}") # all done
  6631. else:
  6632. code.putln("} else {") # needs iteration fallback code
  6633. self.generate_generic_parallel_unpacking_code(
  6634. code, rhs, self.unpacked_items, use_loop=use_loop)
  6635. code.putln("}")
  6636. def generate_generic_parallel_unpacking_code(self, code, rhs, unpacked_items, use_loop, terminate=True):
  6637. code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
  6638. code.globalstate.use_utility_code(UtilityCode.load_cached("IterFinish", "ObjectHandling.c"))
  6639. code.putln("Py_ssize_t index = -1;") # must be at the start of a C block!
  6640. if use_loop:
  6641. code.putln("PyObject** temps[%s] = {%s};" % (
  6642. len(self.unpacked_items),
  6643. ','.join(['&%s' % item.result() for item in unpacked_items])))
  6644. iterator_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  6645. code.putln(
  6646. "%s = PyObject_GetIter(%s); %s" % (
  6647. iterator_temp,
  6648. rhs.py_result(),
  6649. code.error_goto_if_null(iterator_temp, self.pos)))
  6650. code.put_gotref(iterator_temp)
  6651. rhs.generate_disposal_code(code)
  6652. iternext_func = code.funcstate.allocate_temp(self._func_iternext_type, manage_ref=False)
  6653. code.putln("%s = Py_TYPE(%s)->tp_iternext;" % (
  6654. iternext_func, iterator_temp))
  6655. unpacking_error_label = code.new_label('unpacking_failed')
  6656. unpack_code = "%s(%s)" % (iternext_func, iterator_temp)
  6657. if use_loop:
  6658. code.putln("for (index=0; index < %s; index++) {" % len(unpacked_items))
  6659. code.put("PyObject* item = %s; if (unlikely(!item)) " % unpack_code)
  6660. code.put_goto(unpacking_error_label)
  6661. code.put_gotref("item")
  6662. code.putln("*(temps[index]) = item;")
  6663. code.putln("}")
  6664. else:
  6665. for i, item in enumerate(unpacked_items):
  6666. code.put(
  6667. "index = %d; %s = %s; if (unlikely(!%s)) " % (
  6668. i,
  6669. item.result(),
  6670. unpack_code,
  6671. item.result()))
  6672. code.put_goto(unpacking_error_label)
  6673. code.put_gotref(item.py_result())
  6674. if terminate:
  6675. code.globalstate.use_utility_code(
  6676. UtilityCode.load_cached("UnpackItemEndCheck", "ObjectHandling.c"))
  6677. code.put_error_if_neg(self.pos, "__Pyx_IternextUnpackEndCheck(%s, %d)" % (
  6678. unpack_code,
  6679. len(unpacked_items)))
  6680. code.putln("%s = NULL;" % iternext_func)
  6681. code.put_decref_clear(iterator_temp, py_object_type)
  6682. unpacking_done_label = code.new_label('unpacking_done')
  6683. code.put_goto(unpacking_done_label)
  6684. code.put_label(unpacking_error_label)
  6685. code.put_decref_clear(iterator_temp, py_object_type)
  6686. code.putln("%s = NULL;" % iternext_func)
  6687. code.putln("if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);")
  6688. code.putln(code.error_goto(self.pos))
  6689. code.put_label(unpacking_done_label)
  6690. code.funcstate.release_temp(iternext_func)
  6691. if terminate:
  6692. code.funcstate.release_temp(iterator_temp)
  6693. iterator_temp = None
  6694. return iterator_temp
  6695. def generate_starred_assignment_code(self, rhs, code):
  6696. for i, arg in enumerate(self.args):
  6697. if arg.is_starred:
  6698. starred_target = self.unpacked_items[i]
  6699. unpacked_fixed_items_left = self.unpacked_items[:i]
  6700. unpacked_fixed_items_right = self.unpacked_items[i+1:]
  6701. break
  6702. else:
  6703. assert False
  6704. iterator_temp = None
  6705. if unpacked_fixed_items_left:
  6706. for item in unpacked_fixed_items_left:
  6707. item.allocate(code)
  6708. code.putln('{')
  6709. iterator_temp = self.generate_generic_parallel_unpacking_code(
  6710. code, rhs, unpacked_fixed_items_left,
  6711. use_loop=True, terminate=False)
  6712. for i, item in enumerate(unpacked_fixed_items_left):
  6713. value_node = self.coerced_unpacked_items[i]
  6714. value_node.generate_evaluation_code(code)
  6715. code.putln('}')
  6716. starred_target.allocate(code)
  6717. target_list = starred_target.result()
  6718. code.putln("%s = PySequence_List(%s); %s" % (
  6719. target_list,
  6720. iterator_temp or rhs.py_result(),
  6721. code.error_goto_if_null(target_list, self.pos)))
  6722. code.put_gotref(target_list)
  6723. if iterator_temp:
  6724. code.put_decref_clear(iterator_temp, py_object_type)
  6725. code.funcstate.release_temp(iterator_temp)
  6726. else:
  6727. rhs.generate_disposal_code(code)
  6728. if unpacked_fixed_items_right:
  6729. code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
  6730. length_temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
  6731. code.putln('%s = PyList_GET_SIZE(%s);' % (length_temp, target_list))
  6732. code.putln("if (unlikely(%s < %d)) {" % (length_temp, len(unpacked_fixed_items_right)))
  6733. code.putln("__Pyx_RaiseNeedMoreValuesError(%d+%s); %s" % (
  6734. len(unpacked_fixed_items_left), length_temp,
  6735. code.error_goto(self.pos)))
  6736. code.putln('}')
  6737. for item in unpacked_fixed_items_right[::-1]:
  6738. item.allocate(code)
  6739. for i, (item, coerced_arg) in enumerate(zip(unpacked_fixed_items_right[::-1],
  6740. self.coerced_unpacked_items[::-1])):
  6741. code.putln('#if CYTHON_COMPILING_IN_CPYTHON')
  6742. code.putln("%s = PyList_GET_ITEM(%s, %s-%d); " % (
  6743. item.py_result(), target_list, length_temp, i+1))
  6744. # resize the list the hard way
  6745. code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
  6746. code.putln('#else')
  6747. code.putln("%s = PySequence_ITEM(%s, %s-%d); " % (
  6748. item.py_result(), target_list, length_temp, i+1))
  6749. code.putln('#endif')
  6750. code.put_gotref(item.py_result())
  6751. coerced_arg.generate_evaluation_code(code)
  6752. code.putln('#if !CYTHON_COMPILING_IN_CPYTHON')
  6753. sublist_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  6754. code.putln('%s = PySequence_GetSlice(%s, 0, %s-%d); %s' % (
  6755. sublist_temp, target_list, length_temp, len(unpacked_fixed_items_right),
  6756. code.error_goto_if_null(sublist_temp, self.pos)))
  6757. code.put_gotref(sublist_temp)
  6758. code.funcstate.release_temp(length_temp)
  6759. code.put_decref(target_list, py_object_type)
  6760. code.putln('%s = %s; %s = NULL;' % (target_list, sublist_temp, sublist_temp))
  6761. code.putln('#else')
  6762. code.putln('%s = %s;' % (sublist_temp, sublist_temp)) # avoid warning about unused variable
  6763. code.funcstate.release_temp(sublist_temp)
  6764. code.putln('#endif')
  6765. for i, arg in enumerate(self.args):
  6766. arg.generate_assignment_code(self.coerced_unpacked_items[i], code)
  6767. def annotate(self, code):
  6768. for arg in self.args:
  6769. arg.annotate(code)
  6770. if self.unpacked_items:
  6771. for arg in self.unpacked_items:
  6772. arg.annotate(code)
  6773. for arg in self.coerced_unpacked_items:
  6774. arg.annotate(code)
  6775. class TupleNode(SequenceNode):
  6776. # Tuple constructor.
  6777. type = tuple_type
  6778. is_partly_literal = False
  6779. gil_message = "Constructing Python tuple"
  6780. def infer_type(self, env):
  6781. if self.mult_factor or not self.args:
  6782. return tuple_type
  6783. arg_types = [arg.infer_type(env) for arg in self.args]
  6784. if any(type.is_pyobject or type.is_memoryviewslice or type.is_unspecified or type.is_fused
  6785. for type in arg_types):
  6786. return tuple_type
  6787. return env.declare_tuple_type(self.pos, arg_types).type
  6788. def analyse_types(self, env, skip_children=False):
  6789. if len(self.args) == 0:
  6790. self.is_temp = False
  6791. self.is_literal = True
  6792. return self
  6793. if not skip_children:
  6794. for i, arg in enumerate(self.args):
  6795. if arg.is_starred:
  6796. arg.starred_expr_allowed_here = True
  6797. self.args[i] = arg.analyse_types(env)
  6798. if (not self.mult_factor and
  6799. not any((arg.is_starred or arg.type.is_pyobject or arg.type.is_memoryviewslice or arg.type.is_fused)
  6800. for arg in self.args)):
  6801. self.type = env.declare_tuple_type(self.pos, (arg.type for arg in self.args)).type
  6802. self.is_temp = 1
  6803. return self
  6804. node = SequenceNode.analyse_types(self, env, skip_children=True)
  6805. node = node._create_merge_node_if_necessary(env)
  6806. if not node.is_sequence_constructor:
  6807. return node
  6808. if not all(child.is_literal for child in node.args):
  6809. return node
  6810. if not node.mult_factor or (
  6811. node.mult_factor.is_literal and
  6812. isinstance(node.mult_factor.constant_result, _py_int_types)):
  6813. node.is_temp = False
  6814. node.is_literal = True
  6815. else:
  6816. if not node.mult_factor.type.is_pyobject:
  6817. node.mult_factor = node.mult_factor.coerce_to_pyobject(env)
  6818. node.is_temp = True
  6819. node.is_partly_literal = True
  6820. return node
  6821. def analyse_as_type(self, env):
  6822. # ctuple type
  6823. if not self.args:
  6824. return None
  6825. item_types = [arg.analyse_as_type(env) for arg in self.args]
  6826. if any(t is None for t in item_types):
  6827. return None
  6828. entry = env.declare_tuple_type(self.pos, item_types)
  6829. return entry.type
  6830. def coerce_to(self, dst_type, env):
  6831. if self.type.is_ctuple:
  6832. if dst_type.is_ctuple and self.type.size == dst_type.size:
  6833. return self.coerce_to_ctuple(dst_type, env)
  6834. elif dst_type is tuple_type or dst_type is py_object_type:
  6835. coerced_args = [arg.coerce_to_pyobject(env) for arg in self.args]
  6836. return TupleNode(self.pos, args=coerced_args, type=tuple_type, is_temp=1).analyse_types(env, skip_children=True)
  6837. else:
  6838. return self.coerce_to_pyobject(env).coerce_to(dst_type, env)
  6839. elif dst_type.is_ctuple and not self.mult_factor:
  6840. return self.coerce_to_ctuple(dst_type, env)
  6841. else:
  6842. return SequenceNode.coerce_to(self, dst_type, env)
  6843. def as_list(self):
  6844. t = ListNode(self.pos, args=self.args, mult_factor=self.mult_factor)
  6845. if isinstance(self.constant_result, tuple):
  6846. t.constant_result = list(self.constant_result)
  6847. return t
  6848. def is_simple(self):
  6849. # either temp or constant => always simple
  6850. return True
  6851. def nonlocally_immutable(self):
  6852. # either temp or constant => always safe
  6853. return True
  6854. def calculate_result_code(self):
  6855. if len(self.args) > 0:
  6856. return self.result_code
  6857. else:
  6858. return Naming.empty_tuple
  6859. def calculate_constant_result(self):
  6860. self.constant_result = tuple([
  6861. arg.constant_result for arg in self.args])
  6862. def compile_time_value(self, denv):
  6863. values = self.compile_time_value_list(denv)
  6864. try:
  6865. return tuple(values)
  6866. except Exception as e:
  6867. self.compile_time_value_error(e)
  6868. def generate_operation_code(self, code):
  6869. if len(self.args) == 0:
  6870. # result_code is Naming.empty_tuple
  6871. return
  6872. if self.is_literal or self.is_partly_literal:
  6873. tuple_target = code.get_py_const(py_object_type, 'tuple', cleanup_level=2)
  6874. const_code = code.get_cached_constants_writer()
  6875. const_code.mark_pos(self.pos)
  6876. self.generate_sequence_packing_code(const_code, tuple_target, plain=not self.is_literal)
  6877. const_code.put_giveref(tuple_target)
  6878. if self.is_literal:
  6879. self.result_code = tuple_target
  6880. else:
  6881. code.putln('%s = PyNumber_Multiply(%s, %s); %s' % (
  6882. self.result(), tuple_target, self.mult_factor.py_result(),
  6883. code.error_goto_if_null(self.result(), self.pos)
  6884. ))
  6885. code.put_gotref(self.py_result())
  6886. else:
  6887. self.type.entry.used = True
  6888. self.generate_sequence_packing_code(code)
  6889. class ListNode(SequenceNode):
  6890. # List constructor.
  6891. # obj_conversion_errors [PyrexError] used internally
  6892. # orignial_args [ExprNode] used internally
  6893. obj_conversion_errors = []
  6894. type = list_type
  6895. in_module_scope = False
  6896. gil_message = "Constructing Python list"
  6897. def type_dependencies(self, env):
  6898. return ()
  6899. def infer_type(self, env):
  6900. # TOOD: Infer non-object list arrays.
  6901. return list_type
  6902. def analyse_expressions(self, env):
  6903. for arg in self.args:
  6904. if arg.is_starred:
  6905. arg.starred_expr_allowed_here = True
  6906. node = SequenceNode.analyse_expressions(self, env)
  6907. return node.coerce_to_pyobject(env)
  6908. def analyse_types(self, env):
  6909. with local_errors(ignore=True) as errors:
  6910. self.original_args = list(self.args)
  6911. node = SequenceNode.analyse_types(self, env)
  6912. node.obj_conversion_errors = errors
  6913. if env.is_module_scope:
  6914. self.in_module_scope = True
  6915. node = node._create_merge_node_if_necessary(env)
  6916. return node
  6917. def coerce_to(self, dst_type, env):
  6918. if dst_type.is_pyobject:
  6919. for err in self.obj_conversion_errors:
  6920. report_error(err)
  6921. self.obj_conversion_errors = []
  6922. if not self.type.subtype_of(dst_type):
  6923. error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
  6924. elif (dst_type.is_array or dst_type.is_ptr) and dst_type.base_type is not PyrexTypes.c_void_type:
  6925. array_length = len(self.args)
  6926. if self.mult_factor:
  6927. if isinstance(self.mult_factor.constant_result, _py_int_types):
  6928. if self.mult_factor.constant_result <= 0:
  6929. error(self.pos, "Cannot coerce non-positively multiplied list to '%s'" % dst_type)
  6930. else:
  6931. array_length *= self.mult_factor.constant_result
  6932. else:
  6933. error(self.pos, "Cannot coerce dynamically multiplied list to '%s'" % dst_type)
  6934. base_type = dst_type.base_type
  6935. self.type = PyrexTypes.CArrayType(base_type, array_length)
  6936. for i in range(len(self.original_args)):
  6937. arg = self.args[i]
  6938. if isinstance(arg, CoerceToPyTypeNode):
  6939. arg = arg.arg
  6940. self.args[i] = arg.coerce_to(base_type, env)
  6941. elif dst_type.is_cpp_class:
  6942. # TODO(robertwb): Avoid object conversion for vector/list/set.
  6943. return TypecastNode(self.pos, operand=self, type=PyrexTypes.py_object_type).coerce_to(dst_type, env)
  6944. elif self.mult_factor:
  6945. error(self.pos, "Cannot coerce multiplied list to '%s'" % dst_type)
  6946. elif dst_type.is_struct:
  6947. if len(self.args) > len(dst_type.scope.var_entries):
  6948. error(self.pos, "Too many members for '%s'" % dst_type)
  6949. else:
  6950. if len(self.args) < len(dst_type.scope.var_entries):
  6951. warning(self.pos, "Too few members for '%s'" % dst_type, 1)
  6952. for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
  6953. if isinstance(arg, CoerceToPyTypeNode):
  6954. arg = arg.arg
  6955. self.args[i] = arg.coerce_to(member.type, env)
  6956. self.type = dst_type
  6957. elif dst_type.is_ctuple:
  6958. return self.coerce_to_ctuple(dst_type, env)
  6959. else:
  6960. self.type = error_type
  6961. error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
  6962. return self
  6963. def as_list(self): # dummy for compatibility with TupleNode
  6964. return self
  6965. def as_tuple(self):
  6966. t = TupleNode(self.pos, args=self.args, mult_factor=self.mult_factor)
  6967. if isinstance(self.constant_result, list):
  6968. t.constant_result = tuple(self.constant_result)
  6969. return t
  6970. def allocate_temp_result(self, code):
  6971. if self.type.is_array and self.in_module_scope:
  6972. self.temp_code = code.funcstate.allocate_temp(
  6973. self.type, manage_ref=False, static=True)
  6974. else:
  6975. SequenceNode.allocate_temp_result(self, code)
  6976. def release_temp_result(self, env):
  6977. if self.type.is_array:
  6978. # To be valid C++, we must allocate the memory on the stack
  6979. # manually and be sure not to reuse it for something else.
  6980. # Yes, this means that we leak a temp array variable.
  6981. pass
  6982. else:
  6983. SequenceNode.release_temp_result(self, env)
  6984. def calculate_constant_result(self):
  6985. if self.mult_factor:
  6986. raise ValueError() # may exceed the compile time memory
  6987. self.constant_result = [
  6988. arg.constant_result for arg in self.args]
  6989. def compile_time_value(self, denv):
  6990. l = self.compile_time_value_list(denv)
  6991. if self.mult_factor:
  6992. l *= self.mult_factor.compile_time_value(denv)
  6993. return l
  6994. def generate_operation_code(self, code):
  6995. if self.type.is_pyobject:
  6996. for err in self.obj_conversion_errors:
  6997. report_error(err)
  6998. self.generate_sequence_packing_code(code)
  6999. elif self.type.is_array:
  7000. if self.mult_factor:
  7001. code.putln("{")
  7002. code.putln("Py_ssize_t %s;" % Naming.quick_temp_cname)
  7003. code.putln("for ({i} = 0; {i} < {count}; {i}++) {{".format(
  7004. i=Naming.quick_temp_cname, count=self.mult_factor.result()))
  7005. offset = '+ (%d * %s)' % (len(self.args), Naming.quick_temp_cname)
  7006. else:
  7007. offset = ''
  7008. for i, arg in enumerate(self.args):
  7009. if arg.type.is_array:
  7010. code.globalstate.use_utility_code(UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
  7011. code.putln("memcpy(&(%s[%s%s]), %s, sizeof(%s[0]));" % (
  7012. self.result(), i, offset,
  7013. arg.result(), self.result()
  7014. ))
  7015. else:
  7016. code.putln("%s[%s%s] = %s;" % (
  7017. self.result(),
  7018. i,
  7019. offset,
  7020. arg.result()))
  7021. if self.mult_factor:
  7022. code.putln("}")
  7023. code.putln("}")
  7024. elif self.type.is_struct:
  7025. for arg, member in zip(self.args, self.type.scope.var_entries):
  7026. code.putln("%s.%s = %s;" % (
  7027. self.result(),
  7028. member.cname,
  7029. arg.result()))
  7030. else:
  7031. raise InternalError("List type never specified")
  7032. class ScopedExprNode(ExprNode):
  7033. # Abstract base class for ExprNodes that have their own local
  7034. # scope, such as generator expressions.
  7035. #
  7036. # expr_scope Scope the inner scope of the expression
  7037. subexprs = []
  7038. expr_scope = None
  7039. # does this node really have a local scope, e.g. does it leak loop
  7040. # variables or not? non-leaking Py3 behaviour is default, except
  7041. # for list comprehensions where the behaviour differs in Py2 and
  7042. # Py3 (set in Parsing.py based on parser context)
  7043. has_local_scope = True
  7044. def init_scope(self, outer_scope, expr_scope=None):
  7045. if expr_scope is not None:
  7046. self.expr_scope = expr_scope
  7047. elif self.has_local_scope:
  7048. self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
  7049. else:
  7050. self.expr_scope = None
  7051. def analyse_declarations(self, env):
  7052. self.init_scope(env)
  7053. def analyse_scoped_declarations(self, env):
  7054. # this is called with the expr_scope as env
  7055. pass
  7056. def analyse_types(self, env):
  7057. # no recursion here, the children will be analysed separately below
  7058. return self
  7059. def analyse_scoped_expressions(self, env):
  7060. # this is called with the expr_scope as env
  7061. return self
  7062. def generate_evaluation_code(self, code):
  7063. # set up local variables and free their references on exit
  7064. generate_inner_evaluation_code = super(ScopedExprNode, self).generate_evaluation_code
  7065. if not self.has_local_scope or not self.expr_scope.var_entries:
  7066. # no local variables => delegate, done
  7067. generate_inner_evaluation_code(code)
  7068. return
  7069. code.putln('{ /* enter inner scope */')
  7070. py_entries = []
  7071. for _, entry in sorted(item for item in self.expr_scope.entries.items() if item[0]):
  7072. if not entry.in_closure:
  7073. if entry.type.is_pyobject and entry.used:
  7074. py_entries.append(entry)
  7075. if not py_entries:
  7076. # no local Python references => no cleanup required
  7077. generate_inner_evaluation_code(code)
  7078. code.putln('} /* exit inner scope */')
  7079. return
  7080. # must free all local Python references at each exit point
  7081. old_loop_labels = code.new_loop_labels()
  7082. old_error_label = code.new_error_label()
  7083. generate_inner_evaluation_code(code)
  7084. # normal (non-error) exit
  7085. self._generate_vars_cleanup(code, py_entries)
  7086. # error/loop body exit points
  7087. exit_scope = code.new_label('exit_scope')
  7088. code.put_goto(exit_scope)
  7089. for label, old_label in ([(code.error_label, old_error_label)] +
  7090. list(zip(code.get_loop_labels(), old_loop_labels))):
  7091. if code.label_used(label):
  7092. code.put_label(label)
  7093. self._generate_vars_cleanup(code, py_entries)
  7094. code.put_goto(old_label)
  7095. code.put_label(exit_scope)
  7096. code.putln('} /* exit inner scope */')
  7097. code.set_loop_labels(old_loop_labels)
  7098. code.error_label = old_error_label
  7099. def _generate_vars_cleanup(self, code, py_entries):
  7100. for entry in py_entries:
  7101. if entry.is_cglobal:
  7102. code.put_var_gotref(entry)
  7103. code.put_decref_set(entry.cname, "Py_None")
  7104. else:
  7105. code.put_var_xdecref_clear(entry)
  7106. class ComprehensionNode(ScopedExprNode):
  7107. # A list/set/dict comprehension
  7108. child_attrs = ["loop"]
  7109. is_temp = True
  7110. constant_result = not_a_constant
  7111. def infer_type(self, env):
  7112. return self.type
  7113. def analyse_declarations(self, env):
  7114. self.append.target = self # this is used in the PyList_Append of the inner loop
  7115. self.init_scope(env)
  7116. def analyse_scoped_declarations(self, env):
  7117. self.loop.analyse_declarations(env)
  7118. def analyse_types(self, env):
  7119. if not self.has_local_scope:
  7120. self.loop = self.loop.analyse_expressions(env)
  7121. return self
  7122. def analyse_scoped_expressions(self, env):
  7123. if self.has_local_scope:
  7124. self.loop = self.loop.analyse_expressions(env)
  7125. return self
  7126. def may_be_none(self):
  7127. return False
  7128. def generate_result_code(self, code):
  7129. self.generate_operation_code(code)
  7130. def generate_operation_code(self, code):
  7131. if self.type is Builtin.list_type:
  7132. create_code = 'PyList_New(0)'
  7133. elif self.type is Builtin.set_type:
  7134. create_code = 'PySet_New(NULL)'
  7135. elif self.type is Builtin.dict_type:
  7136. create_code = 'PyDict_New()'
  7137. else:
  7138. raise InternalError("illegal type for comprehension: %s" % self.type)
  7139. code.putln('%s = %s; %s' % (
  7140. self.result(), create_code,
  7141. code.error_goto_if_null(self.result(), self.pos)))
  7142. code.put_gotref(self.result())
  7143. self.loop.generate_execution_code(code)
  7144. def annotate(self, code):
  7145. self.loop.annotate(code)
  7146. class ComprehensionAppendNode(Node):
  7147. # Need to be careful to avoid infinite recursion:
  7148. # target must not be in child_attrs/subexprs
  7149. child_attrs = ['expr']
  7150. target = None
  7151. type = PyrexTypes.c_int_type
  7152. def analyse_expressions(self, env):
  7153. self.expr = self.expr.analyse_expressions(env)
  7154. if not self.expr.type.is_pyobject:
  7155. self.expr = self.expr.coerce_to_pyobject(env)
  7156. return self
  7157. def generate_execution_code(self, code):
  7158. if self.target.type is list_type:
  7159. code.globalstate.use_utility_code(
  7160. UtilityCode.load_cached("ListCompAppend", "Optimize.c"))
  7161. function = "__Pyx_ListComp_Append"
  7162. elif self.target.type is set_type:
  7163. function = "PySet_Add"
  7164. else:
  7165. raise InternalError(
  7166. "Invalid type for comprehension node: %s" % self.target.type)
  7167. self.expr.generate_evaluation_code(code)
  7168. code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
  7169. function,
  7170. self.target.result(),
  7171. self.expr.result()
  7172. ), self.pos))
  7173. self.expr.generate_disposal_code(code)
  7174. self.expr.free_temps(code)
  7175. def generate_function_definitions(self, env, code):
  7176. self.expr.generate_function_definitions(env, code)
  7177. def annotate(self, code):
  7178. self.expr.annotate(code)
  7179. class DictComprehensionAppendNode(ComprehensionAppendNode):
  7180. child_attrs = ['key_expr', 'value_expr']
  7181. def analyse_expressions(self, env):
  7182. self.key_expr = self.key_expr.analyse_expressions(env)
  7183. if not self.key_expr.type.is_pyobject:
  7184. self.key_expr = self.key_expr.coerce_to_pyobject(env)
  7185. self.value_expr = self.value_expr.analyse_expressions(env)
  7186. if not self.value_expr.type.is_pyobject:
  7187. self.value_expr = self.value_expr.coerce_to_pyobject(env)
  7188. return self
  7189. def generate_execution_code(self, code):
  7190. self.key_expr.generate_evaluation_code(code)
  7191. self.value_expr.generate_evaluation_code(code)
  7192. code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
  7193. self.target.result(),
  7194. self.key_expr.result(),
  7195. self.value_expr.result()
  7196. ), self.pos))
  7197. self.key_expr.generate_disposal_code(code)
  7198. self.key_expr.free_temps(code)
  7199. self.value_expr.generate_disposal_code(code)
  7200. self.value_expr.free_temps(code)
  7201. def generate_function_definitions(self, env, code):
  7202. self.key_expr.generate_function_definitions(env, code)
  7203. self.value_expr.generate_function_definitions(env, code)
  7204. def annotate(self, code):
  7205. self.key_expr.annotate(code)
  7206. self.value_expr.annotate(code)
  7207. class InlinedGeneratorExpressionNode(ExprNode):
  7208. # An inlined generator expression for which the result is calculated
  7209. # inside of the loop and returned as a single, first and only Generator
  7210. # return value.
  7211. # This will only be created by transforms when replacing safe builtin
  7212. # calls on generator expressions.
  7213. #
  7214. # gen GeneratorExpressionNode the generator, not containing any YieldExprNodes
  7215. # orig_func String the name of the builtin function this node replaces
  7216. # target ExprNode or None a 'target' for a ComprehensionAppend node
  7217. subexprs = ["gen"]
  7218. orig_func = None
  7219. target = None
  7220. is_temp = True
  7221. type = py_object_type
  7222. def __init__(self, pos, gen, comprehension_type=None, **kwargs):
  7223. gbody = gen.def_node.gbody
  7224. gbody.is_inlined = True
  7225. if comprehension_type is not None:
  7226. assert comprehension_type in (list_type, set_type, dict_type), comprehension_type
  7227. gbody.inlined_comprehension_type = comprehension_type
  7228. kwargs.update(
  7229. target=RawCNameExprNode(pos, comprehension_type, Naming.retval_cname),
  7230. type=comprehension_type,
  7231. )
  7232. super(InlinedGeneratorExpressionNode, self).__init__(pos, gen=gen, **kwargs)
  7233. def may_be_none(self):
  7234. return self.orig_func not in ('any', 'all', 'sorted')
  7235. def infer_type(self, env):
  7236. return self.type
  7237. def analyse_types(self, env):
  7238. self.gen = self.gen.analyse_expressions(env)
  7239. return self
  7240. def generate_result_code(self, code):
  7241. code.putln("%s = __Pyx_Generator_Next(%s); %s" % (
  7242. self.result(), self.gen.result(),
  7243. code.error_goto_if_null(self.result(), self.pos)))
  7244. code.put_gotref(self.result())
  7245. class MergedSequenceNode(ExprNode):
  7246. """
  7247. Merge a sequence of iterables into a set/list/tuple.
  7248. The target collection is determined by self.type, which must be set externally.
  7249. args [ExprNode]
  7250. """
  7251. subexprs = ['args']
  7252. is_temp = True
  7253. gil_message = "Constructing Python collection"
  7254. def __init__(self, pos, args, type):
  7255. if type in (list_type, tuple_type) and args and args[0].is_sequence_constructor:
  7256. # construct a list directly from the first argument that we can then extend
  7257. if args[0].type is not list_type:
  7258. args[0] = ListNode(args[0].pos, args=args[0].args, is_temp=True)
  7259. ExprNode.__init__(self, pos, args=args, type=type)
  7260. def calculate_constant_result(self):
  7261. result = []
  7262. for item in self.args:
  7263. if item.is_sequence_constructor and item.mult_factor:
  7264. if item.mult_factor.constant_result <= 0:
  7265. continue
  7266. # otherwise, adding each item once should be enough
  7267. if item.is_set_literal or item.is_sequence_constructor:
  7268. # process items in order
  7269. items = (arg.constant_result for arg in item.args)
  7270. else:
  7271. items = item.constant_result
  7272. result.extend(items)
  7273. if self.type is set_type:
  7274. result = set(result)
  7275. elif self.type is tuple_type:
  7276. result = tuple(result)
  7277. else:
  7278. assert self.type is list_type
  7279. self.constant_result = result
  7280. def compile_time_value(self, denv):
  7281. result = []
  7282. for item in self.args:
  7283. if item.is_sequence_constructor and item.mult_factor:
  7284. if item.mult_factor.compile_time_value(denv) <= 0:
  7285. continue
  7286. if item.is_set_literal or item.is_sequence_constructor:
  7287. # process items in order
  7288. items = (arg.compile_time_value(denv) for arg in item.args)
  7289. else:
  7290. items = item.compile_time_value(denv)
  7291. result.extend(items)
  7292. if self.type is set_type:
  7293. try:
  7294. result = set(result)
  7295. except Exception as e:
  7296. self.compile_time_value_error(e)
  7297. elif self.type is tuple_type:
  7298. result = tuple(result)
  7299. else:
  7300. assert self.type is list_type
  7301. return result
  7302. def type_dependencies(self, env):
  7303. return ()
  7304. def infer_type(self, env):
  7305. return self.type
  7306. def analyse_types(self, env):
  7307. args = [
  7308. arg.analyse_types(env).coerce_to_pyobject(env).as_none_safe_node(
  7309. # FIXME: CPython's error message starts with the runtime function name
  7310. 'argument after * must be an iterable, not NoneType')
  7311. for arg in self.args
  7312. ]
  7313. if len(args) == 1 and args[0].type is self.type:
  7314. # strip this intermediate node and use the bare collection
  7315. return args[0]
  7316. assert self.type in (set_type, list_type, tuple_type)
  7317. self.args = args
  7318. return self
  7319. def may_be_none(self):
  7320. return False
  7321. def generate_evaluation_code(self, code):
  7322. code.mark_pos(self.pos)
  7323. self.allocate_temp_result(code)
  7324. is_set = self.type is set_type
  7325. args = iter(self.args)
  7326. item = next(args)
  7327. item.generate_evaluation_code(code)
  7328. if (is_set and item.is_set_literal or
  7329. not is_set and item.is_sequence_constructor and item.type is list_type):
  7330. code.putln("%s = %s;" % (self.result(), item.py_result()))
  7331. item.generate_post_assignment_code(code)
  7332. else:
  7333. code.putln("%s = %s(%s); %s" % (
  7334. self.result(),
  7335. 'PySet_New' if is_set else 'PySequence_List',
  7336. item.py_result(),
  7337. code.error_goto_if_null(self.result(), self.pos)))
  7338. code.put_gotref(self.py_result())
  7339. item.generate_disposal_code(code)
  7340. item.free_temps(code)
  7341. helpers = set()
  7342. if is_set:
  7343. add_func = "PySet_Add"
  7344. extend_func = "__Pyx_PySet_Update"
  7345. else:
  7346. add_func = "__Pyx_ListComp_Append"
  7347. extend_func = "__Pyx_PyList_Extend"
  7348. for item in args:
  7349. if (is_set and (item.is_set_literal or item.is_sequence_constructor) or
  7350. (item.is_sequence_constructor and not item.mult_factor)):
  7351. if not is_set and item.args:
  7352. helpers.add(("ListCompAppend", "Optimize.c"))
  7353. for arg in item.args:
  7354. arg.generate_evaluation_code(code)
  7355. code.put_error_if_neg(arg.pos, "%s(%s, %s)" % (
  7356. add_func,
  7357. self.result(),
  7358. arg.py_result()))
  7359. arg.generate_disposal_code(code)
  7360. arg.free_temps(code)
  7361. continue
  7362. if is_set:
  7363. helpers.add(("PySet_Update", "Builtins.c"))
  7364. else:
  7365. helpers.add(("ListExtend", "Optimize.c"))
  7366. item.generate_evaluation_code(code)
  7367. code.put_error_if_neg(item.pos, "%s(%s, %s)" % (
  7368. extend_func,
  7369. self.result(),
  7370. item.py_result()))
  7371. item.generate_disposal_code(code)
  7372. item.free_temps(code)
  7373. if self.type is tuple_type:
  7374. code.putln("{")
  7375. code.putln("PyObject *%s = PyList_AsTuple(%s);" % (
  7376. Naming.quick_temp_cname,
  7377. self.result()))
  7378. code.put_decref(self.result(), py_object_type)
  7379. code.putln("%s = %s; %s" % (
  7380. self.result(),
  7381. Naming.quick_temp_cname,
  7382. code.error_goto_if_null(self.result(), self.pos)))
  7383. code.put_gotref(self.result())
  7384. code.putln("}")
  7385. for helper in sorted(helpers):
  7386. code.globalstate.use_utility_code(UtilityCode.load_cached(*helper))
  7387. def annotate(self, code):
  7388. for item in self.args:
  7389. item.annotate(code)
  7390. class SetNode(ExprNode):
  7391. """
  7392. Set constructor.
  7393. """
  7394. subexprs = ['args']
  7395. type = set_type
  7396. is_set_literal = True
  7397. gil_message = "Constructing Python set"
  7398. def analyse_types(self, env):
  7399. for i in range(len(self.args)):
  7400. arg = self.args[i]
  7401. arg = arg.analyse_types(env)
  7402. self.args[i] = arg.coerce_to_pyobject(env)
  7403. self.type = set_type
  7404. self.is_temp = 1
  7405. return self
  7406. def may_be_none(self):
  7407. return False
  7408. def calculate_constant_result(self):
  7409. self.constant_result = set([arg.constant_result for arg in self.args])
  7410. def compile_time_value(self, denv):
  7411. values = [arg.compile_time_value(denv) for arg in self.args]
  7412. try:
  7413. return set(values)
  7414. except Exception as e:
  7415. self.compile_time_value_error(e)
  7416. def generate_evaluation_code(self, code):
  7417. for arg in self.args:
  7418. arg.generate_evaluation_code(code)
  7419. self.allocate_temp_result(code)
  7420. code.putln(
  7421. "%s = PySet_New(0); %s" % (
  7422. self.result(),
  7423. code.error_goto_if_null(self.result(), self.pos)))
  7424. code.put_gotref(self.py_result())
  7425. for arg in self.args:
  7426. code.put_error_if_neg(
  7427. self.pos,
  7428. "PySet_Add(%s, %s)" % (self.result(), arg.py_result()))
  7429. arg.generate_disposal_code(code)
  7430. arg.free_temps(code)
  7431. class DictNode(ExprNode):
  7432. # Dictionary constructor.
  7433. #
  7434. # key_value_pairs [DictItemNode]
  7435. # exclude_null_values [boolean] Do not add NULL values to dict
  7436. #
  7437. # obj_conversion_errors [PyrexError] used internally
  7438. subexprs = ['key_value_pairs']
  7439. is_temp = 1
  7440. exclude_null_values = False
  7441. type = dict_type
  7442. is_dict_literal = True
  7443. reject_duplicates = False
  7444. obj_conversion_errors = []
  7445. @classmethod
  7446. def from_pairs(cls, pos, pairs):
  7447. return cls(pos, key_value_pairs=[
  7448. DictItemNode(pos, key=k, value=v) for k, v in pairs])
  7449. def calculate_constant_result(self):
  7450. self.constant_result = dict([
  7451. item.constant_result for item in self.key_value_pairs])
  7452. def compile_time_value(self, denv):
  7453. pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
  7454. for item in self.key_value_pairs]
  7455. try:
  7456. return dict(pairs)
  7457. except Exception as e:
  7458. self.compile_time_value_error(e)
  7459. def type_dependencies(self, env):
  7460. return ()
  7461. def infer_type(self, env):
  7462. # TOOD: Infer struct constructors.
  7463. return dict_type
  7464. def analyse_types(self, env):
  7465. with local_errors(ignore=True) as errors:
  7466. self.key_value_pairs = [
  7467. item.analyse_types(env)
  7468. for item in self.key_value_pairs
  7469. ]
  7470. self.obj_conversion_errors = errors
  7471. return self
  7472. def may_be_none(self):
  7473. return False
  7474. def coerce_to(self, dst_type, env):
  7475. if dst_type.is_pyobject:
  7476. self.release_errors()
  7477. if self.type.is_struct_or_union:
  7478. if not dict_type.subtype_of(dst_type):
  7479. error(self.pos, "Cannot interpret struct as non-dict type '%s'" % dst_type)
  7480. return DictNode(self.pos, key_value_pairs=[
  7481. DictItemNode(item.pos, key=item.key.coerce_to_pyobject(env),
  7482. value=item.value.coerce_to_pyobject(env))
  7483. for item in self.key_value_pairs])
  7484. if not self.type.subtype_of(dst_type):
  7485. error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
  7486. elif dst_type.is_struct_or_union:
  7487. self.type = dst_type
  7488. if not dst_type.is_struct and len(self.key_value_pairs) != 1:
  7489. error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
  7490. elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
  7491. warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
  7492. for item in self.key_value_pairs:
  7493. if isinstance(item.key, CoerceToPyTypeNode):
  7494. item.key = item.key.arg
  7495. if not item.key.is_string_literal:
  7496. error(item.key.pos, "Invalid struct field identifier")
  7497. item.key = StringNode(item.key.pos, value="<error>")
  7498. else:
  7499. key = str(item.key.value) # converts string literals to unicode in Py3
  7500. member = dst_type.scope.lookup_here(key)
  7501. if not member:
  7502. error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
  7503. else:
  7504. value = item.value
  7505. if isinstance(value, CoerceToPyTypeNode):
  7506. value = value.arg
  7507. item.value = value.coerce_to(member.type, env)
  7508. else:
  7509. self.type = error_type
  7510. error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
  7511. return self
  7512. def release_errors(self):
  7513. for err in self.obj_conversion_errors:
  7514. report_error(err)
  7515. self.obj_conversion_errors = []
  7516. gil_message = "Constructing Python dict"
  7517. def generate_evaluation_code(self, code):
  7518. # Custom method used here because key-value
  7519. # pairs are evaluated and used one at a time.
  7520. code.mark_pos(self.pos)
  7521. self.allocate_temp_result(code)
  7522. is_dict = self.type.is_pyobject
  7523. if is_dict:
  7524. self.release_errors()
  7525. code.putln(
  7526. "%s = __Pyx_PyDict_NewPresized(%d); %s" % (
  7527. self.result(),
  7528. len(self.key_value_pairs),
  7529. code.error_goto_if_null(self.result(), self.pos)))
  7530. code.put_gotref(self.py_result())
  7531. keys_seen = set()
  7532. key_type = None
  7533. needs_error_helper = False
  7534. for item in self.key_value_pairs:
  7535. item.generate_evaluation_code(code)
  7536. if is_dict:
  7537. if self.exclude_null_values:
  7538. code.putln('if (%s) {' % item.value.py_result())
  7539. key = item.key
  7540. if self.reject_duplicates:
  7541. if keys_seen is not None:
  7542. # avoid runtime 'in' checks for literals that we can do at compile time
  7543. if not key.is_string_literal:
  7544. keys_seen = None
  7545. elif key.value in keys_seen:
  7546. # FIXME: this could be a compile time error, at least in Cython code
  7547. keys_seen = None
  7548. elif key_type is not type(key.value):
  7549. if key_type is None:
  7550. key_type = type(key.value)
  7551. keys_seen.add(key.value)
  7552. else:
  7553. # different types => may not be able to compare at compile time
  7554. keys_seen = None
  7555. else:
  7556. keys_seen.add(key.value)
  7557. if keys_seen is None:
  7558. code.putln('if (unlikely(PyDict_Contains(%s, %s))) {' % (
  7559. self.result(), key.py_result()))
  7560. # currently only used in function calls
  7561. needs_error_helper = True
  7562. code.putln('__Pyx_RaiseDoubleKeywordsError("function", %s); %s' % (
  7563. key.py_result(),
  7564. code.error_goto(item.pos)))
  7565. code.putln("} else {")
  7566. code.put_error_if_neg(self.pos, "PyDict_SetItem(%s, %s, %s)" % (
  7567. self.result(),
  7568. item.key.py_result(),
  7569. item.value.py_result()))
  7570. if self.reject_duplicates and keys_seen is None:
  7571. code.putln('}')
  7572. if self.exclude_null_values:
  7573. code.putln('}')
  7574. else:
  7575. code.putln("%s.%s = %s;" % (
  7576. self.result(),
  7577. item.key.value,
  7578. item.value.result()))
  7579. item.generate_disposal_code(code)
  7580. item.free_temps(code)
  7581. if needs_error_helper:
  7582. code.globalstate.use_utility_code(
  7583. UtilityCode.load_cached("RaiseDoubleKeywords", "FunctionArguments.c"))
  7584. def annotate(self, code):
  7585. for item in self.key_value_pairs:
  7586. item.annotate(code)
  7587. class DictItemNode(ExprNode):
  7588. # Represents a single item in a DictNode
  7589. #
  7590. # key ExprNode
  7591. # value ExprNode
  7592. subexprs = ['key', 'value']
  7593. nogil_check = None # Parent DictNode takes care of it
  7594. def calculate_constant_result(self):
  7595. self.constant_result = (
  7596. self.key.constant_result, self.value.constant_result)
  7597. def analyse_types(self, env):
  7598. self.key = self.key.analyse_types(env)
  7599. self.value = self.value.analyse_types(env)
  7600. self.key = self.key.coerce_to_pyobject(env)
  7601. self.value = self.value.coerce_to_pyobject(env)
  7602. return self
  7603. def generate_evaluation_code(self, code):
  7604. self.key.generate_evaluation_code(code)
  7605. self.value.generate_evaluation_code(code)
  7606. def generate_disposal_code(self, code):
  7607. self.key.generate_disposal_code(code)
  7608. self.value.generate_disposal_code(code)
  7609. def free_temps(self, code):
  7610. self.key.free_temps(code)
  7611. self.value.free_temps(code)
  7612. def __iter__(self):
  7613. return iter([self.key, self.value])
  7614. class SortedDictKeysNode(ExprNode):
  7615. # build sorted list of dict keys, e.g. for dir()
  7616. subexprs = ['arg']
  7617. is_temp = True
  7618. def __init__(self, arg):
  7619. ExprNode.__init__(self, arg.pos, arg=arg)
  7620. self.type = Builtin.list_type
  7621. def analyse_types(self, env):
  7622. arg = self.arg.analyse_types(env)
  7623. if arg.type is Builtin.dict_type:
  7624. arg = arg.as_none_safe_node(
  7625. "'NoneType' object is not iterable")
  7626. self.arg = arg
  7627. return self
  7628. def may_be_none(self):
  7629. return False
  7630. def generate_result_code(self, code):
  7631. dict_result = self.arg.py_result()
  7632. if self.arg.type is Builtin.dict_type:
  7633. code.putln('%s = PyDict_Keys(%s); %s' % (
  7634. self.result(), dict_result,
  7635. code.error_goto_if_null(self.result(), self.pos)))
  7636. code.put_gotref(self.py_result())
  7637. else:
  7638. # originally used PyMapping_Keys() here, but that may return a tuple
  7639. code.globalstate.use_utility_code(UtilityCode.load_cached(
  7640. 'PyObjectCallMethod0', 'ObjectHandling.c'))
  7641. keys_cname = code.intern_identifier(StringEncoding.EncodedString("keys"))
  7642. code.putln('%s = __Pyx_PyObject_CallMethod0(%s, %s); %s' % (
  7643. self.result(), dict_result, keys_cname,
  7644. code.error_goto_if_null(self.result(), self.pos)))
  7645. code.put_gotref(self.py_result())
  7646. code.putln("if (unlikely(!PyList_Check(%s))) {" % self.result())
  7647. code.put_decref_set(self.result(), "PySequence_List(%s)" % self.result())
  7648. code.putln(code.error_goto_if_null(self.result(), self.pos))
  7649. code.put_gotref(self.py_result())
  7650. code.putln("}")
  7651. code.put_error_if_neg(
  7652. self.pos, 'PyList_Sort(%s)' % self.py_result())
  7653. class ModuleNameMixin(object):
  7654. def get_py_mod_name(self, code):
  7655. return code.get_py_string_const(
  7656. self.module_name, identifier=True)
  7657. def get_py_qualified_name(self, code):
  7658. return code.get_py_string_const(
  7659. self.qualname, identifier=True)
  7660. class ClassNode(ExprNode, ModuleNameMixin):
  7661. # Helper class used in the implementation of Python
  7662. # class definitions. Constructs a class object given
  7663. # a name, tuple of bases and class dictionary.
  7664. #
  7665. # name EncodedString Name of the class
  7666. # bases ExprNode Base class tuple
  7667. # dict ExprNode Class dict (not owned by this node)
  7668. # doc ExprNode or None Doc string
  7669. # module_name EncodedString Name of defining module
  7670. subexprs = ['bases', 'doc']
  7671. type = py_object_type
  7672. is_temp = True
  7673. def infer_type(self, env):
  7674. # TODO: could return 'type' in some cases
  7675. return py_object_type
  7676. def analyse_types(self, env):
  7677. self.bases = self.bases.analyse_types(env)
  7678. if self.doc:
  7679. self.doc = self.doc.analyse_types(env)
  7680. self.doc = self.doc.coerce_to_pyobject(env)
  7681. env.use_utility_code(UtilityCode.load_cached("CreateClass", "ObjectHandling.c"))
  7682. return self
  7683. def may_be_none(self):
  7684. return True
  7685. gil_message = "Constructing Python class"
  7686. def generate_result_code(self, code):
  7687. cname = code.intern_identifier(self.name)
  7688. if self.doc:
  7689. code.put_error_if_neg(self.pos,
  7690. 'PyDict_SetItem(%s, %s, %s)' % (
  7691. self.dict.py_result(),
  7692. code.intern_identifier(
  7693. StringEncoding.EncodedString("__doc__")),
  7694. self.doc.py_result()))
  7695. py_mod_name = self.get_py_mod_name(code)
  7696. qualname = self.get_py_qualified_name(code)
  7697. code.putln(
  7698. '%s = __Pyx_CreateClass(%s, %s, %s, %s, %s); %s' % (
  7699. self.result(),
  7700. self.bases.py_result(),
  7701. self.dict.py_result(),
  7702. cname,
  7703. qualname,
  7704. py_mod_name,
  7705. code.error_goto_if_null(self.result(), self.pos)))
  7706. code.put_gotref(self.py_result())
  7707. class Py3ClassNode(ExprNode):
  7708. # Helper class used in the implementation of Python3+
  7709. # class definitions. Constructs a class object given
  7710. # a name, tuple of bases and class dictionary.
  7711. #
  7712. # name EncodedString Name of the class
  7713. # dict ExprNode Class dict (not owned by this node)
  7714. # module_name EncodedString Name of defining module
  7715. # calculate_metaclass bool should call CalculateMetaclass()
  7716. # allow_py2_metaclass bool should look for Py2 metaclass
  7717. subexprs = []
  7718. type = py_object_type
  7719. is_temp = True
  7720. def infer_type(self, env):
  7721. # TODO: could return 'type' in some cases
  7722. return py_object_type
  7723. def analyse_types(self, env):
  7724. return self
  7725. def may_be_none(self):
  7726. return True
  7727. gil_message = "Constructing Python class"
  7728. def generate_result_code(self, code):
  7729. code.globalstate.use_utility_code(UtilityCode.load_cached("Py3ClassCreate", "ObjectHandling.c"))
  7730. cname = code.intern_identifier(self.name)
  7731. if self.mkw:
  7732. mkw = self.mkw.py_result()
  7733. else:
  7734. mkw = 'NULL'
  7735. if self.metaclass:
  7736. metaclass = self.metaclass.py_result()
  7737. else:
  7738. metaclass = "((PyObject*)&__Pyx_DefaultClassType)"
  7739. code.putln(
  7740. '%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s, %d, %d); %s' % (
  7741. self.result(),
  7742. metaclass,
  7743. cname,
  7744. self.bases.py_result(),
  7745. self.dict.py_result(),
  7746. mkw,
  7747. self.calculate_metaclass,
  7748. self.allow_py2_metaclass,
  7749. code.error_goto_if_null(self.result(), self.pos)))
  7750. code.put_gotref(self.py_result())
  7751. class PyClassMetaclassNode(ExprNode):
  7752. # Helper class holds Python3 metaclass object
  7753. #
  7754. # bases ExprNode Base class tuple (not owned by this node)
  7755. # mkw ExprNode Class keyword arguments (not owned by this node)
  7756. subexprs = []
  7757. def analyse_types(self, env):
  7758. self.type = py_object_type
  7759. self.is_temp = True
  7760. return self
  7761. def may_be_none(self):
  7762. return True
  7763. def generate_result_code(self, code):
  7764. if self.mkw:
  7765. code.globalstate.use_utility_code(
  7766. UtilityCode.load_cached("Py3MetaclassGet", "ObjectHandling.c"))
  7767. call = "__Pyx_Py3MetaclassGet(%s, %s)" % (
  7768. self.bases.result(),
  7769. self.mkw.result())
  7770. else:
  7771. code.globalstate.use_utility_code(
  7772. UtilityCode.load_cached("CalculateMetaclass", "ObjectHandling.c"))
  7773. call = "__Pyx_CalculateMetaclass(NULL, %s)" % (
  7774. self.bases.result())
  7775. code.putln(
  7776. "%s = %s; %s" % (
  7777. self.result(), call,
  7778. code.error_goto_if_null(self.result(), self.pos)))
  7779. code.put_gotref(self.py_result())
  7780. class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
  7781. # Helper class holds Python3 namespace object
  7782. #
  7783. # All this are not owned by this node
  7784. # metaclass ExprNode Metaclass object
  7785. # bases ExprNode Base class tuple
  7786. # mkw ExprNode Class keyword arguments
  7787. # doc ExprNode or None Doc string (owned)
  7788. subexprs = ['doc']
  7789. def analyse_types(self, env):
  7790. if self.doc:
  7791. self.doc = self.doc.analyse_types(env)
  7792. self.doc = self.doc.coerce_to_pyobject(env)
  7793. self.type = py_object_type
  7794. self.is_temp = 1
  7795. return self
  7796. def may_be_none(self):
  7797. return True
  7798. def generate_result_code(self, code):
  7799. cname = code.intern_identifier(self.name)
  7800. py_mod_name = self.get_py_mod_name(code)
  7801. qualname = self.get_py_qualified_name(code)
  7802. if self.doc:
  7803. doc_code = self.doc.result()
  7804. else:
  7805. doc_code = '(PyObject *) NULL'
  7806. if self.mkw:
  7807. mkw = self.mkw.py_result()
  7808. else:
  7809. mkw = '(PyObject *) NULL'
  7810. if self.metaclass:
  7811. metaclass = self.metaclass.py_result()
  7812. else:
  7813. metaclass = "(PyObject *) NULL"
  7814. code.putln(
  7815. "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s, %s); %s" % (
  7816. self.result(),
  7817. metaclass,
  7818. self.bases.result(),
  7819. cname,
  7820. qualname,
  7821. mkw,
  7822. py_mod_name,
  7823. doc_code,
  7824. code.error_goto_if_null(self.result(), self.pos)))
  7825. code.put_gotref(self.py_result())
  7826. class ClassCellInjectorNode(ExprNode):
  7827. # Initialize CyFunction.func_classobj
  7828. is_temp = True
  7829. type = py_object_type
  7830. subexprs = []
  7831. is_active = False
  7832. def analyse_expressions(self, env):
  7833. return self
  7834. def generate_evaluation_code(self, code):
  7835. if self.is_active:
  7836. self.allocate_temp_result(code)
  7837. code.putln(
  7838. '%s = PyList_New(0); %s' % (
  7839. self.result(),
  7840. code.error_goto_if_null(self.result(), self.pos)))
  7841. code.put_gotref(self.result())
  7842. def generate_injection_code(self, code, classobj_cname):
  7843. if self.is_active:
  7844. code.globalstate.use_utility_code(
  7845. UtilityCode.load_cached("CyFunctionClassCell", "CythonFunction.c"))
  7846. code.put_error_if_neg(self.pos, '__Pyx_CyFunction_InitClassCell(%s, %s)' % (
  7847. self.result(), classobj_cname))
  7848. class ClassCellNode(ExprNode):
  7849. # Class Cell for noargs super()
  7850. subexprs = []
  7851. is_temp = True
  7852. is_generator = False
  7853. type = py_object_type
  7854. def analyse_types(self, env):
  7855. return self
  7856. def generate_result_code(self, code):
  7857. if not self.is_generator:
  7858. code.putln('%s = __Pyx_CyFunction_GetClassObj(%s);' % (
  7859. self.result(),
  7860. Naming.self_cname))
  7861. else:
  7862. code.putln('%s = %s->classobj;' % (
  7863. self.result(), Naming.generator_cname))
  7864. code.putln(
  7865. 'if (!%s) { PyErr_SetString(PyExc_SystemError, '
  7866. '"super(): empty __class__ cell"); %s }' % (
  7867. self.result(),
  7868. code.error_goto(self.pos)))
  7869. code.put_incref(self.result(), py_object_type)
  7870. class PyCFunctionNode(ExprNode, ModuleNameMixin):
  7871. # Helper class used in the implementation of Python
  7872. # functions. Constructs a PyCFunction object
  7873. # from a PyMethodDef struct.
  7874. #
  7875. # pymethdef_cname string PyMethodDef structure
  7876. # self_object ExprNode or None
  7877. # binding bool
  7878. # def_node DefNode the Python function node
  7879. # module_name EncodedString Name of defining module
  7880. # code_object CodeObjectNode the PyCodeObject creator node
  7881. subexprs = ['code_object', 'defaults_tuple', 'defaults_kwdict',
  7882. 'annotations_dict']
  7883. self_object = None
  7884. code_object = None
  7885. binding = False
  7886. def_node = None
  7887. defaults = None
  7888. defaults_struct = None
  7889. defaults_pyobjects = 0
  7890. defaults_tuple = None
  7891. defaults_kwdict = None
  7892. annotations_dict = None
  7893. type = py_object_type
  7894. is_temp = 1
  7895. specialized_cpdefs = None
  7896. is_specialization = False
  7897. @classmethod
  7898. def from_defnode(cls, node, binding):
  7899. return cls(node.pos,
  7900. def_node=node,
  7901. pymethdef_cname=node.entry.pymethdef_cname,
  7902. binding=binding or node.specialized_cpdefs,
  7903. specialized_cpdefs=node.specialized_cpdefs,
  7904. code_object=CodeObjectNode(node))
  7905. def analyse_types(self, env):
  7906. if self.binding:
  7907. self.analyse_default_args(env)
  7908. return self
  7909. def analyse_default_args(self, env):
  7910. """
  7911. Handle non-literal function's default arguments.
  7912. """
  7913. nonliteral_objects = []
  7914. nonliteral_other = []
  7915. default_args = []
  7916. default_kwargs = []
  7917. annotations = []
  7918. # For global cpdef functions and def/cpdef methods in cdef classes, we must use global constants
  7919. # for default arguments to avoid the dependency on the CyFunction object as 'self' argument
  7920. # in the underlying C function. Basically, cpdef functions/methods are static C functions,
  7921. # so their optional arguments must be static, too.
  7922. # TODO: change CyFunction implementation to pass both function object and owning object for method calls
  7923. must_use_constants = env.is_c_class_scope or (self.def_node.is_wrapper and env.is_module_scope)
  7924. for arg in self.def_node.args:
  7925. if arg.default and not must_use_constants:
  7926. if not arg.default.is_literal:
  7927. arg.is_dynamic = True
  7928. if arg.type.is_pyobject:
  7929. nonliteral_objects.append(arg)
  7930. else:
  7931. nonliteral_other.append(arg)
  7932. else:
  7933. arg.default = DefaultLiteralArgNode(arg.pos, arg.default)
  7934. if arg.kw_only:
  7935. default_kwargs.append(arg)
  7936. else:
  7937. default_args.append(arg)
  7938. if arg.annotation:
  7939. arg.annotation = self.analyse_annotation(env, arg.annotation)
  7940. annotations.append((arg.pos, arg.name, arg.annotation))
  7941. for arg in (self.def_node.star_arg, self.def_node.starstar_arg):
  7942. if arg and arg.annotation:
  7943. arg.annotation = self.analyse_annotation(env, arg.annotation)
  7944. annotations.append((arg.pos, arg.name, arg.annotation))
  7945. annotation = self.def_node.return_type_annotation
  7946. if annotation:
  7947. annotation = self.analyse_annotation(env, annotation)
  7948. self.def_node.return_type_annotation = annotation
  7949. annotations.append((annotation.pos, StringEncoding.EncodedString("return"), annotation))
  7950. if nonliteral_objects or nonliteral_other:
  7951. module_scope = env.global_scope()
  7952. cname = module_scope.next_id(Naming.defaults_struct_prefix)
  7953. scope = Symtab.StructOrUnionScope(cname)
  7954. self.defaults = []
  7955. for arg in nonliteral_objects:
  7956. entry = scope.declare_var(arg.name, arg.type, None,
  7957. Naming.arg_prefix + arg.name,
  7958. allow_pyobject=True)
  7959. self.defaults.append((arg, entry))
  7960. for arg in nonliteral_other:
  7961. entry = scope.declare_var(arg.name, arg.type, None,
  7962. Naming.arg_prefix + arg.name,
  7963. allow_pyobject=False, allow_memoryview=True)
  7964. self.defaults.append((arg, entry))
  7965. entry = module_scope.declare_struct_or_union(
  7966. None, 'struct', scope, 1, None, cname=cname)
  7967. self.defaults_struct = scope
  7968. self.defaults_pyobjects = len(nonliteral_objects)
  7969. for arg, entry in self.defaults:
  7970. arg.default_value = '%s->%s' % (
  7971. Naming.dynamic_args_cname, entry.cname)
  7972. self.def_node.defaults_struct = self.defaults_struct.name
  7973. if default_args or default_kwargs:
  7974. if self.defaults_struct is None:
  7975. if default_args:
  7976. defaults_tuple = TupleNode(self.pos, args=[
  7977. arg.default for arg in default_args])
  7978. self.defaults_tuple = defaults_tuple.analyse_types(env).coerce_to_pyobject(env)
  7979. if default_kwargs:
  7980. defaults_kwdict = DictNode(self.pos, key_value_pairs=[
  7981. DictItemNode(
  7982. arg.pos,
  7983. key=IdentifierStringNode(arg.pos, value=arg.name),
  7984. value=arg.default)
  7985. for arg in default_kwargs])
  7986. self.defaults_kwdict = defaults_kwdict.analyse_types(env)
  7987. else:
  7988. if default_args:
  7989. defaults_tuple = DefaultsTupleNode(
  7990. self.pos, default_args, self.defaults_struct)
  7991. else:
  7992. defaults_tuple = NoneNode(self.pos)
  7993. if default_kwargs:
  7994. defaults_kwdict = DefaultsKwDictNode(
  7995. self.pos, default_kwargs, self.defaults_struct)
  7996. else:
  7997. defaults_kwdict = NoneNode(self.pos)
  7998. defaults_getter = Nodes.DefNode(
  7999. self.pos, args=[], star_arg=None, starstar_arg=None,
  8000. body=Nodes.ReturnStatNode(
  8001. self.pos, return_type=py_object_type,
  8002. value=TupleNode(
  8003. self.pos, args=[defaults_tuple, defaults_kwdict])),
  8004. decorators=None,
  8005. name=StringEncoding.EncodedString("__defaults__"))
  8006. # defaults getter must never live in class scopes, it's always a module function
  8007. module_scope = env.global_scope()
  8008. defaults_getter.analyse_declarations(module_scope)
  8009. defaults_getter = defaults_getter.analyse_expressions(module_scope)
  8010. defaults_getter.body = defaults_getter.body.analyse_expressions(
  8011. defaults_getter.local_scope)
  8012. defaults_getter.py_wrapper_required = False
  8013. defaults_getter.pymethdef_required = False
  8014. self.def_node.defaults_getter = defaults_getter
  8015. if annotations:
  8016. annotations_dict = DictNode(self.pos, key_value_pairs=[
  8017. DictItemNode(
  8018. pos, key=IdentifierStringNode(pos, value=name),
  8019. value=value)
  8020. for pos, name, value in annotations])
  8021. self.annotations_dict = annotations_dict.analyse_types(env)
  8022. def analyse_annotation(self, env, annotation):
  8023. if annotation is None:
  8024. return None
  8025. atype = annotation.analyse_as_type(env)
  8026. if atype is not None:
  8027. # Keep parsed types as strings as they might not be Python representable.
  8028. annotation = UnicodeNode(
  8029. annotation.pos,
  8030. value=StringEncoding.EncodedString(atype.declaration_code('', for_display=True)))
  8031. annotation = annotation.analyse_types(env)
  8032. if not annotation.type.is_pyobject:
  8033. annotation = annotation.coerce_to_pyobject(env)
  8034. return annotation
  8035. def may_be_none(self):
  8036. return False
  8037. gil_message = "Constructing Python function"
  8038. def self_result_code(self):
  8039. if self.self_object is None:
  8040. self_result = "NULL"
  8041. else:
  8042. self_result = self.self_object.py_result()
  8043. return self_result
  8044. def generate_result_code(self, code):
  8045. if self.binding:
  8046. self.generate_cyfunction_code(code)
  8047. else:
  8048. self.generate_pycfunction_code(code)
  8049. def generate_pycfunction_code(self, code):
  8050. py_mod_name = self.get_py_mod_name(code)
  8051. code.putln(
  8052. '%s = PyCFunction_NewEx(&%s, %s, %s); %s' % (
  8053. self.result(),
  8054. self.pymethdef_cname,
  8055. self.self_result_code(),
  8056. py_mod_name,
  8057. code.error_goto_if_null(self.result(), self.pos)))
  8058. code.put_gotref(self.py_result())
  8059. def generate_cyfunction_code(self, code):
  8060. if self.specialized_cpdefs:
  8061. def_node = self.specialized_cpdefs[0]
  8062. else:
  8063. def_node = self.def_node
  8064. if self.specialized_cpdefs or self.is_specialization:
  8065. code.globalstate.use_utility_code(
  8066. UtilityCode.load_cached("FusedFunction", "CythonFunction.c"))
  8067. constructor = "__pyx_FusedFunction_NewEx"
  8068. else:
  8069. code.globalstate.use_utility_code(
  8070. UtilityCode.load_cached("CythonFunction", "CythonFunction.c"))
  8071. constructor = "__Pyx_CyFunction_NewEx"
  8072. if self.code_object:
  8073. code_object_result = self.code_object.py_result()
  8074. else:
  8075. code_object_result = 'NULL'
  8076. flags = []
  8077. if def_node.is_staticmethod:
  8078. flags.append('__Pyx_CYFUNCTION_STATICMETHOD')
  8079. elif def_node.is_classmethod:
  8080. flags.append('__Pyx_CYFUNCTION_CLASSMETHOD')
  8081. if def_node.local_scope.parent_scope.is_c_class_scope and not def_node.entry.is_anonymous:
  8082. flags.append('__Pyx_CYFUNCTION_CCLASS')
  8083. if flags:
  8084. flags = ' | '.join(flags)
  8085. else:
  8086. flags = '0'
  8087. code.putln(
  8088. '%s = %s(&%s, %s, %s, %s, %s, %s, %s); %s' % (
  8089. self.result(),
  8090. constructor,
  8091. self.pymethdef_cname,
  8092. flags,
  8093. self.get_py_qualified_name(code),
  8094. self.self_result_code(),
  8095. self.get_py_mod_name(code),
  8096. Naming.moddict_cname,
  8097. code_object_result,
  8098. code.error_goto_if_null(self.result(), self.pos)))
  8099. code.put_gotref(self.py_result())
  8100. if def_node.requires_classobj:
  8101. assert code.pyclass_stack, "pyclass_stack is empty"
  8102. class_node = code.pyclass_stack[-1]
  8103. code.put_incref(self.py_result(), py_object_type)
  8104. code.putln(
  8105. 'PyList_Append(%s, %s);' % (
  8106. class_node.class_cell.result(),
  8107. self.result()))
  8108. code.put_giveref(self.py_result())
  8109. if self.defaults:
  8110. code.putln(
  8111. 'if (!__Pyx_CyFunction_InitDefaults(%s, sizeof(%s), %d)) %s' % (
  8112. self.result(), self.defaults_struct.name,
  8113. self.defaults_pyobjects, code.error_goto(self.pos)))
  8114. defaults = '__Pyx_CyFunction_Defaults(%s, %s)' % (
  8115. self.defaults_struct.name, self.result())
  8116. for arg, entry in self.defaults:
  8117. arg.generate_assignment_code(code, target='%s->%s' % (
  8118. defaults, entry.cname))
  8119. if self.defaults_tuple:
  8120. code.putln('__Pyx_CyFunction_SetDefaultsTuple(%s, %s);' % (
  8121. self.result(), self.defaults_tuple.py_result()))
  8122. if self.defaults_kwdict:
  8123. code.putln('__Pyx_CyFunction_SetDefaultsKwDict(%s, %s);' % (
  8124. self.result(), self.defaults_kwdict.py_result()))
  8125. if def_node.defaults_getter:
  8126. code.putln('__Pyx_CyFunction_SetDefaultsGetter(%s, %s);' % (
  8127. self.result(), def_node.defaults_getter.entry.pyfunc_cname))
  8128. if self.annotations_dict:
  8129. code.putln('__Pyx_CyFunction_SetAnnotationsDict(%s, %s);' % (
  8130. self.result(), self.annotations_dict.py_result()))
  8131. class InnerFunctionNode(PyCFunctionNode):
  8132. # Special PyCFunctionNode that depends on a closure class
  8133. #
  8134. binding = True
  8135. needs_self_code = True
  8136. def self_result_code(self):
  8137. if self.needs_self_code:
  8138. return "((PyObject*)%s)" % Naming.cur_scope_cname
  8139. return "NULL"
  8140. class CodeObjectNode(ExprNode):
  8141. # Create a PyCodeObject for a CyFunction instance.
  8142. #
  8143. # def_node DefNode the Python function node
  8144. # varnames TupleNode a tuple with all local variable names
  8145. subexprs = ['varnames']
  8146. is_temp = False
  8147. result_code = None
  8148. def __init__(self, def_node):
  8149. ExprNode.__init__(self, def_node.pos, def_node=def_node)
  8150. args = list(def_node.args)
  8151. # if we have args/kwargs, then the first two in var_entries are those
  8152. local_vars = [arg for arg in def_node.local_scope.var_entries if arg.name]
  8153. self.varnames = TupleNode(
  8154. def_node.pos,
  8155. args=[IdentifierStringNode(arg.pos, value=arg.name)
  8156. for arg in args + local_vars],
  8157. is_temp=0,
  8158. is_literal=1)
  8159. def may_be_none(self):
  8160. return False
  8161. def calculate_result_code(self, code=None):
  8162. if self.result_code is None:
  8163. self.result_code = code.get_py_const(py_object_type, 'codeobj', cleanup_level=2)
  8164. return self.result_code
  8165. def generate_result_code(self, code):
  8166. if self.result_code is None:
  8167. self.result_code = code.get_py_const(py_object_type, 'codeobj', cleanup_level=2)
  8168. code = code.get_cached_constants_writer()
  8169. code.mark_pos(self.pos)
  8170. func = self.def_node
  8171. func_name = code.get_py_string_const(
  8172. func.name, identifier=True, is_str=False, unicode_value=func.name)
  8173. # FIXME: better way to get the module file path at module init time? Encoding to use?
  8174. file_path = StringEncoding.bytes_literal(func.pos[0].get_filenametable_entry().encode('utf8'), 'utf8')
  8175. file_path_const = code.get_py_string_const(file_path, identifier=False, is_str=True)
  8176. # This combination makes CPython create a new dict for "frame.f_locals" (see GH #1836).
  8177. flags = ['CO_OPTIMIZED', 'CO_NEWLOCALS']
  8178. if self.def_node.star_arg:
  8179. flags.append('CO_VARARGS')
  8180. if self.def_node.starstar_arg:
  8181. flags.append('CO_VARKEYWORDS')
  8182. code.putln("%s = (PyObject*)__Pyx_PyCode_New(%d, %d, %d, 0, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d, %s); %s" % (
  8183. self.result_code,
  8184. len(func.args) - func.num_kwonly_args, # argcount
  8185. func.num_kwonly_args, # kwonlyargcount (Py3 only)
  8186. len(self.varnames.args), # nlocals
  8187. '|'.join(flags) or '0', # flags
  8188. Naming.empty_bytes, # code
  8189. Naming.empty_tuple, # consts
  8190. Naming.empty_tuple, # names (FIXME)
  8191. self.varnames.result(), # varnames
  8192. Naming.empty_tuple, # freevars (FIXME)
  8193. Naming.empty_tuple, # cellvars (FIXME)
  8194. file_path_const, # filename
  8195. func_name, # name
  8196. self.pos[1], # firstlineno
  8197. Naming.empty_bytes, # lnotab
  8198. code.error_goto_if_null(self.result_code, self.pos),
  8199. ))
  8200. class DefaultLiteralArgNode(ExprNode):
  8201. # CyFunction's literal argument default value
  8202. #
  8203. # Evaluate literal only once.
  8204. subexprs = []
  8205. is_literal = True
  8206. is_temp = False
  8207. def __init__(self, pos, arg):
  8208. super(DefaultLiteralArgNode, self).__init__(pos)
  8209. self.arg = arg
  8210. self.type = self.arg.type
  8211. self.evaluated = False
  8212. def analyse_types(self, env):
  8213. return self
  8214. def generate_result_code(self, code):
  8215. pass
  8216. def generate_evaluation_code(self, code):
  8217. if not self.evaluated:
  8218. self.arg.generate_evaluation_code(code)
  8219. self.evaluated = True
  8220. def result(self):
  8221. return self.type.cast_code(self.arg.result())
  8222. class DefaultNonLiteralArgNode(ExprNode):
  8223. # CyFunction's non-literal argument default value
  8224. subexprs = []
  8225. def __init__(self, pos, arg, defaults_struct):
  8226. super(DefaultNonLiteralArgNode, self).__init__(pos)
  8227. self.arg = arg
  8228. self.defaults_struct = defaults_struct
  8229. def analyse_types(self, env):
  8230. self.type = self.arg.type
  8231. self.is_temp = False
  8232. return self
  8233. def generate_result_code(self, code):
  8234. pass
  8235. def result(self):
  8236. return '__Pyx_CyFunction_Defaults(%s, %s)->%s' % (
  8237. self.defaults_struct.name, Naming.self_cname,
  8238. self.defaults_struct.lookup(self.arg.name).cname)
  8239. class DefaultsTupleNode(TupleNode):
  8240. # CyFunction's __defaults__ tuple
  8241. def __init__(self, pos, defaults, defaults_struct):
  8242. args = []
  8243. for arg in defaults:
  8244. if not arg.default.is_literal:
  8245. arg = DefaultNonLiteralArgNode(pos, arg, defaults_struct)
  8246. else:
  8247. arg = arg.default
  8248. args.append(arg)
  8249. super(DefaultsTupleNode, self).__init__(pos, args=args)
  8250. def analyse_types(self, env, skip_children=False):
  8251. return super(DefaultsTupleNode, self).analyse_types(env, skip_children).coerce_to_pyobject(env)
  8252. class DefaultsKwDictNode(DictNode):
  8253. # CyFunction's __kwdefaults__ dict
  8254. def __init__(self, pos, defaults, defaults_struct):
  8255. items = []
  8256. for arg in defaults:
  8257. name = IdentifierStringNode(arg.pos, value=arg.name)
  8258. if not arg.default.is_literal:
  8259. arg = DefaultNonLiteralArgNode(pos, arg, defaults_struct)
  8260. else:
  8261. arg = arg.default
  8262. items.append(DictItemNode(arg.pos, key=name, value=arg))
  8263. super(DefaultsKwDictNode, self).__init__(pos, key_value_pairs=items)
  8264. class LambdaNode(InnerFunctionNode):
  8265. # Lambda expression node (only used as a function reference)
  8266. #
  8267. # args [CArgDeclNode] formal arguments
  8268. # star_arg PyArgDeclNode or None * argument
  8269. # starstar_arg PyArgDeclNode or None ** argument
  8270. # lambda_name string a module-globally unique lambda name
  8271. # result_expr ExprNode
  8272. # def_node DefNode the underlying function 'def' node
  8273. child_attrs = ['def_node']
  8274. name = StringEncoding.EncodedString('<lambda>')
  8275. def analyse_declarations(self, env):
  8276. self.lambda_name = self.def_node.lambda_name = env.next_id('lambda')
  8277. self.def_node.no_assignment_synthesis = True
  8278. self.def_node.pymethdef_required = True
  8279. self.def_node.analyse_declarations(env)
  8280. self.def_node.is_cyfunction = True
  8281. self.pymethdef_cname = self.def_node.entry.pymethdef_cname
  8282. env.add_lambda_def(self.def_node)
  8283. def analyse_types(self, env):
  8284. self.def_node = self.def_node.analyse_expressions(env)
  8285. return super(LambdaNode, self).analyse_types(env)
  8286. def generate_result_code(self, code):
  8287. self.def_node.generate_execution_code(code)
  8288. super(LambdaNode, self).generate_result_code(code)
  8289. class GeneratorExpressionNode(LambdaNode):
  8290. # A generator expression, e.g. (i for i in range(10))
  8291. #
  8292. # Result is a generator.
  8293. #
  8294. # loop ForStatNode the for-loop, containing a YieldExprNode
  8295. # def_node DefNode the underlying generator 'def' node
  8296. name = StringEncoding.EncodedString('genexpr')
  8297. binding = False
  8298. def analyse_declarations(self, env):
  8299. self.genexpr_name = env.next_id('genexpr')
  8300. super(GeneratorExpressionNode, self).analyse_declarations(env)
  8301. # No pymethdef required
  8302. self.def_node.pymethdef_required = False
  8303. self.def_node.py_wrapper_required = False
  8304. self.def_node.is_cyfunction = False
  8305. # Force genexpr signature
  8306. self.def_node.entry.signature = TypeSlots.pyfunction_noargs
  8307. def generate_result_code(self, code):
  8308. code.putln(
  8309. '%s = %s(%s); %s' % (
  8310. self.result(),
  8311. self.def_node.entry.pyfunc_cname,
  8312. self.self_result_code(),
  8313. code.error_goto_if_null(self.result(), self.pos)))
  8314. code.put_gotref(self.py_result())
  8315. class YieldExprNode(ExprNode):
  8316. # Yield expression node
  8317. #
  8318. # arg ExprNode the value to return from the generator
  8319. # label_num integer yield label number
  8320. # is_yield_from boolean is a YieldFromExprNode to delegate to another generator
  8321. subexprs = ['arg']
  8322. type = py_object_type
  8323. label_num = 0
  8324. is_yield_from = False
  8325. is_await = False
  8326. in_async_gen = False
  8327. expr_keyword = 'yield'
  8328. def analyse_types(self, env):
  8329. if not self.label_num or (self.is_yield_from and self.in_async_gen):
  8330. error(self.pos, "'%s' not supported here" % self.expr_keyword)
  8331. self.is_temp = 1
  8332. if self.arg is not None:
  8333. self.arg = self.arg.analyse_types(env)
  8334. if not self.arg.type.is_pyobject:
  8335. self.coerce_yield_argument(env)
  8336. return self
  8337. def coerce_yield_argument(self, env):
  8338. self.arg = self.arg.coerce_to_pyobject(env)
  8339. def generate_evaluation_code(self, code):
  8340. if self.arg:
  8341. self.arg.generate_evaluation_code(code)
  8342. self.arg.make_owned_reference(code)
  8343. code.putln(
  8344. "%s = %s;" % (
  8345. Naming.retval_cname,
  8346. self.arg.result_as(py_object_type)))
  8347. self.arg.generate_post_assignment_code(code)
  8348. self.arg.free_temps(code)
  8349. else:
  8350. code.put_init_to_py_none(Naming.retval_cname, py_object_type)
  8351. self.generate_yield_code(code)
  8352. def generate_yield_code(self, code):
  8353. """
  8354. Generate the code to return the argument in 'Naming.retval_cname'
  8355. and to continue at the yield label.
  8356. """
  8357. label_num, label_name = code.new_yield_label(
  8358. self.expr_keyword.replace(' ', '_'))
  8359. code.use_label(label_name)
  8360. saved = []
  8361. code.funcstate.closure_temps.reset()
  8362. for cname, type, manage_ref in code.funcstate.temps_in_use():
  8363. save_cname = code.funcstate.closure_temps.allocate_temp(type)
  8364. saved.append((cname, save_cname, type))
  8365. if type.is_pyobject:
  8366. code.put_xgiveref(cname)
  8367. code.putln('%s->%s = %s;' % (Naming.cur_scope_cname, save_cname, cname))
  8368. code.put_xgiveref(Naming.retval_cname)
  8369. profile = code.globalstate.directives['profile']
  8370. linetrace = code.globalstate.directives['linetrace']
  8371. if profile or linetrace:
  8372. code.put_trace_return(Naming.retval_cname,
  8373. nogil=not code.funcstate.gil_owned)
  8374. code.put_finish_refcount_context()
  8375. if code.funcstate.current_except is not None:
  8376. # inside of an except block => save away currently handled exception
  8377. code.putln("__Pyx_Coroutine_SwapException(%s);" % Naming.generator_cname)
  8378. else:
  8379. # no exceptions being handled => restore exception state of caller
  8380. code.putln("__Pyx_Coroutine_ResetAndClearException(%s);" % Naming.generator_cname)
  8381. code.putln("/* return from %sgenerator, %sing value */" % (
  8382. 'async ' if self.in_async_gen else '',
  8383. 'await' if self.is_await else 'yield'))
  8384. code.putln("%s->resume_label = %d;" % (
  8385. Naming.generator_cname, label_num))
  8386. if self.in_async_gen and not self.is_await:
  8387. # __Pyx__PyAsyncGenValueWrapperNew() steals a reference to the return value
  8388. code.putln("return __Pyx__PyAsyncGenValueWrapperNew(%s);" % Naming.retval_cname)
  8389. else:
  8390. code.putln("return %s;" % Naming.retval_cname)
  8391. code.put_label(label_name)
  8392. for cname, save_cname, type in saved:
  8393. code.putln('%s = %s->%s;' % (cname, Naming.cur_scope_cname, save_cname))
  8394. if type.is_pyobject:
  8395. code.putln('%s->%s = 0;' % (Naming.cur_scope_cname, save_cname))
  8396. code.put_xgotref(cname)
  8397. self.generate_sent_value_handling_code(code, Naming.sent_value_cname)
  8398. if self.result_is_used:
  8399. self.allocate_temp_result(code)
  8400. code.put('%s = %s; ' % (self.result(), Naming.sent_value_cname))
  8401. code.put_incref(self.result(), py_object_type)
  8402. def generate_sent_value_handling_code(self, code, value_cname):
  8403. code.putln(code.error_goto_if_null(value_cname, self.pos))
  8404. class _YieldDelegationExprNode(YieldExprNode):
  8405. def yield_from_func(self, code):
  8406. raise NotImplementedError()
  8407. def generate_evaluation_code(self, code, source_cname=None, decref_source=False):
  8408. if source_cname is None:
  8409. self.arg.generate_evaluation_code(code)
  8410. code.putln("%s = %s(%s, %s);" % (
  8411. Naming.retval_cname,
  8412. self.yield_from_func(code),
  8413. Naming.generator_cname,
  8414. self.arg.py_result() if source_cname is None else source_cname))
  8415. if source_cname is None:
  8416. self.arg.generate_disposal_code(code)
  8417. self.arg.free_temps(code)
  8418. elif decref_source:
  8419. code.put_decref_clear(source_cname, py_object_type)
  8420. code.put_xgotref(Naming.retval_cname)
  8421. code.putln("if (likely(%s)) {" % Naming.retval_cname)
  8422. self.generate_yield_code(code)
  8423. code.putln("} else {")
  8424. # either error or sub-generator has normally terminated: return value => node result
  8425. if self.result_is_used:
  8426. self.fetch_iteration_result(code)
  8427. else:
  8428. self.handle_iteration_exception(code)
  8429. code.putln("}")
  8430. def fetch_iteration_result(self, code):
  8431. # YieldExprNode has allocated the result temp for us
  8432. code.putln("%s = NULL;" % self.result())
  8433. code.put_error_if_neg(self.pos, "__Pyx_PyGen_FetchStopIterationValue(&%s)" % self.result())
  8434. code.put_gotref(self.result())
  8435. def handle_iteration_exception(self, code):
  8436. code.putln("PyObject* exc_type = __Pyx_PyErr_Occurred();")
  8437. code.putln("if (exc_type) {")
  8438. code.putln("if (likely(exc_type == PyExc_StopIteration || (exc_type != PyExc_GeneratorExit &&"
  8439. " __Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)))) PyErr_Clear();")
  8440. code.putln("else %s" % code.error_goto(self.pos))
  8441. code.putln("}")
  8442. class YieldFromExprNode(_YieldDelegationExprNode):
  8443. # "yield from GEN" expression
  8444. is_yield_from = True
  8445. expr_keyword = 'yield from'
  8446. def coerce_yield_argument(self, env):
  8447. if not self.arg.type.is_string:
  8448. # FIXME: support C arrays and C++ iterators?
  8449. error(self.pos, "yielding from non-Python object not supported")
  8450. self.arg = self.arg.coerce_to_pyobject(env)
  8451. def yield_from_func(self, code):
  8452. code.globalstate.use_utility_code(UtilityCode.load_cached("GeneratorYieldFrom", "Coroutine.c"))
  8453. return "__Pyx_Generator_Yield_From"
  8454. class AwaitExprNode(_YieldDelegationExprNode):
  8455. # 'await' expression node
  8456. #
  8457. # arg ExprNode the Awaitable value to await
  8458. # label_num integer yield label number
  8459. is_await = True
  8460. expr_keyword = 'await'
  8461. def coerce_yield_argument(self, env):
  8462. if self.arg is not None:
  8463. # FIXME: use same check as in YieldFromExprNode.coerce_yield_argument() ?
  8464. self.arg = self.arg.coerce_to_pyobject(env)
  8465. def yield_from_func(self, code):
  8466. code.globalstate.use_utility_code(UtilityCode.load_cached("CoroutineYieldFrom", "Coroutine.c"))
  8467. return "__Pyx_Coroutine_Yield_From"
  8468. class AwaitIterNextExprNode(AwaitExprNode):
  8469. # 'await' expression node as part of 'async for' iteration
  8470. #
  8471. # Breaks out of loop on StopAsyncIteration exception.
  8472. def _generate_break(self, code):
  8473. code.globalstate.use_utility_code(UtilityCode.load_cached("StopAsyncIteration", "Coroutine.c"))
  8474. code.putln("PyObject* exc_type = __Pyx_PyErr_Occurred();")
  8475. code.putln("if (unlikely(exc_type && (exc_type == __Pyx_PyExc_StopAsyncIteration || ("
  8476. " exc_type != PyExc_StopIteration && exc_type != PyExc_GeneratorExit &&"
  8477. " __Pyx_PyErr_GivenExceptionMatches(exc_type, __Pyx_PyExc_StopAsyncIteration))))) {")
  8478. code.putln("PyErr_Clear();")
  8479. code.putln("break;")
  8480. code.putln("}")
  8481. def fetch_iteration_result(self, code):
  8482. assert code.break_label, "AwaitIterNextExprNode outside of 'async for' loop"
  8483. self._generate_break(code)
  8484. super(AwaitIterNextExprNode, self).fetch_iteration_result(code)
  8485. def generate_sent_value_handling_code(self, code, value_cname):
  8486. assert code.break_label, "AwaitIterNextExprNode outside of 'async for' loop"
  8487. code.putln("if (unlikely(!%s)) {" % value_cname)
  8488. self._generate_break(code)
  8489. # all non-break exceptions are errors, as in parent class
  8490. code.putln(code.error_goto(self.pos))
  8491. code.putln("}")
  8492. class GlobalsExprNode(AtomicExprNode):
  8493. type = dict_type
  8494. is_temp = 1
  8495. def analyse_types(self, env):
  8496. env.use_utility_code(Builtin.globals_utility_code)
  8497. return self
  8498. gil_message = "Constructing globals dict"
  8499. def may_be_none(self):
  8500. return False
  8501. def generate_result_code(self, code):
  8502. code.putln('%s = __Pyx_Globals(); %s' % (
  8503. self.result(),
  8504. code.error_goto_if_null(self.result(), self.pos)))
  8505. code.put_gotref(self.result())
  8506. class LocalsDictItemNode(DictItemNode):
  8507. def analyse_types(self, env):
  8508. self.key = self.key.analyse_types(env)
  8509. self.value = self.value.analyse_types(env)
  8510. self.key = self.key.coerce_to_pyobject(env)
  8511. if self.value.type.can_coerce_to_pyobject(env):
  8512. self.value = self.value.coerce_to_pyobject(env)
  8513. else:
  8514. self.value = None
  8515. return self
  8516. class FuncLocalsExprNode(DictNode):
  8517. def __init__(self, pos, env):
  8518. local_vars = sorted([
  8519. entry.name for entry in env.entries.values() if entry.name])
  8520. items = [LocalsDictItemNode(
  8521. pos, key=IdentifierStringNode(pos, value=var),
  8522. value=NameNode(pos, name=var, allow_null=True))
  8523. for var in local_vars]
  8524. DictNode.__init__(self, pos, key_value_pairs=items,
  8525. exclude_null_values=True)
  8526. def analyse_types(self, env):
  8527. node = super(FuncLocalsExprNode, self).analyse_types(env)
  8528. node.key_value_pairs = [ i for i in node.key_value_pairs
  8529. if i.value is not None ]
  8530. return node
  8531. class PyClassLocalsExprNode(AtomicExprNode):
  8532. def __init__(self, pos, pyclass_dict):
  8533. AtomicExprNode.__init__(self, pos)
  8534. self.pyclass_dict = pyclass_dict
  8535. def analyse_types(self, env):
  8536. self.type = self.pyclass_dict.type
  8537. self.is_temp = False
  8538. return self
  8539. def may_be_none(self):
  8540. return False
  8541. def result(self):
  8542. return self.pyclass_dict.result()
  8543. def generate_result_code(self, code):
  8544. pass
  8545. def LocalsExprNode(pos, scope_node, env):
  8546. if env.is_module_scope:
  8547. return GlobalsExprNode(pos)
  8548. if env.is_py_class_scope:
  8549. return PyClassLocalsExprNode(pos, scope_node.dict)
  8550. return FuncLocalsExprNode(pos, env)
  8551. #-------------------------------------------------------------------
  8552. #
  8553. # Unary operator nodes
  8554. #
  8555. #-------------------------------------------------------------------
  8556. compile_time_unary_operators = {
  8557. 'not': operator.not_,
  8558. '~': operator.inv,
  8559. '-': operator.neg,
  8560. '+': operator.pos,
  8561. }
  8562. class UnopNode(ExprNode):
  8563. # operator string
  8564. # operand ExprNode
  8565. #
  8566. # Processing during analyse_expressions phase:
  8567. #
  8568. # analyse_c_operation
  8569. # Called when the operand is not a pyobject.
  8570. # - Check operand type and coerce if needed.
  8571. # - Determine result type and result code fragment.
  8572. # - Allocate temporary for result if needed.
  8573. subexprs = ['operand']
  8574. infix = True
  8575. def calculate_constant_result(self):
  8576. func = compile_time_unary_operators[self.operator]
  8577. self.constant_result = func(self.operand.constant_result)
  8578. def compile_time_value(self, denv):
  8579. func = compile_time_unary_operators.get(self.operator)
  8580. if not func:
  8581. error(self.pos,
  8582. "Unary '%s' not supported in compile-time expression"
  8583. % self.operator)
  8584. operand = self.operand.compile_time_value(denv)
  8585. try:
  8586. return func(operand)
  8587. except Exception as e:
  8588. self.compile_time_value_error(e)
  8589. def infer_type(self, env):
  8590. operand_type = self.operand.infer_type(env)
  8591. if operand_type.is_cpp_class or operand_type.is_ptr:
  8592. cpp_type = operand_type.find_cpp_operation_type(self.operator)
  8593. if cpp_type is not None:
  8594. return cpp_type
  8595. return self.infer_unop_type(env, operand_type)
  8596. def infer_unop_type(self, env, operand_type):
  8597. if operand_type.is_pyobject:
  8598. return py_object_type
  8599. else:
  8600. return operand_type
  8601. def may_be_none(self):
  8602. if self.operand.type and self.operand.type.is_builtin_type:
  8603. if self.operand.type is not type_type:
  8604. return False
  8605. return ExprNode.may_be_none(self)
  8606. def analyse_types(self, env):
  8607. self.operand = self.operand.analyse_types(env)
  8608. if self.is_pythran_operation(env):
  8609. self.type = PythranExpr(pythran_unaryop_type(self.operator, self.operand.type))
  8610. self.is_temp = 1
  8611. elif self.is_py_operation():
  8612. self.coerce_operand_to_pyobject(env)
  8613. self.type = py_object_type
  8614. self.is_temp = 1
  8615. elif self.is_cpp_operation():
  8616. self.analyse_cpp_operation(env)
  8617. else:
  8618. self.analyse_c_operation(env)
  8619. return self
  8620. def check_const(self):
  8621. return self.operand.check_const()
  8622. def is_py_operation(self):
  8623. return self.operand.type.is_pyobject or self.operand.type.is_ctuple
  8624. def is_pythran_operation(self, env):
  8625. np_pythran = has_np_pythran(env)
  8626. op_type = self.operand.type
  8627. return np_pythran and (op_type.is_buffer or op_type.is_pythran_expr)
  8628. def nogil_check(self, env):
  8629. if self.is_py_operation():
  8630. self.gil_error()
  8631. def is_cpp_operation(self):
  8632. type = self.operand.type
  8633. return type.is_cpp_class
  8634. def coerce_operand_to_pyobject(self, env):
  8635. self.operand = self.operand.coerce_to_pyobject(env)
  8636. def generate_result_code(self, code):
  8637. if self.type.is_pythran_expr:
  8638. code.putln("// Pythran unaryop")
  8639. code.putln("__Pyx_call_destructor(%s);" % self.result())
  8640. code.putln("new (&%s) decltype(%s){%s%s};" % (
  8641. self.result(),
  8642. self.result(),
  8643. self.operator,
  8644. self.operand.pythran_result()))
  8645. elif self.operand.type.is_pyobject:
  8646. self.generate_py_operation_code(code)
  8647. elif self.is_temp:
  8648. if self.is_cpp_operation() and self.exception_check == '+':
  8649. translate_cpp_exception(code, self.pos,
  8650. "%s = %s %s;" % (self.result(), self.operator, self.operand.result()),
  8651. self.exception_value, self.in_nogil_context)
  8652. else:
  8653. code.putln("%s = %s %s;" % (self.result(), self.operator, self.operand.result()))
  8654. def generate_py_operation_code(self, code):
  8655. function = self.py_operation_function(code)
  8656. code.putln(
  8657. "%s = %s(%s); %s" % (
  8658. self.result(),
  8659. function,
  8660. self.operand.py_result(),
  8661. code.error_goto_if_null(self.result(), self.pos)))
  8662. code.put_gotref(self.py_result())
  8663. def type_error(self):
  8664. if not self.operand.type.is_error:
  8665. error(self.pos, "Invalid operand type for '%s' (%s)" %
  8666. (self.operator, self.operand.type))
  8667. self.type = PyrexTypes.error_type
  8668. def analyse_cpp_operation(self, env, overload_check=True):
  8669. entry = env.lookup_operator(self.operator, [self.operand])
  8670. if overload_check and not entry:
  8671. self.type_error()
  8672. return
  8673. if entry:
  8674. self.exception_check = entry.type.exception_check
  8675. self.exception_value = entry.type.exception_value
  8676. if self.exception_check == '+':
  8677. self.is_temp = True
  8678. if self.exception_value is None:
  8679. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  8680. else:
  8681. self.exception_check = ''
  8682. self.exception_value = ''
  8683. cpp_type = self.operand.type.find_cpp_operation_type(self.operator)
  8684. if overload_check and cpp_type is None:
  8685. error(self.pos, "'%s' operator not defined for %s" % (
  8686. self.operator, type))
  8687. self.type_error()
  8688. return
  8689. self.type = cpp_type
  8690. class NotNode(UnopNode):
  8691. # 'not' operator
  8692. #
  8693. # operand ExprNode
  8694. operator = '!'
  8695. type = PyrexTypes.c_bint_type
  8696. def calculate_constant_result(self):
  8697. self.constant_result = not self.operand.constant_result
  8698. def compile_time_value(self, denv):
  8699. operand = self.operand.compile_time_value(denv)
  8700. try:
  8701. return not operand
  8702. except Exception as e:
  8703. self.compile_time_value_error(e)
  8704. def infer_unop_type(self, env, operand_type):
  8705. return PyrexTypes.c_bint_type
  8706. def analyse_types(self, env):
  8707. self.operand = self.operand.analyse_types(env)
  8708. operand_type = self.operand.type
  8709. if operand_type.is_cpp_class:
  8710. self.analyse_cpp_operation(env)
  8711. else:
  8712. self.operand = self.operand.coerce_to_boolean(env)
  8713. return self
  8714. def calculate_result_code(self):
  8715. return "(!%s)" % self.operand.result()
  8716. class UnaryPlusNode(UnopNode):
  8717. # unary '+' operator
  8718. operator = '+'
  8719. def analyse_c_operation(self, env):
  8720. self.type = PyrexTypes.widest_numeric_type(
  8721. self.operand.type, PyrexTypes.c_int_type)
  8722. def py_operation_function(self, code):
  8723. return "PyNumber_Positive"
  8724. def calculate_result_code(self):
  8725. if self.is_cpp_operation():
  8726. return "(+%s)" % self.operand.result()
  8727. else:
  8728. return self.operand.result()
  8729. class UnaryMinusNode(UnopNode):
  8730. # unary '-' operator
  8731. operator = '-'
  8732. def analyse_c_operation(self, env):
  8733. if self.operand.type.is_numeric:
  8734. self.type = PyrexTypes.widest_numeric_type(
  8735. self.operand.type, PyrexTypes.c_int_type)
  8736. elif self.operand.type.is_enum:
  8737. self.type = PyrexTypes.c_int_type
  8738. else:
  8739. self.type_error()
  8740. if self.type.is_complex:
  8741. self.infix = False
  8742. def py_operation_function(self, code):
  8743. return "PyNumber_Negative"
  8744. def calculate_result_code(self):
  8745. if self.infix:
  8746. return "(-%s)" % self.operand.result()
  8747. else:
  8748. return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
  8749. def get_constant_c_result_code(self):
  8750. value = self.operand.get_constant_c_result_code()
  8751. if value:
  8752. return "(-%s)" % value
  8753. class TildeNode(UnopNode):
  8754. # unary '~' operator
  8755. def analyse_c_operation(self, env):
  8756. if self.operand.type.is_int:
  8757. self.type = PyrexTypes.widest_numeric_type(
  8758. self.operand.type, PyrexTypes.c_int_type)
  8759. elif self.operand.type.is_enum:
  8760. self.type = PyrexTypes.c_int_type
  8761. else:
  8762. self.type_error()
  8763. def py_operation_function(self, code):
  8764. return "PyNumber_Invert"
  8765. def calculate_result_code(self):
  8766. return "(~%s)" % self.operand.result()
  8767. class CUnopNode(UnopNode):
  8768. def is_py_operation(self):
  8769. return False
  8770. class DereferenceNode(CUnopNode):
  8771. # unary * operator
  8772. operator = '*'
  8773. def infer_unop_type(self, env, operand_type):
  8774. if operand_type.is_ptr:
  8775. return operand_type.base_type
  8776. else:
  8777. return PyrexTypes.error_type
  8778. def analyse_c_operation(self, env):
  8779. if self.operand.type.is_ptr:
  8780. self.type = self.operand.type.base_type
  8781. else:
  8782. self.type_error()
  8783. def calculate_result_code(self):
  8784. return "(*%s)" % self.operand.result()
  8785. class DecrementIncrementNode(CUnopNode):
  8786. # unary ++/-- operator
  8787. def analyse_c_operation(self, env):
  8788. if self.operand.type.is_numeric:
  8789. self.type = PyrexTypes.widest_numeric_type(
  8790. self.operand.type, PyrexTypes.c_int_type)
  8791. elif self.operand.type.is_ptr:
  8792. self.type = self.operand.type
  8793. else:
  8794. self.type_error()
  8795. def calculate_result_code(self):
  8796. if self.is_prefix:
  8797. return "(%s%s)" % (self.operator, self.operand.result())
  8798. else:
  8799. return "(%s%s)" % (self.operand.result(), self.operator)
  8800. def inc_dec_constructor(is_prefix, operator):
  8801. return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
  8802. class AmpersandNode(CUnopNode):
  8803. # The C address-of operator.
  8804. #
  8805. # operand ExprNode
  8806. operator = '&'
  8807. def infer_unop_type(self, env, operand_type):
  8808. return PyrexTypes.c_ptr_type(operand_type)
  8809. def analyse_types(self, env):
  8810. self.operand = self.operand.analyse_types(env)
  8811. argtype = self.operand.type
  8812. if argtype.is_cpp_class:
  8813. self.analyse_cpp_operation(env, overload_check=False)
  8814. if not (argtype.is_cfunction or argtype.is_reference or self.operand.is_addressable()):
  8815. if argtype.is_memoryviewslice:
  8816. self.error("Cannot take address of memoryview slice")
  8817. else:
  8818. self.error("Taking address of non-lvalue (type %s)" % argtype)
  8819. return self
  8820. if argtype.is_pyobject:
  8821. self.error("Cannot take address of Python %s" % (
  8822. "variable '%s'" % self.operand.name if self.operand.is_name else
  8823. "object attribute '%s'" % self.operand.attribute if self.operand.is_attribute else
  8824. "object"))
  8825. return self
  8826. if not argtype.is_cpp_class or not self.type:
  8827. self.type = PyrexTypes.c_ptr_type(argtype)
  8828. return self
  8829. def check_const(self):
  8830. return self.operand.check_const_addr()
  8831. def error(self, mess):
  8832. error(self.pos, mess)
  8833. self.type = PyrexTypes.error_type
  8834. self.result_code = "<error>"
  8835. def calculate_result_code(self):
  8836. return "(&%s)" % self.operand.result()
  8837. def generate_result_code(self, code):
  8838. if (self.operand.type.is_cpp_class and self.exception_check == '+'):
  8839. translate_cpp_exception(code, self.pos,
  8840. "%s = %s %s;" % (self.result(), self.operator, self.operand.result()),
  8841. self.exception_value, self.in_nogil_context)
  8842. unop_node_classes = {
  8843. "+": UnaryPlusNode,
  8844. "-": UnaryMinusNode,
  8845. "~": TildeNode,
  8846. }
  8847. def unop_node(pos, operator, operand):
  8848. # Construct unnop node of appropriate class for
  8849. # given operator.
  8850. if isinstance(operand, IntNode) and operator == '-':
  8851. return IntNode(pos = operand.pos, value = str(-Utils.str_to_number(operand.value)),
  8852. longness=operand.longness, unsigned=operand.unsigned)
  8853. elif isinstance(operand, UnopNode) and operand.operator == operator in '+-':
  8854. warning(pos, "Python has no increment/decrement operator: %s%sx == %s(%sx) == x" % ((operator,)*4), 5)
  8855. return unop_node_classes[operator](pos,
  8856. operator = operator,
  8857. operand = operand)
  8858. class TypecastNode(ExprNode):
  8859. # C type cast
  8860. #
  8861. # operand ExprNode
  8862. # base_type CBaseTypeNode
  8863. # declarator CDeclaratorNode
  8864. # typecheck boolean
  8865. #
  8866. # If used from a transform, one can if wanted specify the attribute
  8867. # "type" directly and leave base_type and declarator to None
  8868. subexprs = ['operand']
  8869. base_type = declarator = type = None
  8870. def type_dependencies(self, env):
  8871. return ()
  8872. def infer_type(self, env):
  8873. if self.type is None:
  8874. base_type = self.base_type.analyse(env)
  8875. _, self.type = self.declarator.analyse(base_type, env)
  8876. return self.type
  8877. def analyse_types(self, env):
  8878. if self.type is None:
  8879. base_type = self.base_type.analyse(env)
  8880. _, self.type = self.declarator.analyse(base_type, env)
  8881. if self.operand.has_constant_result():
  8882. # Must be done after self.type is resolved.
  8883. self.calculate_constant_result()
  8884. if self.type.is_cfunction:
  8885. error(self.pos,
  8886. "Cannot cast to a function type")
  8887. self.type = PyrexTypes.error_type
  8888. self.operand = self.operand.analyse_types(env)
  8889. if self.type is PyrexTypes.c_bint_type:
  8890. # short circuit this to a coercion
  8891. return self.operand.coerce_to_boolean(env)
  8892. to_py = self.type.is_pyobject
  8893. from_py = self.operand.type.is_pyobject
  8894. if from_py and not to_py and self.operand.is_ephemeral():
  8895. if not self.type.is_numeric and not self.type.is_cpp_class:
  8896. error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
  8897. if to_py and not from_py:
  8898. if self.type is bytes_type and self.operand.type.is_int:
  8899. return CoerceIntToBytesNode(self.operand, env)
  8900. elif self.operand.type.can_coerce_to_pyobject(env):
  8901. self.result_ctype = py_object_type
  8902. self.operand = self.operand.coerce_to(self.type, env)
  8903. else:
  8904. if self.operand.type.is_ptr:
  8905. if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
  8906. error(self.pos, "Python objects cannot be cast from pointers of primitive types")
  8907. else:
  8908. # Should this be an error?
  8909. warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type))
  8910. self.operand = self.operand.coerce_to_simple(env)
  8911. elif from_py and not to_py:
  8912. if self.type.create_from_py_utility_code(env):
  8913. self.operand = self.operand.coerce_to(self.type, env)
  8914. elif self.type.is_ptr:
  8915. if not (self.type.base_type.is_void or self.type.base_type.is_struct):
  8916. error(self.pos, "Python objects cannot be cast to pointers of primitive types")
  8917. else:
  8918. warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.type, self.operand.type))
  8919. elif from_py and to_py:
  8920. if self.typecheck:
  8921. self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
  8922. elif isinstance(self.operand, SliceIndexNode):
  8923. # This cast can influence the created type of string slices.
  8924. self.operand = self.operand.coerce_to(self.type, env)
  8925. elif self.type.is_complex and self.operand.type.is_complex:
  8926. self.operand = self.operand.coerce_to_simple(env)
  8927. elif self.operand.type.is_fused:
  8928. self.operand = self.operand.coerce_to(self.type, env)
  8929. #self.type = self.operand.type
  8930. return self
  8931. def is_simple(self):
  8932. # either temp or a C cast => no side effects other than the operand's
  8933. return self.operand.is_simple()
  8934. def is_ephemeral(self):
  8935. # either temp or a C cast => no side effects other than the operand's
  8936. return self.operand.is_ephemeral()
  8937. def nonlocally_immutable(self):
  8938. return self.is_temp or self.operand.nonlocally_immutable()
  8939. def nogil_check(self, env):
  8940. if self.type and self.type.is_pyobject and self.is_temp:
  8941. self.gil_error()
  8942. def check_const(self):
  8943. return self.operand.check_const()
  8944. def calculate_constant_result(self):
  8945. self.constant_result = self.calculate_result_code(self.operand.constant_result)
  8946. def calculate_result_code(self, operand_result = None):
  8947. if operand_result is None:
  8948. operand_result = self.operand.result()
  8949. if self.type.is_complex:
  8950. operand_result = self.operand.result()
  8951. if self.operand.type.is_complex:
  8952. real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
  8953. imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
  8954. else:
  8955. real_part = self.type.real_type.cast_code(operand_result)
  8956. imag_part = "0"
  8957. return "%s(%s, %s)" % (
  8958. self.type.from_parts,
  8959. real_part,
  8960. imag_part)
  8961. else:
  8962. return self.type.cast_code(operand_result)
  8963. def get_constant_c_result_code(self):
  8964. operand_result = self.operand.get_constant_c_result_code()
  8965. if operand_result:
  8966. return self.type.cast_code(operand_result)
  8967. def result_as(self, type):
  8968. if self.type.is_pyobject and not self.is_temp:
  8969. # Optimise away some unnecessary casting
  8970. return self.operand.result_as(type)
  8971. else:
  8972. return ExprNode.result_as(self, type)
  8973. def generate_result_code(self, code):
  8974. if self.is_temp:
  8975. code.putln(
  8976. "%s = (PyObject *)%s;" % (
  8977. self.result(),
  8978. self.operand.result()))
  8979. code.put_incref(self.result(), self.ctype())
  8980. ERR_START = "Start may not be given"
  8981. ERR_NOT_STOP = "Stop must be provided to indicate shape"
  8982. ERR_STEPS = ("Strides may only be given to indicate contiguity. "
  8983. "Consider slicing it after conversion")
  8984. ERR_NOT_POINTER = "Can only create cython.array from pointer or array"
  8985. ERR_BASE_TYPE = "Pointer base type does not match cython.array base type"
  8986. class CythonArrayNode(ExprNode):
  8987. """
  8988. Used when a pointer of base_type is cast to a memoryviewslice with that
  8989. base type. i.e.
  8990. <int[:M:1, :N]> p
  8991. creates a fortran-contiguous cython.array.
  8992. We leave the type set to object so coercions to object are more efficient
  8993. and less work. Acquiring a memoryviewslice from this will be just as
  8994. efficient. ExprNode.coerce_to() will do the additional typecheck on
  8995. self.compile_time_type
  8996. This also handles <int[:, :]> my_c_array
  8997. operand ExprNode the thing we're casting
  8998. base_type_node MemoryViewSliceTypeNode the cast expression node
  8999. """
  9000. subexprs = ['operand', 'shapes']
  9001. shapes = None
  9002. is_temp = True
  9003. mode = "c"
  9004. array_dtype = None
  9005. shape_type = PyrexTypes.c_py_ssize_t_type
  9006. def analyse_types(self, env):
  9007. from . import MemoryView
  9008. self.operand = self.operand.analyse_types(env)
  9009. if self.array_dtype:
  9010. array_dtype = self.array_dtype
  9011. else:
  9012. array_dtype = self.base_type_node.base_type_node.analyse(env)
  9013. axes = self.base_type_node.axes
  9014. self.type = error_type
  9015. self.shapes = []
  9016. ndim = len(axes)
  9017. # Base type of the pointer or C array we are converting
  9018. base_type = self.operand.type
  9019. if not self.operand.type.is_ptr and not self.operand.type.is_array:
  9020. error(self.operand.pos, ERR_NOT_POINTER)
  9021. return self
  9022. # Dimension sizes of C array
  9023. array_dimension_sizes = []
  9024. if base_type.is_array:
  9025. while base_type.is_array:
  9026. array_dimension_sizes.append(base_type.size)
  9027. base_type = base_type.base_type
  9028. elif base_type.is_ptr:
  9029. base_type = base_type.base_type
  9030. else:
  9031. error(self.pos, "unexpected base type %s found" % base_type)
  9032. return self
  9033. if not (base_type.same_as(array_dtype) or base_type.is_void):
  9034. error(self.operand.pos, ERR_BASE_TYPE)
  9035. return self
  9036. elif self.operand.type.is_array and len(array_dimension_sizes) != ndim:
  9037. error(self.operand.pos,
  9038. "Expected %d dimensions, array has %d dimensions" %
  9039. (ndim, len(array_dimension_sizes)))
  9040. return self
  9041. # Verify the start, stop and step values
  9042. # In case of a C array, use the size of C array in each dimension to
  9043. # get an automatic cast
  9044. for axis_no, axis in enumerate(axes):
  9045. if not axis.start.is_none:
  9046. error(axis.start.pos, ERR_START)
  9047. return self
  9048. if axis.stop.is_none:
  9049. if array_dimension_sizes:
  9050. dimsize = array_dimension_sizes[axis_no]
  9051. axis.stop = IntNode(self.pos, value=str(dimsize),
  9052. constant_result=dimsize,
  9053. type=PyrexTypes.c_int_type)
  9054. else:
  9055. error(axis.pos, ERR_NOT_STOP)
  9056. return self
  9057. axis.stop = axis.stop.analyse_types(env)
  9058. shape = axis.stop.coerce_to(self.shape_type, env)
  9059. if not shape.is_literal:
  9060. shape.coerce_to_temp(env)
  9061. self.shapes.append(shape)
  9062. first_or_last = axis_no in (0, ndim - 1)
  9063. if not axis.step.is_none and first_or_last:
  9064. # '1' in the first or last dimension denotes F or C contiguity
  9065. axis.step = axis.step.analyse_types(env)
  9066. if (not axis.step.type.is_int and axis.step.is_literal and not
  9067. axis.step.type.is_error):
  9068. error(axis.step.pos, "Expected an integer literal")
  9069. return self
  9070. if axis.step.compile_time_value(env) != 1:
  9071. error(axis.step.pos, ERR_STEPS)
  9072. return self
  9073. if axis_no == 0:
  9074. self.mode = "fortran"
  9075. elif not axis.step.is_none and not first_or_last:
  9076. # step provided in some other dimension
  9077. error(axis.step.pos, ERR_STEPS)
  9078. return self
  9079. if not self.operand.is_name:
  9080. self.operand = self.operand.coerce_to_temp(env)
  9081. axes = [('direct', 'follow')] * len(axes)
  9082. if self.mode == "fortran":
  9083. axes[0] = ('direct', 'contig')
  9084. else:
  9085. axes[-1] = ('direct', 'contig')
  9086. self.coercion_type = PyrexTypes.MemoryViewSliceType(array_dtype, axes)
  9087. self.coercion_type.validate_memslice_dtype(self.pos)
  9088. self.type = self.get_cython_array_type(env)
  9089. MemoryView.use_cython_array_utility_code(env)
  9090. env.use_utility_code(MemoryView.typeinfo_to_format_code)
  9091. return self
  9092. def allocate_temp_result(self, code):
  9093. if self.temp_code:
  9094. raise RuntimeError("temp allocated multiple times")
  9095. self.temp_code = code.funcstate.allocate_temp(self.type, True)
  9096. def infer_type(self, env):
  9097. return self.get_cython_array_type(env)
  9098. def get_cython_array_type(self, env):
  9099. cython_scope = env.global_scope().context.cython_scope
  9100. cython_scope.load_cythonscope()
  9101. return cython_scope.viewscope.lookup("array").type
  9102. def generate_result_code(self, code):
  9103. from . import Buffer
  9104. shapes = [self.shape_type.cast_code(shape.result())
  9105. for shape in self.shapes]
  9106. dtype = self.coercion_type.dtype
  9107. shapes_temp = code.funcstate.allocate_temp(py_object_type, True)
  9108. format_temp = code.funcstate.allocate_temp(py_object_type, True)
  9109. itemsize = "sizeof(%s)" % dtype.empty_declaration_code()
  9110. type_info = Buffer.get_type_information_cname(code, dtype)
  9111. if self.operand.type.is_ptr:
  9112. code.putln("if (!%s) {" % self.operand.result())
  9113. code.putln( 'PyErr_SetString(PyExc_ValueError,'
  9114. '"Cannot create cython.array from NULL pointer");')
  9115. code.putln(code.error_goto(self.operand.pos))
  9116. code.putln("}")
  9117. code.putln("%s = __pyx_format_from_typeinfo(&%s);" %
  9118. (format_temp, type_info))
  9119. buildvalue_fmt = " __PYX_BUILD_PY_SSIZE_T " * len(shapes)
  9120. code.putln('%s = Py_BuildValue((char*) "(" %s ")", %s);' % (
  9121. shapes_temp, buildvalue_fmt, ", ".join(shapes)))
  9122. err = "!%s || !%s || !PyBytes_AsString(%s)" % (format_temp,
  9123. shapes_temp,
  9124. format_temp)
  9125. code.putln(code.error_goto_if(err, self.pos))
  9126. code.put_gotref(format_temp)
  9127. code.put_gotref(shapes_temp)
  9128. tup = (self.result(), shapes_temp, itemsize, format_temp,
  9129. self.mode, self.operand.result())
  9130. code.putln('%s = __pyx_array_new('
  9131. '%s, %s, PyBytes_AS_STRING(%s), '
  9132. '(char *) "%s", (char *) %s);' % tup)
  9133. code.putln(code.error_goto_if_null(self.result(), self.pos))
  9134. code.put_gotref(self.result())
  9135. def dispose(temp):
  9136. code.put_decref_clear(temp, py_object_type)
  9137. code.funcstate.release_temp(temp)
  9138. dispose(shapes_temp)
  9139. dispose(format_temp)
  9140. @classmethod
  9141. def from_carray(cls, src_node, env):
  9142. """
  9143. Given a C array type, return a CythonArrayNode
  9144. """
  9145. pos = src_node.pos
  9146. base_type = src_node.type
  9147. none_node = NoneNode(pos)
  9148. axes = []
  9149. while base_type.is_array:
  9150. axes.append(SliceNode(pos, start=none_node, stop=none_node,
  9151. step=none_node))
  9152. base_type = base_type.base_type
  9153. axes[-1].step = IntNode(pos, value="1", is_c_literal=True)
  9154. memslicenode = Nodes.MemoryViewSliceTypeNode(pos, axes=axes,
  9155. base_type_node=base_type)
  9156. result = CythonArrayNode(pos, base_type_node=memslicenode,
  9157. operand=src_node, array_dtype=base_type)
  9158. result = result.analyse_types(env)
  9159. return result
  9160. class SizeofNode(ExprNode):
  9161. # Abstract base class for sizeof(x) expression nodes.
  9162. type = PyrexTypes.c_size_t_type
  9163. def check_const(self):
  9164. return True
  9165. def generate_result_code(self, code):
  9166. pass
  9167. class SizeofTypeNode(SizeofNode):
  9168. # C sizeof function applied to a type
  9169. #
  9170. # base_type CBaseTypeNode
  9171. # declarator CDeclaratorNode
  9172. subexprs = []
  9173. arg_type = None
  9174. def analyse_types(self, env):
  9175. # we may have incorrectly interpreted a dotted name as a type rather than an attribute
  9176. # this could be better handled by more uniformly treating types as runtime-available objects
  9177. if 0 and self.base_type.module_path:
  9178. path = self.base_type.module_path
  9179. obj = env.lookup(path[0])
  9180. if obj.as_module is None:
  9181. operand = NameNode(pos=self.pos, name=path[0])
  9182. for attr in path[1:]:
  9183. operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
  9184. operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
  9185. node = SizeofVarNode(self.pos, operand=operand).analyse_types(env)
  9186. return node
  9187. if self.arg_type is None:
  9188. base_type = self.base_type.analyse(env)
  9189. _, arg_type = self.declarator.analyse(base_type, env)
  9190. self.arg_type = arg_type
  9191. self.check_type()
  9192. return self
  9193. def check_type(self):
  9194. arg_type = self.arg_type
  9195. if not arg_type:
  9196. return
  9197. if arg_type.is_pyobject and not arg_type.is_extension_type:
  9198. error(self.pos, "Cannot take sizeof Python object")
  9199. elif arg_type.is_void:
  9200. error(self.pos, "Cannot take sizeof void")
  9201. elif not arg_type.is_complete():
  9202. error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
  9203. def calculate_result_code(self):
  9204. if self.arg_type.is_extension_type:
  9205. # the size of the pointer is boring
  9206. # we want the size of the actual struct
  9207. arg_code = self.arg_type.declaration_code("", deref=1)
  9208. else:
  9209. arg_code = self.arg_type.empty_declaration_code()
  9210. return "(sizeof(%s))" % arg_code
  9211. class SizeofVarNode(SizeofNode):
  9212. # C sizeof function applied to a variable
  9213. #
  9214. # operand ExprNode
  9215. subexprs = ['operand']
  9216. def analyse_types(self, env):
  9217. # We may actually be looking at a type rather than a variable...
  9218. # If we are, traditional analysis would fail...
  9219. operand_as_type = self.operand.analyse_as_type(env)
  9220. if operand_as_type:
  9221. self.arg_type = operand_as_type
  9222. if self.arg_type.is_fused:
  9223. self.arg_type = self.arg_type.specialize(env.fused_to_specific)
  9224. self.__class__ = SizeofTypeNode
  9225. self.check_type()
  9226. else:
  9227. self.operand = self.operand.analyse_types(env)
  9228. return self
  9229. def calculate_result_code(self):
  9230. return "(sizeof(%s))" % self.operand.result()
  9231. def generate_result_code(self, code):
  9232. pass
  9233. class TypeidNode(ExprNode):
  9234. # C++ typeid operator applied to a type or variable
  9235. #
  9236. # operand ExprNode
  9237. # arg_type ExprNode
  9238. # is_variable boolean
  9239. type = PyrexTypes.error_type
  9240. subexprs = ['operand']
  9241. arg_type = None
  9242. is_variable = None
  9243. is_temp = 1
  9244. def get_type_info_type(self, env):
  9245. env_module = env
  9246. while not env_module.is_module_scope:
  9247. env_module = env_module.outer_scope
  9248. typeinfo_module = env_module.find_module('libcpp.typeinfo', self.pos)
  9249. typeinfo_entry = typeinfo_module.lookup('type_info')
  9250. return PyrexTypes.CFakeReferenceType(PyrexTypes.c_const_type(typeinfo_entry.type))
  9251. def analyse_types(self, env):
  9252. type_info = self.get_type_info_type(env)
  9253. if not type_info:
  9254. self.error("The 'libcpp.typeinfo' module must be cimported to use the typeid() operator")
  9255. return self
  9256. self.type = type_info
  9257. as_type = self.operand.analyse_as_type(env)
  9258. if as_type:
  9259. self.arg_type = as_type
  9260. self.is_type = True
  9261. else:
  9262. self.arg_type = self.operand.analyse_types(env)
  9263. self.is_type = False
  9264. if self.arg_type.type.is_pyobject:
  9265. self.error("Cannot use typeid on a Python object")
  9266. return self
  9267. elif self.arg_type.type.is_void:
  9268. self.error("Cannot use typeid on void")
  9269. return self
  9270. elif not self.arg_type.type.is_complete():
  9271. self.error("Cannot use typeid on incomplete type '%s'" % self.arg_type.type)
  9272. return self
  9273. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  9274. return self
  9275. def error(self, mess):
  9276. error(self.pos, mess)
  9277. self.type = PyrexTypes.error_type
  9278. self.result_code = "<error>"
  9279. def check_const(self):
  9280. return True
  9281. def calculate_result_code(self):
  9282. return self.temp_code
  9283. def generate_result_code(self, code):
  9284. if self.is_type:
  9285. arg_code = self.arg_type.empty_declaration_code()
  9286. else:
  9287. arg_code = self.arg_type.result()
  9288. translate_cpp_exception(code, self.pos,
  9289. "%s = typeid(%s);" % (self.temp_code, arg_code),
  9290. None, self.in_nogil_context)
  9291. class TypeofNode(ExprNode):
  9292. # Compile-time type of an expression, as a string.
  9293. #
  9294. # operand ExprNode
  9295. # literal StringNode # internal
  9296. literal = None
  9297. type = py_object_type
  9298. subexprs = ['literal'] # 'operand' will be ignored after type analysis!
  9299. def analyse_types(self, env):
  9300. self.operand = self.operand.analyse_types(env)
  9301. value = StringEncoding.EncodedString(str(self.operand.type)) #self.operand.type.typeof_name())
  9302. literal = StringNode(self.pos, value=value)
  9303. literal = literal.analyse_types(env)
  9304. self.literal = literal.coerce_to_pyobject(env)
  9305. return self
  9306. def analyse_as_type(self, env):
  9307. self.operand = self.operand.analyse_types(env)
  9308. return self.operand.type
  9309. def may_be_none(self):
  9310. return False
  9311. def generate_evaluation_code(self, code):
  9312. self.literal.generate_evaluation_code(code)
  9313. def calculate_result_code(self):
  9314. return self.literal.calculate_result_code()
  9315. #-------------------------------------------------------------------
  9316. #
  9317. # Binary operator nodes
  9318. #
  9319. #-------------------------------------------------------------------
  9320. try:
  9321. matmul_operator = operator.matmul
  9322. except AttributeError:
  9323. def matmul_operator(a, b):
  9324. try:
  9325. func = a.__matmul__
  9326. except AttributeError:
  9327. func = b.__rmatmul__
  9328. return func(a, b)
  9329. compile_time_binary_operators = {
  9330. '<': operator.lt,
  9331. '<=': operator.le,
  9332. '==': operator.eq,
  9333. '!=': operator.ne,
  9334. '>=': operator.ge,
  9335. '>': operator.gt,
  9336. 'is': operator.is_,
  9337. 'is_not': operator.is_not,
  9338. '+': operator.add,
  9339. '&': operator.and_,
  9340. '/': operator.truediv,
  9341. '//': operator.floordiv,
  9342. '<<': operator.lshift,
  9343. '%': operator.mod,
  9344. '*': operator.mul,
  9345. '|': operator.or_,
  9346. '**': operator.pow,
  9347. '>>': operator.rshift,
  9348. '-': operator.sub,
  9349. '^': operator.xor,
  9350. '@': matmul_operator,
  9351. 'in': lambda x, seq: x in seq,
  9352. 'not_in': lambda x, seq: x not in seq,
  9353. }
  9354. def get_compile_time_binop(node):
  9355. func = compile_time_binary_operators.get(node.operator)
  9356. if not func:
  9357. error(node.pos,
  9358. "Binary '%s' not supported in compile-time expression"
  9359. % node.operator)
  9360. return func
  9361. class BinopNode(ExprNode):
  9362. # operator string
  9363. # operand1 ExprNode
  9364. # operand2 ExprNode
  9365. #
  9366. # Processing during analyse_expressions phase:
  9367. #
  9368. # analyse_c_operation
  9369. # Called when neither operand is a pyobject.
  9370. # - Check operand types and coerce if needed.
  9371. # - Determine result type and result code fragment.
  9372. # - Allocate temporary for result if needed.
  9373. subexprs = ['operand1', 'operand2']
  9374. inplace = False
  9375. def calculate_constant_result(self):
  9376. func = compile_time_binary_operators[self.operator]
  9377. self.constant_result = func(
  9378. self.operand1.constant_result,
  9379. self.operand2.constant_result)
  9380. def compile_time_value(self, denv):
  9381. func = get_compile_time_binop(self)
  9382. operand1 = self.operand1.compile_time_value(denv)
  9383. operand2 = self.operand2.compile_time_value(denv)
  9384. try:
  9385. return func(operand1, operand2)
  9386. except Exception as e:
  9387. self.compile_time_value_error(e)
  9388. def infer_type(self, env):
  9389. return self.result_type(self.operand1.infer_type(env),
  9390. self.operand2.infer_type(env), env)
  9391. def analyse_types(self, env):
  9392. self.operand1 = self.operand1.analyse_types(env)
  9393. self.operand2 = self.operand2.analyse_types(env)
  9394. self.analyse_operation(env)
  9395. return self
  9396. def analyse_operation(self, env):
  9397. if self.is_pythran_operation(env):
  9398. self.type = self.result_type(self.operand1.type,
  9399. self.operand2.type, env)
  9400. assert self.type.is_pythran_expr
  9401. self.is_temp = 1
  9402. elif self.is_py_operation():
  9403. self.coerce_operands_to_pyobjects(env)
  9404. self.type = self.result_type(self.operand1.type,
  9405. self.operand2.type, env)
  9406. assert self.type.is_pyobject
  9407. self.is_temp = 1
  9408. elif self.is_cpp_operation():
  9409. self.analyse_cpp_operation(env)
  9410. else:
  9411. self.analyse_c_operation(env)
  9412. def is_py_operation(self):
  9413. return self.is_py_operation_types(self.operand1.type, self.operand2.type)
  9414. def is_py_operation_types(self, type1, type2):
  9415. return type1.is_pyobject or type2.is_pyobject or type1.is_ctuple or type2.is_ctuple
  9416. def is_pythran_operation(self, env):
  9417. return self.is_pythran_operation_types(self.operand1.type, self.operand2.type, env)
  9418. def is_pythran_operation_types(self, type1, type2, env):
  9419. # Support only expr op supported_type, or supported_type op expr
  9420. return has_np_pythran(env) and \
  9421. (is_pythran_supported_operation_type(type1) and is_pythran_supported_operation_type(type2)) and \
  9422. (is_pythran_expr(type1) or is_pythran_expr(type2))
  9423. def is_cpp_operation(self):
  9424. return (self.operand1.type.is_cpp_class
  9425. or self.operand2.type.is_cpp_class)
  9426. def analyse_cpp_operation(self, env):
  9427. entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
  9428. if not entry:
  9429. self.type_error()
  9430. return
  9431. func_type = entry.type
  9432. self.exception_check = func_type.exception_check
  9433. self.exception_value = func_type.exception_value
  9434. if self.exception_check == '+':
  9435. # Used by NumBinopNodes to break up expressions involving multiple
  9436. # operators so that exceptions can be handled properly.
  9437. self.is_temp = 1
  9438. if self.exception_value is None:
  9439. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  9440. if func_type.is_ptr:
  9441. func_type = func_type.base_type
  9442. if len(func_type.args) == 1:
  9443. self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
  9444. else:
  9445. self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
  9446. self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
  9447. self.type = func_type.return_type
  9448. def result_type(self, type1, type2, env):
  9449. if self.is_pythran_operation_types(type1, type2, env):
  9450. return PythranExpr(pythran_binop_type(self.operator, type1, type2))
  9451. if self.is_py_operation_types(type1, type2):
  9452. if type2.is_string:
  9453. type2 = Builtin.bytes_type
  9454. elif type2.is_pyunicode_ptr:
  9455. type2 = Builtin.unicode_type
  9456. if type1.is_string:
  9457. type1 = Builtin.bytes_type
  9458. elif type1.is_pyunicode_ptr:
  9459. type1 = Builtin.unicode_type
  9460. if type1.is_builtin_type or type2.is_builtin_type:
  9461. if type1 is type2 and self.operator in '**%+|&^':
  9462. # FIXME: at least these operators should be safe - others?
  9463. return type1
  9464. result_type = self.infer_builtin_types_operation(type1, type2)
  9465. if result_type is not None:
  9466. return result_type
  9467. return py_object_type
  9468. elif type1.is_error or type2.is_error:
  9469. return PyrexTypes.error_type
  9470. else:
  9471. return self.compute_c_result_type(type1, type2)
  9472. def infer_builtin_types_operation(self, type1, type2):
  9473. return None
  9474. def nogil_check(self, env):
  9475. if self.is_py_operation():
  9476. self.gil_error()
  9477. def coerce_operands_to_pyobjects(self, env):
  9478. self.operand1 = self.operand1.coerce_to_pyobject(env)
  9479. self.operand2 = self.operand2.coerce_to_pyobject(env)
  9480. def check_const(self):
  9481. return self.operand1.check_const() and self.operand2.check_const()
  9482. def is_ephemeral(self):
  9483. return (super(BinopNode, self).is_ephemeral() or
  9484. self.operand1.is_ephemeral() or self.operand2.is_ephemeral())
  9485. def generate_result_code(self, code):
  9486. if self.type.is_pythran_expr:
  9487. code.putln("// Pythran binop")
  9488. code.putln("__Pyx_call_destructor(%s);" % self.result())
  9489. code.putln("new (&%s) decltype(%s){%s %s %s};" % (
  9490. self.result(),
  9491. self.result(),
  9492. self.operand1.pythran_result(),
  9493. self.operator,
  9494. self.operand2.pythran_result()))
  9495. elif self.operand1.type.is_pyobject:
  9496. function = self.py_operation_function(code)
  9497. if self.operator == '**':
  9498. extra_args = ", Py_None"
  9499. else:
  9500. extra_args = ""
  9501. code.putln(
  9502. "%s = %s(%s, %s%s); %s" % (
  9503. self.result(),
  9504. function,
  9505. self.operand1.py_result(),
  9506. self.operand2.py_result(),
  9507. extra_args,
  9508. code.error_goto_if_null(self.result(), self.pos)))
  9509. code.put_gotref(self.py_result())
  9510. elif self.is_temp:
  9511. # C++ overloaded operators with exception values are currently all
  9512. # handled through temporaries.
  9513. if self.is_cpp_operation() and self.exception_check == '+':
  9514. translate_cpp_exception(code, self.pos,
  9515. "%s = %s;" % (self.result(), self.calculate_result_code()),
  9516. self.exception_value, self.in_nogil_context)
  9517. else:
  9518. code.putln("%s = %s;" % (self.result(), self.calculate_result_code()))
  9519. def type_error(self):
  9520. if not (self.operand1.type.is_error
  9521. or self.operand2.type.is_error):
  9522. error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
  9523. (self.operator, self.operand1.type,
  9524. self.operand2.type))
  9525. self.type = PyrexTypes.error_type
  9526. class CBinopNode(BinopNode):
  9527. def analyse_types(self, env):
  9528. node = BinopNode.analyse_types(self, env)
  9529. if node.is_py_operation():
  9530. node.type = PyrexTypes.error_type
  9531. return node
  9532. def py_operation_function(self, code):
  9533. return ""
  9534. def calculate_result_code(self):
  9535. return "(%s %s %s)" % (
  9536. self.operand1.result(),
  9537. self.operator,
  9538. self.operand2.result())
  9539. def compute_c_result_type(self, type1, type2):
  9540. cpp_type = None
  9541. if type1.is_cpp_class or type1.is_ptr:
  9542. cpp_type = type1.find_cpp_operation_type(self.operator, type2)
  9543. # FIXME: handle the reversed case?
  9544. #if cpp_type is None and (type2.is_cpp_class or type2.is_ptr):
  9545. # cpp_type = type2.find_cpp_operation_type(self.operator, type1)
  9546. # FIXME: do we need to handle other cases here?
  9547. return cpp_type
  9548. def c_binop_constructor(operator):
  9549. def make_binop_node(pos, **operands):
  9550. return CBinopNode(pos, operator=operator, **operands)
  9551. return make_binop_node
  9552. class NumBinopNode(BinopNode):
  9553. # Binary operation taking numeric arguments.
  9554. infix = True
  9555. overflow_check = False
  9556. overflow_bit_node = None
  9557. def analyse_c_operation(self, env):
  9558. type1 = self.operand1.type
  9559. type2 = self.operand2.type
  9560. self.type = self.compute_c_result_type(type1, type2)
  9561. if not self.type:
  9562. self.type_error()
  9563. return
  9564. if self.type.is_complex:
  9565. self.infix = False
  9566. if (self.type.is_int
  9567. and env.directives['overflowcheck']
  9568. and self.operator in self.overflow_op_names):
  9569. if (self.operator in ('+', '*')
  9570. and self.operand1.has_constant_result()
  9571. and not self.operand2.has_constant_result()):
  9572. self.operand1, self.operand2 = self.operand2, self.operand1
  9573. self.overflow_check = True
  9574. self.overflow_fold = env.directives['overflowcheck.fold']
  9575. self.func = self.type.overflow_check_binop(
  9576. self.overflow_op_names[self.operator],
  9577. env,
  9578. const_rhs = self.operand2.has_constant_result())
  9579. self.is_temp = True
  9580. if not self.infix or (type1.is_numeric and type2.is_numeric):
  9581. self.operand1 = self.operand1.coerce_to(self.type, env)
  9582. self.operand2 = self.operand2.coerce_to(self.type, env)
  9583. def compute_c_result_type(self, type1, type2):
  9584. if self.c_types_okay(type1, type2):
  9585. widest_type = PyrexTypes.widest_numeric_type(type1, type2)
  9586. if widest_type is PyrexTypes.c_bint_type:
  9587. if self.operator not in '|^&':
  9588. # False + False == 0 # not False!
  9589. widest_type = PyrexTypes.c_int_type
  9590. else:
  9591. widest_type = PyrexTypes.widest_numeric_type(
  9592. widest_type, PyrexTypes.c_int_type)
  9593. return widest_type
  9594. else:
  9595. return None
  9596. def may_be_none(self):
  9597. if self.type and self.type.is_builtin_type:
  9598. # if we know the result type, we know the operation, so it can't be None
  9599. return False
  9600. type1 = self.operand1.type
  9601. type2 = self.operand2.type
  9602. if type1 and type1.is_builtin_type and type2 and type2.is_builtin_type:
  9603. # XXX: I can't think of any case where a binary operation
  9604. # on builtin types evaluates to None - add a special case
  9605. # here if there is one.
  9606. return False
  9607. return super(NumBinopNode, self).may_be_none()
  9608. def get_constant_c_result_code(self):
  9609. value1 = self.operand1.get_constant_c_result_code()
  9610. value2 = self.operand2.get_constant_c_result_code()
  9611. if value1 and value2:
  9612. return "(%s %s %s)" % (value1, self.operator, value2)
  9613. else:
  9614. return None
  9615. def c_types_okay(self, type1, type2):
  9616. #print "NumBinopNode.c_types_okay:", type1, type2 ###
  9617. return (type1.is_numeric or type1.is_enum) \
  9618. and (type2.is_numeric or type2.is_enum)
  9619. def generate_evaluation_code(self, code):
  9620. if self.overflow_check:
  9621. self.overflow_bit_node = self
  9622. self.overflow_bit = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
  9623. code.putln("%s = 0;" % self.overflow_bit)
  9624. super(NumBinopNode, self).generate_evaluation_code(code)
  9625. if self.overflow_check:
  9626. code.putln("if (unlikely(%s)) {" % self.overflow_bit)
  9627. code.putln('PyErr_SetString(PyExc_OverflowError, "value too large");')
  9628. code.putln(code.error_goto(self.pos))
  9629. code.putln("}")
  9630. code.funcstate.release_temp(self.overflow_bit)
  9631. def calculate_result_code(self):
  9632. if self.overflow_bit_node is not None:
  9633. return "%s(%s, %s, &%s)" % (
  9634. self.func,
  9635. self.operand1.result(),
  9636. self.operand2.result(),
  9637. self.overflow_bit_node.overflow_bit)
  9638. elif self.type.is_cpp_class or self.infix:
  9639. if is_pythran_expr(self.type):
  9640. result1, result2 = self.operand1.pythran_result(), self.operand2.pythran_result()
  9641. else:
  9642. result1, result2 = self.operand1.result(), self.operand2.result()
  9643. return "(%s %s %s)" % (result1, self.operator, result2)
  9644. else:
  9645. func = self.type.binary_op(self.operator)
  9646. if func is None:
  9647. error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
  9648. return "%s(%s, %s)" % (
  9649. func,
  9650. self.operand1.result(),
  9651. self.operand2.result())
  9652. def is_py_operation_types(self, type1, type2):
  9653. return (type1.is_unicode_char or
  9654. type2.is_unicode_char or
  9655. BinopNode.is_py_operation_types(self, type1, type2))
  9656. def py_operation_function(self, code):
  9657. function_name = self.py_functions[self.operator]
  9658. if self.inplace:
  9659. function_name = function_name.replace('PyNumber_', 'PyNumber_InPlace')
  9660. return function_name
  9661. py_functions = {
  9662. "|": "PyNumber_Or",
  9663. "^": "PyNumber_Xor",
  9664. "&": "PyNumber_And",
  9665. "<<": "PyNumber_Lshift",
  9666. ">>": "PyNumber_Rshift",
  9667. "+": "PyNumber_Add",
  9668. "-": "PyNumber_Subtract",
  9669. "*": "PyNumber_Multiply",
  9670. "@": "__Pyx_PyNumber_MatrixMultiply",
  9671. "/": "__Pyx_PyNumber_Divide",
  9672. "//": "PyNumber_FloorDivide",
  9673. "%": "PyNumber_Remainder",
  9674. "**": "PyNumber_Power",
  9675. }
  9676. overflow_op_names = {
  9677. "+": "add",
  9678. "-": "sub",
  9679. "*": "mul",
  9680. "<<": "lshift",
  9681. }
  9682. class IntBinopNode(NumBinopNode):
  9683. # Binary operation taking integer arguments.
  9684. def c_types_okay(self, type1, type2):
  9685. #print "IntBinopNode.c_types_okay:", type1, type2 ###
  9686. return (type1.is_int or type1.is_enum) \
  9687. and (type2.is_int or type2.is_enum)
  9688. class AddNode(NumBinopNode):
  9689. # '+' operator.
  9690. def is_py_operation_types(self, type1, type2):
  9691. if type1.is_string and type2.is_string or type1.is_pyunicode_ptr and type2.is_pyunicode_ptr:
  9692. return 1
  9693. else:
  9694. return NumBinopNode.is_py_operation_types(self, type1, type2)
  9695. def infer_builtin_types_operation(self, type1, type2):
  9696. # b'abc' + 'abc' raises an exception in Py3,
  9697. # so we can safely infer the Py2 type for bytes here
  9698. string_types = (bytes_type, bytearray_type, str_type, basestring_type, unicode_type)
  9699. if type1 in string_types and type2 in string_types:
  9700. return string_types[max(string_types.index(type1),
  9701. string_types.index(type2))]
  9702. return None
  9703. def compute_c_result_type(self, type1, type2):
  9704. #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
  9705. if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
  9706. return type1
  9707. elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
  9708. return type2
  9709. else:
  9710. return NumBinopNode.compute_c_result_type(
  9711. self, type1, type2)
  9712. def py_operation_function(self, code):
  9713. is_unicode_concat = False
  9714. if isinstance(self.operand1, FormattedValueNode) or isinstance(self.operand2, FormattedValueNode):
  9715. is_unicode_concat = True
  9716. else:
  9717. type1, type2 = self.operand1.type, self.operand2.type
  9718. if type1 is unicode_type or type2 is unicode_type:
  9719. is_unicode_concat = type1.is_builtin_type and type2.is_builtin_type
  9720. if is_unicode_concat:
  9721. if self.operand1.may_be_none() or self.operand2.may_be_none():
  9722. return '__Pyx_PyUnicode_ConcatSafe'
  9723. else:
  9724. return '__Pyx_PyUnicode_Concat'
  9725. return super(AddNode, self).py_operation_function(code)
  9726. class SubNode(NumBinopNode):
  9727. # '-' operator.
  9728. def compute_c_result_type(self, type1, type2):
  9729. if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
  9730. return type1
  9731. elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
  9732. return PyrexTypes.c_ptrdiff_t_type
  9733. else:
  9734. return NumBinopNode.compute_c_result_type(
  9735. self, type1, type2)
  9736. class MulNode(NumBinopNode):
  9737. # '*' operator.
  9738. def is_py_operation_types(self, type1, type2):
  9739. if ((type1.is_string and type2.is_int) or
  9740. (type2.is_string and type1.is_int)):
  9741. return 1
  9742. else:
  9743. return NumBinopNode.is_py_operation_types(self, type1, type2)
  9744. def infer_builtin_types_operation(self, type1, type2):
  9745. # let's assume that whatever builtin type you multiply a string with
  9746. # will either return a string of the same type or fail with an exception
  9747. string_types = (bytes_type, bytearray_type, str_type, basestring_type, unicode_type)
  9748. if type1 in string_types and type2.is_builtin_type:
  9749. return type1
  9750. if type2 in string_types and type1.is_builtin_type:
  9751. return type2
  9752. # multiplication of containers/numbers with an integer value
  9753. # always (?) returns the same type
  9754. if type1.is_int:
  9755. return type2
  9756. if type2.is_int:
  9757. return type1
  9758. return None
  9759. class MatMultNode(NumBinopNode):
  9760. # '@' operator.
  9761. def is_py_operation_types(self, type1, type2):
  9762. return True
  9763. def generate_evaluation_code(self, code):
  9764. code.globalstate.use_utility_code(UtilityCode.load_cached("MatrixMultiply", "ObjectHandling.c"))
  9765. super(MatMultNode, self).generate_evaluation_code(code)
  9766. class DivNode(NumBinopNode):
  9767. # '/' or '//' operator.
  9768. cdivision = None
  9769. truedivision = None # == "unknown" if operator == '/'
  9770. ctruedivision = False
  9771. cdivision_warnings = False
  9772. zerodivision_check = None
  9773. def find_compile_time_binary_operator(self, op1, op2):
  9774. func = compile_time_binary_operators[self.operator]
  9775. if self.operator == '/' and self.truedivision is None:
  9776. # => true div for floats, floor div for integers
  9777. if isinstance(op1, _py_int_types) and isinstance(op2, _py_int_types):
  9778. func = compile_time_binary_operators['//']
  9779. return func
  9780. def calculate_constant_result(self):
  9781. op1 = self.operand1.constant_result
  9782. op2 = self.operand2.constant_result
  9783. func = self.find_compile_time_binary_operator(op1, op2)
  9784. self.constant_result = func(
  9785. self.operand1.constant_result,
  9786. self.operand2.constant_result)
  9787. def compile_time_value(self, denv):
  9788. operand1 = self.operand1.compile_time_value(denv)
  9789. operand2 = self.operand2.compile_time_value(denv)
  9790. try:
  9791. func = self.find_compile_time_binary_operator(
  9792. operand1, operand2)
  9793. return func(operand1, operand2)
  9794. except Exception as e:
  9795. self.compile_time_value_error(e)
  9796. def _check_truedivision(self, env):
  9797. if self.cdivision or env.directives['cdivision']:
  9798. self.ctruedivision = False
  9799. else:
  9800. self.ctruedivision = self.truedivision
  9801. def infer_type(self, env):
  9802. self._check_truedivision(env)
  9803. return self.result_type(
  9804. self.operand1.infer_type(env),
  9805. self.operand2.infer_type(env), env)
  9806. def analyse_operation(self, env):
  9807. self._check_truedivision(env)
  9808. NumBinopNode.analyse_operation(self, env)
  9809. if self.is_cpp_operation():
  9810. self.cdivision = True
  9811. if not self.type.is_pyobject:
  9812. self.zerodivision_check = (
  9813. self.cdivision is None and not env.directives['cdivision']
  9814. and (not self.operand2.has_constant_result() or
  9815. self.operand2.constant_result == 0))
  9816. if self.zerodivision_check or env.directives['cdivision_warnings']:
  9817. # Need to check ahead of time to warn or raise zero division error
  9818. self.operand1 = self.operand1.coerce_to_simple(env)
  9819. self.operand2 = self.operand2.coerce_to_simple(env)
  9820. def compute_c_result_type(self, type1, type2):
  9821. if self.operator == '/' and self.ctruedivision:
  9822. if not type1.is_float and not type2.is_float:
  9823. widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
  9824. widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
  9825. return widest_type
  9826. return NumBinopNode.compute_c_result_type(self, type1, type2)
  9827. def zero_division_message(self):
  9828. if self.type.is_int:
  9829. return "integer division or modulo by zero"
  9830. else:
  9831. return "float division"
  9832. def generate_evaluation_code(self, code):
  9833. if not self.type.is_pyobject and not self.type.is_complex:
  9834. if self.cdivision is None:
  9835. self.cdivision = (code.globalstate.directives['cdivision']
  9836. or not self.type.signed
  9837. or self.type.is_float)
  9838. if not self.cdivision:
  9839. code.globalstate.use_utility_code(
  9840. UtilityCode.load_cached("DivInt", "CMath.c").specialize(self.type))
  9841. NumBinopNode.generate_evaluation_code(self, code)
  9842. self.generate_div_warning_code(code)
  9843. def generate_div_warning_code(self, code):
  9844. in_nogil = self.in_nogil_context
  9845. if not self.type.is_pyobject:
  9846. if self.zerodivision_check:
  9847. if not self.infix:
  9848. zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
  9849. else:
  9850. zero_test = "%s == 0" % self.operand2.result()
  9851. code.putln("if (unlikely(%s)) {" % zero_test)
  9852. if in_nogil:
  9853. code.put_ensure_gil()
  9854. code.putln('PyErr_SetString(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
  9855. if in_nogil:
  9856. code.put_release_ensured_gil()
  9857. code.putln(code.error_goto(self.pos))
  9858. code.putln("}")
  9859. if self.type.is_int and self.type.signed and self.operator != '%':
  9860. code.globalstate.use_utility_code(UtilityCode.load_cached("UnaryNegOverflows", "Overflow.c"))
  9861. if self.operand2.type.signed == 2:
  9862. # explicitly signed, no runtime check needed
  9863. minus1_check = 'unlikely(%s == -1)' % self.operand2.result()
  9864. else:
  9865. type_of_op2 = self.operand2.type.empty_declaration_code()
  9866. minus1_check = '(!(((%s)-1) > 0)) && unlikely(%s == (%s)-1)' % (
  9867. type_of_op2, self.operand2.result(), type_of_op2)
  9868. code.putln("else if (sizeof(%s) == sizeof(long) && %s "
  9869. " && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
  9870. self.type.empty_declaration_code(),
  9871. minus1_check,
  9872. self.operand1.result()))
  9873. if in_nogil:
  9874. code.put_ensure_gil()
  9875. code.putln('PyErr_SetString(PyExc_OverflowError, "value too large to perform division");')
  9876. if in_nogil:
  9877. code.put_release_ensured_gil()
  9878. code.putln(code.error_goto(self.pos))
  9879. code.putln("}")
  9880. if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
  9881. code.globalstate.use_utility_code(
  9882. UtilityCode.load_cached("CDivisionWarning", "CMath.c"))
  9883. code.putln("if (unlikely((%s < 0) ^ (%s < 0))) {" % (
  9884. self.operand1.result(),
  9885. self.operand2.result()))
  9886. warning_code = "__Pyx_cdivision_warning(%(FILENAME)s, %(LINENO)s)" % {
  9887. 'FILENAME': Naming.filename_cname,
  9888. 'LINENO': Naming.lineno_cname,
  9889. }
  9890. if in_nogil:
  9891. result_code = 'result'
  9892. code.putln("int %s;" % result_code)
  9893. code.put_ensure_gil()
  9894. code.putln(code.set_error_info(self.pos, used=True))
  9895. code.putln("%s = %s;" % (result_code, warning_code))
  9896. code.put_release_ensured_gil()
  9897. else:
  9898. result_code = warning_code
  9899. code.putln(code.set_error_info(self.pos, used=True))
  9900. code.put("if (unlikely(%s)) " % result_code)
  9901. code.put_goto(code.error_label)
  9902. code.putln("}")
  9903. def calculate_result_code(self):
  9904. if self.type.is_complex:
  9905. return NumBinopNode.calculate_result_code(self)
  9906. elif self.type.is_float and self.operator == '//':
  9907. return "floor(%s / %s)" % (
  9908. self.operand1.result(),
  9909. self.operand2.result())
  9910. elif self.truedivision or self.cdivision:
  9911. op1 = self.operand1.result()
  9912. op2 = self.operand2.result()
  9913. if self.truedivision:
  9914. if self.type != self.operand1.type:
  9915. op1 = self.type.cast_code(op1)
  9916. if self.type != self.operand2.type:
  9917. op2 = self.type.cast_code(op2)
  9918. return "(%s / %s)" % (op1, op2)
  9919. else:
  9920. return "__Pyx_div_%s(%s, %s)" % (
  9921. self.type.specialization_name(),
  9922. self.operand1.result(),
  9923. self.operand2.result())
  9924. _find_formatting_types = re.compile(
  9925. br"%"
  9926. br"(?:%|" # %%
  9927. br"(?:\([^)]+\))?" # %(name)
  9928. br"[-+#,0-9 ]*([a-z])" # %.2f etc.
  9929. br")").findall
  9930. # These format conversion types can never trigger a Unicode string conversion in Py2.
  9931. _safe_bytes_formats = set([
  9932. # Excludes 's' and 'r', which can generate non-bytes strings.
  9933. b'd', b'i', b'o', b'u', b'x', b'X', b'e', b'E', b'f', b'F', b'g', b'G', b'c', b'b', b'a',
  9934. ])
  9935. class ModNode(DivNode):
  9936. # '%' operator.
  9937. def is_py_operation_types(self, type1, type2):
  9938. return (type1.is_string
  9939. or type2.is_string
  9940. or NumBinopNode.is_py_operation_types(self, type1, type2))
  9941. def infer_builtin_types_operation(self, type1, type2):
  9942. # b'%s' % xyz raises an exception in Py3<3.5, so it's safe to infer the type for Py2 and later Py3's.
  9943. if type1 is unicode_type:
  9944. # None + xyz may be implemented by RHS
  9945. if type2.is_builtin_type or not self.operand1.may_be_none():
  9946. return type1
  9947. elif type1 in (bytes_type, str_type, basestring_type):
  9948. if type2 is unicode_type:
  9949. return type2
  9950. elif type2.is_numeric:
  9951. return type1
  9952. elif self.operand1.is_string_literal:
  9953. if type1 is str_type or type1 is bytes_type:
  9954. if set(_find_formatting_types(self.operand1.value)) <= _safe_bytes_formats:
  9955. return type1
  9956. return basestring_type
  9957. elif type1 is bytes_type and not type2.is_builtin_type:
  9958. return None # RHS might implement '% operator differently in Py3
  9959. else:
  9960. return basestring_type # either str or unicode, can't tell
  9961. return None
  9962. def zero_division_message(self):
  9963. if self.type.is_int:
  9964. return "integer division or modulo by zero"
  9965. else:
  9966. return "float divmod()"
  9967. def analyse_operation(self, env):
  9968. DivNode.analyse_operation(self, env)
  9969. if not self.type.is_pyobject:
  9970. if self.cdivision is None:
  9971. self.cdivision = env.directives['cdivision'] or not self.type.signed
  9972. if not self.cdivision and not self.type.is_int and not self.type.is_float:
  9973. error(self.pos, "mod operator not supported for type '%s'" % self.type)
  9974. def generate_evaluation_code(self, code):
  9975. if not self.type.is_pyobject and not self.cdivision:
  9976. if self.type.is_int:
  9977. code.globalstate.use_utility_code(
  9978. UtilityCode.load_cached("ModInt", "CMath.c").specialize(self.type))
  9979. else: # float
  9980. code.globalstate.use_utility_code(
  9981. UtilityCode.load_cached("ModFloat", "CMath.c").specialize(
  9982. self.type, math_h_modifier=self.type.math_h_modifier))
  9983. # NOTE: skipping over DivNode here
  9984. NumBinopNode.generate_evaluation_code(self, code)
  9985. self.generate_div_warning_code(code)
  9986. def calculate_result_code(self):
  9987. if self.cdivision:
  9988. if self.type.is_float:
  9989. return "fmod%s(%s, %s)" % (
  9990. self.type.math_h_modifier,
  9991. self.operand1.result(),
  9992. self.operand2.result())
  9993. else:
  9994. return "(%s %% %s)" % (
  9995. self.operand1.result(),
  9996. self.operand2.result())
  9997. else:
  9998. return "__Pyx_mod_%s(%s, %s)" % (
  9999. self.type.specialization_name(),
  10000. self.operand1.result(),
  10001. self.operand2.result())
  10002. def py_operation_function(self, code):
  10003. if self.operand1.type is unicode_type:
  10004. if self.operand1.may_be_none():
  10005. return '__Pyx_PyUnicode_FormatSafe'
  10006. else:
  10007. return 'PyUnicode_Format'
  10008. elif self.operand1.type is str_type:
  10009. if self.operand1.may_be_none():
  10010. return '__Pyx_PyString_FormatSafe'
  10011. else:
  10012. return '__Pyx_PyString_Format'
  10013. return super(ModNode, self).py_operation_function(code)
  10014. class PowNode(NumBinopNode):
  10015. # '**' operator.
  10016. def analyse_c_operation(self, env):
  10017. NumBinopNode.analyse_c_operation(self, env)
  10018. if self.type.is_complex:
  10019. if self.type.real_type.is_float:
  10020. self.operand1 = self.operand1.coerce_to(self.type, env)
  10021. self.operand2 = self.operand2.coerce_to(self.type, env)
  10022. self.pow_func = self.type.binary_op('**')
  10023. else:
  10024. error(self.pos, "complex int powers not supported")
  10025. self.pow_func = "<error>"
  10026. elif self.type.is_float:
  10027. self.pow_func = "pow" + self.type.math_h_modifier
  10028. elif self.type.is_int:
  10029. self.pow_func = "__Pyx_pow_%s" % self.type.empty_declaration_code().replace(' ', '_')
  10030. env.use_utility_code(
  10031. UtilityCode.load_cached("IntPow", "CMath.c").specialize(
  10032. func_name=self.pow_func,
  10033. type=self.type.empty_declaration_code(),
  10034. signed=self.type.signed and 1 or 0))
  10035. elif not self.type.is_error:
  10036. error(self.pos, "got unexpected types for C power operator: %s, %s" %
  10037. (self.operand1.type, self.operand2.type))
  10038. def calculate_result_code(self):
  10039. # Work around MSVC overloading ambiguity.
  10040. def typecast(operand):
  10041. if self.type == operand.type:
  10042. return operand.result()
  10043. else:
  10044. return self.type.cast_code(operand.result())
  10045. return "%s(%s, %s)" % (
  10046. self.pow_func,
  10047. typecast(self.operand1),
  10048. typecast(self.operand2))
  10049. def py_operation_function(self, code):
  10050. if (self.type.is_pyobject and
  10051. self.operand1.constant_result == 2 and
  10052. isinstance(self.operand1.constant_result, _py_int_types) and
  10053. self.operand2.type is py_object_type):
  10054. code.globalstate.use_utility_code(UtilityCode.load_cached('PyNumberPow2', 'Optimize.c'))
  10055. if self.inplace:
  10056. return '__Pyx_PyNumber_InPlacePowerOf2'
  10057. else:
  10058. return '__Pyx_PyNumber_PowerOf2'
  10059. return super(PowNode, self).py_operation_function(code)
  10060. class BoolBinopNode(ExprNode):
  10061. """
  10062. Short-circuiting boolean operation.
  10063. Note that this node provides the same code generation method as
  10064. BoolBinopResultNode to simplify expression nesting.
  10065. operator string "and"/"or"
  10066. operand1 BoolBinopNode/BoolBinopResultNode left operand
  10067. operand2 BoolBinopNode/BoolBinopResultNode right operand
  10068. """
  10069. subexprs = ['operand1', 'operand2']
  10070. is_temp = True
  10071. operator = None
  10072. operand1 = None
  10073. operand2 = None
  10074. def infer_type(self, env):
  10075. type1 = self.operand1.infer_type(env)
  10076. type2 = self.operand2.infer_type(env)
  10077. return PyrexTypes.independent_spanning_type(type1, type2)
  10078. def may_be_none(self):
  10079. if self.operator == 'or':
  10080. return self.operand2.may_be_none()
  10081. else:
  10082. return self.operand1.may_be_none() or self.operand2.may_be_none()
  10083. def calculate_constant_result(self):
  10084. operand1 = self.operand1.constant_result
  10085. operand2 = self.operand2.constant_result
  10086. if self.operator == 'and':
  10087. self.constant_result = operand1 and operand2
  10088. else:
  10089. self.constant_result = operand1 or operand2
  10090. def compile_time_value(self, denv):
  10091. operand1 = self.operand1.compile_time_value(denv)
  10092. operand2 = self.operand2.compile_time_value(denv)
  10093. if self.operator == 'and':
  10094. return operand1 and operand2
  10095. else:
  10096. return operand1 or operand2
  10097. def is_ephemeral(self):
  10098. return self.operand1.is_ephemeral() or self.operand2.is_ephemeral()
  10099. def analyse_types(self, env):
  10100. # Note: we do not do any coercion here as we most likely do not know the final type anyway.
  10101. # We even accept to set self.type to ErrorType if both operands do not have a spanning type.
  10102. # The coercion to the final type and to a "simple" value is left to coerce_to().
  10103. operand1 = self.operand1.analyse_types(env)
  10104. operand2 = self.operand2.analyse_types(env)
  10105. self.type = PyrexTypes.independent_spanning_type(
  10106. operand1.type, operand2.type)
  10107. self.operand1 = self._wrap_operand(operand1, env)
  10108. self.operand2 = self._wrap_operand(operand2, env)
  10109. return self
  10110. def _wrap_operand(self, operand, env):
  10111. if not isinstance(operand, (BoolBinopNode, BoolBinopResultNode)):
  10112. operand = BoolBinopResultNode(operand, self.type, env)
  10113. return operand
  10114. def wrap_operands(self, env):
  10115. """
  10116. Must get called by transforms that want to create a correct BoolBinopNode
  10117. after the type analysis phase.
  10118. """
  10119. self.operand1 = self._wrap_operand(self.operand1, env)
  10120. self.operand2 = self._wrap_operand(self.operand2, env)
  10121. def coerce_to_boolean(self, env):
  10122. return self.coerce_to(PyrexTypes.c_bint_type, env)
  10123. def coerce_to(self, dst_type, env):
  10124. operand1 = self.operand1.coerce_to(dst_type, env)
  10125. operand2 = self.operand2.coerce_to(dst_type, env)
  10126. return BoolBinopNode.from_node(
  10127. self, type=dst_type,
  10128. operator=self.operator,
  10129. operand1=operand1, operand2=operand2)
  10130. def generate_bool_evaluation_code(self, code, final_result_temp, final_result_type, and_label, or_label, end_label, fall_through):
  10131. code.mark_pos(self.pos)
  10132. outer_labels = (and_label, or_label)
  10133. if self.operator == 'and':
  10134. my_label = and_label = code.new_label('next_and')
  10135. else:
  10136. my_label = or_label = code.new_label('next_or')
  10137. self.operand1.generate_bool_evaluation_code(
  10138. code, final_result_temp, final_result_type, and_label, or_label, end_label, my_label)
  10139. and_label, or_label = outer_labels
  10140. code.put_label(my_label)
  10141. self.operand2.generate_bool_evaluation_code(
  10142. code, final_result_temp, final_result_type, and_label, or_label, end_label, fall_through)
  10143. def generate_evaluation_code(self, code):
  10144. self.allocate_temp_result(code)
  10145. result_type = PyrexTypes.py_object_type if self.type.is_pyobject else self.type
  10146. or_label = and_label = None
  10147. end_label = code.new_label('bool_binop_done')
  10148. self.generate_bool_evaluation_code(code, self.result(), result_type, and_label, or_label, end_label, end_label)
  10149. code.put_label(end_label)
  10150. gil_message = "Truth-testing Python object"
  10151. def check_const(self):
  10152. return self.operand1.check_const() and self.operand2.check_const()
  10153. def generate_subexpr_disposal_code(self, code):
  10154. pass # nothing to do here, all done in generate_evaluation_code()
  10155. def free_subexpr_temps(self, code):
  10156. pass # nothing to do here, all done in generate_evaluation_code()
  10157. def generate_operand1_test(self, code):
  10158. # Generate code to test the truth of the first operand.
  10159. if self.type.is_pyobject:
  10160. test_result = code.funcstate.allocate_temp(
  10161. PyrexTypes.c_bint_type, manage_ref=False)
  10162. code.putln(
  10163. "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
  10164. test_result,
  10165. self.operand1.py_result(),
  10166. code.error_goto_if_neg(test_result, self.pos)))
  10167. else:
  10168. test_result = self.operand1.result()
  10169. return (test_result, self.type.is_pyobject)
  10170. class BoolBinopResultNode(ExprNode):
  10171. """
  10172. Intermediate result of a short-circuiting and/or expression.
  10173. Tests the result for 'truthiness' and takes care of coercing the final result
  10174. of the overall expression to the target type.
  10175. Note that this node provides the same code generation method as
  10176. BoolBinopNode to simplify expression nesting.
  10177. arg ExprNode the argument to test
  10178. value ExprNode the coerced result value node
  10179. """
  10180. subexprs = ['arg', 'value']
  10181. is_temp = True
  10182. arg = None
  10183. value = None
  10184. def __init__(self, arg, result_type, env):
  10185. # using 'arg' multiple times, so it must be a simple/temp value
  10186. arg = arg.coerce_to_simple(env)
  10187. # wrap in ProxyNode, in case a transform wants to replace self.arg later
  10188. arg = ProxyNode(arg)
  10189. super(BoolBinopResultNode, self).__init__(
  10190. arg.pos, arg=arg, type=result_type,
  10191. value=CloneNode(arg).coerce_to(result_type, env))
  10192. def coerce_to_boolean(self, env):
  10193. return self.coerce_to(PyrexTypes.c_bint_type, env)
  10194. def coerce_to(self, dst_type, env):
  10195. # unwrap, coerce, rewrap
  10196. arg = self.arg.arg
  10197. if dst_type is PyrexTypes.c_bint_type:
  10198. arg = arg.coerce_to_boolean(env)
  10199. # TODO: unwrap more coercion nodes?
  10200. return BoolBinopResultNode(arg, dst_type, env)
  10201. def nogil_check(self, env):
  10202. # let's leave all errors to BoolBinopNode
  10203. pass
  10204. def generate_operand_test(self, code):
  10205. # Generate code to test the truth of the first operand.
  10206. if self.arg.type.is_pyobject:
  10207. test_result = code.funcstate.allocate_temp(
  10208. PyrexTypes.c_bint_type, manage_ref=False)
  10209. code.putln(
  10210. "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
  10211. test_result,
  10212. self.arg.py_result(),
  10213. code.error_goto_if_neg(test_result, self.pos)))
  10214. else:
  10215. test_result = self.arg.result()
  10216. return (test_result, self.arg.type.is_pyobject)
  10217. def generate_bool_evaluation_code(self, code, final_result_temp, final_result_type, and_label, or_label, end_label, fall_through):
  10218. code.mark_pos(self.pos)
  10219. # x => x
  10220. # x and ... or ... => next 'and' / 'or'
  10221. # False ... or x => next 'or'
  10222. # True and x => next 'and'
  10223. # True or x => True (operand)
  10224. self.arg.generate_evaluation_code(code)
  10225. if and_label or or_label:
  10226. test_result, uses_temp = self.generate_operand_test(code)
  10227. if uses_temp and (and_label and or_label):
  10228. # cannot become final result => free early
  10229. # disposal: uses_temp and (and_label and or_label)
  10230. self.arg.generate_disposal_code(code)
  10231. sense = '!' if or_label else ''
  10232. code.putln("if (%s%s) {" % (sense, test_result))
  10233. if uses_temp:
  10234. code.funcstate.release_temp(test_result)
  10235. if not uses_temp or not (and_label and or_label):
  10236. # disposal: (not uses_temp) or {not (and_label and or_label) [if]}
  10237. self.arg.generate_disposal_code(code)
  10238. if or_label and or_label != fall_through:
  10239. # value is false => short-circuit to next 'or'
  10240. code.put_goto(or_label)
  10241. if and_label:
  10242. # value is true => go to next 'and'
  10243. if or_label:
  10244. code.putln("} else {")
  10245. if not uses_temp:
  10246. # disposal: (not uses_temp) and {(and_label and or_label) [else]}
  10247. self.arg.generate_disposal_code(code)
  10248. if and_label != fall_through:
  10249. code.put_goto(and_label)
  10250. if not and_label or not or_label:
  10251. # if no next 'and' or 'or', we provide the result
  10252. if and_label or or_label:
  10253. code.putln("} else {")
  10254. self.value.generate_evaluation_code(code)
  10255. self.value.make_owned_reference(code)
  10256. code.putln("%s = %s;" % (final_result_temp, self.value.result_as(final_result_type)))
  10257. self.value.generate_post_assignment_code(code)
  10258. # disposal: {not (and_label and or_label) [else]}
  10259. self.arg.generate_disposal_code(code)
  10260. self.value.free_temps(code)
  10261. if end_label != fall_through:
  10262. code.put_goto(end_label)
  10263. if and_label or or_label:
  10264. code.putln("}")
  10265. self.arg.free_temps(code)
  10266. class CondExprNode(ExprNode):
  10267. # Short-circuiting conditional expression.
  10268. #
  10269. # test ExprNode
  10270. # true_val ExprNode
  10271. # false_val ExprNode
  10272. true_val = None
  10273. false_val = None
  10274. subexprs = ['test', 'true_val', 'false_val']
  10275. def type_dependencies(self, env):
  10276. return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
  10277. def infer_type(self, env):
  10278. return PyrexTypes.independent_spanning_type(
  10279. self.true_val.infer_type(env),
  10280. self.false_val.infer_type(env))
  10281. def calculate_constant_result(self):
  10282. if self.test.constant_result:
  10283. self.constant_result = self.true_val.constant_result
  10284. else:
  10285. self.constant_result = self.false_val.constant_result
  10286. def is_ephemeral(self):
  10287. return self.true_val.is_ephemeral() or self.false_val.is_ephemeral()
  10288. def analyse_types(self, env):
  10289. self.test = self.test.analyse_types(env).coerce_to_boolean(env)
  10290. self.true_val = self.true_val.analyse_types(env)
  10291. self.false_val = self.false_val.analyse_types(env)
  10292. self.is_temp = 1
  10293. return self.analyse_result_type(env)
  10294. def analyse_result_type(self, env):
  10295. self.type = PyrexTypes.independent_spanning_type(
  10296. self.true_val.type, self.false_val.type)
  10297. if self.type.is_reference:
  10298. self.type = PyrexTypes.CFakeReferenceType(self.type.ref_base_type)
  10299. if self.type.is_pyobject:
  10300. self.result_ctype = py_object_type
  10301. elif self.true_val.is_ephemeral() or self.false_val.is_ephemeral():
  10302. error(self.pos, "Unsafe C derivative of temporary Python reference used in conditional expression")
  10303. if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
  10304. self.true_val = self.true_val.coerce_to(self.type, env)
  10305. self.false_val = self.false_val.coerce_to(self.type, env)
  10306. if self.type.is_error:
  10307. self.type_error()
  10308. return self
  10309. def coerce_to_integer(self, env):
  10310. self.true_val = self.true_val.coerce_to_integer(env)
  10311. self.false_val = self.false_val.coerce_to_integer(env)
  10312. self.result_ctype = None
  10313. return self.analyse_result_type(env)
  10314. def coerce_to(self, dst_type, env):
  10315. self.true_val = self.true_val.coerce_to(dst_type, env)
  10316. self.false_val = self.false_val.coerce_to(dst_type, env)
  10317. self.result_ctype = None
  10318. return self.analyse_result_type(env)
  10319. def type_error(self):
  10320. if not (self.true_val.type.is_error or self.false_val.type.is_error):
  10321. error(self.pos, "Incompatible types in conditional expression (%s; %s)" %
  10322. (self.true_val.type, self.false_val.type))
  10323. self.type = PyrexTypes.error_type
  10324. def check_const(self):
  10325. return (self.test.check_const()
  10326. and self.true_val.check_const()
  10327. and self.false_val.check_const())
  10328. def generate_evaluation_code(self, code):
  10329. # Because subexprs may not be evaluated we can use a more optimal
  10330. # subexpr allocation strategy than the default, so override evaluation_code.
  10331. code.mark_pos(self.pos)
  10332. self.allocate_temp_result(code)
  10333. self.test.generate_evaluation_code(code)
  10334. code.putln("if (%s) {" % self.test.result())
  10335. self.eval_and_get(code, self.true_val)
  10336. code.putln("} else {")
  10337. self.eval_and_get(code, self.false_val)
  10338. code.putln("}")
  10339. self.test.generate_disposal_code(code)
  10340. self.test.free_temps(code)
  10341. def eval_and_get(self, code, expr):
  10342. expr.generate_evaluation_code(code)
  10343. if self.type.is_memoryviewslice:
  10344. expr.make_owned_memoryviewslice(code)
  10345. else:
  10346. expr.make_owned_reference(code)
  10347. code.putln('%s = %s;' % (self.result(), expr.result_as(self.ctype())))
  10348. expr.generate_post_assignment_code(code)
  10349. expr.free_temps(code)
  10350. def generate_subexpr_disposal_code(self, code):
  10351. pass # done explicitly above (cleanup must separately happen within the if/else blocks)
  10352. def free_subexpr_temps(self, code):
  10353. pass # done explicitly above (cleanup must separately happen within the if/else blocks)
  10354. richcmp_constants = {
  10355. "<" : "Py_LT",
  10356. "<=": "Py_LE",
  10357. "==": "Py_EQ",
  10358. "!=": "Py_NE",
  10359. "<>": "Py_NE",
  10360. ">" : "Py_GT",
  10361. ">=": "Py_GE",
  10362. # the following are faked by special compare functions
  10363. "in" : "Py_EQ",
  10364. "not_in": "Py_NE",
  10365. }
  10366. class CmpNode(object):
  10367. # Mixin class containing code common to PrimaryCmpNodes
  10368. # and CascadedCmpNodes.
  10369. special_bool_cmp_function = None
  10370. special_bool_cmp_utility_code = None
  10371. def infer_type(self, env):
  10372. # TODO: Actually implement this (after merging with -unstable).
  10373. return py_object_type
  10374. def calculate_cascaded_constant_result(self, operand1_result):
  10375. func = compile_time_binary_operators[self.operator]
  10376. operand2_result = self.operand2.constant_result
  10377. if (isinstance(operand1_result, any_string_type) and
  10378. isinstance(operand2_result, any_string_type) and
  10379. type(operand1_result) != type(operand2_result)):
  10380. # string comparison of different types isn't portable
  10381. return
  10382. if self.operator in ('in', 'not_in'):
  10383. if isinstance(self.operand2, (ListNode, TupleNode, SetNode)):
  10384. if not self.operand2.args:
  10385. self.constant_result = self.operator == 'not_in'
  10386. return
  10387. elif isinstance(self.operand2, ListNode) and not self.cascade:
  10388. # tuples are more efficient to store than lists
  10389. self.operand2 = self.operand2.as_tuple()
  10390. elif isinstance(self.operand2, DictNode):
  10391. if not self.operand2.key_value_pairs:
  10392. self.constant_result = self.operator == 'not_in'
  10393. return
  10394. self.constant_result = func(operand1_result, operand2_result)
  10395. def cascaded_compile_time_value(self, operand1, denv):
  10396. func = get_compile_time_binop(self)
  10397. operand2 = self.operand2.compile_time_value(denv)
  10398. try:
  10399. result = func(operand1, operand2)
  10400. except Exception as e:
  10401. self.compile_time_value_error(e)
  10402. result = None
  10403. if result:
  10404. cascade = self.cascade
  10405. if cascade:
  10406. result = result and cascade.cascaded_compile_time_value(operand2, denv)
  10407. return result
  10408. def is_cpp_comparison(self):
  10409. return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
  10410. def find_common_int_type(self, env, op, operand1, operand2):
  10411. # type1 != type2 and at least one of the types is not a C int
  10412. type1 = operand1.type
  10413. type2 = operand2.type
  10414. type1_can_be_int = False
  10415. type2_can_be_int = False
  10416. if operand1.is_string_literal and operand1.can_coerce_to_char_literal():
  10417. type1_can_be_int = True
  10418. if operand2.is_string_literal and operand2.can_coerce_to_char_literal():
  10419. type2_can_be_int = True
  10420. if type1.is_int:
  10421. if type2_can_be_int:
  10422. return type1
  10423. elif type2.is_int:
  10424. if type1_can_be_int:
  10425. return type2
  10426. elif type1_can_be_int:
  10427. if type2_can_be_int:
  10428. if Builtin.unicode_type in (type1, type2):
  10429. return PyrexTypes.c_py_ucs4_type
  10430. else:
  10431. return PyrexTypes.c_uchar_type
  10432. return None
  10433. def find_common_type(self, env, op, operand1, common_type=None):
  10434. operand2 = self.operand2
  10435. type1 = operand1.type
  10436. type2 = operand2.type
  10437. new_common_type = None
  10438. # catch general errors
  10439. if (type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or
  10440. type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type))):
  10441. error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
  10442. new_common_type = error_type
  10443. # try to use numeric comparisons where possible
  10444. elif type1.is_complex or type2.is_complex:
  10445. if (op not in ('==', '!=')
  10446. and (type1.is_complex or type1.is_numeric)
  10447. and (type2.is_complex or type2.is_numeric)):
  10448. error(self.pos, "complex types are unordered")
  10449. new_common_type = error_type
  10450. elif type1.is_pyobject:
  10451. new_common_type = Builtin.complex_type if type1.subtype_of(Builtin.complex_type) else py_object_type
  10452. elif type2.is_pyobject:
  10453. new_common_type = Builtin.complex_type if type2.subtype_of(Builtin.complex_type) else py_object_type
  10454. else:
  10455. new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
  10456. elif type1.is_numeric and type2.is_numeric:
  10457. new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
  10458. elif common_type is None or not common_type.is_pyobject:
  10459. new_common_type = self.find_common_int_type(env, op, operand1, operand2)
  10460. if new_common_type is None:
  10461. # fall back to generic type compatibility tests
  10462. if type1.is_ctuple or type2.is_ctuple:
  10463. new_common_type = py_object_type
  10464. elif type1 == type2:
  10465. new_common_type = type1
  10466. elif type1.is_pyobject or type2.is_pyobject:
  10467. if type2.is_numeric or type2.is_string:
  10468. if operand2.check_for_coercion_error(type1, env):
  10469. new_common_type = error_type
  10470. else:
  10471. new_common_type = py_object_type
  10472. elif type1.is_numeric or type1.is_string:
  10473. if operand1.check_for_coercion_error(type2, env):
  10474. new_common_type = error_type
  10475. else:
  10476. new_common_type = py_object_type
  10477. elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
  10478. new_common_type = py_object_type
  10479. else:
  10480. # one Python type and one non-Python type, not assignable
  10481. self.invalid_types_error(operand1, op, operand2)
  10482. new_common_type = error_type
  10483. elif type1.assignable_from(type2):
  10484. new_common_type = type1
  10485. elif type2.assignable_from(type1):
  10486. new_common_type = type2
  10487. else:
  10488. # C types that we couldn't handle up to here are an error
  10489. self.invalid_types_error(operand1, op, operand2)
  10490. new_common_type = error_type
  10491. if new_common_type.is_string and (isinstance(operand1, BytesNode) or
  10492. isinstance(operand2, BytesNode)):
  10493. # special case when comparing char* to bytes literal: must
  10494. # compare string values!
  10495. new_common_type = bytes_type
  10496. # recursively merge types
  10497. if common_type is None or new_common_type.is_error:
  10498. common_type = new_common_type
  10499. else:
  10500. # we could do a lot better by splitting the comparison
  10501. # into a non-Python part and a Python part, but this is
  10502. # safer for now
  10503. common_type = PyrexTypes.spanning_type(common_type, new_common_type)
  10504. if self.cascade:
  10505. common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
  10506. return common_type
  10507. def invalid_types_error(self, operand1, op, operand2):
  10508. error(self.pos, "Invalid types for '%s' (%s, %s)" %
  10509. (op, operand1.type, operand2.type))
  10510. def is_python_comparison(self):
  10511. return (not self.is_ptr_contains()
  10512. and not self.is_c_string_contains()
  10513. and (self.has_python_operands()
  10514. or (self.cascade and self.cascade.is_python_comparison())
  10515. or self.operator in ('in', 'not_in')))
  10516. def coerce_operands_to(self, dst_type, env):
  10517. operand2 = self.operand2
  10518. if operand2.type != dst_type:
  10519. self.operand2 = operand2.coerce_to(dst_type, env)
  10520. if self.cascade:
  10521. self.cascade.coerce_operands_to(dst_type, env)
  10522. def is_python_result(self):
  10523. return ((self.has_python_operands() and
  10524. self.special_bool_cmp_function is None and
  10525. self.operator not in ('is', 'is_not', 'in', 'not_in') and
  10526. not self.is_c_string_contains() and
  10527. not self.is_ptr_contains())
  10528. or (self.cascade and self.cascade.is_python_result()))
  10529. def is_c_string_contains(self):
  10530. return self.operator in ('in', 'not_in') and \
  10531. ((self.operand1.type.is_int
  10532. and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
  10533. (self.operand1.type.is_unicode_char
  10534. and self.operand2.type is unicode_type))
  10535. def is_ptr_contains(self):
  10536. if self.operator in ('in', 'not_in'):
  10537. container_type = self.operand2.type
  10538. return (container_type.is_ptr or container_type.is_array) \
  10539. and not container_type.is_string
  10540. def find_special_bool_compare_function(self, env, operand1, result_is_bool=False):
  10541. # note: currently operand1 must get coerced to a Python object if we succeed here!
  10542. if self.operator in ('==', '!='):
  10543. type1, type2 = operand1.type, self.operand2.type
  10544. if result_is_bool or (type1.is_builtin_type and type2.is_builtin_type):
  10545. if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
  10546. self.special_bool_cmp_utility_code = UtilityCode.load_cached("UnicodeEquals", "StringTools.c")
  10547. self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
  10548. return True
  10549. elif type1 is Builtin.bytes_type or type2 is Builtin.bytes_type:
  10550. self.special_bool_cmp_utility_code = UtilityCode.load_cached("BytesEquals", "StringTools.c")
  10551. self.special_bool_cmp_function = "__Pyx_PyBytes_Equals"
  10552. return True
  10553. elif type1 is Builtin.basestring_type or type2 is Builtin.basestring_type:
  10554. self.special_bool_cmp_utility_code = UtilityCode.load_cached("UnicodeEquals", "StringTools.c")
  10555. self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
  10556. return True
  10557. elif type1 is Builtin.str_type or type2 is Builtin.str_type:
  10558. self.special_bool_cmp_utility_code = UtilityCode.load_cached("StrEquals", "StringTools.c")
  10559. self.special_bool_cmp_function = "__Pyx_PyString_Equals"
  10560. return True
  10561. elif self.operator in ('in', 'not_in'):
  10562. if self.operand2.type is Builtin.dict_type:
  10563. self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
  10564. self.special_bool_cmp_utility_code = UtilityCode.load_cached("PyDictContains", "ObjectHandling.c")
  10565. self.special_bool_cmp_function = "__Pyx_PyDict_ContainsTF"
  10566. return True
  10567. elif self.operand2.type is Builtin.set_type:
  10568. self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
  10569. self.special_bool_cmp_utility_code = UtilityCode.load_cached("PySetContains", "ObjectHandling.c")
  10570. self.special_bool_cmp_function = "__Pyx_PySet_ContainsTF"
  10571. return True
  10572. elif self.operand2.type is Builtin.unicode_type:
  10573. self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
  10574. self.special_bool_cmp_utility_code = UtilityCode.load_cached("PyUnicodeContains", "StringTools.c")
  10575. self.special_bool_cmp_function = "__Pyx_PyUnicode_ContainsTF"
  10576. return True
  10577. else:
  10578. if not self.operand2.type.is_pyobject:
  10579. self.operand2 = self.operand2.coerce_to_pyobject(env)
  10580. self.special_bool_cmp_utility_code = UtilityCode.load_cached("PySequenceContains", "ObjectHandling.c")
  10581. self.special_bool_cmp_function = "__Pyx_PySequence_ContainsTF"
  10582. return True
  10583. return False
  10584. def generate_operation_code(self, code, result_code,
  10585. operand1, op , operand2):
  10586. if self.type.is_pyobject:
  10587. error_clause = code.error_goto_if_null
  10588. got_ref = "__Pyx_XGOTREF(%s); " % result_code
  10589. if self.special_bool_cmp_function:
  10590. code.globalstate.use_utility_code(
  10591. UtilityCode.load_cached("PyBoolOrNullFromLong", "ObjectHandling.c"))
  10592. coerce_result = "__Pyx_PyBoolOrNull_FromLong"
  10593. else:
  10594. coerce_result = "__Pyx_PyBool_FromLong"
  10595. else:
  10596. error_clause = code.error_goto_if_neg
  10597. got_ref = ""
  10598. coerce_result = ""
  10599. if self.special_bool_cmp_function:
  10600. if operand1.type.is_pyobject:
  10601. result1 = operand1.py_result()
  10602. else:
  10603. result1 = operand1.result()
  10604. if operand2.type.is_pyobject:
  10605. result2 = operand2.py_result()
  10606. else:
  10607. result2 = operand2.result()
  10608. if self.special_bool_cmp_utility_code:
  10609. code.globalstate.use_utility_code(self.special_bool_cmp_utility_code)
  10610. code.putln(
  10611. "%s = %s(%s(%s, %s, %s)); %s%s" % (
  10612. result_code,
  10613. coerce_result,
  10614. self.special_bool_cmp_function,
  10615. result1, result2, richcmp_constants[op],
  10616. got_ref,
  10617. error_clause(result_code, self.pos)))
  10618. elif operand1.type.is_pyobject and op not in ('is', 'is_not'):
  10619. assert op not in ('in', 'not_in'), op
  10620. code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s%s" % (
  10621. result_code,
  10622. operand1.py_result(),
  10623. operand2.py_result(),
  10624. richcmp_constants[op],
  10625. got_ref,
  10626. error_clause(result_code, self.pos)))
  10627. elif operand1.type.is_complex:
  10628. code.putln("%s = %s(%s%s(%s, %s));" % (
  10629. result_code,
  10630. coerce_result,
  10631. op == "!=" and "!" or "",
  10632. operand1.type.unary_op('eq'),
  10633. operand1.result(),
  10634. operand2.result()))
  10635. else:
  10636. type1 = operand1.type
  10637. type2 = operand2.type
  10638. if (type1.is_extension_type or type2.is_extension_type) \
  10639. and not type1.same_as(type2):
  10640. common_type = py_object_type
  10641. elif type1.is_numeric:
  10642. common_type = PyrexTypes.widest_numeric_type(type1, type2)
  10643. else:
  10644. common_type = type1
  10645. code1 = operand1.result_as(common_type)
  10646. code2 = operand2.result_as(common_type)
  10647. statement = "%s = %s(%s %s %s);" % (
  10648. result_code,
  10649. coerce_result,
  10650. code1,
  10651. self.c_operator(op),
  10652. code2)
  10653. if self.is_cpp_comparison() and self.exception_check == '+':
  10654. translate_cpp_exception(code, self.pos, statement, self.exception_value, self.in_nogil_context)
  10655. code.putln(statement)
  10656. def c_operator(self, op):
  10657. if op == 'is':
  10658. return "=="
  10659. elif op == 'is_not':
  10660. return "!="
  10661. else:
  10662. return op
  10663. class PrimaryCmpNode(ExprNode, CmpNode):
  10664. # Non-cascaded comparison or first comparison of
  10665. # a cascaded sequence.
  10666. #
  10667. # operator string
  10668. # operand1 ExprNode
  10669. # operand2 ExprNode
  10670. # cascade CascadedCmpNode
  10671. # We don't use the subexprs mechanism, because
  10672. # things here are too complicated for it to handle.
  10673. # Instead, we override all the framework methods
  10674. # which use it.
  10675. child_attrs = ['operand1', 'operand2', 'coerced_operand2', 'cascade']
  10676. cascade = None
  10677. coerced_operand2 = None
  10678. is_memslice_nonecheck = False
  10679. def infer_type(self, env):
  10680. type1 = self.operand1.infer_type(env)
  10681. type2 = self.operand2.infer_type(env)
  10682. if is_pythran_expr(type1) or is_pythran_expr(type2):
  10683. if is_pythran_supported_type(type1) and is_pythran_supported_type(type2):
  10684. return PythranExpr(pythran_binop_type(self.operator, type1, type2))
  10685. # TODO: implement this for other types.
  10686. return py_object_type
  10687. def type_dependencies(self, env):
  10688. return ()
  10689. def calculate_constant_result(self):
  10690. assert not self.cascade
  10691. self.calculate_cascaded_constant_result(self.operand1.constant_result)
  10692. def compile_time_value(self, denv):
  10693. operand1 = self.operand1.compile_time_value(denv)
  10694. return self.cascaded_compile_time_value(operand1, denv)
  10695. def analyse_types(self, env):
  10696. self.operand1 = self.operand1.analyse_types(env)
  10697. self.operand2 = self.operand2.analyse_types(env)
  10698. if self.is_cpp_comparison():
  10699. self.analyse_cpp_comparison(env)
  10700. if self.cascade:
  10701. error(self.pos, "Cascading comparison not yet supported for cpp types.")
  10702. return self
  10703. type1 = self.operand1.type
  10704. type2 = self.operand2.type
  10705. if is_pythran_expr(type1) or is_pythran_expr(type2):
  10706. if is_pythran_supported_type(type1) and is_pythran_supported_type(type2):
  10707. self.type = PythranExpr(pythran_binop_type(self.operator, type1, type2))
  10708. self.is_pycmp = False
  10709. return self
  10710. if self.analyse_memoryviewslice_comparison(env):
  10711. return self
  10712. if self.cascade:
  10713. self.cascade = self.cascade.analyse_types(env)
  10714. if self.operator in ('in', 'not_in'):
  10715. if self.is_c_string_contains():
  10716. self.is_pycmp = False
  10717. common_type = None
  10718. if self.cascade:
  10719. error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
  10720. return self
  10721. if self.operand2.type is unicode_type:
  10722. env.use_utility_code(UtilityCode.load_cached("PyUCS4InUnicode", "StringTools.c"))
  10723. else:
  10724. if self.operand1.type is PyrexTypes.c_uchar_type:
  10725. self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
  10726. if self.operand2.type is not bytes_type:
  10727. self.operand2 = self.operand2.coerce_to(bytes_type, env)
  10728. env.use_utility_code(UtilityCode.load_cached("BytesContains", "StringTools.c"))
  10729. self.operand2 = self.operand2.as_none_safe_node(
  10730. "argument of type 'NoneType' is not iterable")
  10731. elif self.is_ptr_contains():
  10732. if self.cascade:
  10733. error(self.pos, "Cascading comparison not supported for 'val in sliced pointer'.")
  10734. self.type = PyrexTypes.c_bint_type
  10735. # Will be transformed by IterationTransform
  10736. return self
  10737. elif self.find_special_bool_compare_function(env, self.operand1):
  10738. if not self.operand1.type.is_pyobject:
  10739. self.operand1 = self.operand1.coerce_to_pyobject(env)
  10740. common_type = None # if coercion needed, the method call above has already done it
  10741. self.is_pycmp = False # result is bint
  10742. else:
  10743. common_type = py_object_type
  10744. self.is_pycmp = True
  10745. elif self.find_special_bool_compare_function(env, self.operand1):
  10746. if not self.operand1.type.is_pyobject:
  10747. self.operand1 = self.operand1.coerce_to_pyobject(env)
  10748. common_type = None # if coercion needed, the method call above has already done it
  10749. self.is_pycmp = False # result is bint
  10750. else:
  10751. common_type = self.find_common_type(env, self.operator, self.operand1)
  10752. self.is_pycmp = common_type.is_pyobject
  10753. if common_type is not None and not common_type.is_error:
  10754. if self.operand1.type != common_type:
  10755. self.operand1 = self.operand1.coerce_to(common_type, env)
  10756. self.coerce_operands_to(common_type, env)
  10757. if self.cascade:
  10758. self.operand2 = self.operand2.coerce_to_simple(env)
  10759. self.cascade.coerce_cascaded_operands_to_temp(env)
  10760. operand2 = self.cascade.optimise_comparison(self.operand2, env)
  10761. if operand2 is not self.operand2:
  10762. self.coerced_operand2 = operand2
  10763. if self.is_python_result():
  10764. self.type = PyrexTypes.py_object_type
  10765. else:
  10766. self.type = PyrexTypes.c_bint_type
  10767. cdr = self.cascade
  10768. while cdr:
  10769. cdr.type = self.type
  10770. cdr = cdr.cascade
  10771. if self.is_pycmp or self.cascade or self.special_bool_cmp_function:
  10772. # 1) owned reference, 2) reused value, 3) potential function error return value
  10773. self.is_temp = 1
  10774. return self
  10775. def analyse_cpp_comparison(self, env):
  10776. type1 = self.operand1.type
  10777. type2 = self.operand2.type
  10778. self.is_pycmp = False
  10779. entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
  10780. if entry is None:
  10781. error(self.pos, "Invalid types for '%s' (%s, %s)" %
  10782. (self.operator, type1, type2))
  10783. self.type = PyrexTypes.error_type
  10784. self.result_code = "<error>"
  10785. return
  10786. func_type = entry.type
  10787. if func_type.is_ptr:
  10788. func_type = func_type.base_type
  10789. self.exception_check = func_type.exception_check
  10790. self.exception_value = func_type.exception_value
  10791. if self.exception_check == '+':
  10792. self.is_temp = True
  10793. if self.exception_value is None:
  10794. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  10795. if len(func_type.args) == 1:
  10796. self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
  10797. else:
  10798. self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
  10799. self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
  10800. self.type = func_type.return_type
  10801. def analyse_memoryviewslice_comparison(self, env):
  10802. have_none = self.operand1.is_none or self.operand2.is_none
  10803. have_slice = (self.operand1.type.is_memoryviewslice or
  10804. self.operand2.type.is_memoryviewslice)
  10805. ops = ('==', '!=', 'is', 'is_not')
  10806. if have_slice and have_none and self.operator in ops:
  10807. self.is_pycmp = False
  10808. self.type = PyrexTypes.c_bint_type
  10809. self.is_memslice_nonecheck = True
  10810. return True
  10811. return False
  10812. def coerce_to_boolean(self, env):
  10813. if self.is_pycmp:
  10814. # coercing to bool => may allow for more efficient comparison code
  10815. if self.find_special_bool_compare_function(
  10816. env, self.operand1, result_is_bool=True):
  10817. self.is_pycmp = False
  10818. self.type = PyrexTypes.c_bint_type
  10819. self.is_temp = 1
  10820. if self.cascade:
  10821. operand2 = self.cascade.optimise_comparison(
  10822. self.operand2, env, result_is_bool=True)
  10823. if operand2 is not self.operand2:
  10824. self.coerced_operand2 = operand2
  10825. return self
  10826. # TODO: check if we can optimise parts of the cascade here
  10827. return ExprNode.coerce_to_boolean(self, env)
  10828. def has_python_operands(self):
  10829. return (self.operand1.type.is_pyobject
  10830. or self.operand2.type.is_pyobject)
  10831. def check_const(self):
  10832. if self.cascade:
  10833. self.not_const()
  10834. return False
  10835. else:
  10836. return self.operand1.check_const() and self.operand2.check_const()
  10837. def calculate_result_code(self):
  10838. operand1, operand2 = self.operand1, self.operand2
  10839. if operand1.type.is_complex:
  10840. if self.operator == "!=":
  10841. negation = "!"
  10842. else:
  10843. negation = ""
  10844. return "(%s%s(%s, %s))" % (
  10845. negation,
  10846. operand1.type.binary_op('=='),
  10847. operand1.result(),
  10848. operand2.result())
  10849. elif self.is_c_string_contains():
  10850. if operand2.type is unicode_type:
  10851. method = "__Pyx_UnicodeContainsUCS4"
  10852. else:
  10853. method = "__Pyx_BytesContains"
  10854. if self.operator == "not_in":
  10855. negation = "!"
  10856. else:
  10857. negation = ""
  10858. return "(%s%s(%s, %s))" % (
  10859. negation,
  10860. method,
  10861. operand2.result(),
  10862. operand1.result())
  10863. else:
  10864. if is_pythran_expr(self.type):
  10865. result1, result2 = operand1.pythran_result(), operand2.pythran_result()
  10866. else:
  10867. result1, result2 = operand1.result(), operand2.result()
  10868. if self.is_memslice_nonecheck:
  10869. if operand1.type.is_memoryviewslice:
  10870. result1 = "((PyObject *) %s.memview)" % result1
  10871. else:
  10872. result2 = "((PyObject *) %s.memview)" % result2
  10873. return "(%s %s %s)" % (
  10874. result1,
  10875. self.c_operator(self.operator),
  10876. result2)
  10877. def generate_evaluation_code(self, code):
  10878. self.operand1.generate_evaluation_code(code)
  10879. self.operand2.generate_evaluation_code(code)
  10880. if self.is_temp:
  10881. self.allocate_temp_result(code)
  10882. self.generate_operation_code(code, self.result(),
  10883. self.operand1, self.operator, self.operand2)
  10884. if self.cascade:
  10885. self.cascade.generate_evaluation_code(
  10886. code, self.result(), self.coerced_operand2 or self.operand2,
  10887. needs_evaluation=self.coerced_operand2 is not None)
  10888. self.operand1.generate_disposal_code(code)
  10889. self.operand1.free_temps(code)
  10890. self.operand2.generate_disposal_code(code)
  10891. self.operand2.free_temps(code)
  10892. def generate_subexpr_disposal_code(self, code):
  10893. # If this is called, it is a non-cascaded cmp,
  10894. # so only need to dispose of the two main operands.
  10895. self.operand1.generate_disposal_code(code)
  10896. self.operand2.generate_disposal_code(code)
  10897. def free_subexpr_temps(self, code):
  10898. # If this is called, it is a non-cascaded cmp,
  10899. # so only need to dispose of the two main operands.
  10900. self.operand1.free_temps(code)
  10901. self.operand2.free_temps(code)
  10902. def annotate(self, code):
  10903. self.operand1.annotate(code)
  10904. self.operand2.annotate(code)
  10905. if self.cascade:
  10906. self.cascade.annotate(code)
  10907. class CascadedCmpNode(Node, CmpNode):
  10908. # A CascadedCmpNode is not a complete expression node. It
  10909. # hangs off the side of another comparison node, shares
  10910. # its left operand with that node, and shares its result
  10911. # with the PrimaryCmpNode at the head of the chain.
  10912. #
  10913. # operator string
  10914. # operand2 ExprNode
  10915. # cascade CascadedCmpNode
  10916. child_attrs = ['operand2', 'coerced_operand2', 'cascade']
  10917. cascade = None
  10918. coerced_operand2 = None
  10919. constant_result = constant_value_not_set # FIXME: where to calculate this?
  10920. def infer_type(self, env):
  10921. # TODO: Actually implement this (after merging with -unstable).
  10922. return py_object_type
  10923. def type_dependencies(self, env):
  10924. return ()
  10925. def has_constant_result(self):
  10926. return self.constant_result is not constant_value_not_set and \
  10927. self.constant_result is not not_a_constant
  10928. def analyse_types(self, env):
  10929. self.operand2 = self.operand2.analyse_types(env)
  10930. if self.cascade:
  10931. self.cascade = self.cascade.analyse_types(env)
  10932. return self
  10933. def has_python_operands(self):
  10934. return self.operand2.type.is_pyobject
  10935. def is_cpp_comparison(self):
  10936. # cascaded comparisons aren't currently implemented for c++ classes.
  10937. return False
  10938. def optimise_comparison(self, operand1, env, result_is_bool=False):
  10939. if self.find_special_bool_compare_function(env, operand1, result_is_bool):
  10940. self.is_pycmp = False
  10941. self.type = PyrexTypes.c_bint_type
  10942. if not operand1.type.is_pyobject:
  10943. operand1 = operand1.coerce_to_pyobject(env)
  10944. if self.cascade:
  10945. operand2 = self.cascade.optimise_comparison(self.operand2, env, result_is_bool)
  10946. if operand2 is not self.operand2:
  10947. self.coerced_operand2 = operand2
  10948. return operand1
  10949. def coerce_operands_to_pyobjects(self, env):
  10950. self.operand2 = self.operand2.coerce_to_pyobject(env)
  10951. if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
  10952. self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
  10953. if self.cascade:
  10954. self.cascade.coerce_operands_to_pyobjects(env)
  10955. def coerce_cascaded_operands_to_temp(self, env):
  10956. if self.cascade:
  10957. #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
  10958. self.operand2 = self.operand2.coerce_to_simple(env)
  10959. self.cascade.coerce_cascaded_operands_to_temp(env)
  10960. def generate_evaluation_code(self, code, result, operand1, needs_evaluation=False):
  10961. if self.type.is_pyobject:
  10962. code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
  10963. code.put_decref(result, self.type)
  10964. else:
  10965. code.putln("if (%s) {" % result)
  10966. if needs_evaluation:
  10967. operand1.generate_evaluation_code(code)
  10968. self.operand2.generate_evaluation_code(code)
  10969. self.generate_operation_code(code, result,
  10970. operand1, self.operator, self.operand2)
  10971. if self.cascade:
  10972. self.cascade.generate_evaluation_code(
  10973. code, result, self.coerced_operand2 or self.operand2,
  10974. needs_evaluation=self.coerced_operand2 is not None)
  10975. if needs_evaluation:
  10976. operand1.generate_disposal_code(code)
  10977. operand1.free_temps(code)
  10978. # Cascaded cmp result is always temp
  10979. self.operand2.generate_disposal_code(code)
  10980. self.operand2.free_temps(code)
  10981. code.putln("}")
  10982. def annotate(self, code):
  10983. self.operand2.annotate(code)
  10984. if self.cascade:
  10985. self.cascade.annotate(code)
  10986. binop_node_classes = {
  10987. "or": BoolBinopNode,
  10988. "and": BoolBinopNode,
  10989. "|": IntBinopNode,
  10990. "^": IntBinopNode,
  10991. "&": IntBinopNode,
  10992. "<<": IntBinopNode,
  10993. ">>": IntBinopNode,
  10994. "+": AddNode,
  10995. "-": SubNode,
  10996. "*": MulNode,
  10997. "@": MatMultNode,
  10998. "/": DivNode,
  10999. "//": DivNode,
  11000. "%": ModNode,
  11001. "**": PowNode,
  11002. }
  11003. def binop_node(pos, operator, operand1, operand2, inplace=False, **kwargs):
  11004. # Construct binop node of appropriate class for
  11005. # given operator.
  11006. return binop_node_classes[operator](
  11007. pos,
  11008. operator=operator,
  11009. operand1=operand1,
  11010. operand2=operand2,
  11011. inplace=inplace,
  11012. **kwargs)
  11013. #-------------------------------------------------------------------
  11014. #
  11015. # Coercion nodes
  11016. #
  11017. # Coercion nodes are special in that they are created during
  11018. # the analyse_types phase of parse tree processing.
  11019. # Their __init__ methods consequently incorporate some aspects
  11020. # of that phase.
  11021. #
  11022. #-------------------------------------------------------------------
  11023. class CoercionNode(ExprNode):
  11024. # Abstract base class for coercion nodes.
  11025. #
  11026. # arg ExprNode node being coerced
  11027. subexprs = ['arg']
  11028. constant_result = not_a_constant
  11029. def __init__(self, arg):
  11030. super(CoercionNode, self).__init__(arg.pos)
  11031. self.arg = arg
  11032. if debug_coercion:
  11033. print("%s Coercing %s" % (self, self.arg))
  11034. def calculate_constant_result(self):
  11035. # constant folding can break type coercion, so this is disabled
  11036. pass
  11037. def annotate(self, code):
  11038. self.arg.annotate(code)
  11039. if self.arg.type != self.type:
  11040. file, line, col = self.pos
  11041. code.annotate((file, line, col-1), AnnotationItem(
  11042. style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
  11043. class CoerceToMemViewSliceNode(CoercionNode):
  11044. """
  11045. Coerce an object to a memoryview slice. This holds a new reference in
  11046. a managed temp.
  11047. """
  11048. def __init__(self, arg, dst_type, env):
  11049. assert dst_type.is_memoryviewslice
  11050. assert not arg.type.is_memoryviewslice
  11051. CoercionNode.__init__(self, arg)
  11052. self.type = dst_type
  11053. self.is_temp = 1
  11054. self.env = env
  11055. self.use_managed_ref = True
  11056. self.arg = arg
  11057. def generate_result_code(self, code):
  11058. self.type.create_from_py_utility_code(self.env)
  11059. code.putln(self.type.from_py_call_code(
  11060. self.arg.py_result(),
  11061. self.result(),
  11062. self.pos,
  11063. code
  11064. ))
  11065. class CastNode(CoercionNode):
  11066. # Wrap a node in a C type cast.
  11067. def __init__(self, arg, new_type):
  11068. CoercionNode.__init__(self, arg)
  11069. self.type = new_type
  11070. def may_be_none(self):
  11071. return self.arg.may_be_none()
  11072. def calculate_result_code(self):
  11073. return self.arg.result_as(self.type)
  11074. def generate_result_code(self, code):
  11075. self.arg.generate_result_code(code)
  11076. class PyTypeTestNode(CoercionNode):
  11077. # This node is used to check that a generic Python
  11078. # object is an instance of a particular extension type.
  11079. # This node borrows the result of its argument node.
  11080. exact_builtin_type = True
  11081. def __init__(self, arg, dst_type, env, notnone=False):
  11082. # The arg is know to be a Python object, and
  11083. # the dst_type is known to be an extension type.
  11084. assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
  11085. CoercionNode.__init__(self, arg)
  11086. self.type = dst_type
  11087. self.result_ctype = arg.ctype()
  11088. self.notnone = notnone
  11089. nogil_check = Node.gil_error
  11090. gil_message = "Python type test"
  11091. def analyse_types(self, env):
  11092. return self
  11093. def may_be_none(self):
  11094. if self.notnone:
  11095. return False
  11096. return self.arg.may_be_none()
  11097. def is_simple(self):
  11098. return self.arg.is_simple()
  11099. def result_in_temp(self):
  11100. return self.arg.result_in_temp()
  11101. def is_ephemeral(self):
  11102. return self.arg.is_ephemeral()
  11103. def nonlocally_immutable(self):
  11104. return self.arg.nonlocally_immutable()
  11105. def reanalyse(self):
  11106. if self.type != self.arg.type or not self.arg.is_temp:
  11107. return self
  11108. if not self.type.typeobj_is_available():
  11109. return self
  11110. if self.arg.may_be_none() and self.notnone:
  11111. return self.arg.as_none_safe_node("Cannot convert NoneType to %.200s" % self.type.name)
  11112. return self.arg
  11113. def calculate_constant_result(self):
  11114. # FIXME
  11115. pass
  11116. def calculate_result_code(self):
  11117. return self.arg.result()
  11118. def generate_result_code(self, code):
  11119. if self.type.typeobj_is_available():
  11120. if self.type.is_builtin_type:
  11121. type_test = self.type.type_test_code(
  11122. self.arg.py_result(),
  11123. self.notnone, exact=self.exact_builtin_type)
  11124. else:
  11125. type_test = self.type.type_test_code(
  11126. self.arg.py_result(), self.notnone)
  11127. code.globalstate.use_utility_code(
  11128. UtilityCode.load_cached("ExtTypeTest", "ObjectHandling.c"))
  11129. code.putln("if (!(%s)) %s" % (
  11130. type_test, code.error_goto(self.pos)))
  11131. else:
  11132. error(self.pos, "Cannot test type of extern C class "
  11133. "without type object name specification")
  11134. def generate_post_assignment_code(self, code):
  11135. self.arg.generate_post_assignment_code(code)
  11136. def free_temps(self, code):
  11137. self.arg.free_temps(code)
  11138. class NoneCheckNode(CoercionNode):
  11139. # This node is used to check that a Python object is not None and
  11140. # raises an appropriate exception (as specified by the creating
  11141. # transform).
  11142. is_nonecheck = True
  11143. def __init__(self, arg, exception_type_cname, exception_message,
  11144. exception_format_args=()):
  11145. CoercionNode.__init__(self, arg)
  11146. self.type = arg.type
  11147. self.result_ctype = arg.ctype()
  11148. self.exception_type_cname = exception_type_cname
  11149. self.exception_message = exception_message
  11150. self.exception_format_args = tuple(exception_format_args or ())
  11151. nogil_check = None # this node only guards an operation that would fail already
  11152. def analyse_types(self, env):
  11153. return self
  11154. def may_be_none(self):
  11155. return False
  11156. def is_simple(self):
  11157. return self.arg.is_simple()
  11158. def result_in_temp(self):
  11159. return self.arg.result_in_temp()
  11160. def nonlocally_immutable(self):
  11161. return self.arg.nonlocally_immutable()
  11162. def calculate_result_code(self):
  11163. return self.arg.result()
  11164. def condition(self):
  11165. if self.type.is_pyobject:
  11166. return self.arg.py_result()
  11167. elif self.type.is_memoryviewslice:
  11168. return "((PyObject *) %s.memview)" % self.arg.result()
  11169. else:
  11170. raise Exception("unsupported type")
  11171. @classmethod
  11172. def generate(cls, arg, code, exception_message,
  11173. exception_type_cname="PyExc_TypeError", exception_format_args=(), in_nogil_context=False):
  11174. node = cls(arg, exception_type_cname, exception_message, exception_format_args)
  11175. node.in_nogil_context = in_nogil_context
  11176. node.put_nonecheck(code)
  11177. @classmethod
  11178. def generate_if_needed(cls, arg, code, exception_message,
  11179. exception_type_cname="PyExc_TypeError", exception_format_args=(), in_nogil_context=False):
  11180. if arg.may_be_none():
  11181. cls.generate(arg, code, exception_message, exception_type_cname, exception_format_args, in_nogil_context)
  11182. def put_nonecheck(self, code):
  11183. code.putln(
  11184. "if (unlikely(%s == Py_None)) {" % self.condition())
  11185. if self.in_nogil_context:
  11186. code.put_ensure_gil()
  11187. escape = StringEncoding.escape_byte_string
  11188. if self.exception_format_args:
  11189. code.putln('PyErr_Format(%s, "%s", %s);' % (
  11190. self.exception_type_cname,
  11191. StringEncoding.escape_byte_string(
  11192. self.exception_message.encode('UTF-8')),
  11193. ', '.join([ '"%s"' % escape(str(arg).encode('UTF-8'))
  11194. for arg in self.exception_format_args ])))
  11195. else:
  11196. code.putln('PyErr_SetString(%s, "%s");' % (
  11197. self.exception_type_cname,
  11198. escape(self.exception_message.encode('UTF-8'))))
  11199. if self.in_nogil_context:
  11200. code.put_release_ensured_gil()
  11201. code.putln(code.error_goto(self.pos))
  11202. code.putln("}")
  11203. def generate_result_code(self, code):
  11204. self.put_nonecheck(code)
  11205. def generate_post_assignment_code(self, code):
  11206. self.arg.generate_post_assignment_code(code)
  11207. def free_temps(self, code):
  11208. self.arg.free_temps(code)
  11209. class CoerceToPyTypeNode(CoercionNode):
  11210. # This node is used to convert a C data type
  11211. # to a Python object.
  11212. type = py_object_type
  11213. target_type = py_object_type
  11214. is_temp = 1
  11215. def __init__(self, arg, env, type=py_object_type):
  11216. if not arg.type.create_to_py_utility_code(env):
  11217. error(arg.pos, "Cannot convert '%s' to Python object" % arg.type)
  11218. elif arg.type.is_complex:
  11219. # special case: complex coercion is so complex that it
  11220. # uses a macro ("__pyx_PyComplex_FromComplex()"), for
  11221. # which the argument must be simple
  11222. arg = arg.coerce_to_simple(env)
  11223. CoercionNode.__init__(self, arg)
  11224. if type is py_object_type:
  11225. # be specific about some known types
  11226. if arg.type.is_string or arg.type.is_cpp_string:
  11227. self.type = default_str_type(env)
  11228. elif arg.type.is_pyunicode_ptr or arg.type.is_unicode_char:
  11229. self.type = unicode_type
  11230. elif arg.type.is_complex:
  11231. self.type = Builtin.complex_type
  11232. self.target_type = self.type
  11233. elif arg.type.is_string or arg.type.is_cpp_string:
  11234. if (type not in (bytes_type, bytearray_type)
  11235. and not env.directives['c_string_encoding']):
  11236. error(arg.pos,
  11237. "default encoding required for conversion from '%s' to '%s'" %
  11238. (arg.type, type))
  11239. self.type = self.target_type = type
  11240. else:
  11241. # FIXME: check that the target type and the resulting type are compatible
  11242. self.target_type = type
  11243. gil_message = "Converting to Python object"
  11244. def may_be_none(self):
  11245. # FIXME: is this always safe?
  11246. return False
  11247. def coerce_to_boolean(self, env):
  11248. arg_type = self.arg.type
  11249. if (arg_type == PyrexTypes.c_bint_type or
  11250. (arg_type.is_pyobject and arg_type.name == 'bool')):
  11251. return self.arg.coerce_to_temp(env)
  11252. else:
  11253. return CoerceToBooleanNode(self, env)
  11254. def coerce_to_integer(self, env):
  11255. # If not already some C integer type, coerce to longint.
  11256. if self.arg.type.is_int:
  11257. return self.arg
  11258. else:
  11259. return self.arg.coerce_to(PyrexTypes.c_long_type, env)
  11260. def analyse_types(self, env):
  11261. # The arg is always already analysed
  11262. return self
  11263. def generate_result_code(self, code):
  11264. code.putln('%s; %s' % (
  11265. self.arg.type.to_py_call_code(
  11266. self.arg.result(),
  11267. self.result(),
  11268. self.target_type),
  11269. code.error_goto_if_null(self.result(), self.pos)))
  11270. code.put_gotref(self.py_result())
  11271. class CoerceIntToBytesNode(CoerceToPyTypeNode):
  11272. # This node is used to convert a C int type to a Python bytes
  11273. # object.
  11274. is_temp = 1
  11275. def __init__(self, arg, env):
  11276. arg = arg.coerce_to_simple(env)
  11277. CoercionNode.__init__(self, arg)
  11278. self.type = Builtin.bytes_type
  11279. def generate_result_code(self, code):
  11280. arg = self.arg
  11281. arg_result = arg.result()
  11282. if arg.type not in (PyrexTypes.c_char_type,
  11283. PyrexTypes.c_uchar_type,
  11284. PyrexTypes.c_schar_type):
  11285. if arg.type.signed:
  11286. code.putln("if ((%s < 0) || (%s > 255)) {" % (
  11287. arg_result, arg_result))
  11288. else:
  11289. code.putln("if (%s > 255) {" % arg_result)
  11290. code.putln('PyErr_SetString(PyExc_OverflowError, '
  11291. '"value too large to pack into a byte"); %s' % (
  11292. code.error_goto(self.pos)))
  11293. code.putln('}')
  11294. temp = None
  11295. if arg.type is not PyrexTypes.c_char_type:
  11296. temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
  11297. code.putln("%s = (char)%s;" % (temp, arg_result))
  11298. arg_result = temp
  11299. code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
  11300. self.result(),
  11301. arg_result,
  11302. code.error_goto_if_null(self.result(), self.pos)))
  11303. if temp is not None:
  11304. code.funcstate.release_temp(temp)
  11305. code.put_gotref(self.py_result())
  11306. class CoerceFromPyTypeNode(CoercionNode):
  11307. # This node is used to convert a Python object
  11308. # to a C data type.
  11309. def __init__(self, result_type, arg, env):
  11310. CoercionNode.__init__(self, arg)
  11311. self.type = result_type
  11312. self.is_temp = 1
  11313. if not result_type.create_from_py_utility_code(env):
  11314. error(arg.pos,
  11315. "Cannot convert Python object to '%s'" % result_type)
  11316. if self.type.is_string or self.type.is_pyunicode_ptr:
  11317. if self.arg.is_name and self.arg.entry and self.arg.entry.is_pyglobal:
  11318. warning(arg.pos,
  11319. "Obtaining '%s' from externally modifiable global Python value" % result_type,
  11320. level=1)
  11321. def analyse_types(self, env):
  11322. # The arg is always already analysed
  11323. return self
  11324. def is_ephemeral(self):
  11325. return (self.type.is_ptr and not self.type.is_array) and self.arg.is_ephemeral()
  11326. def generate_result_code(self, code):
  11327. from_py_function = None
  11328. # for certain source types, we can do better than the generic coercion
  11329. if self.type.is_string and self.arg.type is bytes_type:
  11330. if self.type.from_py_function.startswith('__Pyx_PyObject_As'):
  11331. from_py_function = '__Pyx_PyBytes' + self.type.from_py_function[len('__Pyx_PyObject'):]
  11332. NoneCheckNode.generate_if_needed(self.arg, code, "expected bytes, NoneType found")
  11333. code.putln(self.type.from_py_call_code(
  11334. self.arg.py_result(), self.result(), self.pos, code, from_py_function=from_py_function))
  11335. if self.type.is_pyobject:
  11336. code.put_gotref(self.py_result())
  11337. def nogil_check(self, env):
  11338. error(self.pos, "Coercion from Python not allowed without the GIL")
  11339. class CoerceToBooleanNode(CoercionNode):
  11340. # This node is used when a result needs to be used
  11341. # in a boolean context.
  11342. type = PyrexTypes.c_bint_type
  11343. _special_builtins = {
  11344. Builtin.list_type: 'PyList_GET_SIZE',
  11345. Builtin.tuple_type: 'PyTuple_GET_SIZE',
  11346. Builtin.set_type: 'PySet_GET_SIZE',
  11347. Builtin.frozenset_type: 'PySet_GET_SIZE',
  11348. Builtin.bytes_type: 'PyBytes_GET_SIZE',
  11349. Builtin.bytearray_type: 'PyByteArray_GET_SIZE',
  11350. Builtin.unicode_type: '__Pyx_PyUnicode_IS_TRUE',
  11351. }
  11352. def __init__(self, arg, env):
  11353. CoercionNode.__init__(self, arg)
  11354. if arg.type.is_pyobject:
  11355. self.is_temp = 1
  11356. def nogil_check(self, env):
  11357. if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
  11358. self.gil_error()
  11359. gil_message = "Truth-testing Python object"
  11360. def check_const(self):
  11361. if self.is_temp:
  11362. self.not_const()
  11363. return False
  11364. return self.arg.check_const()
  11365. def calculate_result_code(self):
  11366. return "(%s != 0)" % self.arg.result()
  11367. def generate_result_code(self, code):
  11368. if not self.is_temp:
  11369. return
  11370. test_func = self._special_builtins.get(self.arg.type)
  11371. if test_func is not None:
  11372. checks = ["(%s != Py_None)" % self.arg.py_result()] if self.arg.may_be_none() else []
  11373. checks.append("(%s(%s) != 0)" % (test_func, self.arg.py_result()))
  11374. code.putln("%s = %s;" % (self.result(), '&&'.join(checks)))
  11375. else:
  11376. code.putln(
  11377. "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
  11378. self.result(),
  11379. self.arg.py_result(),
  11380. code.error_goto_if_neg(self.result(), self.pos)))
  11381. class CoerceToComplexNode(CoercionNode):
  11382. def __init__(self, arg, dst_type, env):
  11383. if arg.type.is_complex:
  11384. arg = arg.coerce_to_simple(env)
  11385. self.type = dst_type
  11386. CoercionNode.__init__(self, arg)
  11387. dst_type.create_declaration_utility_code(env)
  11388. def calculate_result_code(self):
  11389. if self.arg.type.is_complex:
  11390. real_part = "__Pyx_CREAL(%s)" % self.arg.result()
  11391. imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
  11392. else:
  11393. real_part = self.arg.result()
  11394. imag_part = "0"
  11395. return "%s(%s, %s)" % (
  11396. self.type.from_parts,
  11397. real_part,
  11398. imag_part)
  11399. def generate_result_code(self, code):
  11400. pass
  11401. class CoerceToTempNode(CoercionNode):
  11402. # This node is used to force the result of another node
  11403. # to be stored in a temporary. It is only used if the
  11404. # argument node's result is not already in a temporary.
  11405. def __init__(self, arg, env):
  11406. CoercionNode.__init__(self, arg)
  11407. self.type = self.arg.type.as_argument_type()
  11408. self.constant_result = self.arg.constant_result
  11409. self.is_temp = 1
  11410. if self.type.is_pyobject:
  11411. self.result_ctype = py_object_type
  11412. gil_message = "Creating temporary Python reference"
  11413. def analyse_types(self, env):
  11414. # The arg is always already analysed
  11415. return self
  11416. def coerce_to_boolean(self, env):
  11417. self.arg = self.arg.coerce_to_boolean(env)
  11418. if self.arg.is_simple():
  11419. return self.arg
  11420. self.type = self.arg.type
  11421. self.result_ctype = self.type
  11422. return self
  11423. def generate_result_code(self, code):
  11424. #self.arg.generate_evaluation_code(code) # Already done
  11425. # by generic generate_subexpr_evaluation_code!
  11426. code.putln("%s = %s;" % (
  11427. self.result(), self.arg.result_as(self.ctype())))
  11428. if self.use_managed_ref:
  11429. if self.type.is_pyobject:
  11430. code.put_incref(self.result(), self.ctype())
  11431. elif self.type.is_memoryviewslice:
  11432. code.put_incref_memoryviewslice(self.result(),
  11433. not self.in_nogil_context)
  11434. class ProxyNode(CoercionNode):
  11435. """
  11436. A node that should not be replaced by transforms or other means,
  11437. and hence can be useful to wrap the argument to a clone node
  11438. MyNode -> ProxyNode -> ArgNode
  11439. CloneNode -^
  11440. """
  11441. nogil_check = None
  11442. def __init__(self, arg):
  11443. super(ProxyNode, self).__init__(arg)
  11444. self.constant_result = arg.constant_result
  11445. self._proxy_type()
  11446. def analyse_types(self, env):
  11447. self.arg = self.arg.analyse_expressions(env)
  11448. self._proxy_type()
  11449. return self
  11450. def infer_type(self, env):
  11451. return self.arg.infer_type(env)
  11452. def _proxy_type(self):
  11453. if hasattr(self.arg, 'type'):
  11454. self.type = self.arg.type
  11455. self.result_ctype = self.arg.result_ctype
  11456. if hasattr(self.arg, 'entry'):
  11457. self.entry = self.arg.entry
  11458. def generate_result_code(self, code):
  11459. self.arg.generate_result_code(code)
  11460. def result(self):
  11461. return self.arg.result()
  11462. def is_simple(self):
  11463. return self.arg.is_simple()
  11464. def may_be_none(self):
  11465. return self.arg.may_be_none()
  11466. def generate_evaluation_code(self, code):
  11467. self.arg.generate_evaluation_code(code)
  11468. def generate_disposal_code(self, code):
  11469. self.arg.generate_disposal_code(code)
  11470. def free_temps(self, code):
  11471. self.arg.free_temps(code)
  11472. class CloneNode(CoercionNode):
  11473. # This node is employed when the result of another node needs
  11474. # to be used multiple times. The argument node's result must
  11475. # be in a temporary. This node "borrows" the result from the
  11476. # argument node, and does not generate any evaluation or
  11477. # disposal code for it. The original owner of the argument
  11478. # node is responsible for doing those things.
  11479. subexprs = [] # Arg is not considered a subexpr
  11480. nogil_check = None
  11481. def __init__(self, arg):
  11482. CoercionNode.__init__(self, arg)
  11483. self.constant_result = arg.constant_result
  11484. if hasattr(arg, 'type'):
  11485. self.type = arg.type
  11486. self.result_ctype = arg.result_ctype
  11487. if hasattr(arg, 'entry'):
  11488. self.entry = arg.entry
  11489. def result(self):
  11490. return self.arg.result()
  11491. def may_be_none(self):
  11492. return self.arg.may_be_none()
  11493. def type_dependencies(self, env):
  11494. return self.arg.type_dependencies(env)
  11495. def infer_type(self, env):
  11496. return self.arg.infer_type(env)
  11497. def analyse_types(self, env):
  11498. self.type = self.arg.type
  11499. self.result_ctype = self.arg.result_ctype
  11500. self.is_temp = 1
  11501. if hasattr(self.arg, 'entry'):
  11502. self.entry = self.arg.entry
  11503. return self
  11504. def coerce_to(self, dest_type, env):
  11505. if self.arg.is_literal:
  11506. return self.arg.coerce_to(dest_type, env)
  11507. return super(CloneNode, self).coerce_to(dest_type, env)
  11508. def is_simple(self):
  11509. return True # result is always in a temp (or a name)
  11510. def generate_evaluation_code(self, code):
  11511. pass
  11512. def generate_result_code(self, code):
  11513. pass
  11514. def generate_disposal_code(self, code):
  11515. pass
  11516. def free_temps(self, code):
  11517. pass
  11518. class CMethodSelfCloneNode(CloneNode):
  11519. # Special CloneNode for the self argument of builtin C methods
  11520. # that accepts subtypes of the builtin type. This is safe only
  11521. # for 'final' subtypes, as subtypes of the declared type may
  11522. # override the C method.
  11523. def coerce_to(self, dst_type, env):
  11524. if dst_type.is_builtin_type and self.type.subtype_of(dst_type):
  11525. return self
  11526. return CloneNode.coerce_to(self, dst_type, env)
  11527. class ModuleRefNode(ExprNode):
  11528. # Simple returns the module object
  11529. type = py_object_type
  11530. is_temp = False
  11531. subexprs = []
  11532. def analyse_types(self, env):
  11533. return self
  11534. def may_be_none(self):
  11535. return False
  11536. def calculate_result_code(self):
  11537. return Naming.module_cname
  11538. def generate_result_code(self, code):
  11539. pass
  11540. class DocstringRefNode(ExprNode):
  11541. # Extracts the docstring of the body element
  11542. subexprs = ['body']
  11543. type = py_object_type
  11544. is_temp = True
  11545. def __init__(self, pos, body):
  11546. ExprNode.__init__(self, pos)
  11547. assert body.type.is_pyobject
  11548. self.body = body
  11549. def analyse_types(self, env):
  11550. return self
  11551. def generate_result_code(self, code):
  11552. code.putln('%s = __Pyx_GetAttr(%s, %s); %s' % (
  11553. self.result(), self.body.result(),
  11554. code.intern_identifier(StringEncoding.EncodedString("__doc__")),
  11555. code.error_goto_if_null(self.result(), self.pos)))
  11556. code.put_gotref(self.result())
  11557. #------------------------------------------------------------------------------------
  11558. #
  11559. # Runtime support code
  11560. #
  11561. #------------------------------------------------------------------------------------
  11562. pyerr_occurred_withgil_utility_code= UtilityCode(
  11563. proto = """
  11564. static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
  11565. """,
  11566. impl = """
  11567. static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
  11568. int err;
  11569. #ifdef WITH_THREAD
  11570. PyGILState_STATE _save = PyGILState_Ensure();
  11571. #endif
  11572. err = !!PyErr_Occurred();
  11573. #ifdef WITH_THREAD
  11574. PyGILState_Release(_save);
  11575. #endif
  11576. return err;
  11577. }
  11578. """
  11579. )
  11580. #------------------------------------------------------------------------------------
  11581. raise_unbound_local_error_utility_code = UtilityCode(
  11582. proto = """
  11583. static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
  11584. """,
  11585. impl = """
  11586. static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
  11587. PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
  11588. }
  11589. """)
  11590. raise_closure_name_error_utility_code = UtilityCode(
  11591. proto = """
  11592. static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname);
  11593. """,
  11594. impl = """
  11595. static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname) {
  11596. PyErr_Format(PyExc_NameError, "free variable '%s' referenced before assignment in enclosing scope", varname);
  11597. }
  11598. """)
  11599. # Don't inline the function, it should really never be called in production
  11600. raise_unbound_memoryview_utility_code_nogil = UtilityCode(
  11601. proto = """
  11602. static void __Pyx_RaiseUnboundMemoryviewSliceNogil(const char *varname);
  11603. """,
  11604. impl = """
  11605. static void __Pyx_RaiseUnboundMemoryviewSliceNogil(const char *varname) {
  11606. #ifdef WITH_THREAD
  11607. PyGILState_STATE gilstate = PyGILState_Ensure();
  11608. #endif
  11609. __Pyx_RaiseUnboundLocalError(varname);
  11610. #ifdef WITH_THREAD
  11611. PyGILState_Release(gilstate);
  11612. #endif
  11613. }
  11614. """,
  11615. requires = [raise_unbound_local_error_utility_code])
  11616. #------------------------------------------------------------------------------------
  11617. raise_too_many_values_to_unpack = UtilityCode.load_cached("RaiseTooManyValuesToUnpack", "ObjectHandling.c")
  11618. raise_need_more_values_to_unpack = UtilityCode.load_cached("RaiseNeedMoreValuesToUnpack", "ObjectHandling.c")
  11619. tuple_unpacking_error_code = UtilityCode.load_cached("UnpackTupleError", "ObjectHandling.c")