ExprNodes.py 538 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719
  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. pythran_is_numpy_func_supported, pythran_get_func_include_file, pythran_functor)
  46. from .PyrexTypes import PythranExpr
  47. try:
  48. from __builtin__ import basestring
  49. except ImportError:
  50. # Python 3
  51. basestring = str
  52. any_string_type = (bytes, str)
  53. else:
  54. # Python 2
  55. any_string_type = (bytes, unicode)
  56. if sys.version_info[0] >= 3:
  57. IS_PYTHON3 = True
  58. _py_int_types = int
  59. else:
  60. IS_PYTHON3 = False
  61. _py_int_types = (int, long)
  62. class NotConstant(object):
  63. _obj = None
  64. def __new__(cls):
  65. if NotConstant._obj is None:
  66. NotConstant._obj = super(NotConstant, cls).__new__(cls)
  67. return NotConstant._obj
  68. def __repr__(self):
  69. return "<NOT CONSTANT>"
  70. not_a_constant = NotConstant()
  71. constant_value_not_set = object()
  72. # error messages when coercing from key[0] to key[1]
  73. coercion_error_dict = {
  74. # string related errors
  75. (unicode_type, str_type): ("Cannot convert Unicode string to 'str' implicitly."
  76. " This is not portable and requires explicit encoding."),
  77. (unicode_type, bytes_type): "Cannot convert Unicode string to 'bytes' implicitly, encoding required.",
  78. (unicode_type, PyrexTypes.c_char_ptr_type): "Unicode objects only support coercion to Py_UNICODE*.",
  79. (unicode_type, PyrexTypes.c_const_char_ptr_type): "Unicode objects only support coercion to Py_UNICODE*.",
  80. (unicode_type, PyrexTypes.c_uchar_ptr_type): "Unicode objects only support coercion to Py_UNICODE*.",
  81. (unicode_type, PyrexTypes.c_const_uchar_ptr_type): "Unicode objects only support coercion to Py_UNICODE*.",
  82. (bytes_type, unicode_type): "Cannot convert 'bytes' object to unicode implicitly, decoding required",
  83. (bytes_type, str_type): "Cannot convert 'bytes' object to str implicitly. This is not portable to Py3.",
  84. (bytes_type, basestring_type): ("Cannot convert 'bytes' object to basestring implicitly."
  85. " This is not portable to Py3."),
  86. (bytes_type, PyrexTypes.c_py_unicode_ptr_type): "Cannot convert 'bytes' object to Py_UNICODE*, use 'unicode'.",
  87. (bytes_type, PyrexTypes.c_const_py_unicode_ptr_type): (
  88. "Cannot convert 'bytes' object to Py_UNICODE*, use 'unicode'."),
  89. (basestring_type, bytes_type): "Cannot convert 'basestring' object to bytes implicitly. This is not portable.",
  90. (str_type, unicode_type): ("str objects do not support coercion to unicode,"
  91. " use a unicode string literal instead (u'')"),
  92. (str_type, bytes_type): "Cannot convert 'str' to 'bytes' implicitly. This is not portable.",
  93. (str_type, PyrexTypes.c_char_ptr_type): "'str' objects do not support coercion to C types (use 'bytes'?).",
  94. (str_type, PyrexTypes.c_const_char_ptr_type): "'str' objects do not support coercion to C types (use 'bytes'?).",
  95. (str_type, PyrexTypes.c_uchar_ptr_type): "'str' objects do not support coercion to C types (use 'bytes'?).",
  96. (str_type, PyrexTypes.c_const_uchar_ptr_type): "'str' objects do not support coercion to C types (use 'bytes'?).",
  97. (str_type, PyrexTypes.c_py_unicode_ptr_type): "'str' objects do not support coercion to C types (use 'unicode'?).",
  98. (str_type, PyrexTypes.c_const_py_unicode_ptr_type): (
  99. "'str' objects do not support coercion to C types (use 'unicode'?)."),
  100. (PyrexTypes.c_char_ptr_type, unicode_type): "Cannot convert 'char*' to unicode implicitly, decoding required",
  101. (PyrexTypes.c_const_char_ptr_type, unicode_type): (
  102. "Cannot convert 'char*' to unicode implicitly, decoding required"),
  103. (PyrexTypes.c_uchar_ptr_type, unicode_type): "Cannot convert 'char*' to unicode implicitly, decoding required",
  104. (PyrexTypes.c_const_uchar_ptr_type, unicode_type): (
  105. "Cannot convert 'char*' to unicode implicitly, decoding required"),
  106. }
  107. def find_coercion_error(type_tuple, default, env):
  108. err = coercion_error_dict.get(type_tuple)
  109. if err is None:
  110. return default
  111. elif (env.directives['c_string_encoding'] and
  112. any(t in type_tuple for t in (PyrexTypes.c_char_ptr_type, PyrexTypes.c_uchar_ptr_type,
  113. PyrexTypes.c_const_char_ptr_type, PyrexTypes.c_const_uchar_ptr_type))):
  114. if type_tuple[1].is_pyobject:
  115. return default
  116. elif env.directives['c_string_encoding'] in ('ascii', 'default'):
  117. return default
  118. else:
  119. return "'%s' objects do not support coercion to C types with non-ascii or non-default c_string_encoding" % type_tuple[0].name
  120. else:
  121. return err
  122. def default_str_type(env):
  123. return {
  124. 'bytes': bytes_type,
  125. 'bytearray': bytearray_type,
  126. 'str': str_type,
  127. 'unicode': unicode_type
  128. }.get(env.directives['c_string_type'])
  129. def check_negative_indices(*nodes):
  130. """
  131. Raise a warning on nodes that are known to have negative numeric values.
  132. Used to find (potential) bugs inside of "wraparound=False" sections.
  133. """
  134. for node in nodes:
  135. if node is None or (
  136. not isinstance(node.constant_result, _py_int_types) and
  137. not isinstance(node.constant_result, float)):
  138. continue
  139. if node.constant_result < 0:
  140. warning(node.pos,
  141. "the result of using negative indices inside of "
  142. "code sections marked as 'wraparound=False' is "
  143. "undefined", level=1)
  144. def infer_sequence_item_type(env, seq_node, index_node=None, seq_type=None):
  145. if not seq_node.is_sequence_constructor:
  146. if seq_type is None:
  147. seq_type = seq_node.infer_type(env)
  148. if seq_type is tuple_type:
  149. # tuples are immutable => we can safely follow assignments
  150. if seq_node.cf_state and len(seq_node.cf_state) == 1:
  151. try:
  152. seq_node = seq_node.cf_state[0].rhs
  153. except AttributeError:
  154. pass
  155. if seq_node is not None and seq_node.is_sequence_constructor:
  156. if index_node is not None and index_node.has_constant_result():
  157. try:
  158. item = seq_node.args[index_node.constant_result]
  159. except (ValueError, TypeError, IndexError):
  160. pass
  161. else:
  162. return item.infer_type(env)
  163. # if we're lucky, all items have the same type
  164. item_types = set([item.infer_type(env) for item in seq_node.args])
  165. if len(item_types) == 1:
  166. return item_types.pop()
  167. return None
  168. def make_dedup_key(outer_type, item_nodes):
  169. """
  170. Recursively generate a deduplication key from a sequence of values.
  171. Includes Cython node types to work around the fact that (1, 2.0) == (1.0, 2), for example.
  172. @param outer_type: The type of the outer container.
  173. @param item_nodes: A sequence of constant nodes that will be traversed recursively.
  174. @return: A tuple that can be used as a dict key for deduplication.
  175. """
  176. item_keys = [
  177. (py_object_type, None, type(None)) if node is None
  178. # For sequences and their "mult_factor", see TupleNode.
  179. else make_dedup_key(node.type, [node.mult_factor if node.is_literal else None] + node.args) if node.is_sequence_constructor
  180. else make_dedup_key(node.type, (node.start, node.stop, node.step)) if node.is_slice
  181. # For constants, look at the Python value type if we don't know the concrete Cython type.
  182. else (node.type, node.constant_result,
  183. type(node.constant_result) if node.type is py_object_type else None) if node.has_constant_result()
  184. else None # something we cannot handle => short-circuit below
  185. for node in item_nodes
  186. ]
  187. if None in item_keys:
  188. return None
  189. return outer_type, tuple(item_keys)
  190. # Returns a block of code to translate the exception,
  191. # plus a boolean indicating whether to check for Python exceptions.
  192. def get_exception_handler(exception_value):
  193. if exception_value is None:
  194. return "__Pyx_CppExn2PyErr();", False
  195. elif (exception_value.type == PyrexTypes.c_char_type
  196. and exception_value.value == '*'):
  197. return "__Pyx_CppExn2PyErr();", True
  198. elif exception_value.type.is_pyobject:
  199. return (
  200. 'try { throw; } catch(const std::exception& exn) {'
  201. 'PyErr_SetString(%s, exn.what());'
  202. '} catch(...) { PyErr_SetNone(%s); }' % (
  203. exception_value.entry.cname,
  204. exception_value.entry.cname),
  205. False)
  206. else:
  207. return (
  208. '%s(); if (!PyErr_Occurred())'
  209. 'PyErr_SetString(PyExc_RuntimeError, '
  210. '"Error converting c++ exception.");' % (
  211. exception_value.entry.cname),
  212. False)
  213. def maybe_check_py_error(code, check_py_exception, pos, nogil):
  214. if check_py_exception:
  215. if nogil:
  216. code.putln(code.error_goto_if("__Pyx_ErrOccurredWithGIL()", pos))
  217. else:
  218. code.putln(code.error_goto_if("PyErr_Occurred()", pos))
  219. def translate_cpp_exception(code, pos, inside, py_result, exception_value, nogil):
  220. raise_py_exception, check_py_exception = get_exception_handler(exception_value)
  221. code.putln("try {")
  222. code.putln("%s" % inside)
  223. if py_result:
  224. code.putln(code.error_goto_if_null(py_result, pos))
  225. maybe_check_py_error(code, check_py_exception, pos, nogil)
  226. code.putln("} catch(...) {")
  227. if nogil:
  228. code.put_ensure_gil(declare_gilstate=True)
  229. code.putln(raise_py_exception)
  230. if nogil:
  231. code.put_release_ensured_gil()
  232. code.putln(code.error_goto(pos))
  233. code.putln("}")
  234. # Used to handle the case where an lvalue expression and an overloaded assignment
  235. # both have an exception declaration.
  236. def translate_double_cpp_exception(code, pos, lhs_type, lhs_code, rhs_code,
  237. lhs_exc_val, assign_exc_val, nogil):
  238. handle_lhs_exc, lhc_check_py_exc = get_exception_handler(lhs_exc_val)
  239. handle_assignment_exc, assignment_check_py_exc = get_exception_handler(assign_exc_val)
  240. code.putln("try {")
  241. code.putln(lhs_type.declaration_code("__pyx_local_lvalue = %s;" % lhs_code))
  242. maybe_check_py_error(code, lhc_check_py_exc, pos, nogil)
  243. code.putln("try {")
  244. code.putln("__pyx_local_lvalue = %s;" % rhs_code)
  245. maybe_check_py_error(code, assignment_check_py_exc, pos, nogil)
  246. # Catch any exception from the overloaded assignment.
  247. code.putln("} catch(...) {")
  248. if nogil:
  249. code.put_ensure_gil(declare_gilstate=True)
  250. code.putln(handle_assignment_exc)
  251. if nogil:
  252. code.put_release_ensured_gil()
  253. code.putln(code.error_goto(pos))
  254. code.putln("}")
  255. # Catch any exception from evaluating lhs.
  256. code.putln("} catch(...) {")
  257. if nogil:
  258. code.put_ensure_gil(declare_gilstate=True)
  259. code.putln(handle_lhs_exc)
  260. if nogil:
  261. code.put_release_ensured_gil()
  262. code.putln(code.error_goto(pos))
  263. code.putln('}')
  264. class ExprNode(Node):
  265. # subexprs [string] Class var holding names of subexpr node attrs
  266. # type PyrexType Type of the result
  267. # result_code string Code fragment
  268. # result_ctype string C type of result_code if different from type
  269. # is_temp boolean Result is in a temporary variable
  270. # is_sequence_constructor
  271. # boolean Is a list or tuple constructor expression
  272. # is_starred boolean Is a starred expression (e.g. '*a')
  273. # saved_subexpr_nodes
  274. # [ExprNode or [ExprNode or None] or None]
  275. # Cached result of subexpr_nodes()
  276. # use_managed_ref boolean use ref-counted temps/assignments/etc.
  277. # result_is_used boolean indicates that the result will be dropped and the
  278. # result_code/temp_result can safely be set to None
  279. # is_numpy_attribute boolean Is a Numpy module attribute
  280. # annotation ExprNode or None PEP526 annotation for names or expressions
  281. result_ctype = None
  282. type = None
  283. annotation = None
  284. temp_code = None
  285. old_temp = None # error checker for multiple frees etc.
  286. use_managed_ref = True # can be set by optimisation transforms
  287. result_is_used = True
  288. is_numpy_attribute = False
  289. # The Analyse Expressions phase for expressions is split
  290. # into two sub-phases:
  291. #
  292. # Analyse Types
  293. # Determines the result type of the expression based
  294. # on the types of its sub-expressions, and inserts
  295. # coercion nodes into the expression tree where needed.
  296. # Marks nodes which will need to have temporary variables
  297. # allocated.
  298. #
  299. # Allocate Temps
  300. # Allocates temporary variables where needed, and fills
  301. # in the result_code field of each node.
  302. #
  303. # ExprNode provides some convenience routines which
  304. # perform both of the above phases. These should only
  305. # be called from statement nodes, and only when no
  306. # coercion nodes need to be added around the expression
  307. # being analysed. In that case, the above two phases
  308. # should be invoked separately.
  309. #
  310. # Framework code in ExprNode provides much of the common
  311. # processing for the various phases. It makes use of the
  312. # 'subexprs' class attribute of ExprNodes, which should
  313. # contain a list of the names of attributes which can
  314. # hold sub-nodes or sequences of sub-nodes.
  315. #
  316. # The framework makes use of a number of abstract methods.
  317. # Their responsibilities are as follows.
  318. #
  319. # Declaration Analysis phase
  320. #
  321. # analyse_target_declaration
  322. # Called during the Analyse Declarations phase to analyse
  323. # the LHS of an assignment or argument of a del statement.
  324. # Nodes which cannot be the LHS of an assignment need not
  325. # implement it.
  326. #
  327. # Expression Analysis phase
  328. #
  329. # analyse_types
  330. # - Call analyse_types on all sub-expressions.
  331. # - Check operand types, and wrap coercion nodes around
  332. # sub-expressions where needed.
  333. # - Set the type of this node.
  334. # - If a temporary variable will be required for the
  335. # result, set the is_temp flag of this node.
  336. #
  337. # analyse_target_types
  338. # Called during the Analyse Types phase to analyse
  339. # the LHS of an assignment or argument of a del
  340. # statement. Similar responsibilities to analyse_types.
  341. #
  342. # target_code
  343. # Called by the default implementation of allocate_target_temps.
  344. # Should return a C lvalue for assigning to the node. The default
  345. # implementation calls calculate_result_code.
  346. #
  347. # check_const
  348. # - Check that this node and its subnodes form a
  349. # legal constant expression. If so, do nothing,
  350. # otherwise call not_const.
  351. #
  352. # The default implementation of check_const
  353. # assumes that the expression is not constant.
  354. #
  355. # check_const_addr
  356. # - Same as check_const, except check that the
  357. # expression is a C lvalue whose address is
  358. # constant. Otherwise, call addr_not_const.
  359. #
  360. # The default implementation of calc_const_addr
  361. # assumes that the expression is not a constant
  362. # lvalue.
  363. #
  364. # Code Generation phase
  365. #
  366. # generate_evaluation_code
  367. # - Call generate_evaluation_code for sub-expressions.
  368. # - Perform the functions of generate_result_code
  369. # (see below).
  370. # - If result is temporary, call generate_disposal_code
  371. # on all sub-expressions.
  372. #
  373. # A default implementation of generate_evaluation_code
  374. # is provided which uses the following abstract methods:
  375. #
  376. # generate_result_code
  377. # - Generate any C statements necessary to calculate
  378. # the result of this node from the results of its
  379. # sub-expressions.
  380. #
  381. # calculate_result_code
  382. # - Should return a C code fragment evaluating to the
  383. # result. This is only called when the result is not
  384. # a temporary.
  385. #
  386. # generate_assignment_code
  387. # Called on the LHS of an assignment.
  388. # - Call generate_evaluation_code for sub-expressions.
  389. # - Generate code to perform the assignment.
  390. # - If the assignment absorbed a reference, call
  391. # generate_post_assignment_code on the RHS,
  392. # otherwise call generate_disposal_code on it.
  393. #
  394. # generate_deletion_code
  395. # Called on an argument of a del statement.
  396. # - Call generate_evaluation_code for sub-expressions.
  397. # - Generate code to perform the deletion.
  398. # - Call generate_disposal_code on all sub-expressions.
  399. #
  400. #
  401. is_sequence_constructor = False
  402. is_dict_literal = False
  403. is_set_literal = False
  404. is_string_literal = False
  405. is_attribute = False
  406. is_subscript = False
  407. is_slice = False
  408. is_buffer_access = False
  409. is_memview_index = False
  410. is_memview_slice = False
  411. is_memview_broadcast = False
  412. is_memview_copy_assignment = False
  413. saved_subexpr_nodes = None
  414. is_temp = False
  415. is_target = False
  416. is_starred = False
  417. constant_result = constant_value_not_set
  418. child_attrs = property(fget=operator.attrgetter('subexprs'))
  419. def not_implemented(self, method_name):
  420. print_call_chain(method_name, "not implemented") ###
  421. raise InternalError(
  422. "%s.%s not implemented" %
  423. (self.__class__.__name__, method_name))
  424. def is_lvalue(self):
  425. return 0
  426. def is_addressable(self):
  427. return self.is_lvalue() and not self.type.is_memoryviewslice
  428. def is_ephemeral(self):
  429. # An ephemeral node is one whose result is in
  430. # a Python temporary and we suspect there are no
  431. # other references to it. Certain operations are
  432. # disallowed on such values, since they are
  433. # likely to result in a dangling pointer.
  434. return self.type.is_pyobject and self.is_temp
  435. def subexpr_nodes(self):
  436. # Extract a list of subexpression nodes based
  437. # on the contents of the subexprs class attribute.
  438. nodes = []
  439. for name in self.subexprs:
  440. item = getattr(self, name)
  441. if item is not None:
  442. if type(item) is list:
  443. nodes.extend(item)
  444. else:
  445. nodes.append(item)
  446. return nodes
  447. def result(self):
  448. if self.is_temp:
  449. #if not self.temp_code:
  450. # pos = (os.path.basename(self.pos[0].get_description()),) + self.pos[1:] if self.pos else '(?)'
  451. # raise RuntimeError("temp result name not set in %s at %r" % (
  452. # self.__class__.__name__, pos))
  453. return self.temp_code
  454. else:
  455. return self.calculate_result_code()
  456. def pythran_result(self, type_=None):
  457. if is_pythran_supported_node_or_none(self):
  458. return to_pythran(self)
  459. assert(type_ is not None)
  460. return to_pythran(self, type_)
  461. def is_c_result_required(self):
  462. """
  463. Subtypes may return False here if result temp allocation can be skipped.
  464. """
  465. return True
  466. def result_as(self, type = None):
  467. # Return the result code cast to the specified C type.
  468. if (self.is_temp and self.type.is_pyobject and
  469. type != py_object_type):
  470. # Allocated temporaries are always PyObject *, which may not
  471. # reflect the actual type (e.g. an extension type)
  472. return typecast(type, py_object_type, self.result())
  473. return typecast(type, self.ctype(), self.result())
  474. def py_result(self):
  475. # Return the result code cast to PyObject *.
  476. return self.result_as(py_object_type)
  477. def ctype(self):
  478. # Return the native C type of the result (i.e. the
  479. # C type of the result_code expression).
  480. return self.result_ctype or self.type
  481. def get_constant_c_result_code(self):
  482. # Return the constant value of this node as a result code
  483. # string, or None if the node is not constant. This method
  484. # can be called when the constant result code is required
  485. # before the code generation phase.
  486. #
  487. # The return value is a string that can represent a simple C
  488. # value, a constant C name or a constant C expression. If the
  489. # node type depends on Python code, this must return None.
  490. return None
  491. def calculate_constant_result(self):
  492. # Calculate the constant compile time result value of this
  493. # expression and store it in ``self.constant_result``. Does
  494. # nothing by default, thus leaving ``self.constant_result``
  495. # unknown. If valid, the result can be an arbitrary Python
  496. # value.
  497. #
  498. # This must only be called when it is assured that all
  499. # sub-expressions have a valid constant_result value. The
  500. # ConstantFolding transform will do this.
  501. pass
  502. def has_constant_result(self):
  503. return self.constant_result is not constant_value_not_set and \
  504. self.constant_result is not not_a_constant
  505. def compile_time_value(self, denv):
  506. # Return value of compile-time expression, or report error.
  507. error(self.pos, "Invalid compile-time expression")
  508. def compile_time_value_error(self, e):
  509. error(self.pos, "Error in compile-time expression: %s: %s" % (
  510. e.__class__.__name__, e))
  511. # ------------- Declaration Analysis ----------------
  512. def analyse_target_declaration(self, env):
  513. error(self.pos, "Cannot assign to or delete this")
  514. # ------------- Expression Analysis ----------------
  515. def analyse_const_expression(self, env):
  516. # Called during the analyse_declarations phase of a
  517. # constant expression. Analyses the expression's type,
  518. # checks whether it is a legal const expression,
  519. # and determines its value.
  520. node = self.analyse_types(env)
  521. node.check_const()
  522. return node
  523. def analyse_expressions(self, env):
  524. # Convenience routine performing both the Type
  525. # Analysis and Temp Allocation phases for a whole
  526. # expression.
  527. return self.analyse_types(env)
  528. def analyse_target_expression(self, env, rhs):
  529. # Convenience routine performing both the Type
  530. # Analysis and Temp Allocation phases for the LHS of
  531. # an assignment.
  532. return self.analyse_target_types(env)
  533. def analyse_boolean_expression(self, env):
  534. # Analyse expression and coerce to a boolean.
  535. node = self.analyse_types(env)
  536. bool = node.coerce_to_boolean(env)
  537. return bool
  538. def analyse_temp_boolean_expression(self, env):
  539. # Analyse boolean expression and coerce result into
  540. # a temporary. This is used when a branch is to be
  541. # performed on the result and we won't have an
  542. # opportunity to ensure disposal code is executed
  543. # afterwards. By forcing the result into a temporary,
  544. # we ensure that all disposal has been done by the
  545. # time we get the result.
  546. node = self.analyse_types(env)
  547. return node.coerce_to_boolean(env).coerce_to_simple(env)
  548. # --------------- Type Inference -----------------
  549. def type_dependencies(self, env):
  550. # Returns the list of entries whose types must be determined
  551. # before the type of self can be inferred.
  552. if hasattr(self, 'type') and self.type is not None:
  553. return ()
  554. return sum([node.type_dependencies(env) for node in self.subexpr_nodes()], ())
  555. def infer_type(self, env):
  556. # Attempt to deduce the type of self.
  557. # Differs from analyse_types as it avoids unnecessary
  558. # analysis of subexpressions, but can assume everything
  559. # in self.type_dependencies() has been resolved.
  560. if hasattr(self, 'type') and self.type is not None:
  561. return self.type
  562. elif hasattr(self, 'entry') and self.entry is not None:
  563. return self.entry.type
  564. else:
  565. self.not_implemented("infer_type")
  566. def nonlocally_immutable(self):
  567. # Returns whether this variable is a safe reference, i.e.
  568. # can't be modified as part of globals or closures.
  569. return self.is_literal or self.is_temp or self.type.is_array or self.type.is_cfunction
  570. def inferable_item_node(self, index=0):
  571. """
  572. Return a node that represents the (type) result of an indexing operation,
  573. e.g. for tuple unpacking or iteration.
  574. """
  575. return IndexNode(self.pos, base=self, index=IntNode(
  576. self.pos, value=str(index), constant_result=index, type=PyrexTypes.c_py_ssize_t_type))
  577. # --------------- Type Analysis ------------------
  578. def analyse_as_module(self, env):
  579. # If this node can be interpreted as a reference to a
  580. # cimported module, return its scope, else None.
  581. return None
  582. def analyse_as_type(self, env):
  583. # If this node can be interpreted as a reference to a
  584. # type, return that type, else None.
  585. return None
  586. def analyse_as_extension_type(self, env):
  587. # If this node can be interpreted as a reference to an
  588. # extension type or builtin type, return its type, else None.
  589. return None
  590. def analyse_types(self, env):
  591. self.not_implemented("analyse_types")
  592. def analyse_target_types(self, env):
  593. return self.analyse_types(env)
  594. def nogil_check(self, env):
  595. # By default, any expression based on Python objects is
  596. # prevented in nogil environments. Subtypes must override
  597. # this if they can work without the GIL.
  598. if self.type and self.type.is_pyobject:
  599. self.gil_error()
  600. def gil_assignment_check(self, env):
  601. if env.nogil and self.type.is_pyobject:
  602. error(self.pos, "Assignment of Python object not allowed without gil")
  603. def check_const(self):
  604. self.not_const()
  605. return False
  606. def not_const(self):
  607. error(self.pos, "Not allowed in a constant expression")
  608. def check_const_addr(self):
  609. self.addr_not_const()
  610. return False
  611. def addr_not_const(self):
  612. error(self.pos, "Address is not constant")
  613. # ----------------- Result Allocation -----------------
  614. def result_in_temp(self):
  615. # Return true if result is in a temporary owned by
  616. # this node or one of its subexpressions. Overridden
  617. # by certain nodes which can share the result of
  618. # a subnode.
  619. return self.is_temp
  620. def target_code(self):
  621. # Return code fragment for use as LHS of a C assignment.
  622. return self.calculate_result_code()
  623. def calculate_result_code(self):
  624. self.not_implemented("calculate_result_code")
  625. # def release_target_temp(self, env):
  626. # # Release temporaries used by LHS of an assignment.
  627. # self.release_subexpr_temps(env)
  628. def allocate_temp_result(self, code):
  629. if self.temp_code:
  630. raise RuntimeError("Temp allocated multiple times in %r: %r" % (self.__class__.__name__, self.pos))
  631. type = self.type
  632. if not type.is_void:
  633. if type.is_pyobject:
  634. type = PyrexTypes.py_object_type
  635. elif not (self.result_is_used or type.is_memoryviewslice or self.is_c_result_required()):
  636. self.temp_code = None
  637. return
  638. self.temp_code = code.funcstate.allocate_temp(
  639. type, manage_ref=self.use_managed_ref)
  640. else:
  641. self.temp_code = None
  642. def release_temp_result(self, code):
  643. if not self.temp_code:
  644. if not self.result_is_used:
  645. # not used anyway, so ignore if not set up
  646. return
  647. pos = (os.path.basename(self.pos[0].get_description()),) + self.pos[1:] if self.pos else '(?)'
  648. if self.old_temp:
  649. raise RuntimeError("temp %s released multiple times in %s at %r" % (
  650. self.old_temp, self.__class__.__name__, pos))
  651. else:
  652. raise RuntimeError("no temp, but release requested in %s at %r" % (
  653. self.__class__.__name__, pos))
  654. code.funcstate.release_temp(self.temp_code)
  655. self.old_temp = self.temp_code
  656. self.temp_code = None
  657. # ---------------- Code Generation -----------------
  658. def make_owned_reference(self, code):
  659. """
  660. If result is a pyobject, make sure we own a reference to it.
  661. If the result is in a temp, it is already a new reference.
  662. """
  663. if self.type.is_pyobject and not self.result_in_temp():
  664. code.put_incref(self.result(), self.ctype())
  665. def make_owned_memoryviewslice(self, code):
  666. """
  667. Make sure we own the reference to this memoryview slice.
  668. """
  669. if not self.result_in_temp():
  670. code.put_incref_memoryviewslice(self.result(),
  671. have_gil=self.in_nogil_context)
  672. def generate_evaluation_code(self, code):
  673. # Generate code to evaluate this node and
  674. # its sub-expressions, and dispose of any
  675. # temporary results of its sub-expressions.
  676. self.generate_subexpr_evaluation_code(code)
  677. code.mark_pos(self.pos)
  678. if self.is_temp:
  679. self.allocate_temp_result(code)
  680. self.generate_result_code(code)
  681. if self.is_temp and not (self.type.is_string or self.type.is_pyunicode_ptr):
  682. # If we are temp we do not need to wait until this node is disposed
  683. # before disposing children.
  684. self.generate_subexpr_disposal_code(code)
  685. self.free_subexpr_temps(code)
  686. def generate_subexpr_evaluation_code(self, code):
  687. for node in self.subexpr_nodes():
  688. node.generate_evaluation_code(code)
  689. def generate_result_code(self, code):
  690. self.not_implemented("generate_result_code")
  691. def generate_disposal_code(self, code):
  692. if self.is_temp:
  693. if self.type.is_string or self.type.is_pyunicode_ptr:
  694. # postponed from self.generate_evaluation_code()
  695. self.generate_subexpr_disposal_code(code)
  696. self.free_subexpr_temps(code)
  697. if self.result():
  698. if self.type.is_pyobject:
  699. code.put_decref_clear(self.result(), self.ctype())
  700. elif self.type.is_memoryviewslice:
  701. code.put_xdecref_memoryviewslice(
  702. self.result(), have_gil=not self.in_nogil_context)
  703. code.putln("%s.memview = NULL;" % self.result())
  704. code.putln("%s.data = NULL;" % self.result())
  705. else:
  706. # Already done if self.is_temp
  707. self.generate_subexpr_disposal_code(code)
  708. def generate_subexpr_disposal_code(self, code):
  709. # Generate code to dispose of temporary results
  710. # of all sub-expressions.
  711. for node in self.subexpr_nodes():
  712. node.generate_disposal_code(code)
  713. def generate_post_assignment_code(self, code):
  714. if self.is_temp:
  715. if self.type.is_string or self.type.is_pyunicode_ptr:
  716. # postponed from self.generate_evaluation_code()
  717. self.generate_subexpr_disposal_code(code)
  718. self.free_subexpr_temps(code)
  719. elif self.type.is_pyobject:
  720. code.putln("%s = 0;" % self.result())
  721. elif self.type.is_memoryviewslice:
  722. code.putln("%s.memview = NULL;" % self.result())
  723. code.putln("%s.data = NULL;" % self.result())
  724. else:
  725. self.generate_subexpr_disposal_code(code)
  726. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  727. exception_check=None, exception_value=None):
  728. # Stub method for nodes which are not legal as
  729. # the LHS of an assignment. An error will have
  730. # been reported earlier.
  731. pass
  732. def generate_deletion_code(self, code, ignore_nonexisting=False):
  733. # Stub method for nodes that are not legal as
  734. # the argument of a del statement. An error
  735. # will have been reported earlier.
  736. pass
  737. def free_temps(self, code):
  738. if self.is_temp:
  739. if not self.type.is_void:
  740. self.release_temp_result(code)
  741. else:
  742. self.free_subexpr_temps(code)
  743. def free_subexpr_temps(self, code):
  744. for sub in self.subexpr_nodes():
  745. sub.free_temps(code)
  746. def generate_function_definitions(self, env, code):
  747. pass
  748. # ---------------- Annotation ---------------------
  749. def annotate(self, code):
  750. for node in self.subexpr_nodes():
  751. node.annotate(code)
  752. # ----------------- Coercion ----------------------
  753. def coerce_to(self, dst_type, env):
  754. # Coerce the result so that it can be assigned to
  755. # something of type dst_type. If processing is necessary,
  756. # wraps this node in a coercion node and returns that.
  757. # Otherwise, returns this node unchanged.
  758. #
  759. # This method is called during the analyse_expressions
  760. # phase of the src_node's processing.
  761. #
  762. # Note that subclasses that override this (especially
  763. # ConstNodes) must not (re-)set their own .type attribute
  764. # here. Since expression nodes may turn up in different
  765. # places in the tree (e.g. inside of CloneNodes in cascaded
  766. # assignments), this method must return a new node instance
  767. # if it changes the type.
  768. #
  769. src = self
  770. src_type = self.type
  771. if self.check_for_coercion_error(dst_type, env):
  772. return self
  773. used_as_reference = dst_type.is_reference
  774. if used_as_reference and not src_type.is_reference:
  775. dst_type = dst_type.ref_base_type
  776. if src_type.is_const:
  777. src_type = src_type.const_base_type
  778. if src_type.is_fused or dst_type.is_fused:
  779. # See if we are coercing a fused function to a pointer to a
  780. # specialized function
  781. if (src_type.is_cfunction and not dst_type.is_fused and
  782. dst_type.is_ptr and dst_type.base_type.is_cfunction):
  783. dst_type = dst_type.base_type
  784. for signature in src_type.get_all_specialized_function_types():
  785. if signature.same_as(dst_type):
  786. src.type = signature
  787. src.entry = src.type.entry
  788. src.entry.used = True
  789. return self
  790. if src_type.is_fused:
  791. error(self.pos, "Type is not specialized")
  792. elif src_type.is_null_ptr and dst_type.is_ptr:
  793. # NULL can be implicitly cast to any pointer type
  794. return self
  795. else:
  796. error(self.pos, "Cannot coerce to a type that is not specialized")
  797. self.type = error_type
  798. return self
  799. if self.coercion_type is not None:
  800. # This is purely for error checking purposes!
  801. node = NameNode(self.pos, name='', type=self.coercion_type)
  802. node.coerce_to(dst_type, env)
  803. if dst_type.is_memoryviewslice:
  804. from . import MemoryView
  805. if not src.type.is_memoryviewslice:
  806. if src.type.is_pyobject:
  807. src = CoerceToMemViewSliceNode(src, dst_type, env)
  808. elif src.type.is_array:
  809. src = CythonArrayNode.from_carray(src, env).coerce_to(dst_type, env)
  810. elif not src_type.is_error:
  811. error(self.pos,
  812. "Cannot convert '%s' to memoryviewslice" % (src_type,))
  813. else:
  814. if src.type.writable_needed:
  815. dst_type.writable_needed = True
  816. if not src.type.conforms_to(dst_type, broadcast=self.is_memview_broadcast,
  817. copying=self.is_memview_copy_assignment):
  818. if src.type.dtype.same_as(dst_type.dtype):
  819. msg = "Memoryview '%s' not conformable to memoryview '%s'."
  820. tup = src.type, dst_type
  821. else:
  822. msg = "Different base types for memoryviews (%s, %s)"
  823. tup = src.type.dtype, dst_type.dtype
  824. error(self.pos, msg % tup)
  825. elif dst_type.is_pyobject:
  826. if not src.type.is_pyobject:
  827. if dst_type is bytes_type and src.type.is_int:
  828. src = CoerceIntToBytesNode(src, env)
  829. else:
  830. src = CoerceToPyTypeNode(src, env, type=dst_type)
  831. if not src.type.subtype_of(dst_type):
  832. if src.constant_result is not None:
  833. src = PyTypeTestNode(src, dst_type, env)
  834. elif is_pythran_expr(dst_type) and is_pythran_supported_type(src.type):
  835. # We let the compiler decide whether this is valid
  836. return src
  837. elif is_pythran_expr(src.type):
  838. if is_pythran_supported_type(dst_type):
  839. # Match the case were a pythran expr is assigned to a value, or vice versa.
  840. # We let the C++ compiler decide whether this is valid or not!
  841. return src
  842. # Else, we need to convert the Pythran expression to a Python object
  843. src = CoerceToPyTypeNode(src, env, type=dst_type)
  844. elif src.type.is_pyobject:
  845. if used_as_reference and dst_type.is_cpp_class:
  846. warning(
  847. self.pos,
  848. "Cannot pass Python object as C++ data structure reference (%s &), will pass by copy." % dst_type)
  849. src = CoerceFromPyTypeNode(dst_type, src, env)
  850. elif (dst_type.is_complex
  851. and src_type != dst_type
  852. and dst_type.assignable_from(src_type)):
  853. src = CoerceToComplexNode(src, dst_type, env)
  854. else: # neither src nor dst are py types
  855. # Added the string comparison, since for c types that
  856. # is enough, but Cython gets confused when the types are
  857. # in different pxi files.
  858. # TODO: Remove this hack and require shared declarations.
  859. if not (src.type == dst_type or str(src.type) == str(dst_type) or dst_type.assignable_from(src_type)):
  860. self.fail_assignment(dst_type)
  861. return src
  862. def fail_assignment(self, dst_type):
  863. error(self.pos, "Cannot assign type '%s' to '%s'" % (self.type, dst_type))
  864. def check_for_coercion_error(self, dst_type, env, fail=False, default=None):
  865. if fail and not default:
  866. default = "Cannot assign type '%(FROM)s' to '%(TO)s'"
  867. message = find_coercion_error((self.type, dst_type), default, env)
  868. if message is not None:
  869. error(self.pos, message % {'FROM': self.type, 'TO': dst_type})
  870. return True
  871. if fail:
  872. self.fail_assignment(dst_type)
  873. return True
  874. return False
  875. def coerce_to_pyobject(self, env):
  876. return self.coerce_to(PyrexTypes.py_object_type, env)
  877. def coerce_to_boolean(self, env):
  878. # Coerce result to something acceptable as
  879. # a boolean value.
  880. # if it's constant, calculate the result now
  881. if self.has_constant_result():
  882. bool_value = bool(self.constant_result)
  883. return BoolNode(self.pos, value=bool_value,
  884. constant_result=bool_value)
  885. type = self.type
  886. if type.is_enum or type.is_error:
  887. return self
  888. elif type.is_pyobject or type.is_int or type.is_ptr or type.is_float:
  889. return CoerceToBooleanNode(self, env)
  890. elif type.is_cpp_class and type.scope and type.scope.lookup("operator bool"):
  891. return SimpleCallNode(
  892. self.pos,
  893. function=AttributeNode(
  894. self.pos, obj=self, attribute=StringEncoding.EncodedString('operator bool')),
  895. args=[]).analyse_types(env)
  896. elif type.is_ctuple:
  897. bool_value = len(type.components) == 0
  898. return BoolNode(self.pos, value=bool_value,
  899. constant_result=bool_value)
  900. else:
  901. error(self.pos, "Type '%s' not acceptable as a boolean" % type)
  902. return self
  903. def coerce_to_integer(self, env):
  904. # If not already some C integer type, coerce to longint.
  905. if self.type.is_int:
  906. return self
  907. else:
  908. return self.coerce_to(PyrexTypes.c_long_type, env)
  909. def coerce_to_temp(self, env):
  910. # Ensure that the result is in a temporary.
  911. if self.result_in_temp():
  912. return self
  913. else:
  914. return CoerceToTempNode(self, env)
  915. def coerce_to_simple(self, env):
  916. # Ensure that the result is simple (see is_simple).
  917. if self.is_simple():
  918. return self
  919. else:
  920. return self.coerce_to_temp(env)
  921. def is_simple(self):
  922. # A node is simple if its result is something that can
  923. # be referred to without performing any operations, e.g.
  924. # a constant, local var, C global var, struct member
  925. # reference, or temporary.
  926. return self.result_in_temp()
  927. def may_be_none(self):
  928. if self.type and not (self.type.is_pyobject or
  929. self.type.is_memoryviewslice):
  930. return False
  931. if self.has_constant_result():
  932. return self.constant_result is not None
  933. return True
  934. def as_cython_attribute(self):
  935. return None
  936. def as_none_safe_node(self, message, error="PyExc_TypeError", format_args=()):
  937. # Wraps the node in a NoneCheckNode if it is not known to be
  938. # not-None (e.g. because it is a Python literal).
  939. if self.may_be_none():
  940. return NoneCheckNode(self, error, message, format_args)
  941. else:
  942. return self
  943. @classmethod
  944. def from_node(cls, node, **kwargs):
  945. """Instantiate this node class from another node, properly
  946. copying over all attributes that one would forget otherwise.
  947. """
  948. attributes = "cf_state cf_maybe_null cf_is_null constant_result".split()
  949. for attr_name in attributes:
  950. if attr_name in kwargs:
  951. continue
  952. try:
  953. value = getattr(node, attr_name)
  954. except AttributeError:
  955. pass
  956. else:
  957. kwargs[attr_name] = value
  958. return cls(node.pos, **kwargs)
  959. class AtomicExprNode(ExprNode):
  960. # Abstract base class for expression nodes which have
  961. # no sub-expressions.
  962. subexprs = []
  963. # Override to optimize -- we know we have no children
  964. def generate_subexpr_evaluation_code(self, code):
  965. pass
  966. def generate_subexpr_disposal_code(self, code):
  967. pass
  968. class PyConstNode(AtomicExprNode):
  969. # Abstract base class for constant Python values.
  970. is_literal = 1
  971. type = py_object_type
  972. def is_simple(self):
  973. return 1
  974. def may_be_none(self):
  975. return False
  976. def analyse_types(self, env):
  977. return self
  978. def calculate_result_code(self):
  979. return self.value
  980. def generate_result_code(self, code):
  981. pass
  982. class NoneNode(PyConstNode):
  983. # The constant value None
  984. is_none = 1
  985. value = "Py_None"
  986. constant_result = None
  987. nogil_check = None
  988. def compile_time_value(self, denv):
  989. return None
  990. def may_be_none(self):
  991. return True
  992. def coerce_to(self, dst_type, env):
  993. if not (dst_type.is_pyobject or dst_type.is_memoryviewslice or dst_type.is_error):
  994. # Catch this error early and loudly.
  995. error(self.pos, "Cannot assign None to %s" % dst_type)
  996. return super(NoneNode, self).coerce_to(dst_type, env)
  997. class EllipsisNode(PyConstNode):
  998. # '...' in a subscript list.
  999. value = "Py_Ellipsis"
  1000. constant_result = Ellipsis
  1001. def compile_time_value(self, denv):
  1002. return Ellipsis
  1003. class ConstNode(AtomicExprNode):
  1004. # Abstract base type for literal constant nodes.
  1005. #
  1006. # value string C code fragment
  1007. is_literal = 1
  1008. nogil_check = None
  1009. def is_simple(self):
  1010. return 1
  1011. def nonlocally_immutable(self):
  1012. return 1
  1013. def may_be_none(self):
  1014. return False
  1015. def analyse_types(self, env):
  1016. return self # Types are held in class variables
  1017. def check_const(self):
  1018. return True
  1019. def get_constant_c_result_code(self):
  1020. return self.calculate_result_code()
  1021. def calculate_result_code(self):
  1022. return str(self.value)
  1023. def generate_result_code(self, code):
  1024. pass
  1025. class BoolNode(ConstNode):
  1026. type = PyrexTypes.c_bint_type
  1027. # The constant value True or False
  1028. def calculate_constant_result(self):
  1029. self.constant_result = self.value
  1030. def compile_time_value(self, denv):
  1031. return self.value
  1032. def calculate_result_code(self):
  1033. if self.type.is_pyobject:
  1034. return self.value and 'Py_True' or 'Py_False'
  1035. else:
  1036. return str(int(self.value))
  1037. def coerce_to(self, dst_type, env):
  1038. if dst_type == self.type:
  1039. return self
  1040. if dst_type is py_object_type and self.type is Builtin.bool_type:
  1041. return self
  1042. if dst_type.is_pyobject and self.type.is_int:
  1043. return BoolNode(
  1044. self.pos, value=self.value,
  1045. constant_result=self.constant_result,
  1046. type=Builtin.bool_type)
  1047. if dst_type.is_int and self.type.is_pyobject:
  1048. return BoolNode(
  1049. self.pos, value=self.value,
  1050. constant_result=self.constant_result,
  1051. type=PyrexTypes.c_bint_type)
  1052. return ConstNode.coerce_to(self, dst_type, env)
  1053. class NullNode(ConstNode):
  1054. type = PyrexTypes.c_null_ptr_type
  1055. value = "NULL"
  1056. constant_result = 0
  1057. def get_constant_c_result_code(self):
  1058. return self.value
  1059. class CharNode(ConstNode):
  1060. type = PyrexTypes.c_char_type
  1061. def calculate_constant_result(self):
  1062. self.constant_result = ord(self.value)
  1063. def compile_time_value(self, denv):
  1064. return ord(self.value)
  1065. def calculate_result_code(self):
  1066. return "'%s'" % StringEncoding.escape_char(self.value)
  1067. class IntNode(ConstNode):
  1068. # unsigned "" or "U"
  1069. # longness "" or "L" or "LL"
  1070. # is_c_literal True/False/None creator considers this a C integer literal
  1071. unsigned = ""
  1072. longness = ""
  1073. is_c_literal = None # unknown
  1074. def __init__(self, pos, **kwds):
  1075. ExprNode.__init__(self, pos, **kwds)
  1076. if 'type' not in kwds:
  1077. self.type = self.find_suitable_type_for_value()
  1078. def find_suitable_type_for_value(self):
  1079. if self.constant_result is constant_value_not_set:
  1080. try:
  1081. self.calculate_constant_result()
  1082. except ValueError:
  1083. pass
  1084. # we ignore 'is_c_literal = True' and instead map signed 32bit
  1085. # integers as C long values
  1086. if self.is_c_literal or \
  1087. not self.has_constant_result() or \
  1088. self.unsigned or self.longness == 'LL':
  1089. # clearly a C literal
  1090. rank = (self.longness == 'LL') and 2 or 1
  1091. suitable_type = PyrexTypes.modifiers_and_name_to_type[not self.unsigned, rank, "int"]
  1092. if self.type:
  1093. suitable_type = PyrexTypes.widest_numeric_type(suitable_type, self.type)
  1094. else:
  1095. # C literal or Python literal - split at 32bit boundary
  1096. if -2**31 <= self.constant_result < 2**31:
  1097. if self.type and self.type.is_int:
  1098. suitable_type = self.type
  1099. else:
  1100. suitable_type = PyrexTypes.c_long_type
  1101. else:
  1102. suitable_type = PyrexTypes.py_object_type
  1103. return suitable_type
  1104. def coerce_to(self, dst_type, env):
  1105. if self.type is dst_type:
  1106. return self
  1107. elif dst_type.is_float:
  1108. if self.has_constant_result():
  1109. return FloatNode(self.pos, value='%d.0' % int(self.constant_result), type=dst_type,
  1110. constant_result=float(self.constant_result))
  1111. else:
  1112. return FloatNode(self.pos, value=self.value, type=dst_type,
  1113. constant_result=not_a_constant)
  1114. if dst_type.is_numeric and not dst_type.is_complex:
  1115. node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
  1116. type=dst_type, is_c_literal=True,
  1117. unsigned=self.unsigned, longness=self.longness)
  1118. return node
  1119. elif dst_type.is_pyobject:
  1120. node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
  1121. type=PyrexTypes.py_object_type, is_c_literal=False,
  1122. unsigned=self.unsigned, longness=self.longness)
  1123. else:
  1124. # FIXME: not setting the type here to keep it working with
  1125. # complex numbers. Should they be special cased?
  1126. node = IntNode(self.pos, value=self.value, constant_result=self.constant_result,
  1127. unsigned=self.unsigned, longness=self.longness)
  1128. # We still need to perform normal coerce_to processing on the
  1129. # result, because we might be coercing to an extension type,
  1130. # in which case a type test node will be needed.
  1131. return ConstNode.coerce_to(node, dst_type, env)
  1132. def coerce_to_boolean(self, env):
  1133. return IntNode(
  1134. self.pos, value=self.value,
  1135. constant_result=self.constant_result,
  1136. type=PyrexTypes.c_bint_type,
  1137. unsigned=self.unsigned, longness=self.longness)
  1138. def generate_evaluation_code(self, code):
  1139. if self.type.is_pyobject:
  1140. # pre-allocate a Python version of the number
  1141. plain_integer_string = str(Utils.str_to_number(self.value))
  1142. self.result_code = code.get_py_int(plain_integer_string, self.longness)
  1143. else:
  1144. self.result_code = self.get_constant_c_result_code()
  1145. def get_constant_c_result_code(self):
  1146. unsigned, longness = self.unsigned, self.longness
  1147. literal = self.value_as_c_integer_string()
  1148. if not (unsigned or longness) and self.type.is_int and literal[0] == '-' and literal[1] != '0':
  1149. # negative decimal literal => guess longness from type to prevent wrap-around
  1150. if self.type.rank >= PyrexTypes.c_longlong_type.rank:
  1151. longness = 'LL'
  1152. elif self.type.rank >= PyrexTypes.c_long_type.rank:
  1153. longness = 'L'
  1154. return literal + unsigned + longness
  1155. def value_as_c_integer_string(self):
  1156. value = self.value
  1157. if len(value) <= 2:
  1158. # too short to go wrong (and simplifies code below)
  1159. return value
  1160. neg_sign = ''
  1161. if value[0] == '-':
  1162. neg_sign = '-'
  1163. value = value[1:]
  1164. if value[0] == '0':
  1165. literal_type = value[1] # 0'o' - 0'b' - 0'x'
  1166. # 0x123 hex literals and 0123 octal literals work nicely in C
  1167. # but C-incompatible Py3 oct/bin notations need conversion
  1168. if neg_sign and literal_type in 'oOxX0123456789' and value[2:].isdigit():
  1169. # negative hex/octal literal => prevent C compiler from using
  1170. # unsigned integer types by converting to decimal (see C standard 6.4.4.1)
  1171. value = str(Utils.str_to_number(value))
  1172. elif literal_type in 'oO':
  1173. value = '0' + value[2:] # '0o123' => '0123'
  1174. elif literal_type in 'bB':
  1175. value = str(int(value[2:], 2))
  1176. elif value.isdigit() and not self.unsigned and not self.longness:
  1177. if not neg_sign:
  1178. # C compilers do not consider unsigned types for decimal literals,
  1179. # but they do for hex (see C standard 6.4.4.1)
  1180. value = '0x%X' % int(value)
  1181. return neg_sign + value
  1182. def calculate_result_code(self):
  1183. return self.result_code
  1184. def calculate_constant_result(self):
  1185. self.constant_result = Utils.str_to_number(self.value)
  1186. def compile_time_value(self, denv):
  1187. return Utils.str_to_number(self.value)
  1188. class FloatNode(ConstNode):
  1189. type = PyrexTypes.c_double_type
  1190. def calculate_constant_result(self):
  1191. self.constant_result = float(self.value)
  1192. def compile_time_value(self, denv):
  1193. return float(self.value)
  1194. def coerce_to(self, dst_type, env):
  1195. if dst_type.is_pyobject and self.type.is_float:
  1196. return FloatNode(
  1197. self.pos, value=self.value,
  1198. constant_result=self.constant_result,
  1199. type=Builtin.float_type)
  1200. if dst_type.is_float and self.type.is_pyobject:
  1201. return FloatNode(
  1202. self.pos, value=self.value,
  1203. constant_result=self.constant_result,
  1204. type=dst_type)
  1205. return ConstNode.coerce_to(self, dst_type, env)
  1206. def calculate_result_code(self):
  1207. return self.result_code
  1208. def get_constant_c_result_code(self):
  1209. strval = self.value
  1210. assert isinstance(strval, basestring)
  1211. cmpval = repr(float(strval))
  1212. if cmpval == 'nan':
  1213. return "(Py_HUGE_VAL * 0)"
  1214. elif cmpval == 'inf':
  1215. return "Py_HUGE_VAL"
  1216. elif cmpval == '-inf':
  1217. return "(-Py_HUGE_VAL)"
  1218. else:
  1219. return strval
  1220. def generate_evaluation_code(self, code):
  1221. c_value = self.get_constant_c_result_code()
  1222. if self.type.is_pyobject:
  1223. self.result_code = code.get_py_float(self.value, c_value)
  1224. else:
  1225. self.result_code = c_value
  1226. def _analyse_name_as_type(name, pos, env):
  1227. type = PyrexTypes.parse_basic_type(name)
  1228. if type is not None:
  1229. return type
  1230. global_entry = env.global_scope().lookup(name)
  1231. if global_entry and global_entry.type and (
  1232. global_entry.type.is_extension_type
  1233. or global_entry.type.is_struct_or_union
  1234. or global_entry.type.is_builtin_type
  1235. or global_entry.type.is_cpp_class):
  1236. return global_entry.type
  1237. from .TreeFragment import TreeFragment
  1238. with local_errors(ignore=True):
  1239. pos = (pos[0], pos[1], pos[2]-7)
  1240. try:
  1241. declaration = TreeFragment(u"sizeof(%s)" % name, name=pos[0].filename, initial_pos=pos)
  1242. except CompileError:
  1243. pass
  1244. else:
  1245. sizeof_node = declaration.root.stats[0].expr
  1246. if isinstance(sizeof_node, SizeofTypeNode):
  1247. sizeof_node = sizeof_node.analyse_types(env)
  1248. if isinstance(sizeof_node, SizeofTypeNode):
  1249. return sizeof_node.arg_type
  1250. return None
  1251. class BytesNode(ConstNode):
  1252. # A char* or bytes literal
  1253. #
  1254. # value BytesLiteral
  1255. is_string_literal = True
  1256. # start off as Python 'bytes' to support len() in O(1)
  1257. type = bytes_type
  1258. def calculate_constant_result(self):
  1259. self.constant_result = self.value
  1260. def as_sliced_node(self, start, stop, step=None):
  1261. value = StringEncoding.bytes_literal(self.value[start:stop:step], self.value.encoding)
  1262. return BytesNode(self.pos, value=value, constant_result=value)
  1263. def compile_time_value(self, denv):
  1264. return self.value.byteencode()
  1265. def analyse_as_type(self, env):
  1266. return _analyse_name_as_type(self.value.decode('ISO8859-1'), self.pos, env)
  1267. def can_coerce_to_char_literal(self):
  1268. return len(self.value) == 1
  1269. def coerce_to_boolean(self, env):
  1270. # This is special because testing a C char* for truth directly
  1271. # would yield the wrong result.
  1272. bool_value = bool(self.value)
  1273. return BoolNode(self.pos, value=bool_value, constant_result=bool_value)
  1274. def coerce_to(self, dst_type, env):
  1275. if self.type == dst_type:
  1276. return self
  1277. if dst_type.is_int:
  1278. if not self.can_coerce_to_char_literal():
  1279. error(self.pos, "Only single-character string literals can be coerced into ints.")
  1280. return self
  1281. if dst_type.is_unicode_char:
  1282. error(self.pos, "Bytes literals cannot coerce to Py_UNICODE/Py_UCS4, use a unicode literal instead.")
  1283. return self
  1284. return CharNode(self.pos, value=self.value,
  1285. constant_result=ord(self.value))
  1286. node = BytesNode(self.pos, value=self.value, constant_result=self.constant_result)
  1287. if dst_type.is_pyobject:
  1288. if dst_type in (py_object_type, Builtin.bytes_type):
  1289. node.type = Builtin.bytes_type
  1290. else:
  1291. self.check_for_coercion_error(dst_type, env, fail=True)
  1292. return node
  1293. elif dst_type in (PyrexTypes.c_char_ptr_type, PyrexTypes.c_const_char_ptr_type):
  1294. node.type = dst_type
  1295. return node
  1296. elif dst_type in (PyrexTypes.c_uchar_ptr_type, PyrexTypes.c_const_uchar_ptr_type, PyrexTypes.c_void_ptr_type):
  1297. node.type = (PyrexTypes.c_const_char_ptr_type if dst_type == PyrexTypes.c_const_uchar_ptr_type
  1298. else PyrexTypes.c_char_ptr_type)
  1299. return CastNode(node, dst_type)
  1300. elif dst_type.assignable_from(PyrexTypes.c_char_ptr_type):
  1301. # Exclude the case of passing a C string literal into a non-const C++ string.
  1302. if not dst_type.is_cpp_class or dst_type.is_const:
  1303. node.type = dst_type
  1304. return node
  1305. # We still need to perform normal coerce_to processing on the
  1306. # result, because we might be coercing to an extension type,
  1307. # in which case a type test node will be needed.
  1308. return ConstNode.coerce_to(node, dst_type, env)
  1309. def generate_evaluation_code(self, code):
  1310. if self.type.is_pyobject:
  1311. result = code.get_py_string_const(self.value)
  1312. elif self.type.is_const:
  1313. result = code.get_string_const(self.value)
  1314. else:
  1315. # not const => use plain C string literal and cast to mutable type
  1316. literal = self.value.as_c_string_literal()
  1317. # C++ may require a cast
  1318. result = typecast(self.type, PyrexTypes.c_void_ptr_type, literal)
  1319. self.result_code = result
  1320. def get_constant_c_result_code(self):
  1321. return None # FIXME
  1322. def calculate_result_code(self):
  1323. return self.result_code
  1324. class UnicodeNode(ConstNode):
  1325. # A Py_UNICODE* or unicode literal
  1326. #
  1327. # value EncodedString
  1328. # bytes_value BytesLiteral the literal parsed as bytes string
  1329. # ('-3' unicode literals only)
  1330. is_string_literal = True
  1331. bytes_value = None
  1332. type = unicode_type
  1333. def calculate_constant_result(self):
  1334. self.constant_result = self.value
  1335. def analyse_as_type(self, env):
  1336. return _analyse_name_as_type(self.value, self.pos, env)
  1337. def as_sliced_node(self, start, stop, step=None):
  1338. if StringEncoding.string_contains_surrogates(self.value[:stop]):
  1339. # this is unsafe as it may give different results
  1340. # in different runtimes
  1341. return None
  1342. value = StringEncoding.EncodedString(self.value[start:stop:step])
  1343. value.encoding = self.value.encoding
  1344. if self.bytes_value is not None:
  1345. bytes_value = StringEncoding.bytes_literal(
  1346. self.bytes_value[start:stop:step], self.bytes_value.encoding)
  1347. else:
  1348. bytes_value = None
  1349. return UnicodeNode(
  1350. self.pos, value=value, bytes_value=bytes_value,
  1351. constant_result=value)
  1352. def coerce_to(self, dst_type, env):
  1353. if dst_type is self.type:
  1354. pass
  1355. elif dst_type.is_unicode_char:
  1356. if not self.can_coerce_to_char_literal():
  1357. error(self.pos,
  1358. "Only single-character Unicode string literals or "
  1359. "surrogate pairs can be coerced into Py_UCS4/Py_UNICODE.")
  1360. return self
  1361. int_value = ord(self.value)
  1362. return IntNode(self.pos, type=dst_type, value=str(int_value),
  1363. constant_result=int_value)
  1364. elif not dst_type.is_pyobject:
  1365. if dst_type.is_string and self.bytes_value is not None:
  1366. # special case: '-3' enforced unicode literal used in a
  1367. # C char* context
  1368. return BytesNode(self.pos, value=self.bytes_value
  1369. ).coerce_to(dst_type, env)
  1370. if dst_type.is_pyunicode_ptr:
  1371. node = UnicodeNode(self.pos, value=self.value)
  1372. node.type = dst_type
  1373. return node
  1374. error(self.pos,
  1375. "Unicode literals do not support coercion to C types other "
  1376. "than Py_UNICODE/Py_UCS4 (for characters) or Py_UNICODE* "
  1377. "(for strings).")
  1378. elif dst_type not in (py_object_type, Builtin.basestring_type):
  1379. self.check_for_coercion_error(dst_type, env, fail=True)
  1380. return self
  1381. def can_coerce_to_char_literal(self):
  1382. return len(self.value) == 1
  1383. ## or (len(self.value) == 2
  1384. ## and (0xD800 <= self.value[0] <= 0xDBFF)
  1385. ## and (0xDC00 <= self.value[1] <= 0xDFFF))
  1386. def coerce_to_boolean(self, env):
  1387. bool_value = bool(self.value)
  1388. return BoolNode(self.pos, value=bool_value, constant_result=bool_value)
  1389. def contains_surrogates(self):
  1390. return StringEncoding.string_contains_surrogates(self.value)
  1391. def generate_evaluation_code(self, code):
  1392. if self.type.is_pyobject:
  1393. # FIXME: this should go away entirely!
  1394. # Since string_contains_lone_surrogates() returns False for surrogate pairs in Py2/UCS2,
  1395. # Py2 can generate different code from Py3 here. Let's hope we get away with claiming that
  1396. # the processing of surrogate pairs in code was always ambiguous and lead to different results
  1397. # on P16/32bit Unicode platforms.
  1398. if StringEncoding.string_contains_lone_surrogates(self.value):
  1399. # lone (unpaired) surrogates are not really portable and cannot be
  1400. # decoded by the UTF-8 codec in Py3.3
  1401. self.result_code = code.get_py_const(py_object_type, 'ustring')
  1402. data_cname = code.get_string_const(
  1403. StringEncoding.BytesLiteral(self.value.encode('unicode_escape')))
  1404. const_code = code.get_cached_constants_writer(self.result_code)
  1405. if const_code is None:
  1406. return # already initialised
  1407. const_code.mark_pos(self.pos)
  1408. const_code.putln(
  1409. "%s = PyUnicode_DecodeUnicodeEscape(%s, sizeof(%s) - 1, NULL); %s" % (
  1410. self.result_code,
  1411. data_cname,
  1412. data_cname,
  1413. const_code.error_goto_if_null(self.result_code, self.pos)))
  1414. const_code.put_error_if_neg(
  1415. self.pos, "__Pyx_PyUnicode_READY(%s)" % self.result_code)
  1416. else:
  1417. self.result_code = code.get_py_string_const(self.value)
  1418. else:
  1419. self.result_code = code.get_pyunicode_ptr_const(self.value)
  1420. def calculate_result_code(self):
  1421. return self.result_code
  1422. def compile_time_value(self, env):
  1423. return self.value
  1424. class StringNode(PyConstNode):
  1425. # A Python str object, i.e. a byte string in Python 2.x and a
  1426. # unicode string in Python 3.x
  1427. #
  1428. # value BytesLiteral (or EncodedString with ASCII content)
  1429. # unicode_value EncodedString or None
  1430. # is_identifier boolean
  1431. type = str_type
  1432. is_string_literal = True
  1433. is_identifier = None
  1434. unicode_value = None
  1435. def calculate_constant_result(self):
  1436. if self.unicode_value is not None:
  1437. # only the Unicode value is portable across Py2/3
  1438. self.constant_result = self.unicode_value
  1439. def analyse_as_type(self, env):
  1440. return _analyse_name_as_type(self.unicode_value or self.value.decode('ISO8859-1'), self.pos, env)
  1441. def as_sliced_node(self, start, stop, step=None):
  1442. value = type(self.value)(self.value[start:stop:step])
  1443. value.encoding = self.value.encoding
  1444. if self.unicode_value is not None:
  1445. if StringEncoding.string_contains_surrogates(self.unicode_value[:stop]):
  1446. # this is unsafe as it may give different results in different runtimes
  1447. return None
  1448. unicode_value = StringEncoding.EncodedString(
  1449. self.unicode_value[start:stop:step])
  1450. else:
  1451. unicode_value = None
  1452. return StringNode(
  1453. self.pos, value=value, unicode_value=unicode_value,
  1454. constant_result=value, is_identifier=self.is_identifier)
  1455. def coerce_to(self, dst_type, env):
  1456. if dst_type is not py_object_type and not str_type.subtype_of(dst_type):
  1457. # if dst_type is Builtin.bytes_type:
  1458. # # special case: bytes = 'str literal'
  1459. # return BytesNode(self.pos, value=self.value)
  1460. if not dst_type.is_pyobject:
  1461. return BytesNode(self.pos, value=self.value).coerce_to(dst_type, env)
  1462. if dst_type is not Builtin.basestring_type:
  1463. self.check_for_coercion_error(dst_type, env, fail=True)
  1464. return self
  1465. def can_coerce_to_char_literal(self):
  1466. return not self.is_identifier and len(self.value) == 1
  1467. def generate_evaluation_code(self, code):
  1468. self.result_code = code.get_py_string_const(
  1469. self.value, identifier=self.is_identifier, is_str=True,
  1470. unicode_value=self.unicode_value)
  1471. def get_constant_c_result_code(self):
  1472. return None
  1473. def calculate_result_code(self):
  1474. return self.result_code
  1475. def compile_time_value(self, env):
  1476. if self.value.is_unicode:
  1477. return self.value
  1478. if not IS_PYTHON3:
  1479. # use plain str/bytes object in Py2
  1480. return self.value.byteencode()
  1481. # in Py3, always return a Unicode string
  1482. if self.unicode_value is not None:
  1483. return self.unicode_value
  1484. return self.value.decode('iso8859-1')
  1485. class IdentifierStringNode(StringNode):
  1486. # A special str value that represents an identifier (bytes in Py2,
  1487. # unicode in Py3).
  1488. is_identifier = True
  1489. class ImagNode(AtomicExprNode):
  1490. # Imaginary number literal
  1491. #
  1492. # value string imaginary part (float value)
  1493. type = PyrexTypes.c_double_complex_type
  1494. def calculate_constant_result(self):
  1495. self.constant_result = complex(0.0, float(self.value))
  1496. def compile_time_value(self, denv):
  1497. return complex(0.0, float(self.value))
  1498. def analyse_types(self, env):
  1499. self.type.create_declaration_utility_code(env)
  1500. return self
  1501. def may_be_none(self):
  1502. return False
  1503. def coerce_to(self, dst_type, env):
  1504. if self.type is dst_type:
  1505. return self
  1506. node = ImagNode(self.pos, value=self.value)
  1507. if dst_type.is_pyobject:
  1508. node.is_temp = 1
  1509. node.type = Builtin.complex_type
  1510. # We still need to perform normal coerce_to processing on the
  1511. # result, because we might be coercing to an extension type,
  1512. # in which case a type test node will be needed.
  1513. return AtomicExprNode.coerce_to(node, dst_type, env)
  1514. gil_message = "Constructing complex number"
  1515. def calculate_result_code(self):
  1516. if self.type.is_pyobject:
  1517. return self.result()
  1518. else:
  1519. return "%s(0, %r)" % (self.type.from_parts, float(self.value))
  1520. def generate_result_code(self, code):
  1521. if self.type.is_pyobject:
  1522. code.putln(
  1523. "%s = PyComplex_FromDoubles(0.0, %r); %s" % (
  1524. self.result(),
  1525. float(self.value),
  1526. code.error_goto_if_null(self.result(), self.pos)))
  1527. code.put_gotref(self.py_result())
  1528. class NewExprNode(AtomicExprNode):
  1529. # C++ new statement
  1530. #
  1531. # cppclass node c++ class to create
  1532. type = None
  1533. def infer_type(self, env):
  1534. type = self.cppclass.analyse_as_type(env)
  1535. if type is None or not type.is_cpp_class:
  1536. error(self.pos, "new operator can only be applied to a C++ class")
  1537. self.type = error_type
  1538. return
  1539. self.cpp_check(env)
  1540. constructor = type.get_constructor(self.pos)
  1541. self.class_type = type
  1542. self.entry = constructor
  1543. self.type = constructor.type
  1544. return self.type
  1545. def analyse_types(self, env):
  1546. if self.type is None:
  1547. self.infer_type(env)
  1548. return self
  1549. def may_be_none(self):
  1550. return False
  1551. def generate_result_code(self, code):
  1552. pass
  1553. def calculate_result_code(self):
  1554. return "new " + self.class_type.empty_declaration_code()
  1555. class NameNode(AtomicExprNode):
  1556. # Reference to a local or global variable name.
  1557. #
  1558. # name string Python name of the variable
  1559. # entry Entry Symbol table entry
  1560. # type_entry Entry For extension type names, the original type entry
  1561. # cf_is_null boolean Is uninitialized before this node
  1562. # cf_maybe_null boolean Maybe uninitialized before this node
  1563. # allow_null boolean Don't raise UnboundLocalError
  1564. # nogil boolean Whether it is used in a nogil context
  1565. is_name = True
  1566. is_cython_module = False
  1567. cython_attribute = None
  1568. lhs_of_first_assignment = False # TODO: remove me
  1569. is_used_as_rvalue = 0
  1570. entry = None
  1571. type_entry = None
  1572. cf_maybe_null = True
  1573. cf_is_null = False
  1574. allow_null = False
  1575. nogil = False
  1576. inferred_type = None
  1577. def as_cython_attribute(self):
  1578. return self.cython_attribute
  1579. def type_dependencies(self, env):
  1580. if self.entry is None:
  1581. self.entry = env.lookup(self.name)
  1582. if self.entry is not None and self.entry.type.is_unspecified:
  1583. return (self,)
  1584. else:
  1585. return ()
  1586. def infer_type(self, env):
  1587. if self.entry is None:
  1588. self.entry = env.lookup(self.name)
  1589. if self.entry is None or self.entry.type is unspecified_type:
  1590. if self.inferred_type is not None:
  1591. return self.inferred_type
  1592. return py_object_type
  1593. elif (self.entry.type.is_extension_type or self.entry.type.is_builtin_type) and \
  1594. self.name == self.entry.type.name:
  1595. # Unfortunately the type attribute of type objects
  1596. # is used for the pointer to the type they represent.
  1597. return type_type
  1598. elif self.entry.type.is_cfunction:
  1599. if self.entry.scope.is_builtin_scope:
  1600. # special case: optimised builtin functions must be treated as Python objects
  1601. return py_object_type
  1602. else:
  1603. # special case: referring to a C function must return its pointer
  1604. return PyrexTypes.CPtrType(self.entry.type)
  1605. else:
  1606. # If entry is inferred as pyobject it's safe to use local
  1607. # NameNode's inferred_type.
  1608. if self.entry.type.is_pyobject and self.inferred_type:
  1609. # Overflow may happen if integer
  1610. if not (self.inferred_type.is_int and self.entry.might_overflow):
  1611. return self.inferred_type
  1612. return self.entry.type
  1613. def compile_time_value(self, denv):
  1614. try:
  1615. return denv.lookup(self.name)
  1616. except KeyError:
  1617. error(self.pos, "Compile-time name '%s' not defined" % self.name)
  1618. def get_constant_c_result_code(self):
  1619. if not self.entry or self.entry.type.is_pyobject:
  1620. return None
  1621. return self.entry.cname
  1622. def coerce_to(self, dst_type, env):
  1623. # If coercing to a generic pyobject and this is a builtin
  1624. # C function with a Python equivalent, manufacture a NameNode
  1625. # referring to the Python builtin.
  1626. #print "NameNode.coerce_to:", self.name, dst_type ###
  1627. if dst_type is py_object_type:
  1628. entry = self.entry
  1629. if entry and entry.is_cfunction:
  1630. var_entry = entry.as_variable
  1631. if var_entry:
  1632. if var_entry.is_builtin and var_entry.is_const:
  1633. var_entry = env.declare_builtin(var_entry.name, self.pos)
  1634. node = NameNode(self.pos, name = self.name)
  1635. node.entry = var_entry
  1636. node.analyse_rvalue_entry(env)
  1637. return node
  1638. return super(NameNode, self).coerce_to(dst_type, env)
  1639. def declare_from_annotation(self, env, as_target=False):
  1640. """Implements PEP 526 annotation typing in a fairly relaxed way.
  1641. Annotations are ignored for global variables, Python class attributes and already declared variables.
  1642. String literals are allowed and ignored.
  1643. The ambiguous Python types 'int' and 'long' are ignored and the 'cython.int' form must be used instead.
  1644. """
  1645. if not env.directives['annotation_typing']:
  1646. return
  1647. if env.is_module_scope or env.is_py_class_scope:
  1648. # annotations never create global cdef names and Python classes don't support them anyway
  1649. return
  1650. name = self.name
  1651. if self.entry or env.lookup_here(name) is not None:
  1652. # already declared => ignore annotation
  1653. return
  1654. annotation = self.annotation
  1655. if annotation.is_string_literal:
  1656. # name: "description" => not a type, but still a declared variable or attribute
  1657. atype = None
  1658. else:
  1659. _, atype = analyse_type_annotation(annotation, env)
  1660. if atype is None:
  1661. atype = unspecified_type if as_target and env.directives['infer_types'] != False else py_object_type
  1662. self.entry = env.declare_var(name, atype, self.pos, is_cdef=not as_target)
  1663. self.entry.annotation = annotation
  1664. def analyse_as_module(self, env):
  1665. # Try to interpret this as a reference to a cimported module.
  1666. # Returns the module scope, or None.
  1667. entry = self.entry
  1668. if not entry:
  1669. entry = env.lookup(self.name)
  1670. if entry and entry.as_module:
  1671. return entry.as_module
  1672. return None
  1673. def analyse_as_type(self, env):
  1674. if self.cython_attribute:
  1675. type = PyrexTypes.parse_basic_type(self.cython_attribute)
  1676. else:
  1677. type = PyrexTypes.parse_basic_type(self.name)
  1678. if type:
  1679. return type
  1680. entry = self.entry
  1681. if not entry:
  1682. entry = env.lookup(self.name)
  1683. if entry and entry.is_type:
  1684. return entry.type
  1685. else:
  1686. return None
  1687. def analyse_as_extension_type(self, env):
  1688. # Try to interpret this as a reference to an extension type.
  1689. # Returns the extension type, or None.
  1690. entry = self.entry
  1691. if not entry:
  1692. entry = env.lookup(self.name)
  1693. if entry and entry.is_type:
  1694. if entry.type.is_extension_type or entry.type.is_builtin_type:
  1695. return entry.type
  1696. return None
  1697. def analyse_target_declaration(self, env):
  1698. if not self.entry:
  1699. self.entry = env.lookup_here(self.name)
  1700. if not self.entry and self.annotation is not None:
  1701. # name : type = ...
  1702. self.declare_from_annotation(env, as_target=True)
  1703. if not self.entry:
  1704. if env.directives['warn.undeclared']:
  1705. warning(self.pos, "implicit declaration of '%s'" % self.name, 1)
  1706. if env.directives['infer_types'] != False:
  1707. type = unspecified_type
  1708. else:
  1709. type = py_object_type
  1710. self.entry = env.declare_var(self.name, type, self.pos)
  1711. if self.entry.is_declared_generic:
  1712. self.result_ctype = py_object_type
  1713. if self.entry.as_module:
  1714. # cimported modules namespace can shadow actual variables
  1715. self.entry.is_variable = 1
  1716. def analyse_types(self, env):
  1717. self.initialized_check = env.directives['initializedcheck']
  1718. entry = self.entry
  1719. if entry is None:
  1720. entry = env.lookup(self.name)
  1721. if not entry:
  1722. entry = env.declare_builtin(self.name, self.pos)
  1723. if entry and entry.is_builtin and entry.is_const:
  1724. self.is_literal = True
  1725. if not entry:
  1726. self.type = PyrexTypes.error_type
  1727. return self
  1728. self.entry = entry
  1729. entry.used = 1
  1730. if entry.type.is_buffer:
  1731. from . import Buffer
  1732. Buffer.used_buffer_aux_vars(entry)
  1733. self.analyse_rvalue_entry(env)
  1734. return self
  1735. def analyse_target_types(self, env):
  1736. self.analyse_entry(env, is_target=True)
  1737. entry = self.entry
  1738. if entry.is_cfunction and entry.as_variable:
  1739. # FIXME: unify "is_overridable" flags below
  1740. if (entry.is_overridable or entry.type.is_overridable) or not self.is_lvalue() and entry.fused_cfunction:
  1741. # We need this for assigning to cpdef names and for the fused 'def' TreeFragment
  1742. entry = self.entry = entry.as_variable
  1743. self.type = entry.type
  1744. if self.type.is_const:
  1745. error(self.pos, "Assignment to const '%s'" % self.name)
  1746. if self.type.is_reference:
  1747. error(self.pos, "Assignment to reference '%s'" % self.name)
  1748. if not self.is_lvalue():
  1749. error(self.pos, "Assignment to non-lvalue '%s'" % self.name)
  1750. self.type = PyrexTypes.error_type
  1751. entry.used = 1
  1752. if entry.type.is_buffer:
  1753. from . import Buffer
  1754. Buffer.used_buffer_aux_vars(entry)
  1755. return self
  1756. def analyse_rvalue_entry(self, env):
  1757. #print "NameNode.analyse_rvalue_entry:", self.name ###
  1758. #print "Entry:", self.entry.__dict__ ###
  1759. self.analyse_entry(env)
  1760. entry = self.entry
  1761. if entry.is_declared_generic:
  1762. self.result_ctype = py_object_type
  1763. if entry.is_pyglobal or entry.is_builtin:
  1764. if entry.is_builtin and entry.is_const:
  1765. self.is_temp = 0
  1766. else:
  1767. self.is_temp = 1
  1768. self.is_used_as_rvalue = 1
  1769. elif entry.type.is_memoryviewslice:
  1770. self.is_temp = False
  1771. self.is_used_as_rvalue = True
  1772. self.use_managed_ref = True
  1773. return self
  1774. def nogil_check(self, env):
  1775. self.nogil = True
  1776. if self.is_used_as_rvalue:
  1777. entry = self.entry
  1778. if entry.is_builtin:
  1779. if not entry.is_const: # cached builtins are ok
  1780. self.gil_error()
  1781. elif entry.is_pyglobal:
  1782. self.gil_error()
  1783. gil_message = "Accessing Python global or builtin"
  1784. def analyse_entry(self, env, is_target=False):
  1785. #print "NameNode.analyse_entry:", self.name ###
  1786. self.check_identifier_kind()
  1787. entry = self.entry
  1788. type = entry.type
  1789. if (not is_target and type.is_pyobject and self.inferred_type and
  1790. self.inferred_type.is_builtin_type):
  1791. # assume that type inference is smarter than the static entry
  1792. type = self.inferred_type
  1793. self.type = type
  1794. def check_identifier_kind(self):
  1795. # Check that this is an appropriate kind of name for use in an
  1796. # expression. Also finds the variable entry associated with
  1797. # an extension type.
  1798. entry = self.entry
  1799. if entry.is_type and entry.type.is_extension_type:
  1800. self.type_entry = entry
  1801. if entry.is_type and entry.type.is_enum:
  1802. py_entry = Symtab.Entry(self.name, None, py_object_type)
  1803. py_entry.is_pyglobal = True
  1804. py_entry.scope = self.entry.scope
  1805. self.entry = py_entry
  1806. elif not (entry.is_const or entry.is_variable or
  1807. entry.is_builtin or entry.is_cfunction or
  1808. entry.is_cpp_class):
  1809. if self.entry.as_variable:
  1810. self.entry = self.entry.as_variable
  1811. elif not self.is_cython_module:
  1812. error(self.pos, "'%s' is not a constant, variable or function identifier" % self.name)
  1813. def is_cimported_module_without_shadow(self, env):
  1814. if self.is_cython_module or self.cython_attribute:
  1815. return False
  1816. entry = self.entry or env.lookup(self.name)
  1817. return entry.as_module and not entry.is_variable
  1818. def is_simple(self):
  1819. # If it's not a C variable, it'll be in a temp.
  1820. return 1
  1821. def may_be_none(self):
  1822. if self.cf_state and self.type and (self.type.is_pyobject or
  1823. self.type.is_memoryviewslice):
  1824. # gard against infinite recursion on self-dependencies
  1825. if getattr(self, '_none_checking', False):
  1826. # self-dependency - either this node receives a None
  1827. # value from *another* node, or it can not reference
  1828. # None at this point => safe to assume "not None"
  1829. return False
  1830. self._none_checking = True
  1831. # evaluate control flow state to see if there were any
  1832. # potential None values assigned to the node so far
  1833. may_be_none = False
  1834. for assignment in self.cf_state:
  1835. if assignment.rhs.may_be_none():
  1836. may_be_none = True
  1837. break
  1838. del self._none_checking
  1839. return may_be_none
  1840. return super(NameNode, self).may_be_none()
  1841. def nonlocally_immutable(self):
  1842. if ExprNode.nonlocally_immutable(self):
  1843. return True
  1844. entry = self.entry
  1845. if not entry or entry.in_closure:
  1846. return False
  1847. return entry.is_local or entry.is_arg or entry.is_builtin or entry.is_readonly
  1848. def calculate_target_results(self, env):
  1849. pass
  1850. def check_const(self):
  1851. entry = self.entry
  1852. if entry is not None and not (
  1853. entry.is_const or
  1854. entry.is_cfunction or
  1855. entry.is_builtin or
  1856. entry.type.is_const):
  1857. self.not_const()
  1858. return False
  1859. return True
  1860. def check_const_addr(self):
  1861. entry = self.entry
  1862. if not (entry.is_cglobal or entry.is_cfunction or entry.is_builtin):
  1863. self.addr_not_const()
  1864. return False
  1865. return True
  1866. def is_lvalue(self):
  1867. return (
  1868. self.entry.is_variable and
  1869. not self.entry.is_readonly
  1870. ) or (
  1871. self.entry.is_cfunction and
  1872. self.entry.is_overridable
  1873. )
  1874. def is_addressable(self):
  1875. return self.entry.is_variable and not self.type.is_memoryviewslice
  1876. def is_ephemeral(self):
  1877. # Name nodes are never ephemeral, even if the
  1878. # result is in a temporary.
  1879. return 0
  1880. def calculate_result_code(self):
  1881. entry = self.entry
  1882. if not entry:
  1883. return "<error>" # There was an error earlier
  1884. return entry.cname
  1885. def generate_result_code(self, code):
  1886. assert hasattr(self, 'entry')
  1887. entry = self.entry
  1888. if entry is None:
  1889. return # There was an error earlier
  1890. if entry.utility_code:
  1891. code.globalstate.use_utility_code(entry.utility_code)
  1892. if entry.is_builtin and entry.is_const:
  1893. return # Lookup already cached
  1894. elif entry.is_pyclass_attr:
  1895. assert entry.type.is_pyobject, "Python global or builtin not a Python object"
  1896. interned_cname = code.intern_identifier(self.entry.name)
  1897. if entry.is_builtin:
  1898. namespace = Naming.builtins_cname
  1899. else: # entry.is_pyglobal
  1900. namespace = entry.scope.namespace_cname
  1901. if not self.cf_is_null:
  1902. code.putln(
  1903. '%s = PyObject_GetItem(%s, %s);' % (
  1904. self.result(),
  1905. namespace,
  1906. interned_cname))
  1907. code.putln('if (unlikely(!%s)) {' % self.result())
  1908. code.putln('PyErr_Clear();')
  1909. code.globalstate.use_utility_code(
  1910. UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c"))
  1911. code.putln(
  1912. '__Pyx_GetModuleGlobalName(%s, %s);' % (
  1913. self.result(),
  1914. interned_cname))
  1915. if not self.cf_is_null:
  1916. code.putln("}")
  1917. code.putln(code.error_goto_if_null(self.result(), self.pos))
  1918. code.put_gotref(self.py_result())
  1919. elif entry.is_builtin and not entry.scope.is_module_scope:
  1920. # known builtin
  1921. assert entry.type.is_pyobject, "Python global or builtin not a Python object"
  1922. interned_cname = code.intern_identifier(self.entry.name)
  1923. code.globalstate.use_utility_code(
  1924. UtilityCode.load_cached("GetBuiltinName", "ObjectHandling.c"))
  1925. code.putln(
  1926. '%s = __Pyx_GetBuiltinName(%s); %s' % (
  1927. self.result(),
  1928. interned_cname,
  1929. code.error_goto_if_null(self.result(), self.pos)))
  1930. code.put_gotref(self.py_result())
  1931. elif entry.is_pyglobal or (entry.is_builtin and entry.scope.is_module_scope):
  1932. # name in class body, global name or unknown builtin
  1933. assert entry.type.is_pyobject, "Python global or builtin not a Python object"
  1934. interned_cname = code.intern_identifier(self.entry.name)
  1935. if entry.scope.is_module_scope:
  1936. code.globalstate.use_utility_code(
  1937. UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c"))
  1938. code.putln(
  1939. '__Pyx_GetModuleGlobalName(%s, %s); %s' % (
  1940. self.result(),
  1941. interned_cname,
  1942. code.error_goto_if_null(self.result(), self.pos)))
  1943. else:
  1944. # FIXME: is_pyglobal is also used for class namespace
  1945. code.globalstate.use_utility_code(
  1946. UtilityCode.load_cached("GetNameInClass", "ObjectHandling.c"))
  1947. code.putln(
  1948. '__Pyx_GetNameInClass(%s, %s, %s); %s' % (
  1949. self.result(),
  1950. entry.scope.namespace_cname,
  1951. interned_cname,
  1952. code.error_goto_if_null(self.result(), self.pos)))
  1953. code.put_gotref(self.py_result())
  1954. elif entry.is_local or entry.in_closure or entry.from_closure or entry.type.is_memoryviewslice:
  1955. # Raise UnboundLocalError for objects and memoryviewslices
  1956. raise_unbound = (
  1957. (self.cf_maybe_null or self.cf_is_null) and not self.allow_null)
  1958. null_code = entry.type.check_for_null_code(entry.cname)
  1959. memslice_check = entry.type.is_memoryviewslice and self.initialized_check
  1960. if null_code and raise_unbound and (entry.type.is_pyobject or memslice_check):
  1961. code.put_error_if_unbound(self.pos, entry, self.in_nogil_context)
  1962. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  1963. exception_check=None, exception_value=None):
  1964. #print "NameNode.generate_assignment_code:", self.name ###
  1965. entry = self.entry
  1966. if entry is None:
  1967. return # There was an error earlier
  1968. if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
  1969. and not self.lhs_of_first_assignment and not rhs.in_module_scope):
  1970. error(self.pos, "Literal list must be assigned to pointer at time of declaration")
  1971. # is_pyglobal seems to be True for module level-globals only.
  1972. # We use this to access class->tp_dict if necessary.
  1973. if entry.is_pyglobal:
  1974. assert entry.type.is_pyobject, "Python global or builtin not a Python object"
  1975. interned_cname = code.intern_identifier(self.entry.name)
  1976. namespace = self.entry.scope.namespace_cname
  1977. if entry.is_member:
  1978. # if the entry is a member we have to cheat: SetAttr does not work
  1979. # on types, so we create a descriptor which is then added to tp_dict
  1980. setter = 'PyDict_SetItem'
  1981. namespace = '%s->tp_dict' % namespace
  1982. elif entry.scope.is_module_scope:
  1983. setter = 'PyDict_SetItem'
  1984. namespace = Naming.moddict_cname
  1985. elif entry.is_pyclass_attr:
  1986. code.globalstate.use_utility_code(UtilityCode.load_cached("SetNameInClass", "ObjectHandling.c"))
  1987. setter = '__Pyx_SetNameInClass'
  1988. else:
  1989. assert False, repr(entry)
  1990. code.put_error_if_neg(
  1991. self.pos,
  1992. '%s(%s, %s, %s)' % (
  1993. setter,
  1994. namespace,
  1995. interned_cname,
  1996. rhs.py_result()))
  1997. if debug_disposal_code:
  1998. print("NameNode.generate_assignment_code:")
  1999. print("...generating disposal code for %s" % rhs)
  2000. rhs.generate_disposal_code(code)
  2001. rhs.free_temps(code)
  2002. if entry.is_member:
  2003. # in Py2.6+, we need to invalidate the method cache
  2004. code.putln("PyType_Modified(%s);" %
  2005. entry.scope.parent_type.typeptr_cname)
  2006. else:
  2007. if self.type.is_memoryviewslice:
  2008. self.generate_acquire_memoryviewslice(rhs, code)
  2009. elif self.type.is_buffer:
  2010. # Generate code for doing the buffer release/acquisition.
  2011. # This might raise an exception in which case the assignment (done
  2012. # below) will not happen.
  2013. #
  2014. # The reason this is not in a typetest-like node is because the
  2015. # variables that the acquired buffer info is stored to is allocated
  2016. # per entry and coupled with it.
  2017. self.generate_acquire_buffer(rhs, code)
  2018. assigned = False
  2019. if self.type.is_pyobject:
  2020. #print "NameNode.generate_assignment_code: to", self.name ###
  2021. #print "...from", rhs ###
  2022. #print "...LHS type", self.type, "ctype", self.ctype() ###
  2023. #print "...RHS type", rhs.type, "ctype", rhs.ctype() ###
  2024. if self.use_managed_ref:
  2025. rhs.make_owned_reference(code)
  2026. is_external_ref = entry.is_cglobal or self.entry.in_closure or self.entry.from_closure
  2027. if is_external_ref:
  2028. if not self.cf_is_null:
  2029. if self.cf_maybe_null:
  2030. code.put_xgotref(self.py_result())
  2031. else:
  2032. code.put_gotref(self.py_result())
  2033. assigned = True
  2034. if entry.is_cglobal:
  2035. code.put_decref_set(
  2036. self.result(), rhs.result_as(self.ctype()))
  2037. else:
  2038. if not self.cf_is_null:
  2039. if self.cf_maybe_null:
  2040. code.put_xdecref_set(
  2041. self.result(), rhs.result_as(self.ctype()))
  2042. else:
  2043. code.put_decref_set(
  2044. self.result(), rhs.result_as(self.ctype()))
  2045. else:
  2046. assigned = False
  2047. if is_external_ref:
  2048. code.put_giveref(rhs.py_result())
  2049. if not self.type.is_memoryviewslice:
  2050. if not assigned:
  2051. if overloaded_assignment:
  2052. result = rhs.result()
  2053. if exception_check == '+':
  2054. translate_cpp_exception(
  2055. code, self.pos,
  2056. '%s = %s;' % (self.result(), result),
  2057. self.result() if self.type.is_pyobject else None,
  2058. exception_value, self.in_nogil_context)
  2059. else:
  2060. code.putln('%s = %s;' % (self.result(), result))
  2061. else:
  2062. result = rhs.result_as(self.ctype())
  2063. if is_pythran_expr(self.type):
  2064. code.putln('new (&%s) decltype(%s){%s};' % (self.result(), self.result(), result))
  2065. elif result != self.result():
  2066. code.putln('%s = %s;' % (self.result(), result))
  2067. if debug_disposal_code:
  2068. print("NameNode.generate_assignment_code:")
  2069. print("...generating post-assignment code for %s" % rhs)
  2070. rhs.generate_post_assignment_code(code)
  2071. elif rhs.result_in_temp():
  2072. rhs.generate_post_assignment_code(code)
  2073. rhs.free_temps(code)
  2074. def generate_acquire_memoryviewslice(self, rhs, code):
  2075. """
  2076. Slices, coercions from objects, return values etc are new references.
  2077. We have a borrowed reference in case of dst = src
  2078. """
  2079. from . import MemoryView
  2080. MemoryView.put_acquire_memoryviewslice(
  2081. lhs_cname=self.result(),
  2082. lhs_type=self.type,
  2083. lhs_pos=self.pos,
  2084. rhs=rhs,
  2085. code=code,
  2086. have_gil=not self.in_nogil_context,
  2087. first_assignment=self.cf_is_null)
  2088. def generate_acquire_buffer(self, rhs, code):
  2089. # rhstmp is only used in case the rhs is a complicated expression leading to
  2090. # the object, to avoid repeating the same C expression for every reference
  2091. # to the rhs. It does NOT hold a reference.
  2092. pretty_rhs = isinstance(rhs, NameNode) or rhs.is_temp
  2093. if pretty_rhs:
  2094. rhstmp = rhs.result_as(self.ctype())
  2095. else:
  2096. rhstmp = code.funcstate.allocate_temp(self.entry.type, manage_ref=False)
  2097. code.putln('%s = %s;' % (rhstmp, rhs.result_as(self.ctype())))
  2098. from . import Buffer
  2099. Buffer.put_assign_to_buffer(self.result(), rhstmp, self.entry,
  2100. is_initialized=not self.lhs_of_first_assignment,
  2101. pos=self.pos, code=code)
  2102. if not pretty_rhs:
  2103. code.putln("%s = 0;" % rhstmp)
  2104. code.funcstate.release_temp(rhstmp)
  2105. def generate_deletion_code(self, code, ignore_nonexisting=False):
  2106. if self.entry is None:
  2107. return # There was an error earlier
  2108. elif self.entry.is_pyclass_attr:
  2109. namespace = self.entry.scope.namespace_cname
  2110. interned_cname = code.intern_identifier(self.entry.name)
  2111. if ignore_nonexisting:
  2112. key_error_code = 'PyErr_Clear(); else'
  2113. else:
  2114. # minor hack: fake a NameError on KeyError
  2115. key_error_code = (
  2116. '{ PyErr_Clear(); PyErr_Format(PyExc_NameError, "name \'%%s\' is not defined", "%s"); }' %
  2117. self.entry.name)
  2118. code.putln(
  2119. 'if (unlikely(PyObject_DelItem(%s, %s) < 0)) {'
  2120. ' if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) %s'
  2121. ' %s '
  2122. '}' % (namespace, interned_cname,
  2123. key_error_code,
  2124. code.error_goto(self.pos)))
  2125. elif self.entry.is_pyglobal:
  2126. code.globalstate.use_utility_code(
  2127. UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
  2128. interned_cname = code.intern_identifier(self.entry.name)
  2129. del_code = '__Pyx_PyObject_DelAttrStr(%s, %s)' % (
  2130. Naming.module_cname, interned_cname)
  2131. if ignore_nonexisting:
  2132. code.putln(
  2133. 'if (unlikely(%s < 0)) {'
  2134. ' if (likely(PyErr_ExceptionMatches(PyExc_AttributeError))) PyErr_Clear(); else %s '
  2135. '}' % (del_code, code.error_goto(self.pos)))
  2136. else:
  2137. code.put_error_if_neg(self.pos, del_code)
  2138. elif self.entry.type.is_pyobject or self.entry.type.is_memoryviewslice:
  2139. if not self.cf_is_null:
  2140. if self.cf_maybe_null and not ignore_nonexisting:
  2141. code.put_error_if_unbound(self.pos, self.entry)
  2142. if self.entry.type.is_pyobject:
  2143. if self.entry.in_closure:
  2144. # generator
  2145. if ignore_nonexisting and self.cf_maybe_null:
  2146. code.put_xgotref(self.result())
  2147. else:
  2148. code.put_gotref(self.result())
  2149. if ignore_nonexisting and self.cf_maybe_null:
  2150. code.put_xdecref(self.result(), self.ctype())
  2151. else:
  2152. code.put_decref(self.result(), self.ctype())
  2153. code.putln('%s = NULL;' % self.result())
  2154. else:
  2155. code.put_xdecref_memoryviewslice(self.entry.cname,
  2156. have_gil=not self.nogil)
  2157. else:
  2158. error(self.pos, "Deletion of C names not supported")
  2159. def annotate(self, code):
  2160. if hasattr(self, 'is_called') and self.is_called:
  2161. pos = (self.pos[0], self.pos[1], self.pos[2] - len(self.name) - 1)
  2162. if self.type.is_pyobject:
  2163. style, text = 'py_call', 'python function (%s)'
  2164. else:
  2165. style, text = 'c_call', 'c function (%s)'
  2166. code.annotate(pos, AnnotationItem(style, text % self.type, size=len(self.name)))
  2167. class BackquoteNode(ExprNode):
  2168. # `expr`
  2169. #
  2170. # arg ExprNode
  2171. type = py_object_type
  2172. subexprs = ['arg']
  2173. def analyse_types(self, env):
  2174. self.arg = self.arg.analyse_types(env)
  2175. self.arg = self.arg.coerce_to_pyobject(env)
  2176. self.is_temp = 1
  2177. return self
  2178. gil_message = "Backquote expression"
  2179. def calculate_constant_result(self):
  2180. self.constant_result = repr(self.arg.constant_result)
  2181. def generate_result_code(self, code):
  2182. code.putln(
  2183. "%s = PyObject_Repr(%s); %s" % (
  2184. self.result(),
  2185. self.arg.py_result(),
  2186. code.error_goto_if_null(self.result(), self.pos)))
  2187. code.put_gotref(self.py_result())
  2188. class ImportNode(ExprNode):
  2189. # Used as part of import statement implementation.
  2190. # Implements result =
  2191. # __import__(module_name, globals(), None, name_list, level)
  2192. #
  2193. # module_name StringNode dotted name of module. Empty module
  2194. # name means importing the parent package according
  2195. # to level
  2196. # name_list ListNode or None list of names to be imported
  2197. # level int relative import level:
  2198. # -1: attempt both relative import and absolute import;
  2199. # 0: absolute import;
  2200. # >0: the number of parent directories to search
  2201. # relative to the current module.
  2202. # None: decide the level according to language level and
  2203. # directives
  2204. type = py_object_type
  2205. subexprs = ['module_name', 'name_list']
  2206. def analyse_types(self, env):
  2207. if self.level is None:
  2208. if (env.directives['py2_import'] or
  2209. Future.absolute_import not in env.global_scope().context.future_directives):
  2210. self.level = -1
  2211. else:
  2212. self.level = 0
  2213. module_name = self.module_name.analyse_types(env)
  2214. self.module_name = module_name.coerce_to_pyobject(env)
  2215. if self.name_list:
  2216. name_list = self.name_list.analyse_types(env)
  2217. self.name_list = name_list.coerce_to_pyobject(env)
  2218. self.is_temp = 1
  2219. return self
  2220. gil_message = "Python import"
  2221. def generate_result_code(self, code):
  2222. if self.name_list:
  2223. name_list_code = self.name_list.py_result()
  2224. else:
  2225. name_list_code = "0"
  2226. code.globalstate.use_utility_code(UtilityCode.load_cached("Import", "ImportExport.c"))
  2227. import_code = "__Pyx_Import(%s, %s, %d)" % (
  2228. self.module_name.py_result(),
  2229. name_list_code,
  2230. self.level)
  2231. if (self.level <= 0 and
  2232. self.module_name.is_string_literal and
  2233. self.module_name.value in utility_code_for_imports):
  2234. helper_func, code_name, code_file = utility_code_for_imports[self.module_name.value]
  2235. code.globalstate.use_utility_code(UtilityCode.load_cached(code_name, code_file))
  2236. import_code = '%s(%s)' % (helper_func, import_code)
  2237. code.putln("%s = %s; %s" % (
  2238. self.result(),
  2239. import_code,
  2240. code.error_goto_if_null(self.result(), self.pos)))
  2241. code.put_gotref(self.py_result())
  2242. class IteratorNode(ExprNode):
  2243. # Used as part of for statement implementation.
  2244. #
  2245. # Implements result = iter(sequence)
  2246. #
  2247. # sequence ExprNode
  2248. type = py_object_type
  2249. iter_func_ptr = None
  2250. counter_cname = None
  2251. cpp_iterator_cname = None
  2252. reversed = False # currently only used for list/tuple types (see Optimize.py)
  2253. is_async = False
  2254. subexprs = ['sequence']
  2255. def analyse_types(self, env):
  2256. self.sequence = self.sequence.analyse_types(env)
  2257. if (self.sequence.type.is_array or self.sequence.type.is_ptr) and \
  2258. not self.sequence.type.is_string:
  2259. # C array iteration will be transformed later on
  2260. self.type = self.sequence.type
  2261. elif self.sequence.type.is_cpp_class:
  2262. self.analyse_cpp_types(env)
  2263. else:
  2264. self.sequence = self.sequence.coerce_to_pyobject(env)
  2265. if self.sequence.type in (list_type, tuple_type):
  2266. self.sequence = self.sequence.as_none_safe_node("'NoneType' object is not iterable")
  2267. self.is_temp = 1
  2268. return self
  2269. gil_message = "Iterating over Python object"
  2270. _func_iternext_type = PyrexTypes.CPtrType(PyrexTypes.CFuncType(
  2271. PyrexTypes.py_object_type, [
  2272. PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None),
  2273. ]))
  2274. def type_dependencies(self, env):
  2275. return self.sequence.type_dependencies(env)
  2276. def infer_type(self, env):
  2277. sequence_type = self.sequence.infer_type(env)
  2278. if sequence_type.is_array or sequence_type.is_ptr:
  2279. return sequence_type
  2280. elif sequence_type.is_cpp_class:
  2281. begin = sequence_type.scope.lookup("begin")
  2282. if begin is not None:
  2283. return begin.type.return_type
  2284. elif sequence_type.is_pyobject:
  2285. return sequence_type
  2286. return py_object_type
  2287. def analyse_cpp_types(self, env):
  2288. sequence_type = self.sequence.type
  2289. if sequence_type.is_ptr:
  2290. sequence_type = sequence_type.base_type
  2291. begin = sequence_type.scope.lookup("begin")
  2292. end = sequence_type.scope.lookup("end")
  2293. if (begin is None
  2294. or not begin.type.is_cfunction
  2295. or begin.type.args):
  2296. error(self.pos, "missing begin() on %s" % self.sequence.type)
  2297. self.type = error_type
  2298. return
  2299. if (end is None
  2300. or not end.type.is_cfunction
  2301. or end.type.args):
  2302. error(self.pos, "missing end() on %s" % self.sequence.type)
  2303. self.type = error_type
  2304. return
  2305. iter_type = begin.type.return_type
  2306. if iter_type.is_cpp_class:
  2307. if env.lookup_operator_for_types(
  2308. self.pos,
  2309. "!=",
  2310. [iter_type, end.type.return_type]) is None:
  2311. error(self.pos, "missing operator!= on result of begin() on %s" % self.sequence.type)
  2312. self.type = error_type
  2313. return
  2314. if env.lookup_operator_for_types(self.pos, '++', [iter_type]) is None:
  2315. error(self.pos, "missing operator++ on result of begin() on %s" % self.sequence.type)
  2316. self.type = error_type
  2317. return
  2318. if env.lookup_operator_for_types(self.pos, '*', [iter_type]) is None:
  2319. error(self.pos, "missing operator* on result of begin() on %s" % self.sequence.type)
  2320. self.type = error_type
  2321. return
  2322. self.type = iter_type
  2323. elif iter_type.is_ptr:
  2324. if not (iter_type == end.type.return_type):
  2325. error(self.pos, "incompatible types for begin() and end()")
  2326. self.type = iter_type
  2327. else:
  2328. error(self.pos, "result type of begin() on %s must be a C++ class or pointer" % self.sequence.type)
  2329. self.type = error_type
  2330. return
  2331. def generate_result_code(self, code):
  2332. sequence_type = self.sequence.type
  2333. if sequence_type.is_cpp_class:
  2334. if self.sequence.is_name:
  2335. # safe: C++ won't allow you to reassign to class references
  2336. begin_func = "%s.begin" % self.sequence.result()
  2337. else:
  2338. sequence_type = PyrexTypes.c_ptr_type(sequence_type)
  2339. self.cpp_iterator_cname = code.funcstate.allocate_temp(sequence_type, manage_ref=False)
  2340. code.putln("%s = &%s;" % (self.cpp_iterator_cname, self.sequence.result()))
  2341. begin_func = "%s->begin" % self.cpp_iterator_cname
  2342. # TODO: Limit scope.
  2343. code.putln("%s = %s();" % (self.result(), begin_func))
  2344. return
  2345. if sequence_type.is_array or sequence_type.is_ptr:
  2346. raise InternalError("for in carray slice not transformed")
  2347. is_builtin_sequence = sequence_type in (list_type, tuple_type)
  2348. if not is_builtin_sequence:
  2349. # reversed() not currently optimised (see Optimize.py)
  2350. assert not self.reversed, "internal error: reversed() only implemented for list/tuple objects"
  2351. self.may_be_a_sequence = not sequence_type.is_builtin_type
  2352. if self.may_be_a_sequence:
  2353. code.putln(
  2354. "if (likely(PyList_CheckExact(%s)) || PyTuple_CheckExact(%s)) {" % (
  2355. self.sequence.py_result(),
  2356. self.sequence.py_result()))
  2357. if is_builtin_sequence or self.may_be_a_sequence:
  2358. self.counter_cname = code.funcstate.allocate_temp(
  2359. PyrexTypes.c_py_ssize_t_type, manage_ref=False)
  2360. if self.reversed:
  2361. if sequence_type is list_type:
  2362. init_value = 'PyList_GET_SIZE(%s) - 1' % self.result()
  2363. else:
  2364. init_value = 'PyTuple_GET_SIZE(%s) - 1' % self.result()
  2365. else:
  2366. init_value = '0'
  2367. code.putln("%s = %s; __Pyx_INCREF(%s); %s = %s;" % (
  2368. self.result(),
  2369. self.sequence.py_result(),
  2370. self.result(),
  2371. self.counter_cname,
  2372. init_value))
  2373. if not is_builtin_sequence:
  2374. self.iter_func_ptr = code.funcstate.allocate_temp(self._func_iternext_type, manage_ref=False)
  2375. if self.may_be_a_sequence:
  2376. code.putln("%s = NULL;" % self.iter_func_ptr)
  2377. code.putln("} else {")
  2378. code.put("%s = -1; " % self.counter_cname)
  2379. code.putln("%s = PyObject_GetIter(%s); %s" % (
  2380. self.result(),
  2381. self.sequence.py_result(),
  2382. code.error_goto_if_null(self.result(), self.pos)))
  2383. code.put_gotref(self.py_result())
  2384. # PyObject_GetIter() fails if "tp_iternext" is not set, but the check below
  2385. # makes it visible to the C compiler that the pointer really isn't NULL, so that
  2386. # it can distinguish between the special cases and the generic case
  2387. code.putln("%s = Py_TYPE(%s)->tp_iternext; %s" % (
  2388. self.iter_func_ptr, self.py_result(),
  2389. code.error_goto_if_null(self.iter_func_ptr, self.pos)))
  2390. if self.may_be_a_sequence:
  2391. code.putln("}")
  2392. def generate_next_sequence_item(self, test_name, result_name, code):
  2393. assert self.counter_cname, "internal error: counter_cname temp not prepared"
  2394. final_size = 'Py%s_GET_SIZE(%s)' % (test_name, self.py_result())
  2395. if self.sequence.is_sequence_constructor:
  2396. item_count = len(self.sequence.args)
  2397. if self.sequence.mult_factor is None:
  2398. final_size = item_count
  2399. elif isinstance(self.sequence.mult_factor.constant_result, _py_int_types):
  2400. final_size = item_count * self.sequence.mult_factor.constant_result
  2401. code.putln("if (%s >= %s) break;" % (self.counter_cname, final_size))
  2402. if self.reversed:
  2403. inc_dec = '--'
  2404. else:
  2405. inc_dec = '++'
  2406. code.putln("#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS")
  2407. code.putln(
  2408. "%s = Py%s_GET_ITEM(%s, %s); __Pyx_INCREF(%s); %s%s; %s" % (
  2409. result_name,
  2410. test_name,
  2411. self.py_result(),
  2412. self.counter_cname,
  2413. result_name,
  2414. self.counter_cname,
  2415. inc_dec,
  2416. # use the error label to avoid C compiler warnings if we only use it below
  2417. code.error_goto_if_neg('0', self.pos)
  2418. ))
  2419. code.putln("#else")
  2420. code.putln(
  2421. "%s = PySequence_ITEM(%s, %s); %s%s; %s" % (
  2422. result_name,
  2423. self.py_result(),
  2424. self.counter_cname,
  2425. self.counter_cname,
  2426. inc_dec,
  2427. code.error_goto_if_null(result_name, self.pos)))
  2428. code.put_gotref(result_name)
  2429. code.putln("#endif")
  2430. def generate_iter_next_result_code(self, result_name, code):
  2431. sequence_type = self.sequence.type
  2432. if self.reversed:
  2433. code.putln("if (%s < 0) break;" % self.counter_cname)
  2434. if sequence_type.is_cpp_class:
  2435. if self.cpp_iterator_cname:
  2436. end_func = "%s->end" % self.cpp_iterator_cname
  2437. else:
  2438. end_func = "%s.end" % self.sequence.result()
  2439. # TODO: Cache end() call?
  2440. code.putln("if (!(%s != %s())) break;" % (
  2441. self.result(),
  2442. end_func))
  2443. code.putln("%s = *%s;" % (
  2444. result_name,
  2445. self.result()))
  2446. code.putln("++%s;" % self.result())
  2447. return
  2448. elif sequence_type is list_type:
  2449. self.generate_next_sequence_item('List', result_name, code)
  2450. return
  2451. elif sequence_type is tuple_type:
  2452. self.generate_next_sequence_item('Tuple', result_name, code)
  2453. return
  2454. if self.may_be_a_sequence:
  2455. code.putln("if (likely(!%s)) {" % self.iter_func_ptr)
  2456. code.putln("if (likely(PyList_CheckExact(%s))) {" % self.py_result())
  2457. self.generate_next_sequence_item('List', result_name, code)
  2458. code.putln("} else {")
  2459. self.generate_next_sequence_item('Tuple', result_name, code)
  2460. code.putln("}")
  2461. code.put("} else ")
  2462. code.putln("{")
  2463. code.putln(
  2464. "%s = %s(%s);" % (
  2465. result_name,
  2466. self.iter_func_ptr,
  2467. self.py_result()))
  2468. code.putln("if (unlikely(!%s)) {" % result_name)
  2469. code.putln("PyObject* exc_type = PyErr_Occurred();")
  2470. code.putln("if (exc_type) {")
  2471. code.putln("if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();")
  2472. code.putln("else %s" % code.error_goto(self.pos))
  2473. code.putln("}")
  2474. code.putln("break;")
  2475. code.putln("}")
  2476. code.put_gotref(result_name)
  2477. code.putln("}")
  2478. def free_temps(self, code):
  2479. if self.counter_cname:
  2480. code.funcstate.release_temp(self.counter_cname)
  2481. if self.iter_func_ptr:
  2482. code.funcstate.release_temp(self.iter_func_ptr)
  2483. self.iter_func_ptr = None
  2484. if self.cpp_iterator_cname:
  2485. code.funcstate.release_temp(self.cpp_iterator_cname)
  2486. ExprNode.free_temps(self, code)
  2487. class NextNode(AtomicExprNode):
  2488. # Used as part of for statement implementation.
  2489. # Implements result = next(iterator)
  2490. # Created during analyse_types phase.
  2491. # The iterator is not owned by this node.
  2492. #
  2493. # iterator IteratorNode
  2494. def __init__(self, iterator):
  2495. AtomicExprNode.__init__(self, iterator.pos)
  2496. self.iterator = iterator
  2497. def nogil_check(self, env):
  2498. # ignore - errors (if any) are already handled by IteratorNode
  2499. pass
  2500. def type_dependencies(self, env):
  2501. return self.iterator.type_dependencies(env)
  2502. def infer_type(self, env, iterator_type=None):
  2503. if iterator_type is None:
  2504. iterator_type = self.iterator.infer_type(env)
  2505. if iterator_type.is_ptr or iterator_type.is_array:
  2506. return iterator_type.base_type
  2507. elif self.iterator.sequence.type is bytearray_type:
  2508. # This is a temporary work-around to fix bytearray iteration in 0.29.x
  2509. # It has been fixed properly in master, refer to ticket: 3473
  2510. return py_object_type
  2511. elif iterator_type.is_cpp_class:
  2512. item_type = env.lookup_operator_for_types(self.pos, "*", [iterator_type]).type.return_type
  2513. if item_type.is_reference:
  2514. item_type = item_type.ref_base_type
  2515. if item_type.is_const:
  2516. item_type = item_type.const_base_type
  2517. return item_type
  2518. else:
  2519. # Avoid duplication of complicated logic.
  2520. fake_index_node = IndexNode(
  2521. self.pos,
  2522. base=self.iterator.sequence,
  2523. index=IntNode(self.pos, value='PY_SSIZE_T_MAX',
  2524. type=PyrexTypes.c_py_ssize_t_type))
  2525. return fake_index_node.infer_type(env)
  2526. def analyse_types(self, env):
  2527. self.type = self.infer_type(env, self.iterator.type)
  2528. self.is_temp = 1
  2529. return self
  2530. def generate_result_code(self, code):
  2531. self.iterator.generate_iter_next_result_code(self.result(), code)
  2532. class AsyncIteratorNode(ExprNode):
  2533. # Used as part of 'async for' statement implementation.
  2534. #
  2535. # Implements result = sequence.__aiter__()
  2536. #
  2537. # sequence ExprNode
  2538. subexprs = ['sequence']
  2539. is_async = True
  2540. type = py_object_type
  2541. is_temp = 1
  2542. def infer_type(self, env):
  2543. return py_object_type
  2544. def analyse_types(self, env):
  2545. self.sequence = self.sequence.analyse_types(env)
  2546. if not self.sequence.type.is_pyobject:
  2547. error(self.pos, "async for loops not allowed on C/C++ types")
  2548. self.sequence = self.sequence.coerce_to_pyobject(env)
  2549. return self
  2550. def generate_result_code(self, code):
  2551. code.globalstate.use_utility_code(UtilityCode.load_cached("AsyncIter", "Coroutine.c"))
  2552. code.putln("%s = __Pyx_Coroutine_GetAsyncIter(%s); %s" % (
  2553. self.result(),
  2554. self.sequence.py_result(),
  2555. code.error_goto_if_null(self.result(), self.pos)))
  2556. code.put_gotref(self.result())
  2557. class AsyncNextNode(AtomicExprNode):
  2558. # Used as part of 'async for' statement implementation.
  2559. # Implements result = iterator.__anext__()
  2560. # Created during analyse_types phase.
  2561. # The iterator is not owned by this node.
  2562. #
  2563. # iterator IteratorNode
  2564. type = py_object_type
  2565. is_temp = 1
  2566. def __init__(self, iterator):
  2567. AtomicExprNode.__init__(self, iterator.pos)
  2568. self.iterator = iterator
  2569. def infer_type(self, env):
  2570. return py_object_type
  2571. def analyse_types(self, env):
  2572. return self
  2573. def generate_result_code(self, code):
  2574. code.globalstate.use_utility_code(UtilityCode.load_cached("AsyncIter", "Coroutine.c"))
  2575. code.putln("%s = __Pyx_Coroutine_AsyncIterNext(%s); %s" % (
  2576. self.result(),
  2577. self.iterator.py_result(),
  2578. code.error_goto_if_null(self.result(), self.pos)))
  2579. code.put_gotref(self.result())
  2580. class WithExitCallNode(ExprNode):
  2581. # The __exit__() call of a 'with' statement. Used in both the
  2582. # except and finally clauses.
  2583. # with_stat WithStatNode the surrounding 'with' statement
  2584. # args TupleNode or ResultStatNode the exception info tuple
  2585. # await_expr AwaitExprNode the await expression of an 'async with' statement
  2586. subexprs = ['args', 'await_expr']
  2587. test_if_run = True
  2588. await_expr = None
  2589. def analyse_types(self, env):
  2590. self.args = self.args.analyse_types(env)
  2591. if self.await_expr:
  2592. self.await_expr = self.await_expr.analyse_types(env)
  2593. self.type = PyrexTypes.c_bint_type
  2594. self.is_temp = True
  2595. return self
  2596. def generate_evaluation_code(self, code):
  2597. if self.test_if_run:
  2598. # call only if it was not already called (and decref-cleared)
  2599. code.putln("if (%s) {" % self.with_stat.exit_var)
  2600. self.args.generate_evaluation_code(code)
  2601. result_var = code.funcstate.allocate_temp(py_object_type, manage_ref=False)
  2602. code.mark_pos(self.pos)
  2603. code.globalstate.use_utility_code(UtilityCode.load_cached(
  2604. "PyObjectCall", "ObjectHandling.c"))
  2605. code.putln("%s = __Pyx_PyObject_Call(%s, %s, NULL);" % (
  2606. result_var,
  2607. self.with_stat.exit_var,
  2608. self.args.result()))
  2609. code.put_decref_clear(self.with_stat.exit_var, type=py_object_type)
  2610. self.args.generate_disposal_code(code)
  2611. self.args.free_temps(code)
  2612. code.putln(code.error_goto_if_null(result_var, self.pos))
  2613. code.put_gotref(result_var)
  2614. if self.await_expr:
  2615. # FIXME: result_var temp currently leaks into the closure
  2616. self.await_expr.generate_evaluation_code(code, source_cname=result_var, decref_source=True)
  2617. code.putln("%s = %s;" % (result_var, self.await_expr.py_result()))
  2618. self.await_expr.generate_post_assignment_code(code)
  2619. self.await_expr.free_temps(code)
  2620. if self.result_is_used:
  2621. self.allocate_temp_result(code)
  2622. code.putln("%s = __Pyx_PyObject_IsTrue(%s);" % (self.result(), result_var))
  2623. code.put_decref_clear(result_var, type=py_object_type)
  2624. if self.result_is_used:
  2625. code.put_error_if_neg(self.pos, self.result())
  2626. code.funcstate.release_temp(result_var)
  2627. if self.test_if_run:
  2628. code.putln("}")
  2629. class ExcValueNode(AtomicExprNode):
  2630. # Node created during analyse_types phase
  2631. # of an ExceptClauseNode to fetch the current
  2632. # exception value.
  2633. type = py_object_type
  2634. def __init__(self, pos):
  2635. ExprNode.__init__(self, pos)
  2636. def set_var(self, var):
  2637. self.var = var
  2638. def calculate_result_code(self):
  2639. return self.var
  2640. def generate_result_code(self, code):
  2641. pass
  2642. def analyse_types(self, env):
  2643. return self
  2644. class TempNode(ExprNode):
  2645. # Node created during analyse_types phase
  2646. # of some nodes to hold a temporary value.
  2647. #
  2648. # Note: One must call "allocate" and "release" on
  2649. # the node during code generation to get/release the temp.
  2650. # This is because the temp result is often used outside of
  2651. # the regular cycle.
  2652. subexprs = []
  2653. def __init__(self, pos, type, env=None):
  2654. ExprNode.__init__(self, pos)
  2655. self.type = type
  2656. if type.is_pyobject:
  2657. self.result_ctype = py_object_type
  2658. self.is_temp = 1
  2659. def analyse_types(self, env):
  2660. return self
  2661. def analyse_target_declaration(self, env):
  2662. pass
  2663. def generate_result_code(self, code):
  2664. pass
  2665. def allocate(self, code):
  2666. self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
  2667. def release(self, code):
  2668. code.funcstate.release_temp(self.temp_cname)
  2669. self.temp_cname = None
  2670. def result(self):
  2671. try:
  2672. return self.temp_cname
  2673. except:
  2674. assert False, "Remember to call allocate/release on TempNode"
  2675. raise
  2676. # Do not participate in normal temp alloc/dealloc:
  2677. def allocate_temp_result(self, code):
  2678. pass
  2679. def release_temp_result(self, code):
  2680. pass
  2681. class PyTempNode(TempNode):
  2682. # TempNode holding a Python value.
  2683. def __init__(self, pos, env):
  2684. TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
  2685. class RawCNameExprNode(ExprNode):
  2686. subexprs = []
  2687. def __init__(self, pos, type=None, cname=None):
  2688. ExprNode.__init__(self, pos, type=type)
  2689. if cname is not None:
  2690. self.cname = cname
  2691. def analyse_types(self, env):
  2692. return self
  2693. def set_cname(self, cname):
  2694. self.cname = cname
  2695. def result(self):
  2696. return self.cname
  2697. def generate_result_code(self, code):
  2698. pass
  2699. #-------------------------------------------------------------------
  2700. #
  2701. # F-strings
  2702. #
  2703. #-------------------------------------------------------------------
  2704. class JoinedStrNode(ExprNode):
  2705. # F-strings
  2706. #
  2707. # values [UnicodeNode|FormattedValueNode] Substrings of the f-string
  2708. #
  2709. type = unicode_type
  2710. is_temp = True
  2711. subexprs = ['values']
  2712. def analyse_types(self, env):
  2713. self.values = [v.analyse_types(env).coerce_to_pyobject(env) for v in self.values]
  2714. return self
  2715. def may_be_none(self):
  2716. # PyUnicode_Join() always returns a Unicode string or raises an exception
  2717. return False
  2718. def generate_evaluation_code(self, code):
  2719. code.mark_pos(self.pos)
  2720. num_items = len(self.values)
  2721. list_var = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  2722. ulength_var = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
  2723. max_char_var = code.funcstate.allocate_temp(PyrexTypes.c_py_ucs4_type, manage_ref=False)
  2724. code.putln('%s = PyTuple_New(%s); %s' % (
  2725. list_var,
  2726. num_items,
  2727. code.error_goto_if_null(list_var, self.pos)))
  2728. code.put_gotref(list_var)
  2729. code.putln("%s = 0;" % ulength_var)
  2730. code.putln("%s = 127;" % max_char_var) # at least ASCII character range
  2731. for i, node in enumerate(self.values):
  2732. node.generate_evaluation_code(code)
  2733. node.make_owned_reference(code)
  2734. ulength = "__Pyx_PyUnicode_GET_LENGTH(%s)" % node.py_result()
  2735. max_char_value = "__Pyx_PyUnicode_MAX_CHAR_VALUE(%s)" % node.py_result()
  2736. is_ascii = False
  2737. if isinstance(node, UnicodeNode):
  2738. try:
  2739. # most strings will be ASCII or at least Latin-1
  2740. node.value.encode('iso8859-1')
  2741. max_char_value = '255'
  2742. node.value.encode('us-ascii')
  2743. is_ascii = True
  2744. except UnicodeEncodeError:
  2745. if max_char_value != '255':
  2746. # not ISO8859-1 => check BMP limit
  2747. max_char = max(map(ord, node.value))
  2748. if max_char < 0xD800:
  2749. # BMP-only, no surrogate pairs used
  2750. max_char_value = '65535'
  2751. ulength = str(len(node.value))
  2752. elif max_char >= 65536:
  2753. # cleary outside of BMP, and not on a 16-bit Unicode system
  2754. max_char_value = '1114111'
  2755. ulength = str(len(node.value))
  2756. else:
  2757. # not really worth implementing a check for surrogate pairs here
  2758. # drawback: C code can differ when generating on Py2 with 2-byte Unicode
  2759. pass
  2760. else:
  2761. ulength = str(len(node.value))
  2762. elif isinstance(node, FormattedValueNode) and node.value.type.is_numeric:
  2763. is_ascii = True # formatted C numbers are always ASCII
  2764. if not is_ascii:
  2765. code.putln("%s = (%s > %s) ? %s : %s;" % (
  2766. max_char_var, max_char_value, max_char_var, max_char_value, max_char_var))
  2767. code.putln("%s += %s;" % (ulength_var, ulength))
  2768. code.put_giveref(node.py_result())
  2769. code.putln('PyTuple_SET_ITEM(%s, %s, %s);' % (list_var, i, node.py_result()))
  2770. node.generate_post_assignment_code(code)
  2771. node.free_temps(code)
  2772. code.mark_pos(self.pos)
  2773. self.allocate_temp_result(code)
  2774. code.globalstate.use_utility_code(UtilityCode.load_cached("JoinPyUnicode", "StringTools.c"))
  2775. code.putln('%s = __Pyx_PyUnicode_Join(%s, %d, %s, %s); %s' % (
  2776. self.result(),
  2777. list_var,
  2778. num_items,
  2779. ulength_var,
  2780. max_char_var,
  2781. code.error_goto_if_null(self.py_result(), self.pos)))
  2782. code.put_gotref(self.py_result())
  2783. code.put_decref_clear(list_var, py_object_type)
  2784. code.funcstate.release_temp(list_var)
  2785. code.funcstate.release_temp(ulength_var)
  2786. code.funcstate.release_temp(max_char_var)
  2787. class FormattedValueNode(ExprNode):
  2788. # {}-delimited portions of an f-string
  2789. #
  2790. # value ExprNode The expression itself
  2791. # conversion_char str or None Type conversion (!s, !r, !a, or none, or 'd' for integer conversion)
  2792. # format_spec JoinedStrNode or None Format string passed to __format__
  2793. # c_format_spec str or None If not None, formatting can be done at the C level
  2794. subexprs = ['value', 'format_spec']
  2795. type = unicode_type
  2796. is_temp = True
  2797. c_format_spec = None
  2798. find_conversion_func = {
  2799. 's': 'PyObject_Unicode',
  2800. 'r': 'PyObject_Repr',
  2801. 'a': 'PyObject_ASCII', # NOTE: mapped to PyObject_Repr() in Py2
  2802. 'd': '__Pyx_PyNumber_IntOrLong', # NOTE: internal mapping for '%d' formatting
  2803. }.get
  2804. def may_be_none(self):
  2805. # PyObject_Format() always returns a Unicode string or raises an exception
  2806. return False
  2807. def analyse_types(self, env):
  2808. self.value = self.value.analyse_types(env)
  2809. if not self.format_spec or self.format_spec.is_string_literal:
  2810. c_format_spec = self.format_spec.value if self.format_spec else self.value.type.default_format_spec
  2811. if self.value.type.can_coerce_to_pystring(env, format_spec=c_format_spec):
  2812. self.c_format_spec = c_format_spec
  2813. if self.format_spec:
  2814. self.format_spec = self.format_spec.analyse_types(env).coerce_to_pyobject(env)
  2815. if self.c_format_spec is None:
  2816. self.value = self.value.coerce_to_pyobject(env)
  2817. if not self.format_spec and (not self.conversion_char or self.conversion_char == 's'):
  2818. if self.value.type is unicode_type and not self.value.may_be_none():
  2819. # value is definitely a unicode string and we don't format it any special
  2820. return self.value
  2821. return self
  2822. def generate_result_code(self, code):
  2823. if self.c_format_spec is not None and not self.value.type.is_pyobject:
  2824. convert_func_call = self.value.type.convert_to_pystring(
  2825. self.value.result(), code, self.c_format_spec)
  2826. code.putln("%s = %s; %s" % (
  2827. self.result(),
  2828. convert_func_call,
  2829. code.error_goto_if_null(self.result(), self.pos)))
  2830. code.put_gotref(self.py_result())
  2831. return
  2832. value_result = self.value.py_result()
  2833. value_is_unicode = self.value.type is unicode_type and not self.value.may_be_none()
  2834. if self.format_spec:
  2835. format_func = '__Pyx_PyObject_Format'
  2836. format_spec = self.format_spec.py_result()
  2837. else:
  2838. # common case: expect simple Unicode pass-through if no format spec
  2839. format_func = '__Pyx_PyObject_FormatSimple'
  2840. # passing a Unicode format string in Py2 forces PyObject_Format() to also return a Unicode string
  2841. format_spec = Naming.empty_unicode
  2842. conversion_char = self.conversion_char
  2843. if conversion_char == 's' and value_is_unicode:
  2844. # no need to pipe unicode strings through str()
  2845. conversion_char = None
  2846. if conversion_char:
  2847. fn = self.find_conversion_func(conversion_char)
  2848. assert fn is not None, "invalid conversion character found: '%s'" % conversion_char
  2849. value_result = '%s(%s)' % (fn, value_result)
  2850. code.globalstate.use_utility_code(
  2851. UtilityCode.load_cached("PyObjectFormatAndDecref", "StringTools.c"))
  2852. format_func += 'AndDecref'
  2853. elif self.format_spec:
  2854. code.globalstate.use_utility_code(
  2855. UtilityCode.load_cached("PyObjectFormat", "StringTools.c"))
  2856. else:
  2857. code.globalstate.use_utility_code(
  2858. UtilityCode.load_cached("PyObjectFormatSimple", "StringTools.c"))
  2859. code.putln("%s = %s(%s, %s); %s" % (
  2860. self.result(),
  2861. format_func,
  2862. value_result,
  2863. format_spec,
  2864. code.error_goto_if_null(self.result(), self.pos)))
  2865. code.put_gotref(self.py_result())
  2866. #-------------------------------------------------------------------
  2867. #
  2868. # Parallel nodes (cython.parallel.thread(savailable|id))
  2869. #
  2870. #-------------------------------------------------------------------
  2871. class ParallelThreadsAvailableNode(AtomicExprNode):
  2872. """
  2873. Note: this is disabled and not a valid directive at this moment
  2874. Implements cython.parallel.threadsavailable(). If we are called from the
  2875. sequential part of the application, we need to call omp_get_max_threads(),
  2876. and in the parallel part we can just call omp_get_num_threads()
  2877. """
  2878. type = PyrexTypes.c_int_type
  2879. def analyse_types(self, env):
  2880. self.is_temp = True
  2881. # env.add_include_file("omp.h")
  2882. return self
  2883. def generate_result_code(self, code):
  2884. code.putln("#ifdef _OPENMP")
  2885. code.putln("if (omp_in_parallel()) %s = omp_get_max_threads();" %
  2886. self.temp_code)
  2887. code.putln("else %s = omp_get_num_threads();" % self.temp_code)
  2888. code.putln("#else")
  2889. code.putln("%s = 1;" % self.temp_code)
  2890. code.putln("#endif")
  2891. def result(self):
  2892. return self.temp_code
  2893. class ParallelThreadIdNode(AtomicExprNode): #, Nodes.ParallelNode):
  2894. """
  2895. Implements cython.parallel.threadid()
  2896. """
  2897. type = PyrexTypes.c_int_type
  2898. def analyse_types(self, env):
  2899. self.is_temp = True
  2900. # env.add_include_file("omp.h")
  2901. return self
  2902. def generate_result_code(self, code):
  2903. code.putln("#ifdef _OPENMP")
  2904. code.putln("%s = omp_get_thread_num();" % self.temp_code)
  2905. code.putln("#else")
  2906. code.putln("%s = 0;" % self.temp_code)
  2907. code.putln("#endif")
  2908. def result(self):
  2909. return self.temp_code
  2910. #-------------------------------------------------------------------
  2911. #
  2912. # Trailer nodes
  2913. #
  2914. #-------------------------------------------------------------------
  2915. class _IndexingBaseNode(ExprNode):
  2916. # Base class for indexing nodes.
  2917. #
  2918. # base ExprNode the value being indexed
  2919. def is_ephemeral(self):
  2920. # in most cases, indexing will return a safe reference to an object in a container,
  2921. # so we consider the result safe if the base object is
  2922. return self.base.is_ephemeral() or self.base.type in (
  2923. basestring_type, str_type, bytes_type, bytearray_type, unicode_type)
  2924. def check_const_addr(self):
  2925. return self.base.check_const_addr() and self.index.check_const()
  2926. def is_lvalue(self):
  2927. # NOTE: references currently have both is_reference and is_ptr
  2928. # set. Since pointers and references have different lvalue
  2929. # rules, we must be careful to separate the two.
  2930. if self.type.is_reference:
  2931. if self.type.ref_base_type.is_array:
  2932. # fixed-sized arrays aren't l-values
  2933. return False
  2934. elif self.type.is_ptr:
  2935. # non-const pointers can always be reassigned
  2936. return True
  2937. # Just about everything else returned by the index operator
  2938. # can be an lvalue.
  2939. return True
  2940. class IndexNode(_IndexingBaseNode):
  2941. # Sequence indexing.
  2942. #
  2943. # base ExprNode
  2944. # index ExprNode
  2945. # type_indices [PyrexType]
  2946. #
  2947. # is_fused_index boolean Whether the index is used to specialize a
  2948. # c(p)def function
  2949. subexprs = ['base', 'index']
  2950. type_indices = None
  2951. is_subscript = True
  2952. is_fused_index = False
  2953. def calculate_constant_result(self):
  2954. self.constant_result = self.base.constant_result[self.index.constant_result]
  2955. def compile_time_value(self, denv):
  2956. base = self.base.compile_time_value(denv)
  2957. index = self.index.compile_time_value(denv)
  2958. try:
  2959. return base[index]
  2960. except Exception as e:
  2961. self.compile_time_value_error(e)
  2962. def is_simple(self):
  2963. base = self.base
  2964. return (base.is_simple() and self.index.is_simple()
  2965. and base.type and (base.type.is_ptr or base.type.is_array))
  2966. def may_be_none(self):
  2967. base_type = self.base.type
  2968. if base_type:
  2969. if base_type.is_string:
  2970. return False
  2971. if isinstance(self.index, SliceNode):
  2972. # slicing!
  2973. if base_type in (bytes_type, bytearray_type, str_type, unicode_type,
  2974. basestring_type, list_type, tuple_type):
  2975. return False
  2976. return ExprNode.may_be_none(self)
  2977. def analyse_target_declaration(self, env):
  2978. pass
  2979. def analyse_as_type(self, env):
  2980. base_type = self.base.analyse_as_type(env)
  2981. if base_type and not base_type.is_pyobject:
  2982. if base_type.is_cpp_class:
  2983. if isinstance(self.index, TupleNode):
  2984. template_values = self.index.args
  2985. else:
  2986. template_values = [self.index]
  2987. type_node = Nodes.TemplatedTypeNode(
  2988. pos=self.pos,
  2989. positional_args=template_values,
  2990. keyword_args=None)
  2991. return type_node.analyse(env, base_type=base_type)
  2992. elif self.index.is_slice or self.index.is_sequence_constructor:
  2993. # memory view
  2994. from . import MemoryView
  2995. env.use_utility_code(MemoryView.view_utility_code)
  2996. axes = [self.index] if self.index.is_slice else list(self.index.args)
  2997. return PyrexTypes.MemoryViewSliceType(base_type, MemoryView.get_axes_specs(env, axes))
  2998. else:
  2999. # C array
  3000. index = self.index.compile_time_value(env)
  3001. if index is not None:
  3002. try:
  3003. index = int(index)
  3004. except (ValueError, TypeError):
  3005. pass
  3006. else:
  3007. return PyrexTypes.CArrayType(base_type, index)
  3008. error(self.pos, "Array size must be a compile time constant")
  3009. return None
  3010. def type_dependencies(self, env):
  3011. return self.base.type_dependencies(env) + self.index.type_dependencies(env)
  3012. def infer_type(self, env):
  3013. base_type = self.base.infer_type(env)
  3014. if self.index.is_slice:
  3015. # slicing!
  3016. if base_type.is_string:
  3017. # sliced C strings must coerce to Python
  3018. return bytes_type
  3019. elif base_type.is_pyunicode_ptr:
  3020. # sliced Py_UNICODE* strings must coerce to Python
  3021. return unicode_type
  3022. elif base_type in (unicode_type, bytes_type, str_type,
  3023. bytearray_type, list_type, tuple_type):
  3024. # slicing these returns the same type
  3025. return base_type
  3026. else:
  3027. # TODO: Handle buffers (hopefully without too much redundancy).
  3028. return py_object_type
  3029. index_type = self.index.infer_type(env)
  3030. if index_type and index_type.is_int or isinstance(self.index, IntNode):
  3031. # indexing!
  3032. if base_type is unicode_type:
  3033. # Py_UCS4 will automatically coerce to a unicode string
  3034. # if required, so this is safe. We only infer Py_UCS4
  3035. # when the index is a C integer type. Otherwise, we may
  3036. # need to use normal Python item access, in which case
  3037. # it's faster to return the one-char unicode string than
  3038. # to receive it, throw it away, and potentially rebuild it
  3039. # on a subsequent PyObject coercion.
  3040. return PyrexTypes.c_py_ucs4_type
  3041. elif base_type is str_type:
  3042. # always returns str - Py2: bytes, Py3: unicode
  3043. return base_type
  3044. elif base_type is bytearray_type:
  3045. return PyrexTypes.c_uchar_type
  3046. elif isinstance(self.base, BytesNode):
  3047. #if env.global_scope().context.language_level >= 3:
  3048. # # inferring 'char' can be made to work in Python 3 mode
  3049. # return PyrexTypes.c_char_type
  3050. # Py2/3 return different types on indexing bytes objects
  3051. return py_object_type
  3052. elif base_type in (tuple_type, list_type):
  3053. # if base is a literal, take a look at its values
  3054. item_type = infer_sequence_item_type(
  3055. env, self.base, self.index, seq_type=base_type)
  3056. if item_type is not None:
  3057. return item_type
  3058. elif base_type.is_ptr or base_type.is_array:
  3059. return base_type.base_type
  3060. elif base_type.is_ctuple and isinstance(self.index, IntNode):
  3061. if self.index.has_constant_result():
  3062. index = self.index.constant_result
  3063. if index < 0:
  3064. index += base_type.size
  3065. if 0 <= index < base_type.size:
  3066. return base_type.components[index]
  3067. if base_type.is_cpp_class:
  3068. class FakeOperand:
  3069. def __init__(self, **kwds):
  3070. self.__dict__.update(kwds)
  3071. operands = [
  3072. FakeOperand(pos=self.pos, type=base_type),
  3073. FakeOperand(pos=self.pos, type=index_type),
  3074. ]
  3075. index_func = env.lookup_operator('[]', operands)
  3076. if index_func is not None:
  3077. return index_func.type.return_type
  3078. if is_pythran_expr(base_type) and is_pythran_expr(index_type):
  3079. index_with_type = (self.index, index_type)
  3080. return PythranExpr(pythran_indexing_type(base_type, [index_with_type]))
  3081. # may be slicing or indexing, we don't know
  3082. if base_type in (unicode_type, str_type):
  3083. # these types always returns their own type on Python indexing/slicing
  3084. return base_type
  3085. else:
  3086. # TODO: Handle buffers (hopefully without too much redundancy).
  3087. return py_object_type
  3088. def analyse_types(self, env):
  3089. return self.analyse_base_and_index_types(env, getting=True)
  3090. def analyse_target_types(self, env):
  3091. node = self.analyse_base_and_index_types(env, setting=True)
  3092. if node.type.is_const:
  3093. error(self.pos, "Assignment to const dereference")
  3094. if node is self and not node.is_lvalue():
  3095. error(self.pos, "Assignment to non-lvalue of type '%s'" % node.type)
  3096. return node
  3097. def analyse_base_and_index_types(self, env, getting=False, setting=False,
  3098. analyse_base=True):
  3099. # Note: This might be cleaned up by having IndexNode
  3100. # parsed in a saner way and only construct the tuple if
  3101. # needed.
  3102. if analyse_base:
  3103. self.base = self.base.analyse_types(env)
  3104. if self.base.type.is_error:
  3105. # Do not visit child tree if base is undeclared to avoid confusing
  3106. # error messages
  3107. self.type = PyrexTypes.error_type
  3108. return self
  3109. is_slice = self.index.is_slice
  3110. if not env.directives['wraparound']:
  3111. if is_slice:
  3112. check_negative_indices(self.index.start, self.index.stop)
  3113. else:
  3114. check_negative_indices(self.index)
  3115. # Potentially overflowing index value.
  3116. if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
  3117. self.index = self.index.coerce_to_pyobject(env)
  3118. is_memslice = self.base.type.is_memoryviewslice
  3119. # Handle the case where base is a literal char* (and we expect a string, not an int)
  3120. if not is_memslice and (isinstance(self.base, BytesNode) or is_slice):
  3121. if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
  3122. self.base = self.base.coerce_to_pyobject(env)
  3123. replacement_node = self.analyse_as_buffer_operation(env, getting)
  3124. if replacement_node is not None:
  3125. return replacement_node
  3126. self.nogil = env.nogil
  3127. base_type = self.base.type
  3128. if not base_type.is_cfunction:
  3129. self.index = self.index.analyse_types(env)
  3130. self.original_index_type = self.index.type
  3131. if base_type.is_unicode_char:
  3132. # we infer Py_UNICODE/Py_UCS4 for unicode strings in some
  3133. # cases, but indexing must still work for them
  3134. if setting:
  3135. warning(self.pos, "cannot assign to Unicode string index", level=1)
  3136. elif self.index.constant_result in (0, -1):
  3137. # uchar[0] => uchar
  3138. return self.base
  3139. self.base = self.base.coerce_to_pyobject(env)
  3140. base_type = self.base.type
  3141. if base_type.is_pyobject:
  3142. return self.analyse_as_pyobject(env, is_slice, getting, setting)
  3143. elif base_type.is_ptr or base_type.is_array:
  3144. return self.analyse_as_c_array(env, is_slice)
  3145. elif base_type.is_cpp_class:
  3146. return self.analyse_as_cpp(env, setting)
  3147. elif base_type.is_cfunction:
  3148. return self.analyse_as_c_function(env)
  3149. elif base_type.is_ctuple:
  3150. return self.analyse_as_c_tuple(env, getting, setting)
  3151. else:
  3152. error(self.pos,
  3153. "Attempting to index non-array type '%s'" %
  3154. base_type)
  3155. self.type = PyrexTypes.error_type
  3156. return self
  3157. def analyse_as_pyobject(self, env, is_slice, getting, setting):
  3158. base_type = self.base.type
  3159. if self.index.type.is_unicode_char and base_type is not dict_type:
  3160. # TODO: eventually fold into case below and remove warning, once people have adapted their code
  3161. warning(self.pos,
  3162. "Item lookup of unicode character codes now always converts to a Unicode string. "
  3163. "Use an explicit C integer cast to get back the previous integer lookup behaviour.", level=1)
  3164. self.index = self.index.coerce_to_pyobject(env)
  3165. self.is_temp = 1
  3166. elif self.index.type.is_int and base_type is not dict_type:
  3167. if (getting
  3168. and (base_type in (list_type, tuple_type, bytearray_type))
  3169. and (not self.index.type.signed
  3170. or not env.directives['wraparound']
  3171. or (isinstance(self.index, IntNode) and
  3172. self.index.has_constant_result() and self.index.constant_result >= 0))
  3173. and not env.directives['boundscheck']):
  3174. self.is_temp = 0
  3175. else:
  3176. self.is_temp = 1
  3177. self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
  3178. self.original_index_type.create_to_py_utility_code(env)
  3179. else:
  3180. self.index = self.index.coerce_to_pyobject(env)
  3181. self.is_temp = 1
  3182. if self.index.type.is_int and base_type is unicode_type:
  3183. # Py_UNICODE/Py_UCS4 will automatically coerce to a unicode string
  3184. # if required, so this is fast and safe
  3185. self.type = PyrexTypes.c_py_ucs4_type
  3186. elif self.index.type.is_int and base_type is bytearray_type:
  3187. if setting:
  3188. self.type = PyrexTypes.c_uchar_type
  3189. else:
  3190. # not using 'uchar' to enable fast and safe error reporting as '-1'
  3191. self.type = PyrexTypes.c_int_type
  3192. elif is_slice and base_type in (bytes_type, bytearray_type, str_type, unicode_type, list_type, tuple_type):
  3193. self.type = base_type
  3194. else:
  3195. item_type = None
  3196. if base_type in (list_type, tuple_type) and self.index.type.is_int:
  3197. item_type = infer_sequence_item_type(
  3198. env, self.base, self.index, seq_type=base_type)
  3199. if item_type is None:
  3200. item_type = py_object_type
  3201. self.type = item_type
  3202. if base_type in (list_type, tuple_type, dict_type):
  3203. # do the None check explicitly (not in a helper) to allow optimising it away
  3204. self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
  3205. self.wrap_in_nonecheck_node(env, getting)
  3206. return self
  3207. def analyse_as_c_array(self, env, is_slice):
  3208. base_type = self.base.type
  3209. self.type = base_type.base_type
  3210. if is_slice:
  3211. self.type = base_type
  3212. elif self.index.type.is_pyobject:
  3213. self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env)
  3214. elif not self.index.type.is_int:
  3215. error(self.pos, "Invalid index type '%s'" % self.index.type)
  3216. return self
  3217. def analyse_as_cpp(self, env, setting):
  3218. base_type = self.base.type
  3219. function = env.lookup_operator("[]", [self.base, self.index])
  3220. if function is None:
  3221. error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
  3222. self.type = PyrexTypes.error_type
  3223. self.result_code = "<error>"
  3224. return self
  3225. func_type = function.type
  3226. if func_type.is_ptr:
  3227. func_type = func_type.base_type
  3228. self.exception_check = func_type.exception_check
  3229. self.exception_value = func_type.exception_value
  3230. if self.exception_check:
  3231. if not setting:
  3232. self.is_temp = True
  3233. if self.exception_value is None:
  3234. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  3235. self.index = self.index.coerce_to(func_type.args[0].type, env)
  3236. self.type = func_type.return_type
  3237. if setting and not func_type.return_type.is_reference:
  3238. error(self.pos, "Can't set non-reference result '%s'" % self.type)
  3239. return self
  3240. def analyse_as_c_function(self, env):
  3241. base_type = self.base.type
  3242. if base_type.is_fused:
  3243. self.parse_indexed_fused_cdef(env)
  3244. else:
  3245. self.type_indices = self.parse_index_as_types(env)
  3246. self.index = None # FIXME: use a dedicated Node class instead of generic IndexNode
  3247. if base_type.templates is None:
  3248. error(self.pos, "Can only parameterize template functions.")
  3249. self.type = error_type
  3250. elif self.type_indices is None:
  3251. # Error recorded earlier.
  3252. self.type = error_type
  3253. elif len(base_type.templates) != len(self.type_indices):
  3254. error(self.pos, "Wrong number of template arguments: expected %s, got %s" % (
  3255. (len(base_type.templates), len(self.type_indices))))
  3256. self.type = error_type
  3257. else:
  3258. self.type = base_type.specialize(dict(zip(base_type.templates, self.type_indices)))
  3259. # FIXME: use a dedicated Node class instead of generic IndexNode
  3260. return self
  3261. def analyse_as_c_tuple(self, env, getting, setting):
  3262. base_type = self.base.type
  3263. if isinstance(self.index, IntNode) and self.index.has_constant_result():
  3264. index = self.index.constant_result
  3265. if -base_type.size <= index < base_type.size:
  3266. if index < 0:
  3267. index += base_type.size
  3268. self.type = base_type.components[index]
  3269. else:
  3270. error(self.pos,
  3271. "Index %s out of bounds for '%s'" %
  3272. (index, base_type))
  3273. self.type = PyrexTypes.error_type
  3274. return self
  3275. else:
  3276. self.base = self.base.coerce_to_pyobject(env)
  3277. return self.analyse_base_and_index_types(env, getting=getting, setting=setting, analyse_base=False)
  3278. def analyse_as_buffer_operation(self, env, getting):
  3279. """
  3280. Analyse buffer indexing and memoryview indexing/slicing
  3281. """
  3282. if isinstance(self.index, TupleNode):
  3283. indices = self.index.args
  3284. else:
  3285. indices = [self.index]
  3286. base = self.base
  3287. base_type = base.type
  3288. replacement_node = None
  3289. if base_type.is_memoryviewslice:
  3290. # memoryviewslice indexing or slicing
  3291. from . import MemoryView
  3292. if base.is_memview_slice:
  3293. # For memory views, "view[i][j]" is the same as "view[i, j]" => use the latter for speed.
  3294. merged_indices = base.merged_indices(indices)
  3295. if merged_indices is not None:
  3296. base = base.base
  3297. base_type = base.type
  3298. indices = merged_indices
  3299. have_slices, indices, newaxes = MemoryView.unellipsify(indices, base_type.ndim)
  3300. if have_slices:
  3301. replacement_node = MemoryViewSliceNode(self.pos, indices=indices, base=base)
  3302. else:
  3303. replacement_node = MemoryViewIndexNode(self.pos, indices=indices, base=base)
  3304. elif base_type.is_buffer or base_type.is_pythran_expr:
  3305. if base_type.is_pythran_expr or len(indices) == base_type.ndim:
  3306. # Buffer indexing
  3307. is_buffer_access = True
  3308. indices = [index.analyse_types(env) for index in indices]
  3309. if base_type.is_pythran_expr:
  3310. do_replacement = all(
  3311. index.type.is_int or index.is_slice or index.type.is_pythran_expr
  3312. for index in indices)
  3313. if do_replacement:
  3314. for i,index in enumerate(indices):
  3315. if index.is_slice:
  3316. index = SliceIntNode(index.pos, start=index.start, stop=index.stop, step=index.step)
  3317. index = index.analyse_types(env)
  3318. indices[i] = index
  3319. else:
  3320. do_replacement = all(index.type.is_int for index in indices)
  3321. if do_replacement:
  3322. replacement_node = BufferIndexNode(self.pos, indices=indices, base=base)
  3323. # On cloning, indices is cloned. Otherwise, unpack index into indices.
  3324. assert not isinstance(self.index, CloneNode)
  3325. if replacement_node is not None:
  3326. replacement_node = replacement_node.analyse_types(env, getting)
  3327. return replacement_node
  3328. def wrap_in_nonecheck_node(self, env, getting):
  3329. if not env.directives['nonecheck'] or not self.base.may_be_none():
  3330. return
  3331. self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
  3332. def parse_index_as_types(self, env, required=True):
  3333. if isinstance(self.index, TupleNode):
  3334. indices = self.index.args
  3335. else:
  3336. indices = [self.index]
  3337. type_indices = []
  3338. for index in indices:
  3339. type_indices.append(index.analyse_as_type(env))
  3340. if type_indices[-1] is None:
  3341. if required:
  3342. error(index.pos, "not parsable as a type")
  3343. return None
  3344. return type_indices
  3345. def parse_indexed_fused_cdef(self, env):
  3346. """
  3347. Interpret fused_cdef_func[specific_type1, ...]
  3348. Note that if this method is called, we are an indexed cdef function
  3349. with fused argument types, and this IndexNode will be replaced by the
  3350. NameNode with specific entry just after analysis of expressions by
  3351. AnalyseExpressionsTransform.
  3352. """
  3353. self.type = PyrexTypes.error_type
  3354. self.is_fused_index = True
  3355. base_type = self.base.type
  3356. positions = []
  3357. if self.index.is_name or self.index.is_attribute:
  3358. positions.append(self.index.pos)
  3359. elif isinstance(self.index, TupleNode):
  3360. for arg in self.index.args:
  3361. positions.append(arg.pos)
  3362. specific_types = self.parse_index_as_types(env, required=False)
  3363. if specific_types is None:
  3364. self.index = self.index.analyse_types(env)
  3365. if not self.base.entry.as_variable:
  3366. error(self.pos, "Can only index fused functions with types")
  3367. else:
  3368. # A cpdef function indexed with Python objects
  3369. self.base.entry = self.entry = self.base.entry.as_variable
  3370. self.base.type = self.type = self.entry.type
  3371. self.base.is_temp = True
  3372. self.is_temp = True
  3373. self.entry.used = True
  3374. self.is_fused_index = False
  3375. return
  3376. for i, type in enumerate(specific_types):
  3377. specific_types[i] = type.specialize_fused(env)
  3378. fused_types = base_type.get_fused_types()
  3379. if len(specific_types) > len(fused_types):
  3380. return error(self.pos, "Too many types specified")
  3381. elif len(specific_types) < len(fused_types):
  3382. t = fused_types[len(specific_types)]
  3383. return error(self.pos, "Not enough types specified to specialize "
  3384. "the function, %s is still fused" % t)
  3385. # See if our index types form valid specializations
  3386. for pos, specific_type, fused_type in zip(positions,
  3387. specific_types,
  3388. fused_types):
  3389. if not any([specific_type.same_as(t) for t in fused_type.types]):
  3390. return error(pos, "Type not in fused type")
  3391. if specific_type is None or specific_type.is_error:
  3392. return
  3393. fused_to_specific = dict(zip(fused_types, specific_types))
  3394. type = base_type.specialize(fused_to_specific)
  3395. if type.is_fused:
  3396. # Only partially specific, this is invalid
  3397. error(self.pos,
  3398. "Index operation makes function only partially specific")
  3399. else:
  3400. # Fully specific, find the signature with the specialized entry
  3401. for signature in self.base.type.get_all_specialized_function_types():
  3402. if type.same_as(signature):
  3403. self.type = signature
  3404. if self.base.is_attribute:
  3405. # Pretend to be a normal attribute, for cdef extension
  3406. # methods
  3407. self.entry = signature.entry
  3408. self.is_attribute = True
  3409. self.obj = self.base.obj
  3410. self.type.entry.used = True
  3411. self.base.type = signature
  3412. self.base.entry = signature.entry
  3413. break
  3414. else:
  3415. # This is a bug
  3416. raise InternalError("Couldn't find the right signature")
  3417. gil_message = "Indexing Python object"
  3418. def calculate_result_code(self):
  3419. if self.base.type in (list_type, tuple_type, bytearray_type):
  3420. if self.base.type is list_type:
  3421. index_code = "PyList_GET_ITEM(%s, %s)"
  3422. elif self.base.type is tuple_type:
  3423. index_code = "PyTuple_GET_ITEM(%s, %s)"
  3424. elif self.base.type is bytearray_type:
  3425. index_code = "((unsigned char)(PyByteArray_AS_STRING(%s)[%s]))"
  3426. else:
  3427. assert False, "unexpected base type in indexing: %s" % self.base.type
  3428. elif self.base.type.is_cfunction:
  3429. return "%s<%s>" % (
  3430. self.base.result(),
  3431. ",".join([param.empty_declaration_code() for param in self.type_indices]))
  3432. elif self.base.type.is_ctuple:
  3433. index = self.index.constant_result
  3434. if index < 0:
  3435. index += self.base.type.size
  3436. return "%s.f%s" % (self.base.result(), index)
  3437. else:
  3438. if (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
  3439. error(self.pos, "Invalid use of pointer slice")
  3440. return
  3441. index_code = "(%s[%s])"
  3442. return index_code % (self.base.result(), self.index.result())
  3443. def extra_index_params(self, code):
  3444. if self.index.type.is_int:
  3445. is_list = self.base.type is list_type
  3446. wraparound = (
  3447. bool(code.globalstate.directives['wraparound']) and
  3448. self.original_index_type.signed and
  3449. not (isinstance(self.index.constant_result, _py_int_types)
  3450. and self.index.constant_result >= 0))
  3451. boundscheck = bool(code.globalstate.directives['boundscheck'])
  3452. return ", %s, %d, %s, %d, %d, %d" % (
  3453. self.original_index_type.empty_declaration_code(),
  3454. self.original_index_type.signed and 1 or 0,
  3455. self.original_index_type.to_py_function,
  3456. is_list, wraparound, boundscheck)
  3457. else:
  3458. return ""
  3459. def generate_result_code(self, code):
  3460. if not self.is_temp:
  3461. # all handled in self.calculate_result_code()
  3462. return
  3463. utility_code = None
  3464. if self.type.is_pyobject:
  3465. error_value = 'NULL'
  3466. if self.index.type.is_int:
  3467. if self.base.type is list_type:
  3468. function = "__Pyx_GetItemInt_List"
  3469. elif self.base.type is tuple_type:
  3470. function = "__Pyx_GetItemInt_Tuple"
  3471. else:
  3472. function = "__Pyx_GetItemInt"
  3473. utility_code = TempitaUtilityCode.load_cached("GetItemInt", "ObjectHandling.c")
  3474. else:
  3475. if self.base.type is dict_type:
  3476. function = "__Pyx_PyDict_GetItem"
  3477. utility_code = UtilityCode.load_cached("DictGetItem", "ObjectHandling.c")
  3478. elif self.base.type is py_object_type and self.index.type in (str_type, unicode_type):
  3479. # obj[str] is probably doing a dict lookup
  3480. function = "__Pyx_PyObject_Dict_GetItem"
  3481. utility_code = UtilityCode.load_cached("DictGetItem", "ObjectHandling.c")
  3482. else:
  3483. function = "__Pyx_PyObject_GetItem"
  3484. code.globalstate.use_utility_code(
  3485. TempitaUtilityCode.load_cached("GetItemInt", "ObjectHandling.c"))
  3486. utility_code = UtilityCode.load_cached("ObjectGetItem", "ObjectHandling.c")
  3487. elif self.type.is_unicode_char and self.base.type is unicode_type:
  3488. assert self.index.type.is_int
  3489. function = "__Pyx_GetItemInt_Unicode"
  3490. error_value = '(Py_UCS4)-1'
  3491. utility_code = UtilityCode.load_cached("GetItemIntUnicode", "StringTools.c")
  3492. elif self.base.type is bytearray_type:
  3493. assert self.index.type.is_int
  3494. assert self.type.is_int
  3495. function = "__Pyx_GetItemInt_ByteArray"
  3496. error_value = '-1'
  3497. utility_code = UtilityCode.load_cached("GetItemIntByteArray", "StringTools.c")
  3498. elif not (self.base.type.is_cpp_class and self.exception_check):
  3499. assert False, "unexpected type %s and base type %s for indexing" % (
  3500. self.type, self.base.type)
  3501. if utility_code is not None:
  3502. code.globalstate.use_utility_code(utility_code)
  3503. if self.index.type.is_int:
  3504. index_code = self.index.result()
  3505. else:
  3506. index_code = self.index.py_result()
  3507. if self.base.type.is_cpp_class and self.exception_check:
  3508. translate_cpp_exception(code, self.pos,
  3509. "%s = %s[%s];" % (self.result(), self.base.result(),
  3510. self.index.result()),
  3511. self.result() if self.type.is_pyobject else None,
  3512. self.exception_value, self.in_nogil_context)
  3513. else:
  3514. error_check = '!%s' if error_value == 'NULL' else '%%s == %s' % error_value
  3515. code.putln(
  3516. "%s = %s(%s, %s%s); %s" % (
  3517. self.result(),
  3518. function,
  3519. self.base.py_result(),
  3520. index_code,
  3521. self.extra_index_params(code),
  3522. code.error_goto_if(error_check % self.result(), self.pos)))
  3523. if self.type.is_pyobject:
  3524. code.put_gotref(self.py_result())
  3525. def generate_setitem_code(self, value_code, code):
  3526. if self.index.type.is_int:
  3527. if self.base.type is bytearray_type:
  3528. code.globalstate.use_utility_code(
  3529. UtilityCode.load_cached("SetItemIntByteArray", "StringTools.c"))
  3530. function = "__Pyx_SetItemInt_ByteArray"
  3531. else:
  3532. code.globalstate.use_utility_code(
  3533. UtilityCode.load_cached("SetItemInt", "ObjectHandling.c"))
  3534. function = "__Pyx_SetItemInt"
  3535. index_code = self.index.result()
  3536. else:
  3537. index_code = self.index.py_result()
  3538. if self.base.type is dict_type:
  3539. function = "PyDict_SetItem"
  3540. # It would seem that we could specialized lists/tuples, but that
  3541. # shouldn't happen here.
  3542. # Both PyList_SetItem() and PyTuple_SetItem() take a Py_ssize_t as
  3543. # index instead of an object, and bad conversion here would give
  3544. # the wrong exception. Also, tuples are supposed to be immutable,
  3545. # and raise a TypeError when trying to set their entries
  3546. # (PyTuple_SetItem() is for creating new tuples from scratch).
  3547. else:
  3548. function = "PyObject_SetItem"
  3549. code.putln(code.error_goto_if_neg(
  3550. "%s(%s, %s, %s%s)" % (
  3551. function,
  3552. self.base.py_result(),
  3553. index_code,
  3554. value_code,
  3555. self.extra_index_params(code)),
  3556. self.pos))
  3557. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  3558. exception_check=None, exception_value=None):
  3559. self.generate_subexpr_evaluation_code(code)
  3560. if self.type.is_pyobject:
  3561. self.generate_setitem_code(rhs.py_result(), code)
  3562. elif self.base.type is bytearray_type:
  3563. value_code = self._check_byte_value(code, rhs)
  3564. self.generate_setitem_code(value_code, code)
  3565. elif self.base.type.is_cpp_class and self.exception_check and self.exception_check == '+':
  3566. if overloaded_assignment and exception_check and \
  3567. self.exception_value != exception_value:
  3568. # Handle the case that both the index operator and the assignment
  3569. # operator have a c++ exception handler and they are not the same.
  3570. translate_double_cpp_exception(code, self.pos, self.type,
  3571. self.result(), rhs.result(), self.exception_value,
  3572. exception_value, self.in_nogil_context)
  3573. else:
  3574. # Handle the case that only the index operator has a
  3575. # c++ exception handler, or that
  3576. # both exception handlers are the same.
  3577. translate_cpp_exception(code, self.pos,
  3578. "%s = %s;" % (self.result(), rhs.result()),
  3579. self.result() if self.type.is_pyobject else None,
  3580. self.exception_value, self.in_nogil_context)
  3581. else:
  3582. code.putln(
  3583. "%s = %s;" % (self.result(), rhs.result()))
  3584. self.generate_subexpr_disposal_code(code)
  3585. self.free_subexpr_temps(code)
  3586. rhs.generate_disposal_code(code)
  3587. rhs.free_temps(code)
  3588. def _check_byte_value(self, code, rhs):
  3589. # TODO: should we do this generally on downcasts, or just here?
  3590. assert rhs.type.is_int, repr(rhs.type)
  3591. value_code = rhs.result()
  3592. if rhs.has_constant_result():
  3593. if 0 <= rhs.constant_result < 256:
  3594. return value_code
  3595. needs_cast = True # make at least the C compiler happy
  3596. warning(rhs.pos,
  3597. "value outside of range(0, 256)"
  3598. " when assigning to byte: %s" % rhs.constant_result,
  3599. level=1)
  3600. else:
  3601. needs_cast = rhs.type != PyrexTypes.c_uchar_type
  3602. if not self.nogil:
  3603. conditions = []
  3604. if rhs.is_literal or rhs.type.signed:
  3605. conditions.append('%s < 0' % value_code)
  3606. if (rhs.is_literal or not
  3607. (rhs.is_temp and rhs.type in (
  3608. PyrexTypes.c_uchar_type, PyrexTypes.c_char_type,
  3609. PyrexTypes.c_schar_type))):
  3610. conditions.append('%s > 255' % value_code)
  3611. if conditions:
  3612. code.putln("if (unlikely(%s)) {" % ' || '.join(conditions))
  3613. code.putln(
  3614. 'PyErr_SetString(PyExc_ValueError,'
  3615. ' "byte must be in range(0, 256)"); %s' %
  3616. code.error_goto(self.pos))
  3617. code.putln("}")
  3618. if needs_cast:
  3619. value_code = '((unsigned char)%s)' % value_code
  3620. return value_code
  3621. def generate_deletion_code(self, code, ignore_nonexisting=False):
  3622. self.generate_subexpr_evaluation_code(code)
  3623. #if self.type.is_pyobject:
  3624. if self.index.type.is_int:
  3625. function = "__Pyx_DelItemInt"
  3626. index_code = self.index.result()
  3627. code.globalstate.use_utility_code(
  3628. UtilityCode.load_cached("DelItemInt", "ObjectHandling.c"))
  3629. else:
  3630. index_code = self.index.py_result()
  3631. if self.base.type is dict_type:
  3632. function = "PyDict_DelItem"
  3633. else:
  3634. function = "PyObject_DelItem"
  3635. code.putln(code.error_goto_if_neg(
  3636. "%s(%s, %s%s)" % (
  3637. function,
  3638. self.base.py_result(),
  3639. index_code,
  3640. self.extra_index_params(code)),
  3641. self.pos))
  3642. self.generate_subexpr_disposal_code(code)
  3643. self.free_subexpr_temps(code)
  3644. class BufferIndexNode(_IndexingBaseNode):
  3645. """
  3646. Indexing of buffers and memoryviews. This node is created during type
  3647. analysis from IndexNode and replaces it.
  3648. Attributes:
  3649. base - base node being indexed
  3650. indices - list of indexing expressions
  3651. """
  3652. subexprs = ['base', 'indices']
  3653. is_buffer_access = True
  3654. # Whether we're assigning to a buffer (in that case it needs to be writable)
  3655. writable_needed = False
  3656. # Any indexing temp variables that we need to clean up.
  3657. index_temps = ()
  3658. def analyse_target_types(self, env):
  3659. self.analyse_types(env, getting=False)
  3660. def analyse_types(self, env, getting=True):
  3661. """
  3662. Analyse types for buffer indexing only. Overridden by memoryview
  3663. indexing and slicing subclasses
  3664. """
  3665. # self.indices are already analyzed
  3666. if not self.base.is_name and not is_pythran_expr(self.base.type):
  3667. error(self.pos, "Can only index buffer variables")
  3668. self.type = error_type
  3669. return self
  3670. if not getting:
  3671. if not self.base.entry.type.writable:
  3672. error(self.pos, "Writing to readonly buffer")
  3673. else:
  3674. self.writable_needed = True
  3675. if self.base.type.is_buffer:
  3676. self.base.entry.buffer_aux.writable_needed = True
  3677. self.none_error_message = "'NoneType' object is not subscriptable"
  3678. self.analyse_buffer_index(env, getting)
  3679. self.wrap_in_nonecheck_node(env)
  3680. return self
  3681. def analyse_buffer_index(self, env, getting):
  3682. if is_pythran_expr(self.base.type):
  3683. index_with_type_list = [(idx, idx.type) for idx in self.indices]
  3684. self.type = PythranExpr(pythran_indexing_type(self.base.type, index_with_type_list))
  3685. else:
  3686. self.base = self.base.coerce_to_simple(env)
  3687. self.type = self.base.type.dtype
  3688. self.buffer_type = self.base.type
  3689. if getting and (self.type.is_pyobject or self.type.is_pythran_expr):
  3690. self.is_temp = True
  3691. def analyse_assignment(self, rhs):
  3692. """
  3693. Called by IndexNode when this node is assigned to,
  3694. with the rhs of the assignment
  3695. """
  3696. def wrap_in_nonecheck_node(self, env):
  3697. if not env.directives['nonecheck'] or not self.base.may_be_none():
  3698. return
  3699. self.base = self.base.as_none_safe_node(self.none_error_message)
  3700. def nogil_check(self, env):
  3701. if self.is_buffer_access or self.is_memview_index:
  3702. if self.type.is_pyobject:
  3703. error(self.pos, "Cannot access buffer with object dtype without gil")
  3704. self.type = error_type
  3705. def calculate_result_code(self):
  3706. return "(*%s)" % self.buffer_ptr_code
  3707. def buffer_entry(self):
  3708. base = self.base
  3709. if self.base.is_nonecheck:
  3710. base = base.arg
  3711. return base.type.get_entry(base)
  3712. def get_index_in_temp(self, code, ivar):
  3713. ret = code.funcstate.allocate_temp(
  3714. PyrexTypes.widest_numeric_type(
  3715. ivar.type,
  3716. PyrexTypes.c_ssize_t_type if ivar.type.signed else PyrexTypes.c_size_t_type),
  3717. manage_ref=False)
  3718. code.putln("%s = %s;" % (ret, ivar.result()))
  3719. return ret
  3720. def buffer_lookup_code(self, code):
  3721. """
  3722. ndarray[1, 2, 3] and memslice[1, 2, 3]
  3723. """
  3724. if self.in_nogil_context:
  3725. if self.is_buffer_access or self.is_memview_index:
  3726. if code.globalstate.directives['boundscheck']:
  3727. warning(self.pos, "Use boundscheck(False) for faster access", level=1)
  3728. # Assign indices to temps of at least (s)size_t to allow further index calculations.
  3729. self.index_temps = index_temps = [self.get_index_in_temp(code,ivar) for ivar in self.indices]
  3730. # Generate buffer access code using these temps
  3731. from . import Buffer
  3732. buffer_entry = self.buffer_entry()
  3733. if buffer_entry.type.is_buffer:
  3734. negative_indices = buffer_entry.type.negative_indices
  3735. else:
  3736. negative_indices = Buffer.buffer_defaults['negative_indices']
  3737. return buffer_entry, Buffer.put_buffer_lookup_code(
  3738. entry=buffer_entry,
  3739. index_signeds=[ivar.type.signed for ivar in self.indices],
  3740. index_cnames=index_temps,
  3741. directives=code.globalstate.directives,
  3742. pos=self.pos, code=code,
  3743. negative_indices=negative_indices,
  3744. in_nogil_context=self.in_nogil_context)
  3745. def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
  3746. self.generate_subexpr_evaluation_code(code)
  3747. self.generate_buffer_setitem_code(rhs, code)
  3748. self.generate_subexpr_disposal_code(code)
  3749. self.free_subexpr_temps(code)
  3750. rhs.generate_disposal_code(code)
  3751. rhs.free_temps(code)
  3752. def generate_buffer_setitem_code(self, rhs, code, op=""):
  3753. base_type = self.base.type
  3754. if is_pythran_expr(base_type) and is_pythran_supported_type(rhs.type):
  3755. obj = code.funcstate.allocate_temp(PythranExpr(pythran_type(self.base.type)), manage_ref=False)
  3756. # We have got to do this because we have to declare pythran objects
  3757. # at the beginning of the functions.
  3758. # Indeed, Cython uses "goto" statement for error management, and
  3759. # RAII doesn't work with that kind of construction.
  3760. # Moreover, the way Pythran expressions are made is that they don't
  3761. # support move-assignation easily.
  3762. # This, we explicitly destroy then in-place new objects in this
  3763. # case.
  3764. code.putln("__Pyx_call_destructor(%s);" % obj)
  3765. code.putln("new (&%s) decltype(%s){%s};" % (obj, obj, self.base.pythran_result()))
  3766. code.putln("%s%s %s= %s;" % (
  3767. obj,
  3768. pythran_indexing_code(self.indices),
  3769. op,
  3770. rhs.pythran_result()))
  3771. code.funcstate.release_temp(obj)
  3772. return
  3773. # Used from generate_assignment_code and InPlaceAssignmentNode
  3774. buffer_entry, ptrexpr = self.buffer_lookup_code(code)
  3775. if self.buffer_type.dtype.is_pyobject:
  3776. # Must manage refcounts. XDecref what is already there
  3777. # and incref what we put in (NumPy allows there to be NULL)
  3778. ptr = code.funcstate.allocate_temp(buffer_entry.buf_ptr_type,
  3779. manage_ref=False)
  3780. rhs_code = rhs.result()
  3781. code.putln("%s = %s;" % (ptr, ptrexpr))
  3782. code.put_xgotref("*%s" % ptr)
  3783. code.putln("__Pyx_INCREF(%s); __Pyx_XDECREF(*%s);" % (
  3784. rhs_code, ptr))
  3785. code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
  3786. code.put_xgiveref("*%s" % ptr)
  3787. code.funcstate.release_temp(ptr)
  3788. else:
  3789. # Simple case
  3790. code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
  3791. def generate_result_code(self, code):
  3792. if is_pythran_expr(self.base.type):
  3793. res = self.result()
  3794. code.putln("__Pyx_call_destructor(%s);" % res)
  3795. code.putln("new (&%s) decltype(%s){%s%s};" % (
  3796. res,
  3797. res,
  3798. self.base.pythran_result(),
  3799. pythran_indexing_code(self.indices)))
  3800. return
  3801. buffer_entry, self.buffer_ptr_code = self.buffer_lookup_code(code)
  3802. if self.type.is_pyobject:
  3803. # is_temp is True, so must pull out value and incref it.
  3804. # NOTE: object temporary results for nodes are declared
  3805. # as PyObject *, so we need a cast
  3806. res = self.result()
  3807. code.putln("%s = (PyObject *) *%s;" % (res, self.buffer_ptr_code))
  3808. # NumPy does (occasionally) allow NULL to denote None.
  3809. code.putln("if (unlikely(%s == NULL)) %s = Py_None;" % (res, res))
  3810. code.putln("__Pyx_INCREF((PyObject*)%s);" % res)
  3811. def free_subexpr_temps(self, code):
  3812. for temp in self.index_temps:
  3813. code.funcstate.release_temp(temp)
  3814. self.index_temps = ()
  3815. super(BufferIndexNode, self).free_subexpr_temps(code)
  3816. class MemoryViewIndexNode(BufferIndexNode):
  3817. is_memview_index = True
  3818. is_buffer_access = False
  3819. warned_untyped_idx = False
  3820. def analyse_types(self, env, getting=True):
  3821. # memoryviewslice indexing or slicing
  3822. from . import MemoryView
  3823. self.is_pythran_mode = has_np_pythran(env)
  3824. indices = self.indices
  3825. have_slices, indices, newaxes = MemoryView.unellipsify(indices, self.base.type.ndim)
  3826. if not getting:
  3827. self.writable_needed = True
  3828. if self.base.is_name or self.base.is_attribute:
  3829. self.base.entry.type.writable_needed = True
  3830. self.memslice_index = (not newaxes and len(indices) == self.base.type.ndim)
  3831. axes = []
  3832. index_type = PyrexTypes.c_py_ssize_t_type
  3833. new_indices = []
  3834. if len(indices) - len(newaxes) > self.base.type.ndim:
  3835. self.type = error_type
  3836. error(indices[self.base.type.ndim].pos,
  3837. "Too many indices specified for type %s" % self.base.type)
  3838. return self
  3839. axis_idx = 0
  3840. for i, index in enumerate(indices[:]):
  3841. index = index.analyse_types(env)
  3842. if index.is_none:
  3843. self.is_memview_slice = True
  3844. new_indices.append(index)
  3845. axes.append(('direct', 'strided'))
  3846. continue
  3847. access, packing = self.base.type.axes[axis_idx]
  3848. axis_idx += 1
  3849. if index.is_slice:
  3850. self.is_memview_slice = True
  3851. if index.step.is_none:
  3852. axes.append((access, packing))
  3853. else:
  3854. axes.append((access, 'strided'))
  3855. # Coerce start, stop and step to temps of the right type
  3856. for attr in ('start', 'stop', 'step'):
  3857. value = getattr(index, attr)
  3858. if not value.is_none:
  3859. value = value.coerce_to(index_type, env)
  3860. #value = value.coerce_to_temp(env)
  3861. setattr(index, attr, value)
  3862. new_indices.append(value)
  3863. elif index.type.is_int or index.type.is_pyobject:
  3864. if index.type.is_pyobject and not self.warned_untyped_idx:
  3865. warning(index.pos, "Index should be typed for more efficient access", level=2)
  3866. MemoryViewIndexNode.warned_untyped_idx = True
  3867. self.is_memview_index = True
  3868. index = index.coerce_to(index_type, env)
  3869. indices[i] = index
  3870. new_indices.append(index)
  3871. else:
  3872. self.type = error_type
  3873. error(index.pos, "Invalid index for memoryview specified, type %s" % index.type)
  3874. return self
  3875. ### FIXME: replace by MemoryViewSliceNode if is_memview_slice ?
  3876. self.is_memview_index = self.is_memview_index and not self.is_memview_slice
  3877. self.indices = new_indices
  3878. # All indices with all start/stop/step for slices.
  3879. # We need to keep this around.
  3880. self.original_indices = indices
  3881. self.nogil = env.nogil
  3882. self.analyse_operation(env, getting, axes)
  3883. self.wrap_in_nonecheck_node(env)
  3884. return self
  3885. def analyse_operation(self, env, getting, axes):
  3886. self.none_error_message = "Cannot index None memoryview slice"
  3887. self.analyse_buffer_index(env, getting)
  3888. def analyse_broadcast_operation(self, rhs):
  3889. """
  3890. Support broadcasting for slice assignment.
  3891. E.g.
  3892. m_2d[...] = m_1d # or,
  3893. m_1d[...] = m_2d # if the leading dimension has extent 1
  3894. """
  3895. if self.type.is_memoryviewslice:
  3896. lhs = self
  3897. if lhs.is_memview_broadcast or rhs.is_memview_broadcast:
  3898. lhs.is_memview_broadcast = True
  3899. rhs.is_memview_broadcast = True
  3900. def analyse_as_memview_scalar_assignment(self, rhs):
  3901. lhs = self.analyse_assignment(rhs)
  3902. if lhs:
  3903. rhs.is_memview_copy_assignment = lhs.is_memview_copy_assignment
  3904. return lhs
  3905. return self
  3906. class MemoryViewSliceNode(MemoryViewIndexNode):
  3907. is_memview_slice = True
  3908. # No-op slicing operation, this node will be replaced
  3909. is_ellipsis_noop = False
  3910. is_memview_scalar_assignment = False
  3911. is_memview_index = False
  3912. is_memview_broadcast = False
  3913. def analyse_ellipsis_noop(self, env, getting):
  3914. """Slicing operations needing no evaluation, i.e. m[...] or m[:, :]"""
  3915. ### FIXME: replace directly
  3916. self.is_ellipsis_noop = all(
  3917. index.is_slice and index.start.is_none and index.stop.is_none and index.step.is_none
  3918. for index in self.indices)
  3919. if self.is_ellipsis_noop:
  3920. self.type = self.base.type
  3921. def analyse_operation(self, env, getting, axes):
  3922. from . import MemoryView
  3923. if not getting:
  3924. self.is_memview_broadcast = True
  3925. self.none_error_message = "Cannot assign to None memoryview slice"
  3926. else:
  3927. self.none_error_message = "Cannot slice None memoryview slice"
  3928. self.analyse_ellipsis_noop(env, getting)
  3929. if self.is_ellipsis_noop:
  3930. return
  3931. self.index = None
  3932. self.is_temp = True
  3933. self.use_managed_ref = True
  3934. if not MemoryView.validate_axes(self.pos, axes):
  3935. self.type = error_type
  3936. return
  3937. self.type = PyrexTypes.MemoryViewSliceType(self.base.type.dtype, axes)
  3938. if not (self.base.is_simple() or self.base.result_in_temp()):
  3939. self.base = self.base.coerce_to_temp(env)
  3940. def analyse_assignment(self, rhs):
  3941. if not rhs.type.is_memoryviewslice and (
  3942. self.type.dtype.assignable_from(rhs.type) or
  3943. rhs.type.is_pyobject):
  3944. # scalar assignment
  3945. return MemoryCopyScalar(self.pos, self)
  3946. else:
  3947. return MemoryCopySlice(self.pos, self)
  3948. def merged_indices(self, indices):
  3949. """Return a new list of indices/slices with 'indices' merged into the current ones
  3950. according to slicing rules.
  3951. Is used to implement "view[i][j]" => "view[i, j]".
  3952. Return None if the indices cannot (easily) be merged at compile time.
  3953. """
  3954. if not indices:
  3955. return None
  3956. # NOTE: Need to evaluate "self.original_indices" here as they might differ from "self.indices".
  3957. new_indices = self.original_indices[:]
  3958. indices = indices[:]
  3959. for i, s in enumerate(self.original_indices):
  3960. if s.is_slice:
  3961. if s.start.is_none and s.stop.is_none and s.step.is_none:
  3962. # Full slice found, replace by index.
  3963. new_indices[i] = indices[0]
  3964. indices.pop(0)
  3965. if not indices:
  3966. return new_indices
  3967. else:
  3968. # Found something non-trivial, e.g. a partial slice.
  3969. return None
  3970. elif not s.type.is_int:
  3971. # Not a slice, not an integer index => could be anything...
  3972. return None
  3973. if indices:
  3974. if len(new_indices) + len(indices) > self.base.type.ndim:
  3975. return None
  3976. new_indices += indices
  3977. return new_indices
  3978. def is_simple(self):
  3979. if self.is_ellipsis_noop:
  3980. # TODO: fix SimpleCallNode.is_simple()
  3981. return self.base.is_simple() or self.base.result_in_temp()
  3982. return self.result_in_temp()
  3983. def calculate_result_code(self):
  3984. """This is called in case this is a no-op slicing node"""
  3985. return self.base.result()
  3986. def generate_result_code(self, code):
  3987. if self.is_ellipsis_noop:
  3988. return ### FIXME: remove
  3989. buffer_entry = self.buffer_entry()
  3990. have_gil = not self.in_nogil_context
  3991. # TODO Mark: this is insane, do it better
  3992. have_slices = False
  3993. it = iter(self.indices)
  3994. for index in self.original_indices:
  3995. if index.is_slice:
  3996. have_slices = True
  3997. if not index.start.is_none:
  3998. index.start = next(it)
  3999. if not index.stop.is_none:
  4000. index.stop = next(it)
  4001. if not index.step.is_none:
  4002. index.step = next(it)
  4003. else:
  4004. next(it)
  4005. assert not list(it)
  4006. buffer_entry.generate_buffer_slice_code(
  4007. code, self.original_indices, self.result(),
  4008. have_gil=have_gil, have_slices=have_slices,
  4009. directives=code.globalstate.directives)
  4010. def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
  4011. if self.is_ellipsis_noop:
  4012. self.generate_subexpr_evaluation_code(code)
  4013. else:
  4014. self.generate_evaluation_code(code)
  4015. if self.is_memview_scalar_assignment:
  4016. self.generate_memoryviewslice_assign_scalar_code(rhs, code)
  4017. else:
  4018. self.generate_memoryviewslice_setslice_code(rhs, code)
  4019. if self.is_ellipsis_noop:
  4020. self.generate_subexpr_disposal_code(code)
  4021. else:
  4022. self.generate_disposal_code(code)
  4023. rhs.generate_disposal_code(code)
  4024. rhs.free_temps(code)
  4025. class MemoryCopyNode(ExprNode):
  4026. """
  4027. Wraps a memoryview slice for slice assignment.
  4028. dst: destination mememoryview slice
  4029. """
  4030. subexprs = ['dst']
  4031. def __init__(self, pos, dst):
  4032. super(MemoryCopyNode, self).__init__(pos)
  4033. self.dst = dst
  4034. self.type = dst.type
  4035. def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
  4036. self.dst.generate_evaluation_code(code)
  4037. self._generate_assignment_code(rhs, code)
  4038. self.dst.generate_disposal_code(code)
  4039. self.dst.free_temps(code)
  4040. rhs.generate_disposal_code(code)
  4041. rhs.free_temps(code)
  4042. class MemoryCopySlice(MemoryCopyNode):
  4043. """
  4044. Copy the contents of slice src to slice dst. Does not support indirect
  4045. slices.
  4046. memslice1[...] = memslice2
  4047. memslice1[:] = memslice2
  4048. """
  4049. is_memview_copy_assignment = True
  4050. copy_slice_cname = "__pyx_memoryview_copy_contents"
  4051. def _generate_assignment_code(self, src, code):
  4052. dst = self.dst
  4053. src.type.assert_direct_dims(src.pos)
  4054. dst.type.assert_direct_dims(dst.pos)
  4055. code.putln(code.error_goto_if_neg(
  4056. "%s(%s, %s, %d, %d, %d)" % (self.copy_slice_cname,
  4057. src.result(), dst.result(),
  4058. src.type.ndim, dst.type.ndim,
  4059. dst.type.dtype.is_pyobject),
  4060. dst.pos))
  4061. class MemoryCopyScalar(MemoryCopyNode):
  4062. """
  4063. Assign a scalar to a slice. dst must be simple, scalar will be assigned
  4064. to a correct type and not just something assignable.
  4065. memslice1[...] = 0.0
  4066. memslice1[:] = 0.0
  4067. """
  4068. def __init__(self, pos, dst):
  4069. super(MemoryCopyScalar, self).__init__(pos, dst)
  4070. self.type = dst.type.dtype
  4071. def _generate_assignment_code(self, scalar, code):
  4072. from . import MemoryView
  4073. self.dst.type.assert_direct_dims(self.dst.pos)
  4074. dtype = self.dst.type.dtype
  4075. type_decl = dtype.declaration_code("")
  4076. slice_decl = self.dst.type.declaration_code("")
  4077. code.begin_block()
  4078. code.putln("%s __pyx_temp_scalar = %s;" % (type_decl, scalar.result()))
  4079. if self.dst.result_in_temp() or self.dst.is_simple():
  4080. dst_temp = self.dst.result()
  4081. else:
  4082. code.putln("%s __pyx_temp_slice = %s;" % (slice_decl, self.dst.result()))
  4083. dst_temp = "__pyx_temp_slice"
  4084. slice_iter_obj = MemoryView.slice_iter(self.dst.type, dst_temp,
  4085. self.dst.type.ndim, code)
  4086. p = slice_iter_obj.start_loops()
  4087. if dtype.is_pyobject:
  4088. code.putln("Py_DECREF(*(PyObject **) %s);" % p)
  4089. code.putln("*((%s *) %s) = __pyx_temp_scalar;" % (type_decl, p))
  4090. if dtype.is_pyobject:
  4091. code.putln("Py_INCREF(__pyx_temp_scalar);")
  4092. slice_iter_obj.end_loops()
  4093. code.end_block()
  4094. class SliceIndexNode(ExprNode):
  4095. # 2-element slice indexing
  4096. #
  4097. # base ExprNode
  4098. # start ExprNode or None
  4099. # stop ExprNode or None
  4100. # slice ExprNode or None constant slice object
  4101. subexprs = ['base', 'start', 'stop', 'slice']
  4102. slice = None
  4103. def infer_type(self, env):
  4104. base_type = self.base.infer_type(env)
  4105. if base_type.is_string or base_type.is_cpp_class:
  4106. return bytes_type
  4107. elif base_type.is_pyunicode_ptr:
  4108. return unicode_type
  4109. elif base_type in (bytes_type, bytearray_type, str_type, unicode_type,
  4110. basestring_type, list_type, tuple_type):
  4111. return base_type
  4112. elif base_type.is_ptr or base_type.is_array:
  4113. return PyrexTypes.c_array_type(base_type.base_type, None)
  4114. return py_object_type
  4115. def inferable_item_node(self, index=0):
  4116. # slicing shouldn't change the result type of the base, but the index might
  4117. if index is not not_a_constant and self.start:
  4118. if self.start.has_constant_result():
  4119. index += self.start.constant_result
  4120. else:
  4121. index = not_a_constant
  4122. return self.base.inferable_item_node(index)
  4123. def may_be_none(self):
  4124. base_type = self.base.type
  4125. if base_type:
  4126. if base_type.is_string:
  4127. return False
  4128. if base_type in (bytes_type, str_type, unicode_type,
  4129. basestring_type, list_type, tuple_type):
  4130. return False
  4131. return ExprNode.may_be_none(self)
  4132. def calculate_constant_result(self):
  4133. if self.start is None:
  4134. start = None
  4135. else:
  4136. start = self.start.constant_result
  4137. if self.stop is None:
  4138. stop = None
  4139. else:
  4140. stop = self.stop.constant_result
  4141. self.constant_result = self.base.constant_result[start:stop]
  4142. def compile_time_value(self, denv):
  4143. base = self.base.compile_time_value(denv)
  4144. if self.start is None:
  4145. start = 0
  4146. else:
  4147. start = self.start.compile_time_value(denv)
  4148. if self.stop is None:
  4149. stop = None
  4150. else:
  4151. stop = self.stop.compile_time_value(denv)
  4152. try:
  4153. return base[start:stop]
  4154. except Exception as e:
  4155. self.compile_time_value_error(e)
  4156. def analyse_target_declaration(self, env):
  4157. pass
  4158. def analyse_target_types(self, env):
  4159. node = self.analyse_types(env, getting=False)
  4160. # when assigning, we must accept any Python type
  4161. if node.type.is_pyobject:
  4162. node.type = py_object_type
  4163. return node
  4164. def analyse_types(self, env, getting=True):
  4165. self.base = self.base.analyse_types(env)
  4166. if self.base.type.is_buffer or self.base.type.is_pythran_expr or self.base.type.is_memoryviewslice:
  4167. none_node = NoneNode(self.pos)
  4168. index = SliceNode(self.pos,
  4169. start=self.start or none_node,
  4170. stop=self.stop or none_node,
  4171. step=none_node)
  4172. index_node = IndexNode(self.pos, index=index, base=self.base)
  4173. return index_node.analyse_base_and_index_types(
  4174. env, getting=getting, setting=not getting,
  4175. analyse_base=False)
  4176. if self.start:
  4177. self.start = self.start.analyse_types(env)
  4178. if self.stop:
  4179. self.stop = self.stop.analyse_types(env)
  4180. if not env.directives['wraparound']:
  4181. check_negative_indices(self.start, self.stop)
  4182. base_type = self.base.type
  4183. if base_type.is_array and not getting:
  4184. # cannot assign directly to C array => try to assign by making a copy
  4185. if not self.start and not self.stop:
  4186. self.type = base_type
  4187. else:
  4188. self.type = PyrexTypes.CPtrType(base_type.base_type)
  4189. elif base_type.is_string or base_type.is_cpp_string:
  4190. self.type = default_str_type(env)
  4191. elif base_type.is_pyunicode_ptr:
  4192. self.type = unicode_type
  4193. elif base_type.is_ptr:
  4194. self.type = base_type
  4195. elif base_type.is_array:
  4196. # we need a ptr type here instead of an array type, as
  4197. # array types can result in invalid type casts in the C
  4198. # code
  4199. self.type = PyrexTypes.CPtrType(base_type.base_type)
  4200. else:
  4201. self.base = self.base.coerce_to_pyobject(env)
  4202. self.type = py_object_type
  4203. if base_type.is_builtin_type:
  4204. # slicing builtin types returns something of the same type
  4205. self.type = base_type
  4206. self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
  4207. if self.type is py_object_type:
  4208. if (not self.start or self.start.is_literal) and \
  4209. (not self.stop or self.stop.is_literal):
  4210. # cache the constant slice object, in case we need it
  4211. none_node = NoneNode(self.pos)
  4212. self.slice = SliceNode(
  4213. self.pos,
  4214. start=copy.deepcopy(self.start or none_node),
  4215. stop=copy.deepcopy(self.stop or none_node),
  4216. step=none_node
  4217. ).analyse_types(env)
  4218. else:
  4219. c_int = PyrexTypes.c_py_ssize_t_type
  4220. def allow_none(node, default_value, env):
  4221. # Coerce to Py_ssize_t, but allow None as meaning the default slice bound.
  4222. from .UtilNodes import EvalWithTempExprNode, ResultRefNode
  4223. node_ref = ResultRefNode(node)
  4224. new_expr = CondExprNode(
  4225. node.pos,
  4226. true_val=IntNode(
  4227. node.pos,
  4228. type=c_int,
  4229. value=default_value,
  4230. constant_result=int(default_value) if default_value.isdigit() else not_a_constant,
  4231. ),
  4232. false_val=node_ref.coerce_to(c_int, env),
  4233. test=PrimaryCmpNode(
  4234. node.pos,
  4235. operand1=node_ref,
  4236. operator='is',
  4237. operand2=NoneNode(node.pos),
  4238. ).analyse_types(env)
  4239. ).analyse_result_type(env)
  4240. return EvalWithTempExprNode(node_ref, new_expr)
  4241. if self.start:
  4242. if self.start.type.is_pyobject:
  4243. self.start = allow_none(self.start, '0', env)
  4244. self.start = self.start.coerce_to(c_int, env)
  4245. if self.stop:
  4246. if self.stop.type.is_pyobject:
  4247. self.stop = allow_none(self.stop, 'PY_SSIZE_T_MAX', env)
  4248. self.stop = self.stop.coerce_to(c_int, env)
  4249. self.is_temp = 1
  4250. return self
  4251. def analyse_as_type(self, env):
  4252. base_type = self.base.analyse_as_type(env)
  4253. if base_type and not base_type.is_pyobject:
  4254. if not self.start and not self.stop:
  4255. # memory view
  4256. from . import MemoryView
  4257. env.use_utility_code(MemoryView.view_utility_code)
  4258. none_node = NoneNode(self.pos)
  4259. slice_node = SliceNode(
  4260. self.pos,
  4261. start=none_node,
  4262. stop=none_node,
  4263. step=none_node,
  4264. )
  4265. return PyrexTypes.MemoryViewSliceType(
  4266. base_type, MemoryView.get_axes_specs(env, [slice_node]))
  4267. return None
  4268. nogil_check = Node.gil_error
  4269. gil_message = "Slicing Python object"
  4270. get_slice_utility_code = TempitaUtilityCode.load(
  4271. "SliceObject", "ObjectHandling.c", context={'access': 'Get'})
  4272. set_slice_utility_code = TempitaUtilityCode.load(
  4273. "SliceObject", "ObjectHandling.c", context={'access': 'Set'})
  4274. def coerce_to(self, dst_type, env):
  4275. if ((self.base.type.is_string or self.base.type.is_cpp_string)
  4276. and dst_type in (bytes_type, bytearray_type, str_type, unicode_type)):
  4277. if (dst_type not in (bytes_type, bytearray_type)
  4278. and not env.directives['c_string_encoding']):
  4279. error(self.pos,
  4280. "default encoding required for conversion from '%s' to '%s'" %
  4281. (self.base.type, dst_type))
  4282. self.type = dst_type
  4283. if dst_type.is_array and self.base.type.is_array:
  4284. if not self.start and not self.stop:
  4285. # redundant slice building, copy C arrays directly
  4286. return self.base.coerce_to(dst_type, env)
  4287. # else: check array size if possible
  4288. return super(SliceIndexNode, self).coerce_to(dst_type, env)
  4289. def generate_result_code(self, code):
  4290. if not self.type.is_pyobject:
  4291. error(self.pos,
  4292. "Slicing is not currently supported for '%s'." % self.type)
  4293. return
  4294. base_result = self.base.result()
  4295. result = self.result()
  4296. start_code = self.start_code()
  4297. stop_code = self.stop_code()
  4298. if self.base.type.is_string:
  4299. base_result = self.base.result()
  4300. if self.base.type not in (PyrexTypes.c_char_ptr_type, PyrexTypes.c_const_char_ptr_type):
  4301. base_result = '((const char*)%s)' % base_result
  4302. if self.type is bytearray_type:
  4303. type_name = 'ByteArray'
  4304. else:
  4305. type_name = self.type.name.title()
  4306. if self.stop is None:
  4307. code.putln(
  4308. "%s = __Pyx_Py%s_FromString(%s + %s); %s" % (
  4309. result,
  4310. type_name,
  4311. base_result,
  4312. start_code,
  4313. code.error_goto_if_null(result, self.pos)))
  4314. else:
  4315. code.putln(
  4316. "%s = __Pyx_Py%s_FromStringAndSize(%s + %s, %s - %s); %s" % (
  4317. result,
  4318. type_name,
  4319. base_result,
  4320. start_code,
  4321. stop_code,
  4322. start_code,
  4323. code.error_goto_if_null(result, self.pos)))
  4324. elif self.base.type.is_pyunicode_ptr:
  4325. base_result = self.base.result()
  4326. if self.base.type != PyrexTypes.c_py_unicode_ptr_type:
  4327. base_result = '((const Py_UNICODE*)%s)' % base_result
  4328. if self.stop is None:
  4329. code.putln(
  4330. "%s = __Pyx_PyUnicode_FromUnicode(%s + %s); %s" % (
  4331. result,
  4332. base_result,
  4333. start_code,
  4334. code.error_goto_if_null(result, self.pos)))
  4335. else:
  4336. code.putln(
  4337. "%s = __Pyx_PyUnicode_FromUnicodeAndLength(%s + %s, %s - %s); %s" % (
  4338. result,
  4339. base_result,
  4340. start_code,
  4341. stop_code,
  4342. start_code,
  4343. code.error_goto_if_null(result, self.pos)))
  4344. elif self.base.type is unicode_type:
  4345. code.globalstate.use_utility_code(
  4346. UtilityCode.load_cached("PyUnicode_Substring", "StringTools.c"))
  4347. code.putln(
  4348. "%s = __Pyx_PyUnicode_Substring(%s, %s, %s); %s" % (
  4349. result,
  4350. base_result,
  4351. start_code,
  4352. stop_code,
  4353. code.error_goto_if_null(result, self.pos)))
  4354. elif self.type is py_object_type:
  4355. code.globalstate.use_utility_code(self.get_slice_utility_code)
  4356. (has_c_start, has_c_stop, c_start, c_stop,
  4357. py_start, py_stop, py_slice) = self.get_slice_config()
  4358. code.putln(
  4359. "%s = __Pyx_PyObject_GetSlice(%s, %s, %s, %s, %s, %s, %d, %d, %d); %s" % (
  4360. result,
  4361. self.base.py_result(),
  4362. c_start, c_stop,
  4363. py_start, py_stop, py_slice,
  4364. has_c_start, has_c_stop,
  4365. bool(code.globalstate.directives['wraparound']),
  4366. code.error_goto_if_null(result, self.pos)))
  4367. else:
  4368. if self.base.type is list_type:
  4369. code.globalstate.use_utility_code(
  4370. TempitaUtilityCode.load_cached("SliceTupleAndList", "ObjectHandling.c"))
  4371. cfunc = '__Pyx_PyList_GetSlice'
  4372. elif self.base.type is tuple_type:
  4373. code.globalstate.use_utility_code(
  4374. TempitaUtilityCode.load_cached("SliceTupleAndList", "ObjectHandling.c"))
  4375. cfunc = '__Pyx_PyTuple_GetSlice'
  4376. else:
  4377. cfunc = 'PySequence_GetSlice'
  4378. code.putln(
  4379. "%s = %s(%s, %s, %s); %s" % (
  4380. result,
  4381. cfunc,
  4382. self.base.py_result(),
  4383. start_code,
  4384. stop_code,
  4385. code.error_goto_if_null(result, self.pos)))
  4386. code.put_gotref(self.py_result())
  4387. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  4388. exception_check=None, exception_value=None):
  4389. self.generate_subexpr_evaluation_code(code)
  4390. if self.type.is_pyobject:
  4391. code.globalstate.use_utility_code(self.set_slice_utility_code)
  4392. (has_c_start, has_c_stop, c_start, c_stop,
  4393. py_start, py_stop, py_slice) = self.get_slice_config()
  4394. code.put_error_if_neg(self.pos,
  4395. "__Pyx_PyObject_SetSlice(%s, %s, %s, %s, %s, %s, %s, %d, %d, %d)" % (
  4396. self.base.py_result(),
  4397. rhs.py_result(),
  4398. c_start, c_stop,
  4399. py_start, py_stop, py_slice,
  4400. has_c_start, has_c_stop,
  4401. bool(code.globalstate.directives['wraparound'])))
  4402. else:
  4403. start_offset = self.start_code() if self.start else '0'
  4404. if rhs.type.is_array:
  4405. array_length = rhs.type.size
  4406. self.generate_slice_guard_code(code, array_length)
  4407. else:
  4408. array_length = '%s - %s' % (self.stop_code(), start_offset)
  4409. code.globalstate.use_utility_code(UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
  4410. code.putln("memcpy(&(%s[%s]), %s, sizeof(%s[0]) * (%s));" % (
  4411. self.base.result(), start_offset,
  4412. rhs.result(),
  4413. self.base.result(), array_length
  4414. ))
  4415. self.generate_subexpr_disposal_code(code)
  4416. self.free_subexpr_temps(code)
  4417. rhs.generate_disposal_code(code)
  4418. rhs.free_temps(code)
  4419. def generate_deletion_code(self, code, ignore_nonexisting=False):
  4420. if not self.base.type.is_pyobject:
  4421. error(self.pos,
  4422. "Deleting slices is only supported for Python types, not '%s'." % self.type)
  4423. return
  4424. self.generate_subexpr_evaluation_code(code)
  4425. code.globalstate.use_utility_code(self.set_slice_utility_code)
  4426. (has_c_start, has_c_stop, c_start, c_stop,
  4427. py_start, py_stop, py_slice) = self.get_slice_config()
  4428. code.put_error_if_neg(self.pos,
  4429. "__Pyx_PyObject_DelSlice(%s, %s, %s, %s, %s, %s, %d, %d, %d)" % (
  4430. self.base.py_result(),
  4431. c_start, c_stop,
  4432. py_start, py_stop, py_slice,
  4433. has_c_start, has_c_stop,
  4434. bool(code.globalstate.directives['wraparound'])))
  4435. self.generate_subexpr_disposal_code(code)
  4436. self.free_subexpr_temps(code)
  4437. def get_slice_config(self):
  4438. has_c_start, c_start, py_start = False, '0', 'NULL'
  4439. if self.start:
  4440. has_c_start = not self.start.type.is_pyobject
  4441. if has_c_start:
  4442. c_start = self.start.result()
  4443. else:
  4444. py_start = '&%s' % self.start.py_result()
  4445. has_c_stop, c_stop, py_stop = False, '0', 'NULL'
  4446. if self.stop:
  4447. has_c_stop = not self.stop.type.is_pyobject
  4448. if has_c_stop:
  4449. c_stop = self.stop.result()
  4450. else:
  4451. py_stop = '&%s' % self.stop.py_result()
  4452. py_slice = self.slice and '&%s' % self.slice.py_result() or 'NULL'
  4453. return (has_c_start, has_c_stop, c_start, c_stop,
  4454. py_start, py_stop, py_slice)
  4455. def generate_slice_guard_code(self, code, target_size):
  4456. if not self.base.type.is_array:
  4457. return
  4458. slice_size = self.base.type.size
  4459. try:
  4460. total_length = slice_size = int(slice_size)
  4461. except ValueError:
  4462. total_length = None
  4463. start = stop = None
  4464. if self.stop:
  4465. stop = self.stop.result()
  4466. try:
  4467. stop = int(stop)
  4468. if stop < 0:
  4469. if total_length is None:
  4470. slice_size = '%s + %d' % (slice_size, stop)
  4471. else:
  4472. slice_size += stop
  4473. else:
  4474. slice_size = stop
  4475. stop = None
  4476. except ValueError:
  4477. pass
  4478. if self.start:
  4479. start = self.start.result()
  4480. try:
  4481. start = int(start)
  4482. if start < 0:
  4483. if total_length is None:
  4484. start = '%s + %d' % (self.base.type.size, start)
  4485. else:
  4486. start += total_length
  4487. if isinstance(slice_size, _py_int_types):
  4488. slice_size -= start
  4489. else:
  4490. slice_size = '%s - (%s)' % (slice_size, start)
  4491. start = None
  4492. except ValueError:
  4493. pass
  4494. runtime_check = None
  4495. compile_time_check = False
  4496. try:
  4497. int_target_size = int(target_size)
  4498. except ValueError:
  4499. int_target_size = None
  4500. else:
  4501. compile_time_check = isinstance(slice_size, _py_int_types)
  4502. if compile_time_check and slice_size < 0:
  4503. if int_target_size > 0:
  4504. error(self.pos, "Assignment to empty slice.")
  4505. elif compile_time_check and start is None and stop is None:
  4506. # we know the exact slice length
  4507. if int_target_size != slice_size:
  4508. error(self.pos, "Assignment to slice of wrong length, expected %s, got %s" % (
  4509. slice_size, target_size))
  4510. elif start is not None:
  4511. if stop is None:
  4512. stop = slice_size
  4513. runtime_check = "(%s)-(%s)" % (stop, start)
  4514. elif stop is not None:
  4515. runtime_check = stop
  4516. else:
  4517. runtime_check = slice_size
  4518. if runtime_check:
  4519. code.putln("if (unlikely((%s) != (%s))) {" % (runtime_check, target_size))
  4520. code.putln(
  4521. 'PyErr_Format(PyExc_ValueError, "Assignment to slice of wrong length,'
  4522. ' expected %%" CYTHON_FORMAT_SSIZE_T "d, got %%" CYTHON_FORMAT_SSIZE_T "d",'
  4523. ' (Py_ssize_t)(%s), (Py_ssize_t)(%s));' % (
  4524. target_size, runtime_check))
  4525. code.putln(code.error_goto(self.pos))
  4526. code.putln("}")
  4527. def start_code(self):
  4528. if self.start:
  4529. return self.start.result()
  4530. else:
  4531. return "0"
  4532. def stop_code(self):
  4533. if self.stop:
  4534. return self.stop.result()
  4535. elif self.base.type.is_array:
  4536. return self.base.type.size
  4537. else:
  4538. return "PY_SSIZE_T_MAX"
  4539. def calculate_result_code(self):
  4540. # self.result() is not used, but this method must exist
  4541. return "<unused>"
  4542. class SliceNode(ExprNode):
  4543. # start:stop:step in subscript list
  4544. #
  4545. # start ExprNode
  4546. # stop ExprNode
  4547. # step ExprNode
  4548. subexprs = ['start', 'stop', 'step']
  4549. is_slice = True
  4550. type = slice_type
  4551. is_temp = 1
  4552. def calculate_constant_result(self):
  4553. self.constant_result = slice(
  4554. self.start.constant_result,
  4555. self.stop.constant_result,
  4556. self.step.constant_result)
  4557. def compile_time_value(self, denv):
  4558. start = self.start.compile_time_value(denv)
  4559. stop = self.stop.compile_time_value(denv)
  4560. step = self.step.compile_time_value(denv)
  4561. try:
  4562. return slice(start, stop, step)
  4563. except Exception as e:
  4564. self.compile_time_value_error(e)
  4565. def may_be_none(self):
  4566. return False
  4567. def analyse_types(self, env):
  4568. start = self.start.analyse_types(env)
  4569. stop = self.stop.analyse_types(env)
  4570. step = self.step.analyse_types(env)
  4571. self.start = start.coerce_to_pyobject(env)
  4572. self.stop = stop.coerce_to_pyobject(env)
  4573. self.step = step.coerce_to_pyobject(env)
  4574. if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
  4575. self.is_literal = True
  4576. self.is_temp = False
  4577. return self
  4578. gil_message = "Constructing Python slice object"
  4579. def calculate_result_code(self):
  4580. return self.result_code
  4581. def generate_result_code(self, code):
  4582. if self.is_literal:
  4583. dedup_key = make_dedup_key(self.type, (self,))
  4584. self.result_code = code.get_py_const(py_object_type, 'slice', cleanup_level=2, dedup_key=dedup_key)
  4585. code = code.get_cached_constants_writer(self.result_code)
  4586. if code is None:
  4587. return # already initialised
  4588. code.mark_pos(self.pos)
  4589. code.putln(
  4590. "%s = PySlice_New(%s, %s, %s); %s" % (
  4591. self.result(),
  4592. self.start.py_result(),
  4593. self.stop.py_result(),
  4594. self.step.py_result(),
  4595. code.error_goto_if_null(self.result(), self.pos)))
  4596. code.put_gotref(self.py_result())
  4597. if self.is_literal:
  4598. code.put_giveref(self.py_result())
  4599. class SliceIntNode(SliceNode):
  4600. # start:stop:step in subscript list
  4601. # This is just a node to hold start,stop and step nodes that can be
  4602. # converted to integers. This does not generate a slice python object.
  4603. #
  4604. # start ExprNode
  4605. # stop ExprNode
  4606. # step ExprNode
  4607. is_temp = 0
  4608. def calculate_constant_result(self):
  4609. self.constant_result = slice(
  4610. self.start.constant_result,
  4611. self.stop.constant_result,
  4612. self.step.constant_result)
  4613. def compile_time_value(self, denv):
  4614. start = self.start.compile_time_value(denv)
  4615. stop = self.stop.compile_time_value(denv)
  4616. step = self.step.compile_time_value(denv)
  4617. try:
  4618. return slice(start, stop, step)
  4619. except Exception as e:
  4620. self.compile_time_value_error(e)
  4621. def may_be_none(self):
  4622. return False
  4623. def analyse_types(self, env):
  4624. self.start = self.start.analyse_types(env)
  4625. self.stop = self.stop.analyse_types(env)
  4626. self.step = self.step.analyse_types(env)
  4627. if not self.start.is_none:
  4628. self.start = self.start.coerce_to_integer(env)
  4629. if not self.stop.is_none:
  4630. self.stop = self.stop.coerce_to_integer(env)
  4631. if not self.step.is_none:
  4632. self.step = self.step.coerce_to_integer(env)
  4633. if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
  4634. self.is_literal = True
  4635. self.is_temp = False
  4636. return self
  4637. def calculate_result_code(self):
  4638. pass
  4639. def generate_result_code(self, code):
  4640. for a in self.start,self.stop,self.step:
  4641. if isinstance(a, CloneNode):
  4642. a.arg.result()
  4643. class CallNode(ExprNode):
  4644. # allow overriding the default 'may_be_none' behaviour
  4645. may_return_none = None
  4646. def infer_type(self, env):
  4647. # TODO(robertwb): Reduce redundancy with analyse_types.
  4648. function = self.function
  4649. func_type = function.infer_type(env)
  4650. if isinstance(function, NewExprNode):
  4651. # note: needs call to infer_type() above
  4652. return PyrexTypes.CPtrType(function.class_type)
  4653. if func_type is py_object_type:
  4654. # function might have lied for safety => try to find better type
  4655. entry = getattr(function, 'entry', None)
  4656. if entry is not None:
  4657. func_type = entry.type or func_type
  4658. if func_type.is_ptr:
  4659. func_type = func_type.base_type
  4660. if func_type.is_cfunction:
  4661. if getattr(self.function, 'entry', None) and hasattr(self, 'args'):
  4662. alternatives = self.function.entry.all_alternatives()
  4663. arg_types = [arg.infer_type(env) for arg in self.args]
  4664. func_entry = PyrexTypes.best_match(arg_types, alternatives)
  4665. if func_entry:
  4666. func_type = func_entry.type
  4667. if func_type.is_ptr:
  4668. func_type = func_type.base_type
  4669. return func_type.return_type
  4670. return func_type.return_type
  4671. elif func_type is type_type:
  4672. if function.is_name and function.entry and function.entry.type:
  4673. result_type = function.entry.type
  4674. if result_type.is_extension_type:
  4675. return result_type
  4676. elif result_type.is_builtin_type:
  4677. if function.entry.name == 'float':
  4678. return PyrexTypes.c_double_type
  4679. elif function.entry.name in Builtin.types_that_construct_their_instance:
  4680. return result_type
  4681. return py_object_type
  4682. def type_dependencies(self, env):
  4683. # TODO: Update when Danilo's C++ code merged in to handle the
  4684. # the case of function overloading.
  4685. return self.function.type_dependencies(env)
  4686. def is_simple(self):
  4687. # C function calls could be considered simple, but they may
  4688. # have side-effects that may hit when multiple operations must
  4689. # be effected in order, e.g. when constructing the argument
  4690. # sequence for a function call or comparing values.
  4691. return False
  4692. def may_be_none(self):
  4693. if self.may_return_none is not None:
  4694. return self.may_return_none
  4695. func_type = self.function.type
  4696. if func_type is type_type and self.function.is_name:
  4697. entry = self.function.entry
  4698. if entry.type.is_extension_type:
  4699. return False
  4700. if (entry.type.is_builtin_type and
  4701. entry.name in Builtin.types_that_construct_their_instance):
  4702. return False
  4703. return ExprNode.may_be_none(self)
  4704. def set_py_result_type(self, function, func_type=None):
  4705. if func_type is None:
  4706. func_type = function.type
  4707. if func_type is Builtin.type_type and (
  4708. function.is_name and
  4709. function.entry and
  4710. function.entry.is_builtin and
  4711. function.entry.name in Builtin.types_that_construct_their_instance):
  4712. # calling a builtin type that returns a specific object type
  4713. if function.entry.name == 'float':
  4714. # the following will come true later on in a transform
  4715. self.type = PyrexTypes.c_double_type
  4716. self.result_ctype = PyrexTypes.c_double_type
  4717. else:
  4718. self.type = Builtin.builtin_types[function.entry.name]
  4719. self.result_ctype = py_object_type
  4720. self.may_return_none = False
  4721. elif function.is_name and function.type_entry:
  4722. # We are calling an extension type constructor. As long as we do not
  4723. # support __new__(), the result type is clear
  4724. self.type = function.type_entry.type
  4725. self.result_ctype = py_object_type
  4726. self.may_return_none = False
  4727. else:
  4728. self.type = py_object_type
  4729. def analyse_as_type_constructor(self, env):
  4730. type = self.function.analyse_as_type(env)
  4731. if type and type.is_struct_or_union:
  4732. args, kwds = self.explicit_args_kwds()
  4733. items = []
  4734. for arg, member in zip(args, type.scope.var_entries):
  4735. items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
  4736. if kwds:
  4737. items += kwds.key_value_pairs
  4738. self.key_value_pairs = items
  4739. self.__class__ = DictNode
  4740. self.analyse_types(env) # FIXME
  4741. self.coerce_to(type, env)
  4742. return True
  4743. elif type and type.is_cpp_class:
  4744. self.args = [ arg.analyse_types(env) for arg in self.args ]
  4745. constructor = type.scope.lookup("<init>")
  4746. if not constructor:
  4747. error(self.function.pos, "no constructor found for C++ type '%s'" % self.function.name)
  4748. self.type = error_type
  4749. return self
  4750. self.function = RawCNameExprNode(self.function.pos, constructor.type)
  4751. self.function.entry = constructor
  4752. self.function.set_cname(type.empty_declaration_code())
  4753. self.analyse_c_function_call(env)
  4754. self.type = type
  4755. return True
  4756. def is_lvalue(self):
  4757. return self.type.is_reference
  4758. def nogil_check(self, env):
  4759. func_type = self.function_type()
  4760. if func_type.is_pyobject:
  4761. self.gil_error()
  4762. elif not func_type.is_error and not getattr(func_type, 'nogil', False):
  4763. self.gil_error()
  4764. gil_message = "Calling gil-requiring function"
  4765. class SimpleCallNode(CallNode):
  4766. # Function call without keyword, * or ** args.
  4767. #
  4768. # function ExprNode
  4769. # args [ExprNode]
  4770. # arg_tuple ExprNode or None used internally
  4771. # self ExprNode or None used internally
  4772. # coerced_self ExprNode or None used internally
  4773. # wrapper_call bool used internally
  4774. # has_optional_args bool used internally
  4775. # nogil bool used internally
  4776. subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
  4777. self = None
  4778. coerced_self = None
  4779. arg_tuple = None
  4780. wrapper_call = False
  4781. has_optional_args = False
  4782. nogil = False
  4783. analysed = False
  4784. overflowcheck = False
  4785. def compile_time_value(self, denv):
  4786. function = self.function.compile_time_value(denv)
  4787. args = [arg.compile_time_value(denv) for arg in self.args]
  4788. try:
  4789. return function(*args)
  4790. except Exception as e:
  4791. self.compile_time_value_error(e)
  4792. def analyse_as_type(self, env):
  4793. attr = self.function.as_cython_attribute()
  4794. if attr == 'pointer':
  4795. if len(self.args) != 1:
  4796. error(self.args.pos, "only one type allowed.")
  4797. else:
  4798. type = self.args[0].analyse_as_type(env)
  4799. if not type:
  4800. error(self.args[0].pos, "Unknown type")
  4801. else:
  4802. return PyrexTypes.CPtrType(type)
  4803. elif attr == 'typeof':
  4804. if len(self.args) != 1:
  4805. error(self.args.pos, "only one type allowed.")
  4806. operand = self.args[0].analyse_types(env)
  4807. return operand.type
  4808. def explicit_args_kwds(self):
  4809. return self.args, None
  4810. def analyse_types(self, env):
  4811. if self.analyse_as_type_constructor(env):
  4812. return self
  4813. if self.analysed:
  4814. return self
  4815. self.analysed = True
  4816. self.function.is_called = 1
  4817. self.function = self.function.analyse_types(env)
  4818. function = self.function
  4819. if function.is_attribute and function.entry and function.entry.is_cmethod:
  4820. # Take ownership of the object from which the attribute
  4821. # was obtained, because we need to pass it as 'self'.
  4822. self.self = function.obj
  4823. function.obj = CloneNode(self.self)
  4824. func_type = self.function_type()
  4825. self.is_numpy_call_with_exprs = False
  4826. if (has_np_pythran(env) and function.is_numpy_attribute and
  4827. pythran_is_numpy_func_supported(function)):
  4828. has_pythran_args = True
  4829. self.arg_tuple = TupleNode(self.pos, args = self.args)
  4830. self.arg_tuple = self.arg_tuple.analyse_types(env)
  4831. for arg in self.arg_tuple.args:
  4832. has_pythran_args &= is_pythran_supported_node_or_none(arg)
  4833. self.is_numpy_call_with_exprs = bool(has_pythran_args)
  4834. if self.is_numpy_call_with_exprs:
  4835. env.add_include_file(pythran_get_func_include_file(function))
  4836. return NumPyMethodCallNode.from_node(
  4837. self,
  4838. function_cname=pythran_functor(function),
  4839. arg_tuple=self.arg_tuple,
  4840. type=PythranExpr(pythran_func_type(function, self.arg_tuple.args)),
  4841. )
  4842. elif func_type.is_pyobject:
  4843. self.arg_tuple = TupleNode(self.pos, args = self.args)
  4844. self.arg_tuple = self.arg_tuple.analyse_types(env).coerce_to_pyobject(env)
  4845. self.args = None
  4846. self.set_py_result_type(function, func_type)
  4847. self.is_temp = 1
  4848. else:
  4849. self.args = [ arg.analyse_types(env) for arg in self.args ]
  4850. self.analyse_c_function_call(env)
  4851. if func_type.exception_check == '+':
  4852. self.is_temp = True
  4853. return self
  4854. def function_type(self):
  4855. # Return the type of the function being called, coercing a function
  4856. # pointer to a function if necessary. If the function has fused
  4857. # arguments, return the specific type.
  4858. func_type = self.function.type
  4859. if func_type.is_ptr:
  4860. func_type = func_type.base_type
  4861. return func_type
  4862. def analyse_c_function_call(self, env):
  4863. func_type = self.function.type
  4864. if func_type is error_type:
  4865. self.type = error_type
  4866. return
  4867. if func_type.is_cfunction and func_type.is_static_method:
  4868. if self.self and self.self.type.is_extension_type:
  4869. # To support this we'd need to pass self to determine whether
  4870. # it was overloaded in Python space (possibly via a Cython
  4871. # superclass turning a cdef method into a cpdef one).
  4872. error(self.pos, "Cannot call a static method on an instance variable.")
  4873. args = self.args
  4874. elif self.self:
  4875. args = [self.self] + self.args
  4876. else:
  4877. args = self.args
  4878. if func_type.is_cpp_class:
  4879. overloaded_entry = self.function.type.scope.lookup("operator()")
  4880. if overloaded_entry is None:
  4881. self.type = PyrexTypes.error_type
  4882. self.result_code = "<error>"
  4883. return
  4884. elif hasattr(self.function, 'entry'):
  4885. overloaded_entry = self.function.entry
  4886. elif self.function.is_subscript and self.function.is_fused_index:
  4887. overloaded_entry = self.function.type.entry
  4888. else:
  4889. overloaded_entry = None
  4890. if overloaded_entry:
  4891. if self.function.type.is_fused:
  4892. functypes = self.function.type.get_all_specialized_function_types()
  4893. alternatives = [f.entry for f in functypes]
  4894. else:
  4895. alternatives = overloaded_entry.all_alternatives()
  4896. entry = PyrexTypes.best_match(
  4897. [arg.type for arg in args], alternatives, self.pos, env, args)
  4898. if not entry:
  4899. self.type = PyrexTypes.error_type
  4900. self.result_code = "<error>"
  4901. return
  4902. entry.used = True
  4903. if not func_type.is_cpp_class:
  4904. self.function.entry = entry
  4905. self.function.type = entry.type
  4906. func_type = self.function_type()
  4907. else:
  4908. entry = None
  4909. func_type = self.function_type()
  4910. if not func_type.is_cfunction:
  4911. error(self.pos, "Calling non-function type '%s'" % func_type)
  4912. self.type = PyrexTypes.error_type
  4913. self.result_code = "<error>"
  4914. return
  4915. # Check no. of args
  4916. max_nargs = len(func_type.args)
  4917. expected_nargs = max_nargs - func_type.optional_arg_count
  4918. actual_nargs = len(args)
  4919. if func_type.optional_arg_count and expected_nargs != actual_nargs:
  4920. self.has_optional_args = 1
  4921. self.is_temp = 1
  4922. # check 'self' argument
  4923. if entry and entry.is_cmethod and func_type.args and not func_type.is_static_method:
  4924. formal_arg = func_type.args[0]
  4925. arg = args[0]
  4926. if formal_arg.not_none:
  4927. if self.self:
  4928. self.self = self.self.as_none_safe_node(
  4929. "'NoneType' object has no attribute '%{0}s'".format('.30' if len(entry.name) <= 30 else ''),
  4930. error='PyExc_AttributeError',
  4931. format_args=[entry.name])
  4932. else:
  4933. # unbound method
  4934. arg = arg.as_none_safe_node(
  4935. "descriptor '%s' requires a '%s' object but received a 'NoneType'",
  4936. format_args=[entry.name, formal_arg.type.name])
  4937. if self.self:
  4938. if formal_arg.accept_builtin_subtypes:
  4939. arg = CMethodSelfCloneNode(self.self)
  4940. else:
  4941. arg = CloneNode(self.self)
  4942. arg = self.coerced_self = arg.coerce_to(formal_arg.type, env)
  4943. elif formal_arg.type.is_builtin_type:
  4944. # special case: unbound methods of builtins accept subtypes
  4945. arg = arg.coerce_to(formal_arg.type, env)
  4946. if arg.type.is_builtin_type and isinstance(arg, PyTypeTestNode):
  4947. arg.exact_builtin_type = False
  4948. args[0] = arg
  4949. # Coerce arguments
  4950. some_args_in_temps = False
  4951. for i in range(min(max_nargs, actual_nargs)):
  4952. formal_arg = func_type.args[i]
  4953. formal_type = formal_arg.type
  4954. arg = args[i].coerce_to(formal_type, env)
  4955. if formal_arg.not_none:
  4956. # C methods must do the None checks at *call* time
  4957. arg = arg.as_none_safe_node(
  4958. "cannot pass None into a C function argument that is declared 'not None'")
  4959. if arg.is_temp:
  4960. if i > 0:
  4961. # first argument in temp doesn't impact subsequent arguments
  4962. some_args_in_temps = True
  4963. elif arg.type.is_pyobject and not env.nogil:
  4964. if i == 0 and self.self is not None:
  4965. # a method's cloned "self" argument is ok
  4966. pass
  4967. elif arg.nonlocally_immutable():
  4968. # plain local variables are ok
  4969. pass
  4970. else:
  4971. # we do not safely own the argument's reference,
  4972. # but we must make sure it cannot be collected
  4973. # before we return from the function, so we create
  4974. # an owned temp reference to it
  4975. if i > 0: # first argument doesn't matter
  4976. some_args_in_temps = True
  4977. arg = arg.coerce_to_temp(env)
  4978. args[i] = arg
  4979. # handle additional varargs parameters
  4980. for i in range(max_nargs, actual_nargs):
  4981. arg = args[i]
  4982. if arg.type.is_pyobject:
  4983. if arg.type is str_type:
  4984. arg_ctype = PyrexTypes.c_char_ptr_type
  4985. else:
  4986. arg_ctype = arg.type.default_coerced_ctype()
  4987. if arg_ctype is None:
  4988. error(self.args[i].pos,
  4989. "Python object cannot be passed as a varargs parameter")
  4990. else:
  4991. args[i] = arg = arg.coerce_to(arg_ctype, env)
  4992. if arg.is_temp and i > 0:
  4993. some_args_in_temps = True
  4994. if some_args_in_temps:
  4995. # if some args are temps and others are not, they may get
  4996. # constructed in the wrong order (temps first) => make
  4997. # sure they are either all temps or all not temps (except
  4998. # for the last argument, which is evaluated last in any
  4999. # case)
  5000. for i in range(actual_nargs-1):
  5001. if i == 0 and self.self is not None:
  5002. continue # self is ok
  5003. arg = args[i]
  5004. if arg.nonlocally_immutable():
  5005. # locals, C functions, unassignable types are safe.
  5006. pass
  5007. elif arg.type.is_cpp_class:
  5008. # Assignment has side effects, avoid.
  5009. pass
  5010. elif env.nogil and arg.type.is_pyobject:
  5011. # can't copy a Python reference into a temp in nogil
  5012. # env (this is safe: a construction would fail in
  5013. # nogil anyway)
  5014. pass
  5015. else:
  5016. #self.args[i] = arg.coerce_to_temp(env)
  5017. # instead: issue a warning
  5018. if i > 0 or i == 1 and self.self is not None: # skip first arg
  5019. warning(arg.pos, "Argument evaluation order in C function call is undefined and may not be as expected", 0)
  5020. break
  5021. self.args[:] = args
  5022. # Calc result type and code fragment
  5023. if isinstance(self.function, NewExprNode):
  5024. self.type = PyrexTypes.CPtrType(self.function.class_type)
  5025. else:
  5026. self.type = func_type.return_type
  5027. if self.function.is_name or self.function.is_attribute:
  5028. func_entry = self.function.entry
  5029. if func_entry and (func_entry.utility_code or func_entry.utility_code_definition):
  5030. self.is_temp = 1 # currently doesn't work for self.calculate_result_code()
  5031. if self.type.is_pyobject:
  5032. self.result_ctype = py_object_type
  5033. self.is_temp = 1
  5034. elif func_type.exception_value is not None or func_type.exception_check:
  5035. self.is_temp = 1
  5036. elif self.type.is_memoryviewslice:
  5037. self.is_temp = 1
  5038. # func_type.exception_check = True
  5039. if self.is_temp and self.type.is_reference:
  5040. self.type = PyrexTypes.CFakeReferenceType(self.type.ref_base_type)
  5041. # Called in 'nogil' context?
  5042. self.nogil = env.nogil
  5043. if (self.nogil and
  5044. func_type.exception_check and
  5045. func_type.exception_check != '+'):
  5046. env.use_utility_code(pyerr_occurred_withgil_utility_code)
  5047. # C++ exception handler
  5048. if func_type.exception_check == '+':
  5049. if func_type.exception_value is None:
  5050. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  5051. self.overflowcheck = env.directives['overflowcheck']
  5052. def calculate_result_code(self):
  5053. return self.c_call_code()
  5054. def c_call_code(self):
  5055. func_type = self.function_type()
  5056. if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
  5057. return "<error>"
  5058. formal_args = func_type.args
  5059. arg_list_code = []
  5060. args = list(zip(formal_args, self.args))
  5061. max_nargs = len(func_type.args)
  5062. expected_nargs = max_nargs - func_type.optional_arg_count
  5063. actual_nargs = len(self.args)
  5064. for formal_arg, actual_arg in args[:expected_nargs]:
  5065. arg_code = actual_arg.result_as(formal_arg.type)
  5066. arg_list_code.append(arg_code)
  5067. if func_type.is_overridable:
  5068. arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
  5069. if func_type.optional_arg_count:
  5070. if expected_nargs == actual_nargs:
  5071. optional_args = 'NULL'
  5072. else:
  5073. optional_args = "&%s" % self.opt_arg_struct
  5074. arg_list_code.append(optional_args)
  5075. for actual_arg in self.args[len(formal_args):]:
  5076. arg_list_code.append(actual_arg.result())
  5077. result = "%s(%s)" % (self.function.result(), ', '.join(arg_list_code))
  5078. return result
  5079. def is_c_result_required(self):
  5080. func_type = self.function_type()
  5081. if not func_type.exception_value or func_type.exception_check == '+':
  5082. return False # skip allocation of unused result temp
  5083. return True
  5084. def generate_evaluation_code(self, code):
  5085. function = self.function
  5086. if function.is_name or function.is_attribute:
  5087. code.globalstate.use_entry_utility_code(function.entry)
  5088. abs_function_cnames = ('abs', 'labs', '__Pyx_abs_longlong')
  5089. is_signed_int = self.type.is_int and self.type.signed
  5090. if self.overflowcheck and is_signed_int and function.result() in abs_function_cnames:
  5091. code.globalstate.use_utility_code(UtilityCode.load_cached("Common", "Overflow.c"))
  5092. code.putln('if (unlikely(%s == __PYX_MIN(%s))) {\
  5093. PyErr_SetString(PyExc_OverflowError,\
  5094. "Trying to take the absolute value of the most negative integer is not defined."); %s; }' % (
  5095. self.args[0].result(),
  5096. self.args[0].type.empty_declaration_code(),
  5097. code.error_goto(self.pos)))
  5098. if not function.type.is_pyobject or len(self.arg_tuple.args) > 1 or (
  5099. self.arg_tuple.args and self.arg_tuple.is_literal):
  5100. super(SimpleCallNode, self).generate_evaluation_code(code)
  5101. return
  5102. # Special case 0-args and try to avoid explicit tuple creation for Python calls with 1 arg.
  5103. arg = self.arg_tuple.args[0] if self.arg_tuple.args else None
  5104. subexprs = (self.self, self.coerced_self, function, arg)
  5105. for subexpr in subexprs:
  5106. if subexpr is not None:
  5107. subexpr.generate_evaluation_code(code)
  5108. code.mark_pos(self.pos)
  5109. assert self.is_temp
  5110. self.allocate_temp_result(code)
  5111. if arg is None:
  5112. code.globalstate.use_utility_code(UtilityCode.load_cached(
  5113. "PyObjectCallNoArg", "ObjectHandling.c"))
  5114. code.putln(
  5115. "%s = __Pyx_PyObject_CallNoArg(%s); %s" % (
  5116. self.result(),
  5117. function.py_result(),
  5118. code.error_goto_if_null(self.result(), self.pos)))
  5119. else:
  5120. code.globalstate.use_utility_code(UtilityCode.load_cached(
  5121. "PyObjectCallOneArg", "ObjectHandling.c"))
  5122. code.putln(
  5123. "%s = __Pyx_PyObject_CallOneArg(%s, %s); %s" % (
  5124. self.result(),
  5125. function.py_result(),
  5126. arg.py_result(),
  5127. code.error_goto_if_null(self.result(), self.pos)))
  5128. code.put_gotref(self.py_result())
  5129. for subexpr in subexprs:
  5130. if subexpr is not None:
  5131. subexpr.generate_disposal_code(code)
  5132. subexpr.free_temps(code)
  5133. def generate_result_code(self, code):
  5134. func_type = self.function_type()
  5135. if func_type.is_pyobject:
  5136. arg_code = self.arg_tuple.py_result()
  5137. code.globalstate.use_utility_code(UtilityCode.load_cached(
  5138. "PyObjectCall", "ObjectHandling.c"))
  5139. code.putln(
  5140. "%s = __Pyx_PyObject_Call(%s, %s, NULL); %s" % (
  5141. self.result(),
  5142. self.function.py_result(),
  5143. arg_code,
  5144. code.error_goto_if_null(self.result(), self.pos)))
  5145. code.put_gotref(self.py_result())
  5146. elif func_type.is_cfunction:
  5147. if self.has_optional_args:
  5148. actual_nargs = len(self.args)
  5149. expected_nargs = len(func_type.args) - func_type.optional_arg_count
  5150. self.opt_arg_struct = code.funcstate.allocate_temp(
  5151. func_type.op_arg_struct.base_type, manage_ref=True)
  5152. code.putln("%s.%s = %s;" % (
  5153. self.opt_arg_struct,
  5154. Naming.pyrex_prefix + "n",
  5155. len(self.args) - expected_nargs))
  5156. args = list(zip(func_type.args, self.args))
  5157. for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
  5158. code.putln("%s.%s = %s;" % (
  5159. self.opt_arg_struct,
  5160. func_type.opt_arg_cname(formal_arg.name),
  5161. actual_arg.result_as(formal_arg.type)))
  5162. exc_checks = []
  5163. if self.type.is_pyobject and self.is_temp:
  5164. exc_checks.append("!%s" % self.result())
  5165. elif self.type.is_memoryviewslice:
  5166. assert self.is_temp
  5167. exc_checks.append(self.type.error_condition(self.result()))
  5168. elif func_type.exception_check != '+':
  5169. exc_val = func_type.exception_value
  5170. exc_check = func_type.exception_check
  5171. if exc_val is not None:
  5172. exc_checks.append("%s == %s" % (self.result(), func_type.return_type.cast_code(exc_val)))
  5173. if exc_check:
  5174. if self.nogil:
  5175. exc_checks.append("__Pyx_ErrOccurredWithGIL()")
  5176. else:
  5177. exc_checks.append("PyErr_Occurred()")
  5178. if self.is_temp or exc_checks:
  5179. rhs = self.c_call_code()
  5180. if self.result():
  5181. lhs = "%s = " % self.result()
  5182. if self.is_temp and self.type.is_pyobject:
  5183. #return_type = self.type # func_type.return_type
  5184. #print "SimpleCallNode.generate_result_code: casting", rhs, \
  5185. # "from", return_type, "to pyobject" ###
  5186. rhs = typecast(py_object_type, self.type, rhs)
  5187. else:
  5188. lhs = ""
  5189. if func_type.exception_check == '+':
  5190. translate_cpp_exception(code, self.pos, '%s%s;' % (lhs, rhs),
  5191. self.result() if self.type.is_pyobject else None,
  5192. func_type.exception_value, self.nogil)
  5193. else:
  5194. if exc_checks:
  5195. goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
  5196. else:
  5197. goto_error = ""
  5198. code.putln("%s%s; %s" % (lhs, rhs, goto_error))
  5199. if self.type.is_pyobject and self.result():
  5200. code.put_gotref(self.py_result())
  5201. if self.has_optional_args:
  5202. code.funcstate.release_temp(self.opt_arg_struct)
  5203. class NumPyMethodCallNode(ExprNode):
  5204. # Pythran call to a NumPy function or method.
  5205. #
  5206. # function_cname string the function/method to call
  5207. # arg_tuple TupleNode the arguments as an args tuple
  5208. subexprs = ['arg_tuple']
  5209. is_temp = True
  5210. may_return_none = True
  5211. def generate_evaluation_code(self, code):
  5212. code.mark_pos(self.pos)
  5213. self.allocate_temp_result(code)
  5214. assert self.arg_tuple.mult_factor is None
  5215. args = self.arg_tuple.args
  5216. for arg in args:
  5217. arg.generate_evaluation_code(code)
  5218. code.putln("// function evaluation code for numpy function")
  5219. code.putln("__Pyx_call_destructor(%s);" % self.result())
  5220. code.putln("new (&%s) decltype(%s){%s{}(%s)};" % (
  5221. self.result(),
  5222. self.result(),
  5223. self.function_cname,
  5224. ", ".join(a.pythran_result() for a in args)))
  5225. class PyMethodCallNode(SimpleCallNode):
  5226. # Specialised call to a (potential) PyMethodObject with non-constant argument tuple.
  5227. # Allows the self argument to be injected directly instead of repacking a tuple for it.
  5228. #
  5229. # function ExprNode the function/method object to call
  5230. # arg_tuple TupleNode the arguments for the args tuple
  5231. subexprs = ['function', 'arg_tuple']
  5232. is_temp = True
  5233. def generate_evaluation_code(self, code):
  5234. code.mark_pos(self.pos)
  5235. self.allocate_temp_result(code)
  5236. self.function.generate_evaluation_code(code)
  5237. assert self.arg_tuple.mult_factor is None
  5238. args = self.arg_tuple.args
  5239. for arg in args:
  5240. arg.generate_evaluation_code(code)
  5241. # make sure function is in temp so that we can replace the reference below if it's a method
  5242. reuse_function_temp = self.function.is_temp
  5243. if reuse_function_temp:
  5244. function = self.function.result()
  5245. else:
  5246. function = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  5247. self.function.make_owned_reference(code)
  5248. code.put("%s = %s; " % (function, self.function.py_result()))
  5249. self.function.generate_disposal_code(code)
  5250. self.function.free_temps(code)
  5251. self_arg = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  5252. code.putln("%s = NULL;" % self_arg)
  5253. arg_offset_cname = None
  5254. if len(args) > 1:
  5255. arg_offset_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
  5256. code.putln("%s = 0;" % arg_offset_cname)
  5257. def attribute_is_likely_method(attr):
  5258. obj = attr.obj
  5259. if obj.is_name and obj.entry.is_pyglobal:
  5260. return False # more likely to be a function
  5261. return True
  5262. if self.function.is_attribute:
  5263. likely_method = 'likely' if attribute_is_likely_method(self.function) else 'unlikely'
  5264. elif self.function.is_name and self.function.cf_state:
  5265. # not an attribute itself, but might have been assigned from one (e.g. bound method)
  5266. for assignment in self.function.cf_state:
  5267. value = assignment.rhs
  5268. if value and value.is_attribute and value.obj.type and value.obj.type.is_pyobject:
  5269. if attribute_is_likely_method(value):
  5270. likely_method = 'likely'
  5271. break
  5272. else:
  5273. likely_method = 'unlikely'
  5274. else:
  5275. likely_method = 'unlikely'
  5276. code.putln("if (CYTHON_UNPACK_METHODS && %s(PyMethod_Check(%s))) {" % (likely_method, function))
  5277. code.putln("%s = PyMethod_GET_SELF(%s);" % (self_arg, function))
  5278. # the following is always true in Py3 (kept only for safety),
  5279. # but is false for unbound methods in Py2
  5280. code.putln("if (likely(%s)) {" % self_arg)
  5281. code.putln("PyObject* function = PyMethod_GET_FUNCTION(%s);" % function)
  5282. code.put_incref(self_arg, py_object_type)
  5283. code.put_incref("function", py_object_type)
  5284. # free method object as early to possible to enable reuse from CPython's freelist
  5285. code.put_decref_set(function, "function")
  5286. if len(args) > 1:
  5287. code.putln("%s = 1;" % arg_offset_cname)
  5288. code.putln("}")
  5289. code.putln("}")
  5290. if not args:
  5291. # fastest special case: try to avoid tuple creation
  5292. code.globalstate.use_utility_code(
  5293. UtilityCode.load_cached("PyObjectCallNoArg", "ObjectHandling.c"))
  5294. code.globalstate.use_utility_code(
  5295. UtilityCode.load_cached("PyObjectCallOneArg", "ObjectHandling.c"))
  5296. code.putln(
  5297. "%s = (%s) ? __Pyx_PyObject_CallOneArg(%s, %s) : __Pyx_PyObject_CallNoArg(%s);" % (
  5298. self.result(), self_arg,
  5299. function, self_arg,
  5300. function))
  5301. code.put_xdecref_clear(self_arg, py_object_type)
  5302. code.funcstate.release_temp(self_arg)
  5303. code.putln(code.error_goto_if_null(self.result(), self.pos))
  5304. code.put_gotref(self.py_result())
  5305. elif len(args) == 1:
  5306. # fastest special case: try to avoid tuple creation
  5307. code.globalstate.use_utility_code(
  5308. UtilityCode.load_cached("PyObjectCall2Args", "ObjectHandling.c"))
  5309. code.globalstate.use_utility_code(
  5310. UtilityCode.load_cached("PyObjectCallOneArg", "ObjectHandling.c"))
  5311. arg = args[0]
  5312. code.putln(
  5313. "%s = (%s) ? __Pyx_PyObject_Call2Args(%s, %s, %s) : __Pyx_PyObject_CallOneArg(%s, %s);" % (
  5314. self.result(), self_arg,
  5315. function, self_arg, arg.py_result(),
  5316. function, arg.py_result()))
  5317. code.put_xdecref_clear(self_arg, py_object_type)
  5318. code.funcstate.release_temp(self_arg)
  5319. arg.generate_disposal_code(code)
  5320. arg.free_temps(code)
  5321. code.putln(code.error_goto_if_null(self.result(), self.pos))
  5322. code.put_gotref(self.py_result())
  5323. else:
  5324. code.globalstate.use_utility_code(
  5325. UtilityCode.load_cached("PyFunctionFastCall", "ObjectHandling.c"))
  5326. code.globalstate.use_utility_code(
  5327. UtilityCode.load_cached("PyCFunctionFastCall", "ObjectHandling.c"))
  5328. for test_func, call_prefix in [('PyFunction_Check', 'Py'), ('__Pyx_PyFastCFunction_Check', 'PyC')]:
  5329. code.putln("#if CYTHON_FAST_%sCALL" % call_prefix.upper())
  5330. code.putln("if (%s(%s)) {" % (test_func, function))
  5331. code.putln("PyObject *%s[%d] = {%s, %s};" % (
  5332. Naming.quick_temp_cname,
  5333. len(args)+1,
  5334. self_arg,
  5335. ', '.join(arg.py_result() for arg in args)))
  5336. code.putln("%s = __Pyx_%sFunction_FastCall(%s, %s+1-%s, %d+%s); %s" % (
  5337. self.result(),
  5338. call_prefix,
  5339. function,
  5340. Naming.quick_temp_cname,
  5341. arg_offset_cname,
  5342. len(args),
  5343. arg_offset_cname,
  5344. code.error_goto_if_null(self.result(), self.pos)))
  5345. code.put_xdecref_clear(self_arg, py_object_type)
  5346. code.put_gotref(self.py_result())
  5347. for arg in args:
  5348. arg.generate_disposal_code(code)
  5349. code.putln("} else")
  5350. code.putln("#endif")
  5351. code.putln("{")
  5352. args_tuple = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  5353. code.putln("%s = PyTuple_New(%d+%s); %s" % (
  5354. args_tuple, len(args), arg_offset_cname,
  5355. code.error_goto_if_null(args_tuple, self.pos)))
  5356. code.put_gotref(args_tuple)
  5357. if len(args) > 1:
  5358. code.putln("if (%s) {" % self_arg)
  5359. code.putln("__Pyx_GIVEREF(%s); PyTuple_SET_ITEM(%s, 0, %s); %s = NULL;" % (
  5360. self_arg, args_tuple, self_arg, self_arg)) # stealing owned ref in this case
  5361. code.funcstate.release_temp(self_arg)
  5362. if len(args) > 1:
  5363. code.putln("}")
  5364. for i, arg in enumerate(args):
  5365. arg.make_owned_reference(code)
  5366. code.put_giveref(arg.py_result())
  5367. code.putln("PyTuple_SET_ITEM(%s, %d+%s, %s);" % (
  5368. args_tuple, i, arg_offset_cname, arg.py_result()))
  5369. if len(args) > 1:
  5370. code.funcstate.release_temp(arg_offset_cname)
  5371. for arg in args:
  5372. arg.generate_post_assignment_code(code)
  5373. arg.free_temps(code)
  5374. code.globalstate.use_utility_code(
  5375. UtilityCode.load_cached("PyObjectCall", "ObjectHandling.c"))
  5376. code.putln(
  5377. "%s = __Pyx_PyObject_Call(%s, %s, NULL); %s" % (
  5378. self.result(),
  5379. function, args_tuple,
  5380. code.error_goto_if_null(self.result(), self.pos)))
  5381. code.put_gotref(self.py_result())
  5382. code.put_decref_clear(args_tuple, py_object_type)
  5383. code.funcstate.release_temp(args_tuple)
  5384. if len(args) == 1:
  5385. code.putln("}")
  5386. code.putln("}") # !CYTHON_FAST_PYCALL
  5387. if reuse_function_temp:
  5388. self.function.generate_disposal_code(code)
  5389. self.function.free_temps(code)
  5390. else:
  5391. code.put_decref_clear(function, py_object_type)
  5392. code.funcstate.release_temp(function)
  5393. class InlinedDefNodeCallNode(CallNode):
  5394. # Inline call to defnode
  5395. #
  5396. # function PyCFunctionNode
  5397. # function_name NameNode
  5398. # args [ExprNode]
  5399. subexprs = ['args', 'function_name']
  5400. is_temp = 1
  5401. type = py_object_type
  5402. function = None
  5403. function_name = None
  5404. def can_be_inlined(self):
  5405. func_type= self.function.def_node
  5406. if func_type.star_arg or func_type.starstar_arg:
  5407. return False
  5408. if len(func_type.args) != len(self.args):
  5409. return False
  5410. if func_type.num_kwonly_args:
  5411. return False # actually wrong number of arguments
  5412. return True
  5413. def analyse_types(self, env):
  5414. self.function_name = self.function_name.analyse_types(env)
  5415. self.args = [ arg.analyse_types(env) for arg in self.args ]
  5416. func_type = self.function.def_node
  5417. actual_nargs = len(self.args)
  5418. # Coerce arguments
  5419. some_args_in_temps = False
  5420. for i in range(actual_nargs):
  5421. formal_type = func_type.args[i].type
  5422. arg = self.args[i].coerce_to(formal_type, env)
  5423. if arg.is_temp:
  5424. if i > 0:
  5425. # first argument in temp doesn't impact subsequent arguments
  5426. some_args_in_temps = True
  5427. elif arg.type.is_pyobject and not env.nogil:
  5428. if arg.nonlocally_immutable():
  5429. # plain local variables are ok
  5430. pass
  5431. else:
  5432. # we do not safely own the argument's reference,
  5433. # but we must make sure it cannot be collected
  5434. # before we return from the function, so we create
  5435. # an owned temp reference to it
  5436. if i > 0: # first argument doesn't matter
  5437. some_args_in_temps = True
  5438. arg = arg.coerce_to_temp(env)
  5439. self.args[i] = arg
  5440. if some_args_in_temps:
  5441. # if some args are temps and others are not, they may get
  5442. # constructed in the wrong order (temps first) => make
  5443. # sure they are either all temps or all not temps (except
  5444. # for the last argument, which is evaluated last in any
  5445. # case)
  5446. for i in range(actual_nargs-1):
  5447. arg = self.args[i]
  5448. if arg.nonlocally_immutable():
  5449. # locals, C functions, unassignable types are safe.
  5450. pass
  5451. elif arg.type.is_cpp_class:
  5452. # Assignment has side effects, avoid.
  5453. pass
  5454. elif env.nogil and arg.type.is_pyobject:
  5455. # can't copy a Python reference into a temp in nogil
  5456. # env (this is safe: a construction would fail in
  5457. # nogil anyway)
  5458. pass
  5459. else:
  5460. #self.args[i] = arg.coerce_to_temp(env)
  5461. # instead: issue a warning
  5462. if i > 0:
  5463. warning(arg.pos, "Argument evaluation order in C function call is undefined and may not be as expected", 0)
  5464. break
  5465. return self
  5466. def generate_result_code(self, code):
  5467. arg_code = [self.function_name.py_result()]
  5468. func_type = self.function.def_node
  5469. for arg, proto_arg in zip(self.args, func_type.args):
  5470. if arg.type.is_pyobject:
  5471. arg_code.append(arg.result_as(proto_arg.type))
  5472. else:
  5473. arg_code.append(arg.result())
  5474. arg_code = ', '.join(arg_code)
  5475. code.putln(
  5476. "%s = %s(%s); %s" % (
  5477. self.result(),
  5478. self.function.def_node.entry.pyfunc_cname,
  5479. arg_code,
  5480. code.error_goto_if_null(self.result(), self.pos)))
  5481. code.put_gotref(self.py_result())
  5482. class PythonCapiFunctionNode(ExprNode):
  5483. subexprs = []
  5484. def __init__(self, pos, py_name, cname, func_type, utility_code = None):
  5485. ExprNode.__init__(self, pos, name=py_name, cname=cname,
  5486. type=func_type, utility_code=utility_code)
  5487. def analyse_types(self, env):
  5488. return self
  5489. def generate_result_code(self, code):
  5490. if self.utility_code:
  5491. code.globalstate.use_utility_code(self.utility_code)
  5492. def calculate_result_code(self):
  5493. return self.cname
  5494. class PythonCapiCallNode(SimpleCallNode):
  5495. # Python C-API Function call (only created in transforms)
  5496. # By default, we assume that the call never returns None, as this
  5497. # is true for most C-API functions in CPython. If this does not
  5498. # apply to a call, set the following to True (or None to inherit
  5499. # the default behaviour).
  5500. may_return_none = False
  5501. def __init__(self, pos, function_name, func_type,
  5502. utility_code = None, py_name=None, **kwargs):
  5503. self.type = func_type.return_type
  5504. self.result_ctype = self.type
  5505. self.function = PythonCapiFunctionNode(
  5506. pos, py_name, function_name, func_type,
  5507. utility_code = utility_code)
  5508. # call this last so that we can override the constructed
  5509. # attributes above with explicit keyword arguments if required
  5510. SimpleCallNode.__init__(self, pos, **kwargs)
  5511. class CachedBuiltinMethodCallNode(CallNode):
  5512. # Python call to a method of a known Python builtin (only created in transforms)
  5513. subexprs = ['obj', 'args']
  5514. is_temp = True
  5515. def __init__(self, call_node, obj, method_name, args):
  5516. super(CachedBuiltinMethodCallNode, self).__init__(
  5517. call_node.pos,
  5518. obj=obj, method_name=method_name, args=args,
  5519. may_return_none=call_node.may_return_none,
  5520. type=call_node.type)
  5521. def may_be_none(self):
  5522. if self.may_return_none is not None:
  5523. return self.may_return_none
  5524. return ExprNode.may_be_none(self)
  5525. def generate_result_code(self, code):
  5526. type_cname = self.obj.type.cname
  5527. obj_cname = self.obj.py_result()
  5528. args = [arg.py_result() for arg in self.args]
  5529. call_code = code.globalstate.cached_unbound_method_call_code(
  5530. obj_cname, type_cname, self.method_name, args)
  5531. code.putln("%s = %s; %s" % (
  5532. self.result(), call_code,
  5533. code.error_goto_if_null(self.result(), self.pos)
  5534. ))
  5535. code.put_gotref(self.result())
  5536. class GeneralCallNode(CallNode):
  5537. # General Python function call, including keyword,
  5538. # * and ** arguments.
  5539. #
  5540. # function ExprNode
  5541. # positional_args ExprNode Tuple of positional arguments
  5542. # keyword_args ExprNode or None Dict of keyword arguments
  5543. type = py_object_type
  5544. subexprs = ['function', 'positional_args', 'keyword_args']
  5545. nogil_check = Node.gil_error
  5546. def compile_time_value(self, denv):
  5547. function = self.function.compile_time_value(denv)
  5548. positional_args = self.positional_args.compile_time_value(denv)
  5549. keyword_args = self.keyword_args.compile_time_value(denv)
  5550. try:
  5551. return function(*positional_args, **keyword_args)
  5552. except Exception as e:
  5553. self.compile_time_value_error(e)
  5554. def explicit_args_kwds(self):
  5555. if (self.keyword_args and not self.keyword_args.is_dict_literal or
  5556. not self.positional_args.is_sequence_constructor):
  5557. raise CompileError(self.pos,
  5558. 'Compile-time keyword arguments must be explicit.')
  5559. return self.positional_args.args, self.keyword_args
  5560. def analyse_types(self, env):
  5561. if self.analyse_as_type_constructor(env):
  5562. return self
  5563. self.function = self.function.analyse_types(env)
  5564. if not self.function.type.is_pyobject:
  5565. if self.function.type.is_error:
  5566. self.type = error_type
  5567. return self
  5568. if hasattr(self.function, 'entry'):
  5569. node = self.map_to_simple_call_node()
  5570. if node is not None and node is not self:
  5571. return node.analyse_types(env)
  5572. elif self.function.entry.as_variable:
  5573. self.function = self.function.coerce_to_pyobject(env)
  5574. elif node is self:
  5575. error(self.pos,
  5576. "Non-trivial keyword arguments and starred "
  5577. "arguments not allowed in cdef functions.")
  5578. else:
  5579. # error was already reported
  5580. pass
  5581. else:
  5582. self.function = self.function.coerce_to_pyobject(env)
  5583. if self.keyword_args:
  5584. self.keyword_args = self.keyword_args.analyse_types(env)
  5585. self.positional_args = self.positional_args.analyse_types(env)
  5586. self.positional_args = \
  5587. self.positional_args.coerce_to_pyobject(env)
  5588. self.set_py_result_type(self.function)
  5589. self.is_temp = 1
  5590. return self
  5591. def map_to_simple_call_node(self):
  5592. """
  5593. Tries to map keyword arguments to declared positional arguments.
  5594. Returns self to try a Python call, None to report an error
  5595. or a SimpleCallNode if the mapping succeeds.
  5596. """
  5597. if not isinstance(self.positional_args, TupleNode):
  5598. # has starred argument
  5599. return self
  5600. if not self.keyword_args.is_dict_literal:
  5601. # keywords come from arbitrary expression => nothing to do here
  5602. return self
  5603. function = self.function
  5604. entry = getattr(function, 'entry', None)
  5605. if not entry:
  5606. return self
  5607. function_type = entry.type
  5608. if function_type.is_ptr:
  5609. function_type = function_type.base_type
  5610. if not function_type.is_cfunction:
  5611. return self
  5612. pos_args = self.positional_args.args
  5613. kwargs = self.keyword_args
  5614. declared_args = function_type.args
  5615. if entry.is_cmethod:
  5616. declared_args = declared_args[1:] # skip 'self'
  5617. if len(pos_args) > len(declared_args):
  5618. error(self.pos, "function call got too many positional arguments, "
  5619. "expected %d, got %s" % (len(declared_args),
  5620. len(pos_args)))
  5621. return None
  5622. matched_args = set([ arg.name for arg in declared_args[:len(pos_args)]
  5623. if arg.name ])
  5624. unmatched_args = declared_args[len(pos_args):]
  5625. matched_kwargs_count = 0
  5626. args = list(pos_args)
  5627. # check for duplicate keywords
  5628. seen = set(matched_args)
  5629. has_errors = False
  5630. for arg in kwargs.key_value_pairs:
  5631. name = arg.key.value
  5632. if name in seen:
  5633. error(arg.pos, "argument '%s' passed twice" % name)
  5634. has_errors = True
  5635. # continue to report more errors if there are any
  5636. seen.add(name)
  5637. # match keywords that are passed in order
  5638. for decl_arg, arg in zip(unmatched_args, kwargs.key_value_pairs):
  5639. name = arg.key.value
  5640. if decl_arg.name == name:
  5641. matched_args.add(name)
  5642. matched_kwargs_count += 1
  5643. args.append(arg.value)
  5644. else:
  5645. break
  5646. # match keyword arguments that are passed out-of-order, but keep
  5647. # the evaluation of non-simple arguments in order by moving them
  5648. # into temps
  5649. from .UtilNodes import EvalWithTempExprNode, LetRefNode
  5650. temps = []
  5651. if len(kwargs.key_value_pairs) > matched_kwargs_count:
  5652. unmatched_args = declared_args[len(args):]
  5653. keywords = dict([ (arg.key.value, (i+len(pos_args), arg))
  5654. for i, arg in enumerate(kwargs.key_value_pairs) ])
  5655. first_missing_keyword = None
  5656. for decl_arg in unmatched_args:
  5657. name = decl_arg.name
  5658. if name not in keywords:
  5659. # missing keyword argument => either done or error
  5660. if not first_missing_keyword:
  5661. first_missing_keyword = name
  5662. continue
  5663. elif first_missing_keyword:
  5664. if entry.as_variable:
  5665. # we might be able to convert the function to a Python
  5666. # object, which then allows full calling semantics
  5667. # with default values in gaps - currently, we only
  5668. # support optional arguments at the end
  5669. return self
  5670. # wasn't the last keyword => gaps are not supported
  5671. error(self.pos, "C function call is missing "
  5672. "argument '%s'" % first_missing_keyword)
  5673. return None
  5674. pos, arg = keywords[name]
  5675. matched_args.add(name)
  5676. matched_kwargs_count += 1
  5677. if arg.value.is_simple():
  5678. args.append(arg.value)
  5679. else:
  5680. temp = LetRefNode(arg.value)
  5681. assert temp.is_simple()
  5682. args.append(temp)
  5683. temps.append((pos, temp))
  5684. if temps:
  5685. # may have to move preceding non-simple args into temps
  5686. final_args = []
  5687. new_temps = []
  5688. first_temp_arg = temps[0][-1]
  5689. for arg_value in args:
  5690. if arg_value is first_temp_arg:
  5691. break # done
  5692. if arg_value.is_simple():
  5693. final_args.append(arg_value)
  5694. else:
  5695. temp = LetRefNode(arg_value)
  5696. new_temps.append(temp)
  5697. final_args.append(temp)
  5698. if new_temps:
  5699. args = final_args
  5700. temps = new_temps + [ arg for i,arg in sorted(temps) ]
  5701. # check for unexpected keywords
  5702. for arg in kwargs.key_value_pairs:
  5703. name = arg.key.value
  5704. if name not in matched_args:
  5705. has_errors = True
  5706. error(arg.pos,
  5707. "C function got unexpected keyword argument '%s'" %
  5708. name)
  5709. if has_errors:
  5710. # error was reported already
  5711. return None
  5712. # all keywords mapped to positional arguments
  5713. # if we are missing arguments, SimpleCallNode will figure it out
  5714. node = SimpleCallNode(self.pos, function=function, args=args)
  5715. for temp in temps[::-1]:
  5716. node = EvalWithTempExprNode(temp, node)
  5717. return node
  5718. def generate_result_code(self, code):
  5719. if self.type.is_error: return
  5720. if self.keyword_args:
  5721. kwargs = self.keyword_args.py_result()
  5722. else:
  5723. kwargs = 'NULL'
  5724. code.globalstate.use_utility_code(UtilityCode.load_cached(
  5725. "PyObjectCall", "ObjectHandling.c"))
  5726. code.putln(
  5727. "%s = __Pyx_PyObject_Call(%s, %s, %s); %s" % (
  5728. self.result(),
  5729. self.function.py_result(),
  5730. self.positional_args.py_result(),
  5731. kwargs,
  5732. code.error_goto_if_null(self.result(), self.pos)))
  5733. code.put_gotref(self.py_result())
  5734. class AsTupleNode(ExprNode):
  5735. # Convert argument to tuple. Used for normalising
  5736. # the * argument of a function call.
  5737. #
  5738. # arg ExprNode
  5739. subexprs = ['arg']
  5740. is_temp = 1
  5741. def calculate_constant_result(self):
  5742. self.constant_result = tuple(self.arg.constant_result)
  5743. def compile_time_value(self, denv):
  5744. arg = self.arg.compile_time_value(denv)
  5745. try:
  5746. return tuple(arg)
  5747. except Exception as e:
  5748. self.compile_time_value_error(e)
  5749. def analyse_types(self, env):
  5750. self.arg = self.arg.analyse_types(env).coerce_to_pyobject(env)
  5751. if self.arg.type is tuple_type:
  5752. return self.arg.as_none_safe_node("'NoneType' object is not iterable")
  5753. self.type = tuple_type
  5754. return self
  5755. def may_be_none(self):
  5756. return False
  5757. nogil_check = Node.gil_error
  5758. gil_message = "Constructing Python tuple"
  5759. def generate_result_code(self, code):
  5760. cfunc = "__Pyx_PySequence_Tuple" if self.arg.type in (py_object_type, tuple_type) else "PySequence_Tuple"
  5761. code.putln(
  5762. "%s = %s(%s); %s" % (
  5763. self.result(),
  5764. cfunc, self.arg.py_result(),
  5765. code.error_goto_if_null(self.result(), self.pos)))
  5766. code.put_gotref(self.py_result())
  5767. class MergedDictNode(ExprNode):
  5768. # Helper class for keyword arguments and other merged dicts.
  5769. #
  5770. # keyword_args [DictNode or other ExprNode]
  5771. subexprs = ['keyword_args']
  5772. is_temp = 1
  5773. type = dict_type
  5774. reject_duplicates = True
  5775. def calculate_constant_result(self):
  5776. result = {}
  5777. reject_duplicates = self.reject_duplicates
  5778. for item in self.keyword_args:
  5779. if item.is_dict_literal:
  5780. # process items in order
  5781. items = ((key.constant_result, value.constant_result)
  5782. for key, value in item.key_value_pairs)
  5783. else:
  5784. items = item.constant_result.iteritems()
  5785. for key, value in items:
  5786. if reject_duplicates and key in result:
  5787. raise ValueError("duplicate keyword argument found: %s" % key)
  5788. result[key] = value
  5789. self.constant_result = result
  5790. def compile_time_value(self, denv):
  5791. result = {}
  5792. reject_duplicates = self.reject_duplicates
  5793. for item in self.keyword_args:
  5794. if item.is_dict_literal:
  5795. # process items in order
  5796. items = [(key.compile_time_value(denv), value.compile_time_value(denv))
  5797. for key, value in item.key_value_pairs]
  5798. else:
  5799. items = item.compile_time_value(denv).iteritems()
  5800. try:
  5801. for key, value in items:
  5802. if reject_duplicates and key in result:
  5803. raise ValueError("duplicate keyword argument found: %s" % key)
  5804. result[key] = value
  5805. except Exception as e:
  5806. self.compile_time_value_error(e)
  5807. return result
  5808. def type_dependencies(self, env):
  5809. return ()
  5810. def infer_type(self, env):
  5811. return dict_type
  5812. def analyse_types(self, env):
  5813. self.keyword_args = [
  5814. arg.analyse_types(env).coerce_to_pyobject(env).as_none_safe_node(
  5815. # FIXME: CPython's error message starts with the runtime function name
  5816. 'argument after ** must be a mapping, not NoneType')
  5817. for arg in self.keyword_args
  5818. ]
  5819. return self
  5820. def may_be_none(self):
  5821. return False
  5822. gil_message = "Constructing Python dict"
  5823. def generate_evaluation_code(self, code):
  5824. code.mark_pos(self.pos)
  5825. self.allocate_temp_result(code)
  5826. args = iter(self.keyword_args)
  5827. item = next(args)
  5828. item.generate_evaluation_code(code)
  5829. if item.type is not dict_type:
  5830. # CPython supports calling functions with non-dicts, so do we
  5831. code.putln('if (likely(PyDict_CheckExact(%s))) {' %
  5832. item.py_result())
  5833. if item.is_dict_literal:
  5834. item.make_owned_reference(code)
  5835. code.putln("%s = %s;" % (self.result(), item.py_result()))
  5836. item.generate_post_assignment_code(code)
  5837. else:
  5838. code.putln("%s = PyDict_Copy(%s); %s" % (
  5839. self.result(),
  5840. item.py_result(),
  5841. code.error_goto_if_null(self.result(), item.pos)))
  5842. code.put_gotref(self.result())
  5843. item.generate_disposal_code(code)
  5844. if item.type is not dict_type:
  5845. code.putln('} else {')
  5846. code.putln("%s = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, %s, NULL); %s" % (
  5847. self.result(),
  5848. item.py_result(),
  5849. code.error_goto_if_null(self.result(), self.pos)))
  5850. code.put_gotref(self.py_result())
  5851. item.generate_disposal_code(code)
  5852. code.putln('}')
  5853. item.free_temps(code)
  5854. helpers = set()
  5855. for item in args:
  5856. if item.is_dict_literal:
  5857. # inline update instead of creating an intermediate dict
  5858. for arg in item.key_value_pairs:
  5859. arg.generate_evaluation_code(code)
  5860. if self.reject_duplicates:
  5861. code.putln("if (unlikely(PyDict_Contains(%s, %s))) {" % (
  5862. self.result(),
  5863. arg.key.py_result()))
  5864. helpers.add("RaiseDoubleKeywords")
  5865. # FIXME: find out function name at runtime!
  5866. code.putln('__Pyx_RaiseDoubleKeywordsError("function", %s); %s' % (
  5867. arg.key.py_result(),
  5868. code.error_goto(self.pos)))
  5869. code.putln("}")
  5870. code.put_error_if_neg(arg.key.pos, "PyDict_SetItem(%s, %s, %s)" % (
  5871. self.result(),
  5872. arg.key.py_result(),
  5873. arg.value.py_result()))
  5874. arg.generate_disposal_code(code)
  5875. arg.free_temps(code)
  5876. else:
  5877. item.generate_evaluation_code(code)
  5878. if self.reject_duplicates:
  5879. # merge mapping into kwdict one by one as we need to check for duplicates
  5880. helpers.add("MergeKeywords")
  5881. code.put_error_if_neg(item.pos, "__Pyx_MergeKeywords(%s, %s)" % (
  5882. self.result(), item.py_result()))
  5883. else:
  5884. # simple case, just add all entries
  5885. helpers.add("RaiseMappingExpected")
  5886. code.putln("if (unlikely(PyDict_Update(%s, %s) < 0)) {" % (
  5887. self.result(), item.py_result()))
  5888. code.putln("if (PyErr_ExceptionMatches(PyExc_AttributeError)) "
  5889. "__Pyx_RaiseMappingExpectedError(%s);" % item.py_result())
  5890. code.putln(code.error_goto(item.pos))
  5891. code.putln("}")
  5892. item.generate_disposal_code(code)
  5893. item.free_temps(code)
  5894. for helper in sorted(helpers):
  5895. code.globalstate.use_utility_code(UtilityCode.load_cached(helper, "FunctionArguments.c"))
  5896. def annotate(self, code):
  5897. for item in self.keyword_args:
  5898. item.annotate(code)
  5899. class AttributeNode(ExprNode):
  5900. # obj.attribute
  5901. #
  5902. # obj ExprNode
  5903. # attribute string
  5904. # needs_none_check boolean Used if obj is an extension type.
  5905. # If set to True, it is known that the type is not None.
  5906. #
  5907. # Used internally:
  5908. #
  5909. # is_py_attr boolean Is a Python getattr operation
  5910. # member string C name of struct member
  5911. # is_called boolean Function call is being done on result
  5912. # entry Entry Symbol table entry of attribute
  5913. is_attribute = 1
  5914. subexprs = ['obj']
  5915. type = PyrexTypes.error_type
  5916. entry = None
  5917. is_called = 0
  5918. needs_none_check = True
  5919. is_memslice_transpose = False
  5920. is_special_lookup = False
  5921. is_py_attr = 0
  5922. def as_cython_attribute(self):
  5923. if (isinstance(self.obj, NameNode) and
  5924. self.obj.is_cython_module and not
  5925. self.attribute == u"parallel"):
  5926. return self.attribute
  5927. cy = self.obj.as_cython_attribute()
  5928. if cy:
  5929. return "%s.%s" % (cy, self.attribute)
  5930. return None
  5931. def coerce_to(self, dst_type, env):
  5932. # If coercing to a generic pyobject and this is a cpdef function
  5933. # we can create the corresponding attribute
  5934. if dst_type is py_object_type:
  5935. entry = self.entry
  5936. if entry and entry.is_cfunction and entry.as_variable:
  5937. # must be a cpdef function
  5938. self.is_temp = 1
  5939. self.entry = entry.as_variable
  5940. self.analyse_as_python_attribute(env)
  5941. return self
  5942. return ExprNode.coerce_to(self, dst_type, env)
  5943. def calculate_constant_result(self):
  5944. attr = self.attribute
  5945. if attr.startswith("__") and attr.endswith("__"):
  5946. return
  5947. self.constant_result = getattr(self.obj.constant_result, attr)
  5948. def compile_time_value(self, denv):
  5949. attr = self.attribute
  5950. if attr.startswith("__") and attr.endswith("__"):
  5951. error(self.pos,
  5952. "Invalid attribute name '%s' in compile-time expression" % attr)
  5953. return None
  5954. obj = self.obj.compile_time_value(denv)
  5955. try:
  5956. return getattr(obj, attr)
  5957. except Exception as e:
  5958. self.compile_time_value_error(e)
  5959. def type_dependencies(self, env):
  5960. return self.obj.type_dependencies(env)
  5961. def infer_type(self, env):
  5962. # FIXME: this is way too redundant with analyse_types()
  5963. node = self.analyse_as_cimported_attribute_node(env, target=False)
  5964. if node is not None:
  5965. if node.entry.type and node.entry.type.is_cfunction:
  5966. # special-case - function converted to pointer
  5967. return PyrexTypes.CPtrType(node.entry.type)
  5968. else:
  5969. return node.entry.type
  5970. node = self.analyse_as_type_attribute(env)
  5971. if node is not None:
  5972. return node.entry.type
  5973. obj_type = self.obj.infer_type(env)
  5974. self.analyse_attribute(env, obj_type=obj_type)
  5975. if obj_type.is_builtin_type and self.type.is_cfunction:
  5976. # special case: C-API replacements for C methods of
  5977. # builtin types cannot be inferred as C functions as
  5978. # that would prevent their use as bound methods
  5979. return py_object_type
  5980. elif self.entry and self.entry.is_cmethod:
  5981. # special case: bound methods should not be inferred
  5982. # as their unbound method types
  5983. return py_object_type
  5984. return self.type
  5985. def analyse_target_declaration(self, env):
  5986. pass
  5987. def analyse_target_types(self, env):
  5988. node = self.analyse_types(env, target = 1)
  5989. if node.type.is_const:
  5990. error(self.pos, "Assignment to const attribute '%s'" % self.attribute)
  5991. if not node.is_lvalue():
  5992. error(self.pos, "Assignment to non-lvalue of type '%s'" % self.type)
  5993. return node
  5994. def analyse_types(self, env, target = 0):
  5995. self.initialized_check = env.directives['initializedcheck']
  5996. node = self.analyse_as_cimported_attribute_node(env, target)
  5997. if node is None and not target:
  5998. node = self.analyse_as_type_attribute(env)
  5999. if node is None:
  6000. node = self.analyse_as_ordinary_attribute_node(env, target)
  6001. assert node is not None
  6002. if node.entry:
  6003. node.entry.used = True
  6004. if node.is_attribute:
  6005. node.wrap_obj_in_nonecheck(env)
  6006. return node
  6007. def analyse_as_cimported_attribute_node(self, env, target):
  6008. # Try to interpret this as a reference to an imported
  6009. # C const, type, var or function. If successful, mutates
  6010. # this node into a NameNode and returns 1, otherwise
  6011. # returns 0.
  6012. module_scope = self.obj.analyse_as_module(env)
  6013. if module_scope:
  6014. entry = module_scope.lookup_here(self.attribute)
  6015. if entry and (
  6016. entry.is_cglobal or entry.is_cfunction
  6017. or entry.is_type or entry.is_const):
  6018. return self.as_name_node(env, entry, target)
  6019. if self.is_cimported_module_without_shadow(env):
  6020. error(self.pos, "cimported module has no attribute '%s'" % self.attribute)
  6021. return self
  6022. return None
  6023. def analyse_as_type_attribute(self, env):
  6024. # Try to interpret this as a reference to an unbound
  6025. # C method of an extension type or builtin type. If successful,
  6026. # creates a corresponding NameNode and returns it, otherwise
  6027. # returns None.
  6028. if self.obj.is_string_literal:
  6029. return
  6030. type = self.obj.analyse_as_type(env)
  6031. if type:
  6032. if type.is_extension_type or type.is_builtin_type or type.is_cpp_class:
  6033. entry = type.scope.lookup_here(self.attribute)
  6034. if entry and (entry.is_cmethod or type.is_cpp_class and entry.type.is_cfunction):
  6035. if type.is_builtin_type:
  6036. if not self.is_called:
  6037. # must handle this as Python object
  6038. return None
  6039. ubcm_entry = entry
  6040. else:
  6041. # Create a temporary entry describing the C method
  6042. # as an ordinary function.
  6043. if entry.func_cname and not hasattr(entry.type, 'op_arg_struct'):
  6044. cname = entry.func_cname
  6045. if entry.type.is_static_method or (
  6046. env.parent_scope and env.parent_scope.is_cpp_class_scope):
  6047. ctype = entry.type
  6048. elif type.is_cpp_class:
  6049. error(self.pos, "%s not a static member of %s" % (entry.name, type))
  6050. ctype = PyrexTypes.error_type
  6051. else:
  6052. # Fix self type.
  6053. ctype = copy.copy(entry.type)
  6054. ctype.args = ctype.args[:]
  6055. ctype.args[0] = PyrexTypes.CFuncTypeArg('self', type, 'self', None)
  6056. else:
  6057. cname = "%s->%s" % (type.vtabptr_cname, entry.cname)
  6058. ctype = entry.type
  6059. ubcm_entry = Symtab.Entry(entry.name, cname, ctype)
  6060. ubcm_entry.is_cfunction = 1
  6061. ubcm_entry.func_cname = entry.func_cname
  6062. ubcm_entry.is_unbound_cmethod = 1
  6063. ubcm_entry.scope = entry.scope
  6064. return self.as_name_node(env, ubcm_entry, target=False)
  6065. elif type.is_enum:
  6066. if self.attribute in type.values:
  6067. for entry in type.entry.enum_values:
  6068. if entry.name == self.attribute:
  6069. return self.as_name_node(env, entry, target=False)
  6070. else:
  6071. error(self.pos, "%s not a known value of %s" % (self.attribute, type))
  6072. else:
  6073. error(self.pos, "%s not a known value of %s" % (self.attribute, type))
  6074. return None
  6075. def analyse_as_type(self, env):
  6076. module_scope = self.obj.analyse_as_module(env)
  6077. if module_scope:
  6078. return module_scope.lookup_type(self.attribute)
  6079. if not self.obj.is_string_literal:
  6080. base_type = self.obj.analyse_as_type(env)
  6081. if base_type and hasattr(base_type, 'scope') and base_type.scope is not None:
  6082. return base_type.scope.lookup_type(self.attribute)
  6083. return None
  6084. def analyse_as_extension_type(self, env):
  6085. # Try to interpret this as a reference to an extension type
  6086. # in a cimported module. Returns the extension type, or None.
  6087. module_scope = self.obj.analyse_as_module(env)
  6088. if module_scope:
  6089. entry = module_scope.lookup_here(self.attribute)
  6090. if entry and entry.is_type:
  6091. if entry.type.is_extension_type or entry.type.is_builtin_type:
  6092. return entry.type
  6093. return None
  6094. def analyse_as_module(self, env):
  6095. # Try to interpret this as a reference to a cimported module
  6096. # in another cimported module. Returns the module scope, or None.
  6097. module_scope = self.obj.analyse_as_module(env)
  6098. if module_scope:
  6099. entry = module_scope.lookup_here(self.attribute)
  6100. if entry and entry.as_module:
  6101. return entry.as_module
  6102. return None
  6103. def as_name_node(self, env, entry, target):
  6104. # Create a corresponding NameNode from this node and complete the
  6105. # analyse_types phase.
  6106. node = NameNode.from_node(self, name=self.attribute, entry=entry)
  6107. if target:
  6108. node = node.analyse_target_types(env)
  6109. else:
  6110. node = node.analyse_rvalue_entry(env)
  6111. node.entry.used = 1
  6112. return node
  6113. def analyse_as_ordinary_attribute_node(self, env, target):
  6114. self.obj = self.obj.analyse_types(env)
  6115. self.analyse_attribute(env)
  6116. if self.entry and self.entry.is_cmethod and not self.is_called:
  6117. # error(self.pos, "C method can only be called")
  6118. pass
  6119. ## Reference to C array turns into pointer to first element.
  6120. #while self.type.is_array:
  6121. # self.type = self.type.element_ptr_type()
  6122. if self.is_py_attr:
  6123. if not target:
  6124. self.is_temp = 1
  6125. self.result_ctype = py_object_type
  6126. elif target and self.obj.type.is_builtin_type:
  6127. error(self.pos, "Assignment to an immutable object field")
  6128. #elif self.type.is_memoryviewslice and not target:
  6129. # self.is_temp = True
  6130. return self
  6131. def analyse_attribute(self, env, obj_type = None):
  6132. # Look up attribute and set self.type and self.member.
  6133. immutable_obj = obj_type is not None # used during type inference
  6134. self.is_py_attr = 0
  6135. self.member = self.attribute
  6136. if obj_type is None:
  6137. if self.obj.type.is_string or self.obj.type.is_pyunicode_ptr:
  6138. self.obj = self.obj.coerce_to_pyobject(env)
  6139. obj_type = self.obj.type
  6140. else:
  6141. if obj_type.is_string or obj_type.is_pyunicode_ptr:
  6142. obj_type = py_object_type
  6143. if obj_type.is_ptr or obj_type.is_array:
  6144. obj_type = obj_type.base_type
  6145. self.op = "->"
  6146. elif obj_type.is_extension_type or obj_type.is_builtin_type:
  6147. self.op = "->"
  6148. elif obj_type.is_reference and obj_type.is_fake_reference:
  6149. self.op = "->"
  6150. else:
  6151. self.op = "."
  6152. if obj_type.has_attributes:
  6153. if obj_type.attributes_known():
  6154. entry = obj_type.scope.lookup_here(self.attribute)
  6155. if obj_type.is_memoryviewslice and not entry:
  6156. if self.attribute == 'T':
  6157. self.is_memslice_transpose = True
  6158. self.is_temp = True
  6159. self.use_managed_ref = True
  6160. self.type = self.obj.type.transpose(self.pos)
  6161. return
  6162. else:
  6163. obj_type.declare_attribute(self.attribute, env, self.pos)
  6164. entry = obj_type.scope.lookup_here(self.attribute)
  6165. if entry and entry.is_member:
  6166. entry = None
  6167. else:
  6168. error(self.pos,
  6169. "Cannot select attribute of incomplete type '%s'"
  6170. % obj_type)
  6171. self.type = PyrexTypes.error_type
  6172. return
  6173. self.entry = entry
  6174. if entry:
  6175. if obj_type.is_extension_type and entry.name == "__weakref__":
  6176. error(self.pos, "Illegal use of special attribute __weakref__")
  6177. # def methods need the normal attribute lookup
  6178. # because they do not have struct entries
  6179. # fused function go through assignment synthesis
  6180. # (foo = pycfunction(foo_func_obj)) and need to go through
  6181. # regular Python lookup as well
  6182. if (entry.is_variable and not entry.fused_cfunction) or entry.is_cmethod:
  6183. self.type = entry.type
  6184. self.member = entry.cname
  6185. return
  6186. else:
  6187. # If it's not a variable or C method, it must be a Python
  6188. # method of an extension type, so we treat it like a Python
  6189. # attribute.
  6190. pass
  6191. # If we get here, the base object is not a struct/union/extension
  6192. # type, or it is an extension type and the attribute is either not
  6193. # declared or is declared as a Python method. Treat it as a Python
  6194. # attribute reference.
  6195. self.analyse_as_python_attribute(env, obj_type, immutable_obj)
  6196. def analyse_as_python_attribute(self, env, obj_type=None, immutable_obj=False):
  6197. if obj_type is None:
  6198. obj_type = self.obj.type
  6199. # mangle private '__*' Python attributes used inside of a class
  6200. self.attribute = env.mangle_class_private_name(self.attribute)
  6201. self.member = self.attribute
  6202. self.type = py_object_type
  6203. self.is_py_attr = 1
  6204. if not obj_type.is_pyobject and not obj_type.is_error:
  6205. # Expose python methods for immutable objects.
  6206. if (obj_type.is_string or obj_type.is_cpp_string
  6207. or obj_type.is_buffer or obj_type.is_memoryviewslice
  6208. or obj_type.is_numeric
  6209. or (obj_type.is_ctuple and obj_type.can_coerce_to_pyobject(env))
  6210. or (obj_type.is_struct and obj_type.can_coerce_to_pyobject(env))):
  6211. if not immutable_obj:
  6212. self.obj = self.obj.coerce_to_pyobject(env)
  6213. elif (obj_type.is_cfunction and (self.obj.is_name or self.obj.is_attribute)
  6214. and self.obj.entry.as_variable
  6215. and self.obj.entry.as_variable.type.is_pyobject):
  6216. # might be an optimised builtin function => unpack it
  6217. if not immutable_obj:
  6218. self.obj = self.obj.coerce_to_pyobject(env)
  6219. else:
  6220. error(self.pos,
  6221. "Object of type '%s' has no attribute '%s'" %
  6222. (obj_type, self.attribute))
  6223. def wrap_obj_in_nonecheck(self, env):
  6224. if not env.directives['nonecheck']:
  6225. return
  6226. msg = None
  6227. format_args = ()
  6228. if (self.obj.type.is_extension_type and self.needs_none_check and not
  6229. self.is_py_attr):
  6230. msg = "'NoneType' object has no attribute '%{0}s'".format('.30' if len(self.attribute) <= 30 else '')
  6231. format_args = (self.attribute,)
  6232. elif self.obj.type.is_memoryviewslice:
  6233. if self.is_memslice_transpose:
  6234. msg = "Cannot transpose None memoryview slice"
  6235. else:
  6236. entry = self.obj.type.scope.lookup_here(self.attribute)
  6237. if entry:
  6238. # copy/is_c_contig/shape/strides etc
  6239. msg = "Cannot access '%s' attribute of None memoryview slice"
  6240. format_args = (entry.name,)
  6241. if msg:
  6242. self.obj = self.obj.as_none_safe_node(msg, 'PyExc_AttributeError',
  6243. format_args=format_args)
  6244. def nogil_check(self, env):
  6245. if self.is_py_attr:
  6246. self.gil_error()
  6247. gil_message = "Accessing Python attribute"
  6248. def is_cimported_module_without_shadow(self, env):
  6249. return self.obj.is_cimported_module_without_shadow(env)
  6250. def is_simple(self):
  6251. if self.obj:
  6252. return self.result_in_temp() or self.obj.is_simple()
  6253. else:
  6254. return NameNode.is_simple(self)
  6255. def is_lvalue(self):
  6256. if self.obj:
  6257. return True
  6258. else:
  6259. return NameNode.is_lvalue(self)
  6260. def is_ephemeral(self):
  6261. if self.obj:
  6262. return self.obj.is_ephemeral()
  6263. else:
  6264. return NameNode.is_ephemeral(self)
  6265. def calculate_result_code(self):
  6266. #print "AttributeNode.calculate_result_code:", self.member ###
  6267. #print "...obj node =", self.obj, "code", self.obj.result() ###
  6268. #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
  6269. obj = self.obj
  6270. obj_code = obj.result_as(obj.type)
  6271. #print "...obj_code =", obj_code ###
  6272. if self.entry and self.entry.is_cmethod:
  6273. if obj.type.is_extension_type and not self.entry.is_builtin_cmethod:
  6274. if self.entry.final_func_cname:
  6275. return self.entry.final_func_cname
  6276. if self.type.from_fused:
  6277. # If the attribute was specialized through indexing, make
  6278. # sure to get the right fused name, as our entry was
  6279. # replaced by our parent index node
  6280. # (AnalyseExpressionsTransform)
  6281. self.member = self.entry.cname
  6282. return "((struct %s *)%s%s%s)->%s" % (
  6283. obj.type.vtabstruct_cname, obj_code, self.op,
  6284. obj.type.vtabslot_cname, self.member)
  6285. elif self.result_is_used:
  6286. return self.member
  6287. # Generating no code at all for unused access to optimised builtin
  6288. # methods fixes the problem that some optimisations only exist as
  6289. # macros, i.e. there is no function pointer to them, so we would
  6290. # generate invalid C code here.
  6291. return
  6292. elif obj.type.is_complex:
  6293. return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
  6294. else:
  6295. if obj.type.is_builtin_type and self.entry and self.entry.is_variable:
  6296. # accessing a field of a builtin type, need to cast better than result_as() does
  6297. obj_code = obj.type.cast_code(obj.result(), to_object_struct = True)
  6298. return "%s%s%s" % (obj_code, self.op, self.member)
  6299. def generate_result_code(self, code):
  6300. if self.is_py_attr:
  6301. if self.is_special_lookup:
  6302. code.globalstate.use_utility_code(
  6303. UtilityCode.load_cached("PyObjectLookupSpecial", "ObjectHandling.c"))
  6304. lookup_func_name = '__Pyx_PyObject_LookupSpecial'
  6305. else:
  6306. code.globalstate.use_utility_code(
  6307. UtilityCode.load_cached("PyObjectGetAttrStr", "ObjectHandling.c"))
  6308. lookup_func_name = '__Pyx_PyObject_GetAttrStr'
  6309. code.putln(
  6310. '%s = %s(%s, %s); %s' % (
  6311. self.result(),
  6312. lookup_func_name,
  6313. self.obj.py_result(),
  6314. code.intern_identifier(self.attribute),
  6315. code.error_goto_if_null(self.result(), self.pos)))
  6316. code.put_gotref(self.py_result())
  6317. elif self.type.is_memoryviewslice:
  6318. if self.is_memslice_transpose:
  6319. # transpose the slice
  6320. for access, packing in self.type.axes:
  6321. if access == 'ptr':
  6322. error(self.pos, "Transposing not supported for slices "
  6323. "with indirect dimensions")
  6324. return
  6325. code.putln("%s = %s;" % (self.result(), self.obj.result()))
  6326. code.put_incref_memoryviewslice(self.result(), have_gil=True)
  6327. T = "__pyx_memslice_transpose(&%s) == 0"
  6328. code.putln(code.error_goto_if(T % self.result(), self.pos))
  6329. elif self.initialized_check:
  6330. code.putln(
  6331. 'if (unlikely(!%s.memview)) {'
  6332. 'PyErr_SetString(PyExc_AttributeError,'
  6333. '"Memoryview is not initialized");'
  6334. '%s'
  6335. '}' % (self.result(), code.error_goto(self.pos)))
  6336. else:
  6337. # result_code contains what is needed, but we may need to insert
  6338. # a check and raise an exception
  6339. if self.obj.type and self.obj.type.is_extension_type:
  6340. pass
  6341. elif self.entry and self.entry.is_cmethod:
  6342. # C method implemented as function call with utility code
  6343. code.globalstate.use_entry_utility_code(self.entry)
  6344. def generate_disposal_code(self, code):
  6345. if self.is_temp and self.type.is_memoryviewslice and self.is_memslice_transpose:
  6346. # mirror condition for putting the memview incref here:
  6347. code.put_xdecref_memoryviewslice(
  6348. self.result(), have_gil=True)
  6349. code.putln("%s.memview = NULL;" % self.result())
  6350. code.putln("%s.data = NULL;" % self.result())
  6351. else:
  6352. ExprNode.generate_disposal_code(self, code)
  6353. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  6354. exception_check=None, exception_value=None):
  6355. self.obj.generate_evaluation_code(code)
  6356. if self.is_py_attr:
  6357. code.globalstate.use_utility_code(
  6358. UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
  6359. code.put_error_if_neg(self.pos,
  6360. '__Pyx_PyObject_SetAttrStr(%s, %s, %s)' % (
  6361. self.obj.py_result(),
  6362. code.intern_identifier(self.attribute),
  6363. rhs.py_result()))
  6364. rhs.generate_disposal_code(code)
  6365. rhs.free_temps(code)
  6366. elif self.obj.type.is_complex:
  6367. code.putln("__Pyx_SET_C%s(%s, %s);" % (
  6368. self.member.upper(),
  6369. self.obj.result_as(self.obj.type),
  6370. rhs.result_as(self.ctype())))
  6371. rhs.generate_disposal_code(code)
  6372. rhs.free_temps(code)
  6373. else:
  6374. select_code = self.result()
  6375. if self.type.is_pyobject and self.use_managed_ref:
  6376. rhs.make_owned_reference(code)
  6377. code.put_giveref(rhs.py_result())
  6378. code.put_gotref(select_code)
  6379. code.put_decref(select_code, self.ctype())
  6380. elif self.type.is_memoryviewslice:
  6381. from . import MemoryView
  6382. MemoryView.put_assign_to_memviewslice(
  6383. select_code, rhs, rhs.result(), self.type, code)
  6384. if not self.type.is_memoryviewslice:
  6385. code.putln(
  6386. "%s = %s;" % (
  6387. select_code,
  6388. rhs.result_as(self.ctype())))
  6389. #rhs.result()))
  6390. rhs.generate_post_assignment_code(code)
  6391. rhs.free_temps(code)
  6392. self.obj.generate_disposal_code(code)
  6393. self.obj.free_temps(code)
  6394. def generate_deletion_code(self, code, ignore_nonexisting=False):
  6395. self.obj.generate_evaluation_code(code)
  6396. if self.is_py_attr or (self.entry.scope.is_property_scope
  6397. and u'__del__' in self.entry.scope.entries):
  6398. code.globalstate.use_utility_code(
  6399. UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
  6400. code.put_error_if_neg(self.pos,
  6401. '__Pyx_PyObject_DelAttrStr(%s, %s)' % (
  6402. self.obj.py_result(),
  6403. code.intern_identifier(self.attribute)))
  6404. else:
  6405. error(self.pos, "Cannot delete C attribute of extension type")
  6406. self.obj.generate_disposal_code(code)
  6407. self.obj.free_temps(code)
  6408. def annotate(self, code):
  6409. if self.is_py_attr:
  6410. style, text = 'py_attr', 'python attribute (%s)'
  6411. else:
  6412. style, text = 'c_attr', 'c attribute (%s)'
  6413. code.annotate(self.pos, AnnotationItem(style, text % self.type, size=len(self.attribute)))
  6414. #-------------------------------------------------------------------
  6415. #
  6416. # Constructor nodes
  6417. #
  6418. #-------------------------------------------------------------------
  6419. class StarredUnpackingNode(ExprNode):
  6420. # A starred expression like "*a"
  6421. #
  6422. # This is only allowed in sequence assignment or construction such as
  6423. #
  6424. # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
  6425. #
  6426. # and will be special cased during type analysis (or generate an error
  6427. # if it's found at unexpected places).
  6428. #
  6429. # target ExprNode
  6430. subexprs = ['target']
  6431. is_starred = 1
  6432. type = py_object_type
  6433. is_temp = 1
  6434. starred_expr_allowed_here = False
  6435. def __init__(self, pos, target):
  6436. ExprNode.__init__(self, pos, target=target)
  6437. def analyse_declarations(self, env):
  6438. if not self.starred_expr_allowed_here:
  6439. error(self.pos, "starred expression is not allowed here")
  6440. self.target.analyse_declarations(env)
  6441. def infer_type(self, env):
  6442. return self.target.infer_type(env)
  6443. def analyse_types(self, env):
  6444. if not self.starred_expr_allowed_here:
  6445. error(self.pos, "starred expression is not allowed here")
  6446. self.target = self.target.analyse_types(env)
  6447. self.type = self.target.type
  6448. return self
  6449. def analyse_target_declaration(self, env):
  6450. self.target.analyse_target_declaration(env)
  6451. def analyse_target_types(self, env):
  6452. self.target = self.target.analyse_target_types(env)
  6453. self.type = self.target.type
  6454. return self
  6455. def calculate_result_code(self):
  6456. return ""
  6457. def generate_result_code(self, code):
  6458. pass
  6459. class SequenceNode(ExprNode):
  6460. # Base class for list and tuple constructor nodes.
  6461. # Contains common code for performing sequence unpacking.
  6462. #
  6463. # args [ExprNode]
  6464. # unpacked_items [ExprNode] or None
  6465. # coerced_unpacked_items [ExprNode] or None
  6466. # mult_factor ExprNode the integer number of content repetitions ([1,2]*3)
  6467. subexprs = ['args', 'mult_factor']
  6468. is_sequence_constructor = 1
  6469. unpacked_items = None
  6470. mult_factor = None
  6471. slow = False # trade speed for code size (e.g. use PyTuple_Pack())
  6472. def compile_time_value_list(self, denv):
  6473. return [arg.compile_time_value(denv) for arg in self.args]
  6474. def replace_starred_target_node(self):
  6475. # replace a starred node in the targets by the contained expression
  6476. self.starred_assignment = False
  6477. args = []
  6478. for arg in self.args:
  6479. if arg.is_starred:
  6480. if self.starred_assignment:
  6481. error(arg.pos, "more than 1 starred expression in assignment")
  6482. self.starred_assignment = True
  6483. arg = arg.target
  6484. arg.is_starred = True
  6485. args.append(arg)
  6486. self.args = args
  6487. def analyse_target_declaration(self, env):
  6488. self.replace_starred_target_node()
  6489. for arg in self.args:
  6490. arg.analyse_target_declaration(env)
  6491. def analyse_types(self, env, skip_children=False):
  6492. for i, arg in enumerate(self.args):
  6493. if not skip_children:
  6494. arg = arg.analyse_types(env)
  6495. self.args[i] = arg.coerce_to_pyobject(env)
  6496. if self.mult_factor:
  6497. self.mult_factor = self.mult_factor.analyse_types(env)
  6498. if not self.mult_factor.type.is_int:
  6499. self.mult_factor = self.mult_factor.coerce_to_pyobject(env)
  6500. self.is_temp = 1
  6501. # not setting self.type here, subtypes do this
  6502. return self
  6503. def coerce_to_ctuple(self, dst_type, env):
  6504. if self.type == dst_type:
  6505. return self
  6506. assert not self.mult_factor
  6507. if len(self.args) != dst_type.size:
  6508. error(self.pos, "trying to coerce sequence to ctuple of wrong length, expected %d, got %d" % (
  6509. dst_type.size, len(self.args)))
  6510. coerced_args = [arg.coerce_to(type, env) for arg, type in zip(self.args, dst_type.components)]
  6511. return TupleNode(self.pos, args=coerced_args, type=dst_type, is_temp=True)
  6512. def _create_merge_node_if_necessary(self, env):
  6513. self._flatten_starred_args()
  6514. if not any(arg.is_starred for arg in self.args):
  6515. return self
  6516. # convert into MergedSequenceNode by building partial sequences
  6517. args = []
  6518. values = []
  6519. for arg in self.args:
  6520. if arg.is_starred:
  6521. if values:
  6522. args.append(TupleNode(values[0].pos, args=values).analyse_types(env, skip_children=True))
  6523. values = []
  6524. args.append(arg.target)
  6525. else:
  6526. values.append(arg)
  6527. if values:
  6528. args.append(TupleNode(values[0].pos, args=values).analyse_types(env, skip_children=True))
  6529. node = MergedSequenceNode(self.pos, args, self.type)
  6530. if self.mult_factor:
  6531. node = binop_node(
  6532. self.pos, '*', node, self.mult_factor.coerce_to_pyobject(env),
  6533. inplace=True, type=self.type, is_temp=True)
  6534. return node
  6535. def _flatten_starred_args(self):
  6536. args = []
  6537. for arg in self.args:
  6538. if arg.is_starred and arg.target.is_sequence_constructor and not arg.target.mult_factor:
  6539. args.extend(arg.target.args)
  6540. else:
  6541. args.append(arg)
  6542. self.args[:] = args
  6543. def may_be_none(self):
  6544. return False
  6545. def analyse_target_types(self, env):
  6546. if self.mult_factor:
  6547. error(self.pos, "can't assign to multiplied sequence")
  6548. self.unpacked_items = []
  6549. self.coerced_unpacked_items = []
  6550. self.any_coerced_items = False
  6551. for i, arg in enumerate(self.args):
  6552. arg = self.args[i] = arg.analyse_target_types(env)
  6553. if arg.is_starred:
  6554. if not arg.type.assignable_from(list_type):
  6555. error(arg.pos,
  6556. "starred target must have Python object (list) type")
  6557. if arg.type is py_object_type:
  6558. arg.type = list_type
  6559. unpacked_item = PyTempNode(self.pos, env)
  6560. coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
  6561. if unpacked_item is not coerced_unpacked_item:
  6562. self.any_coerced_items = True
  6563. self.unpacked_items.append(unpacked_item)
  6564. self.coerced_unpacked_items.append(coerced_unpacked_item)
  6565. self.type = py_object_type
  6566. return self
  6567. def generate_result_code(self, code):
  6568. self.generate_operation_code(code)
  6569. def generate_sequence_packing_code(self, code, target=None, plain=False):
  6570. if target is None:
  6571. target = self.result()
  6572. size_factor = c_mult = ''
  6573. mult_factor = None
  6574. if self.mult_factor and not plain:
  6575. mult_factor = self.mult_factor
  6576. if mult_factor.type.is_int:
  6577. c_mult = mult_factor.result()
  6578. if (isinstance(mult_factor.constant_result, _py_int_types) and
  6579. mult_factor.constant_result > 0):
  6580. size_factor = ' * %s' % mult_factor.constant_result
  6581. elif mult_factor.type.signed:
  6582. size_factor = ' * ((%s<0) ? 0:%s)' % (c_mult, c_mult)
  6583. else:
  6584. size_factor = ' * (%s)' % (c_mult,)
  6585. if self.type is tuple_type and (self.is_literal or self.slow) and not c_mult:
  6586. # use PyTuple_Pack() to avoid generating huge amounts of one-time code
  6587. code.putln('%s = PyTuple_Pack(%d, %s); %s' % (
  6588. target,
  6589. len(self.args),
  6590. ', '.join(arg.py_result() for arg in self.args),
  6591. code.error_goto_if_null(target, self.pos)))
  6592. code.put_gotref(target)
  6593. elif self.type.is_ctuple:
  6594. for i, arg in enumerate(self.args):
  6595. code.putln("%s.f%s = %s;" % (
  6596. target, i, arg.result()))
  6597. else:
  6598. # build the tuple/list step by step, potentially multiplying it as we go
  6599. if self.type is list_type:
  6600. create_func, set_item_func = 'PyList_New', 'PyList_SET_ITEM'
  6601. elif self.type is tuple_type:
  6602. create_func, set_item_func = 'PyTuple_New', 'PyTuple_SET_ITEM'
  6603. else:
  6604. raise InternalError("sequence packing for unexpected type %s" % self.type)
  6605. arg_count = len(self.args)
  6606. code.putln("%s = %s(%s%s); %s" % (
  6607. target, create_func, arg_count, size_factor,
  6608. code.error_goto_if_null(target, self.pos)))
  6609. code.put_gotref(target)
  6610. if c_mult:
  6611. # FIXME: can't use a temp variable here as the code may
  6612. # end up in the constant building function. Temps
  6613. # currently don't work there.
  6614. #counter = code.funcstate.allocate_temp(mult_factor.type, manage_ref=False)
  6615. counter = Naming.quick_temp_cname
  6616. code.putln('{ Py_ssize_t %s;' % counter)
  6617. if arg_count == 1:
  6618. offset = counter
  6619. else:
  6620. offset = '%s * %s' % (counter, arg_count)
  6621. code.putln('for (%s=0; %s < %s; %s++) {' % (
  6622. counter, counter, c_mult, counter
  6623. ))
  6624. else:
  6625. offset = ''
  6626. for i in range(arg_count):
  6627. arg = self.args[i]
  6628. if c_mult or not arg.result_in_temp():
  6629. code.put_incref(arg.result(), arg.ctype())
  6630. code.put_giveref(arg.py_result())
  6631. code.putln("%s(%s, %s, %s);" % (
  6632. set_item_func,
  6633. target,
  6634. (offset and i) and ('%s + %s' % (offset, i)) or (offset or i),
  6635. arg.py_result()))
  6636. if c_mult:
  6637. code.putln('}')
  6638. #code.funcstate.release_temp(counter)
  6639. code.putln('}')
  6640. if mult_factor is not None and mult_factor.type.is_pyobject:
  6641. code.putln('{ PyObject* %s = PyNumber_InPlaceMultiply(%s, %s); %s' % (
  6642. Naming.quick_temp_cname, target, mult_factor.py_result(),
  6643. code.error_goto_if_null(Naming.quick_temp_cname, self.pos)
  6644. ))
  6645. code.put_gotref(Naming.quick_temp_cname)
  6646. code.put_decref(target, py_object_type)
  6647. code.putln('%s = %s;' % (target, Naming.quick_temp_cname))
  6648. code.putln('}')
  6649. def generate_subexpr_disposal_code(self, code):
  6650. if self.mult_factor and self.mult_factor.type.is_int:
  6651. super(SequenceNode, self).generate_subexpr_disposal_code(code)
  6652. elif self.type is tuple_type and (self.is_literal or self.slow):
  6653. super(SequenceNode, self).generate_subexpr_disposal_code(code)
  6654. else:
  6655. # We call generate_post_assignment_code here instead
  6656. # of generate_disposal_code, because values were stored
  6657. # in the tuple using a reference-stealing operation.
  6658. for arg in self.args:
  6659. arg.generate_post_assignment_code(code)
  6660. # Should NOT call free_temps -- this is invoked by the default
  6661. # generate_evaluation_code which will do that.
  6662. if self.mult_factor:
  6663. self.mult_factor.generate_disposal_code(code)
  6664. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  6665. exception_check=None, exception_value=None):
  6666. if self.starred_assignment:
  6667. self.generate_starred_assignment_code(rhs, code)
  6668. else:
  6669. self.generate_parallel_assignment_code(rhs, code)
  6670. for item in self.unpacked_items:
  6671. item.release(code)
  6672. rhs.free_temps(code)
  6673. _func_iternext_type = PyrexTypes.CPtrType(PyrexTypes.CFuncType(
  6674. PyrexTypes.py_object_type, [
  6675. PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None),
  6676. ]))
  6677. def generate_parallel_assignment_code(self, rhs, code):
  6678. # Need to work around the fact that generate_evaluation_code
  6679. # allocates the temps in a rather hacky way -- the assignment
  6680. # is evaluated twice, within each if-block.
  6681. for item in self.unpacked_items:
  6682. item.allocate(code)
  6683. special_unpack = (rhs.type is py_object_type
  6684. or rhs.type in (tuple_type, list_type)
  6685. or not rhs.type.is_builtin_type)
  6686. long_enough_for_a_loop = len(self.unpacked_items) > 3
  6687. if special_unpack:
  6688. self.generate_special_parallel_unpacking_code(
  6689. code, rhs, use_loop=long_enough_for_a_loop)
  6690. else:
  6691. code.putln("{")
  6692. self.generate_generic_parallel_unpacking_code(
  6693. code, rhs, self.unpacked_items, use_loop=long_enough_for_a_loop)
  6694. code.putln("}")
  6695. for value_node in self.coerced_unpacked_items:
  6696. value_node.generate_evaluation_code(code)
  6697. for i in range(len(self.args)):
  6698. self.args[i].generate_assignment_code(
  6699. self.coerced_unpacked_items[i], code)
  6700. def generate_special_parallel_unpacking_code(self, code, rhs, use_loop):
  6701. sequence_type_test = '1'
  6702. none_check = "likely(%s != Py_None)" % rhs.py_result()
  6703. if rhs.type is list_type:
  6704. sequence_types = ['List']
  6705. if rhs.may_be_none():
  6706. sequence_type_test = none_check
  6707. elif rhs.type is tuple_type:
  6708. sequence_types = ['Tuple']
  6709. if rhs.may_be_none():
  6710. sequence_type_test = none_check
  6711. else:
  6712. sequence_types = ['Tuple', 'List']
  6713. tuple_check = 'likely(PyTuple_CheckExact(%s))' % rhs.py_result()
  6714. list_check = 'PyList_CheckExact(%s)' % rhs.py_result()
  6715. sequence_type_test = "(%s) || (%s)" % (tuple_check, list_check)
  6716. code.putln("if (%s) {" % sequence_type_test)
  6717. code.putln("PyObject* sequence = %s;" % rhs.py_result())
  6718. # list/tuple => check size
  6719. code.putln("Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);")
  6720. code.putln("if (unlikely(size != %d)) {" % len(self.args))
  6721. code.globalstate.use_utility_code(raise_too_many_values_to_unpack)
  6722. code.putln("if (size > %d) __Pyx_RaiseTooManyValuesError(%d);" % (
  6723. len(self.args), len(self.args)))
  6724. code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
  6725. code.putln("else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);")
  6726. # < 0 => exception
  6727. code.putln(code.error_goto(self.pos))
  6728. code.putln("}")
  6729. code.putln("#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS")
  6730. # unpack items from list/tuple in unrolled loop (can't fail)
  6731. if len(sequence_types) == 2:
  6732. code.putln("if (likely(Py%s_CheckExact(sequence))) {" % sequence_types[0])
  6733. for i, item in enumerate(self.unpacked_items):
  6734. code.putln("%s = Py%s_GET_ITEM(sequence, %d); " % (
  6735. item.result(), sequence_types[0], i))
  6736. if len(sequence_types) == 2:
  6737. code.putln("} else {")
  6738. for i, item in enumerate(self.unpacked_items):
  6739. code.putln("%s = Py%s_GET_ITEM(sequence, %d); " % (
  6740. item.result(), sequence_types[1], i))
  6741. code.putln("}")
  6742. for item in self.unpacked_items:
  6743. code.put_incref(item.result(), item.ctype())
  6744. code.putln("#else")
  6745. # in non-CPython, use the PySequence protocol (which can fail)
  6746. if not use_loop:
  6747. for i, item in enumerate(self.unpacked_items):
  6748. code.putln("%s = PySequence_ITEM(sequence, %d); %s" % (
  6749. item.result(), i,
  6750. code.error_goto_if_null(item.result(), self.pos)))
  6751. code.put_gotref(item.result())
  6752. else:
  6753. code.putln("{")
  6754. code.putln("Py_ssize_t i;")
  6755. code.putln("PyObject** temps[%s] = {%s};" % (
  6756. len(self.unpacked_items),
  6757. ','.join(['&%s' % item.result() for item in self.unpacked_items])))
  6758. code.putln("for (i=0; i < %s; i++) {" % len(self.unpacked_items))
  6759. code.putln("PyObject* item = PySequence_ITEM(sequence, i); %s" % (
  6760. code.error_goto_if_null('item', self.pos)))
  6761. code.put_gotref('item')
  6762. code.putln("*(temps[i]) = item;")
  6763. code.putln("}")
  6764. code.putln("}")
  6765. code.putln("#endif")
  6766. rhs.generate_disposal_code(code)
  6767. if sequence_type_test == '1':
  6768. code.putln("}") # all done
  6769. elif sequence_type_test == none_check:
  6770. # either tuple/list or None => save some code by generating the error directly
  6771. code.putln("} else {")
  6772. code.globalstate.use_utility_code(
  6773. UtilityCode.load_cached("RaiseNoneIterError", "ObjectHandling.c"))
  6774. code.putln("__Pyx_RaiseNoneNotIterableError(); %s" % code.error_goto(self.pos))
  6775. code.putln("}") # all done
  6776. else:
  6777. code.putln("} else {") # needs iteration fallback code
  6778. self.generate_generic_parallel_unpacking_code(
  6779. code, rhs, self.unpacked_items, use_loop=use_loop)
  6780. code.putln("}")
  6781. def generate_generic_parallel_unpacking_code(self, code, rhs, unpacked_items, use_loop, terminate=True):
  6782. code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
  6783. code.globalstate.use_utility_code(UtilityCode.load_cached("IterFinish", "ObjectHandling.c"))
  6784. code.putln("Py_ssize_t index = -1;") # must be at the start of a C block!
  6785. if use_loop:
  6786. code.putln("PyObject** temps[%s] = {%s};" % (
  6787. len(self.unpacked_items),
  6788. ','.join(['&%s' % item.result() for item in unpacked_items])))
  6789. iterator_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  6790. code.putln(
  6791. "%s = PyObject_GetIter(%s); %s" % (
  6792. iterator_temp,
  6793. rhs.py_result(),
  6794. code.error_goto_if_null(iterator_temp, self.pos)))
  6795. code.put_gotref(iterator_temp)
  6796. rhs.generate_disposal_code(code)
  6797. iternext_func = code.funcstate.allocate_temp(self._func_iternext_type, manage_ref=False)
  6798. code.putln("%s = Py_TYPE(%s)->tp_iternext;" % (
  6799. iternext_func, iterator_temp))
  6800. unpacking_error_label = code.new_label('unpacking_failed')
  6801. unpack_code = "%s(%s)" % (iternext_func, iterator_temp)
  6802. if use_loop:
  6803. code.putln("for (index=0; index < %s; index++) {" % len(unpacked_items))
  6804. code.put("PyObject* item = %s; if (unlikely(!item)) " % unpack_code)
  6805. code.put_goto(unpacking_error_label)
  6806. code.put_gotref("item")
  6807. code.putln("*(temps[index]) = item;")
  6808. code.putln("}")
  6809. else:
  6810. for i, item in enumerate(unpacked_items):
  6811. code.put(
  6812. "index = %d; %s = %s; if (unlikely(!%s)) " % (
  6813. i,
  6814. item.result(),
  6815. unpack_code,
  6816. item.result()))
  6817. code.put_goto(unpacking_error_label)
  6818. code.put_gotref(item.py_result())
  6819. if terminate:
  6820. code.globalstate.use_utility_code(
  6821. UtilityCode.load_cached("UnpackItemEndCheck", "ObjectHandling.c"))
  6822. code.put_error_if_neg(self.pos, "__Pyx_IternextUnpackEndCheck(%s, %d)" % (
  6823. unpack_code,
  6824. len(unpacked_items)))
  6825. code.putln("%s = NULL;" % iternext_func)
  6826. code.put_decref_clear(iterator_temp, py_object_type)
  6827. unpacking_done_label = code.new_label('unpacking_done')
  6828. code.put_goto(unpacking_done_label)
  6829. code.put_label(unpacking_error_label)
  6830. code.put_decref_clear(iterator_temp, py_object_type)
  6831. code.putln("%s = NULL;" % iternext_func)
  6832. code.putln("if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);")
  6833. code.putln(code.error_goto(self.pos))
  6834. code.put_label(unpacking_done_label)
  6835. code.funcstate.release_temp(iternext_func)
  6836. if terminate:
  6837. code.funcstate.release_temp(iterator_temp)
  6838. iterator_temp = None
  6839. return iterator_temp
  6840. def generate_starred_assignment_code(self, rhs, code):
  6841. for i, arg in enumerate(self.args):
  6842. if arg.is_starred:
  6843. starred_target = self.unpacked_items[i]
  6844. unpacked_fixed_items_left = self.unpacked_items[:i]
  6845. unpacked_fixed_items_right = self.unpacked_items[i+1:]
  6846. break
  6847. else:
  6848. assert False
  6849. iterator_temp = None
  6850. if unpacked_fixed_items_left:
  6851. for item in unpacked_fixed_items_left:
  6852. item.allocate(code)
  6853. code.putln('{')
  6854. iterator_temp = self.generate_generic_parallel_unpacking_code(
  6855. code, rhs, unpacked_fixed_items_left,
  6856. use_loop=True, terminate=False)
  6857. for i, item in enumerate(unpacked_fixed_items_left):
  6858. value_node = self.coerced_unpacked_items[i]
  6859. value_node.generate_evaluation_code(code)
  6860. code.putln('}')
  6861. starred_target.allocate(code)
  6862. target_list = starred_target.result()
  6863. code.putln("%s = PySequence_List(%s); %s" % (
  6864. target_list,
  6865. iterator_temp or rhs.py_result(),
  6866. code.error_goto_if_null(target_list, self.pos)))
  6867. code.put_gotref(target_list)
  6868. if iterator_temp:
  6869. code.put_decref_clear(iterator_temp, py_object_type)
  6870. code.funcstate.release_temp(iterator_temp)
  6871. else:
  6872. rhs.generate_disposal_code(code)
  6873. if unpacked_fixed_items_right:
  6874. code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
  6875. length_temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
  6876. code.putln('%s = PyList_GET_SIZE(%s);' % (length_temp, target_list))
  6877. code.putln("if (unlikely(%s < %d)) {" % (length_temp, len(unpacked_fixed_items_right)))
  6878. code.putln("__Pyx_RaiseNeedMoreValuesError(%d+%s); %s" % (
  6879. len(unpacked_fixed_items_left), length_temp,
  6880. code.error_goto(self.pos)))
  6881. code.putln('}')
  6882. for item in unpacked_fixed_items_right[::-1]:
  6883. item.allocate(code)
  6884. for i, (item, coerced_arg) in enumerate(zip(unpacked_fixed_items_right[::-1],
  6885. self.coerced_unpacked_items[::-1])):
  6886. code.putln('#if CYTHON_COMPILING_IN_CPYTHON')
  6887. code.putln("%s = PyList_GET_ITEM(%s, %s-%d); " % (
  6888. item.py_result(), target_list, length_temp, i+1))
  6889. # resize the list the hard way
  6890. code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
  6891. code.putln('#else')
  6892. code.putln("%s = PySequence_ITEM(%s, %s-%d); " % (
  6893. item.py_result(), target_list, length_temp, i+1))
  6894. code.putln('#endif')
  6895. code.put_gotref(item.py_result())
  6896. coerced_arg.generate_evaluation_code(code)
  6897. code.putln('#if !CYTHON_COMPILING_IN_CPYTHON')
  6898. sublist_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  6899. code.putln('%s = PySequence_GetSlice(%s, 0, %s-%d); %s' % (
  6900. sublist_temp, target_list, length_temp, len(unpacked_fixed_items_right),
  6901. code.error_goto_if_null(sublist_temp, self.pos)))
  6902. code.put_gotref(sublist_temp)
  6903. code.funcstate.release_temp(length_temp)
  6904. code.put_decref(target_list, py_object_type)
  6905. code.putln('%s = %s; %s = NULL;' % (target_list, sublist_temp, sublist_temp))
  6906. code.putln('#else')
  6907. code.putln('(void)%s;' % sublist_temp) # avoid warning about unused variable
  6908. code.funcstate.release_temp(sublist_temp)
  6909. code.putln('#endif')
  6910. for i, arg in enumerate(self.args):
  6911. arg.generate_assignment_code(self.coerced_unpacked_items[i], code)
  6912. def annotate(self, code):
  6913. for arg in self.args:
  6914. arg.annotate(code)
  6915. if self.unpacked_items:
  6916. for arg in self.unpacked_items:
  6917. arg.annotate(code)
  6918. for arg in self.coerced_unpacked_items:
  6919. arg.annotate(code)
  6920. class TupleNode(SequenceNode):
  6921. # Tuple constructor.
  6922. type = tuple_type
  6923. is_partly_literal = False
  6924. gil_message = "Constructing Python tuple"
  6925. def infer_type(self, env):
  6926. if self.mult_factor or not self.args:
  6927. return tuple_type
  6928. arg_types = [arg.infer_type(env) for arg in self.args]
  6929. if any(type.is_pyobject or type.is_memoryviewslice or type.is_unspecified or type.is_fused
  6930. for type in arg_types):
  6931. return tuple_type
  6932. return env.declare_tuple_type(self.pos, arg_types).type
  6933. def analyse_types(self, env, skip_children=False):
  6934. if len(self.args) == 0:
  6935. self.is_temp = False
  6936. self.is_literal = True
  6937. return self
  6938. if not skip_children:
  6939. for i, arg in enumerate(self.args):
  6940. if arg.is_starred:
  6941. arg.starred_expr_allowed_here = True
  6942. self.args[i] = arg.analyse_types(env)
  6943. if (not self.mult_factor and
  6944. not any((arg.is_starred or arg.type.is_pyobject or arg.type.is_memoryviewslice or arg.type.is_fused)
  6945. for arg in self.args)):
  6946. self.type = env.declare_tuple_type(self.pos, (arg.type for arg in self.args)).type
  6947. self.is_temp = 1
  6948. return self
  6949. node = SequenceNode.analyse_types(self, env, skip_children=True)
  6950. node = node._create_merge_node_if_necessary(env)
  6951. if not node.is_sequence_constructor:
  6952. return node
  6953. if not all(child.is_literal for child in node.args):
  6954. return node
  6955. if not node.mult_factor or (
  6956. node.mult_factor.is_literal and
  6957. isinstance(node.mult_factor.constant_result, _py_int_types)):
  6958. node.is_temp = False
  6959. node.is_literal = True
  6960. else:
  6961. if not node.mult_factor.type.is_pyobject:
  6962. node.mult_factor = node.mult_factor.coerce_to_pyobject(env)
  6963. node.is_temp = True
  6964. node.is_partly_literal = True
  6965. return node
  6966. def analyse_as_type(self, env):
  6967. # ctuple type
  6968. if not self.args:
  6969. return None
  6970. item_types = [arg.analyse_as_type(env) for arg in self.args]
  6971. if any(t is None for t in item_types):
  6972. return None
  6973. entry = env.declare_tuple_type(self.pos, item_types)
  6974. return entry.type
  6975. def coerce_to(self, dst_type, env):
  6976. if self.type.is_ctuple:
  6977. if dst_type.is_ctuple and self.type.size == dst_type.size:
  6978. return self.coerce_to_ctuple(dst_type, env)
  6979. elif dst_type is tuple_type or dst_type is py_object_type:
  6980. coerced_args = [arg.coerce_to_pyobject(env) for arg in self.args]
  6981. return TupleNode(self.pos, args=coerced_args, type=tuple_type, is_temp=1).analyse_types(env, skip_children=True)
  6982. else:
  6983. return self.coerce_to_pyobject(env).coerce_to(dst_type, env)
  6984. elif dst_type.is_ctuple and not self.mult_factor:
  6985. return self.coerce_to_ctuple(dst_type, env)
  6986. else:
  6987. return SequenceNode.coerce_to(self, dst_type, env)
  6988. def as_list(self):
  6989. t = ListNode(self.pos, args=self.args, mult_factor=self.mult_factor)
  6990. if isinstance(self.constant_result, tuple):
  6991. t.constant_result = list(self.constant_result)
  6992. return t
  6993. def is_simple(self):
  6994. # either temp or constant => always simple
  6995. return True
  6996. def nonlocally_immutable(self):
  6997. # either temp or constant => always safe
  6998. return True
  6999. def calculate_result_code(self):
  7000. if len(self.args) > 0:
  7001. return self.result_code
  7002. else:
  7003. return Naming.empty_tuple
  7004. def calculate_constant_result(self):
  7005. self.constant_result = tuple([
  7006. arg.constant_result for arg in self.args])
  7007. def compile_time_value(self, denv):
  7008. values = self.compile_time_value_list(denv)
  7009. try:
  7010. return tuple(values)
  7011. except Exception as e:
  7012. self.compile_time_value_error(e)
  7013. def generate_operation_code(self, code):
  7014. if len(self.args) == 0:
  7015. # result_code is Naming.empty_tuple
  7016. return
  7017. if self.is_literal or self.is_partly_literal:
  7018. # The "mult_factor" is part of the deduplication if it is also constant, i.e. when
  7019. # we deduplicate the multiplied result. Otherwise, only deduplicate the constant part.
  7020. dedup_key = make_dedup_key(self.type, [self.mult_factor if self.is_literal else None] + self.args)
  7021. tuple_target = code.get_py_const(py_object_type, 'tuple', cleanup_level=2, dedup_key=dedup_key)
  7022. const_code = code.get_cached_constants_writer(tuple_target)
  7023. if const_code is not None:
  7024. # constant is not yet initialised
  7025. const_code.mark_pos(self.pos)
  7026. self.generate_sequence_packing_code(const_code, tuple_target, plain=not self.is_literal)
  7027. const_code.put_giveref(tuple_target)
  7028. if self.is_literal:
  7029. self.result_code = tuple_target
  7030. else:
  7031. code.putln('%s = PyNumber_Multiply(%s, %s); %s' % (
  7032. self.result(), tuple_target, self.mult_factor.py_result(),
  7033. code.error_goto_if_null(self.result(), self.pos)
  7034. ))
  7035. code.put_gotref(self.py_result())
  7036. else:
  7037. self.type.entry.used = True
  7038. self.generate_sequence_packing_code(code)
  7039. class ListNode(SequenceNode):
  7040. # List constructor.
  7041. # obj_conversion_errors [PyrexError] used internally
  7042. # orignial_args [ExprNode] used internally
  7043. obj_conversion_errors = []
  7044. type = list_type
  7045. in_module_scope = False
  7046. gil_message = "Constructing Python list"
  7047. def type_dependencies(self, env):
  7048. return ()
  7049. def infer_type(self, env):
  7050. # TODO: Infer non-object list arrays.
  7051. return list_type
  7052. def analyse_expressions(self, env):
  7053. for arg in self.args:
  7054. if arg.is_starred:
  7055. arg.starred_expr_allowed_here = True
  7056. node = SequenceNode.analyse_expressions(self, env)
  7057. return node.coerce_to_pyobject(env)
  7058. def analyse_types(self, env):
  7059. with local_errors(ignore=True) as errors:
  7060. self.original_args = list(self.args)
  7061. node = SequenceNode.analyse_types(self, env)
  7062. node.obj_conversion_errors = errors
  7063. if env.is_module_scope:
  7064. self.in_module_scope = True
  7065. node = node._create_merge_node_if_necessary(env)
  7066. return node
  7067. def coerce_to(self, dst_type, env):
  7068. if dst_type.is_pyobject:
  7069. for err in self.obj_conversion_errors:
  7070. report_error(err)
  7071. self.obj_conversion_errors = []
  7072. if not self.type.subtype_of(dst_type):
  7073. error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
  7074. elif (dst_type.is_array or dst_type.is_ptr) and dst_type.base_type is not PyrexTypes.c_void_type:
  7075. array_length = len(self.args)
  7076. if self.mult_factor:
  7077. if isinstance(self.mult_factor.constant_result, _py_int_types):
  7078. if self.mult_factor.constant_result <= 0:
  7079. error(self.pos, "Cannot coerce non-positively multiplied list to '%s'" % dst_type)
  7080. else:
  7081. array_length *= self.mult_factor.constant_result
  7082. else:
  7083. error(self.pos, "Cannot coerce dynamically multiplied list to '%s'" % dst_type)
  7084. base_type = dst_type.base_type
  7085. self.type = PyrexTypes.CArrayType(base_type, array_length)
  7086. for i in range(len(self.original_args)):
  7087. arg = self.args[i]
  7088. if isinstance(arg, CoerceToPyTypeNode):
  7089. arg = arg.arg
  7090. self.args[i] = arg.coerce_to(base_type, env)
  7091. elif dst_type.is_cpp_class:
  7092. # TODO(robertwb): Avoid object conversion for vector/list/set.
  7093. return TypecastNode(self.pos, operand=self, type=PyrexTypes.py_object_type).coerce_to(dst_type, env)
  7094. elif self.mult_factor:
  7095. error(self.pos, "Cannot coerce multiplied list to '%s'" % dst_type)
  7096. elif dst_type.is_struct:
  7097. if len(self.args) > len(dst_type.scope.var_entries):
  7098. error(self.pos, "Too many members for '%s'" % dst_type)
  7099. else:
  7100. if len(self.args) < len(dst_type.scope.var_entries):
  7101. warning(self.pos, "Too few members for '%s'" % dst_type, 1)
  7102. for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
  7103. if isinstance(arg, CoerceToPyTypeNode):
  7104. arg = arg.arg
  7105. self.args[i] = arg.coerce_to(member.type, env)
  7106. self.type = dst_type
  7107. elif dst_type.is_ctuple:
  7108. return self.coerce_to_ctuple(dst_type, env)
  7109. else:
  7110. self.type = error_type
  7111. error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
  7112. return self
  7113. def as_list(self): # dummy for compatibility with TupleNode
  7114. return self
  7115. def as_tuple(self):
  7116. t = TupleNode(self.pos, args=self.args, mult_factor=self.mult_factor)
  7117. if isinstance(self.constant_result, list):
  7118. t.constant_result = tuple(self.constant_result)
  7119. return t
  7120. def allocate_temp_result(self, code):
  7121. if self.type.is_array:
  7122. if self.in_module_scope:
  7123. self.temp_code = code.funcstate.allocate_temp(
  7124. self.type, manage_ref=False, static=True, reusable=False)
  7125. else:
  7126. # To be valid C++, we must allocate the memory on the stack
  7127. # manually and be sure not to reuse it for something else.
  7128. # Yes, this means that we leak a temp array variable.
  7129. self.temp_code = code.funcstate.allocate_temp(
  7130. self.type, manage_ref=False, reusable=False)
  7131. else:
  7132. SequenceNode.allocate_temp_result(self, code)
  7133. def calculate_constant_result(self):
  7134. if self.mult_factor:
  7135. raise ValueError() # may exceed the compile time memory
  7136. self.constant_result = [
  7137. arg.constant_result for arg in self.args]
  7138. def compile_time_value(self, denv):
  7139. l = self.compile_time_value_list(denv)
  7140. if self.mult_factor:
  7141. l *= self.mult_factor.compile_time_value(denv)
  7142. return l
  7143. def generate_operation_code(self, code):
  7144. if self.type.is_pyobject:
  7145. for err in self.obj_conversion_errors:
  7146. report_error(err)
  7147. self.generate_sequence_packing_code(code)
  7148. elif self.type.is_array:
  7149. if self.mult_factor:
  7150. code.putln("{")
  7151. code.putln("Py_ssize_t %s;" % Naming.quick_temp_cname)
  7152. code.putln("for ({i} = 0; {i} < {count}; {i}++) {{".format(
  7153. i=Naming.quick_temp_cname, count=self.mult_factor.result()))
  7154. offset = '+ (%d * %s)' % (len(self.args), Naming.quick_temp_cname)
  7155. else:
  7156. offset = ''
  7157. for i, arg in enumerate(self.args):
  7158. if arg.type.is_array:
  7159. code.globalstate.use_utility_code(UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
  7160. code.putln("memcpy(&(%s[%s%s]), %s, sizeof(%s[0]));" % (
  7161. self.result(), i, offset,
  7162. arg.result(), self.result()
  7163. ))
  7164. else:
  7165. code.putln("%s[%s%s] = %s;" % (
  7166. self.result(),
  7167. i,
  7168. offset,
  7169. arg.result()))
  7170. if self.mult_factor:
  7171. code.putln("}")
  7172. code.putln("}")
  7173. elif self.type.is_struct:
  7174. for arg, member in zip(self.args, self.type.scope.var_entries):
  7175. code.putln("%s.%s = %s;" % (
  7176. self.result(),
  7177. member.cname,
  7178. arg.result()))
  7179. else:
  7180. raise InternalError("List type never specified")
  7181. class ScopedExprNode(ExprNode):
  7182. # Abstract base class for ExprNodes that have their own local
  7183. # scope, such as generator expressions.
  7184. #
  7185. # expr_scope Scope the inner scope of the expression
  7186. subexprs = []
  7187. expr_scope = None
  7188. # does this node really have a local scope, e.g. does it leak loop
  7189. # variables or not? non-leaking Py3 behaviour is default, except
  7190. # for list comprehensions where the behaviour differs in Py2 and
  7191. # Py3 (set in Parsing.py based on parser context)
  7192. has_local_scope = True
  7193. def init_scope(self, outer_scope, expr_scope=None):
  7194. if expr_scope is not None:
  7195. self.expr_scope = expr_scope
  7196. elif self.has_local_scope:
  7197. self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
  7198. else:
  7199. self.expr_scope = None
  7200. def analyse_declarations(self, env):
  7201. self.init_scope(env)
  7202. def analyse_scoped_declarations(self, env):
  7203. # this is called with the expr_scope as env
  7204. pass
  7205. def analyse_types(self, env):
  7206. # no recursion here, the children will be analysed separately below
  7207. return self
  7208. def analyse_scoped_expressions(self, env):
  7209. # this is called with the expr_scope as env
  7210. return self
  7211. def generate_evaluation_code(self, code):
  7212. # set up local variables and free their references on exit
  7213. generate_inner_evaluation_code = super(ScopedExprNode, self).generate_evaluation_code
  7214. if not self.has_local_scope or not self.expr_scope.var_entries:
  7215. # no local variables => delegate, done
  7216. generate_inner_evaluation_code(code)
  7217. return
  7218. code.putln('{ /* enter inner scope */')
  7219. py_entries = []
  7220. for _, entry in sorted(item for item in self.expr_scope.entries.items() if item[0]):
  7221. if not entry.in_closure:
  7222. if entry.type.is_pyobject and entry.used:
  7223. py_entries.append(entry)
  7224. if not py_entries:
  7225. # no local Python references => no cleanup required
  7226. generate_inner_evaluation_code(code)
  7227. code.putln('} /* exit inner scope */')
  7228. return
  7229. # must free all local Python references at each exit point
  7230. old_loop_labels = code.new_loop_labels()
  7231. old_error_label = code.new_error_label()
  7232. generate_inner_evaluation_code(code)
  7233. # normal (non-error) exit
  7234. self._generate_vars_cleanup(code, py_entries)
  7235. # error/loop body exit points
  7236. exit_scope = code.new_label('exit_scope')
  7237. code.put_goto(exit_scope)
  7238. for label, old_label in ([(code.error_label, old_error_label)] +
  7239. list(zip(code.get_loop_labels(), old_loop_labels))):
  7240. if code.label_used(label):
  7241. code.put_label(label)
  7242. self._generate_vars_cleanup(code, py_entries)
  7243. code.put_goto(old_label)
  7244. code.put_label(exit_scope)
  7245. code.putln('} /* exit inner scope */')
  7246. code.set_loop_labels(old_loop_labels)
  7247. code.error_label = old_error_label
  7248. def _generate_vars_cleanup(self, code, py_entries):
  7249. for entry in py_entries:
  7250. if entry.is_cglobal:
  7251. code.put_var_gotref(entry)
  7252. code.put_decref_set(entry.cname, "Py_None")
  7253. else:
  7254. code.put_var_xdecref_clear(entry)
  7255. class ComprehensionNode(ScopedExprNode):
  7256. # A list/set/dict comprehension
  7257. child_attrs = ["loop"]
  7258. is_temp = True
  7259. constant_result = not_a_constant
  7260. def infer_type(self, env):
  7261. return self.type
  7262. def analyse_declarations(self, env):
  7263. self.append.target = self # this is used in the PyList_Append of the inner loop
  7264. self.init_scope(env)
  7265. def analyse_scoped_declarations(self, env):
  7266. self.loop.analyse_declarations(env)
  7267. def analyse_types(self, env):
  7268. if not self.has_local_scope:
  7269. self.loop = self.loop.analyse_expressions(env)
  7270. return self
  7271. def analyse_scoped_expressions(self, env):
  7272. if self.has_local_scope:
  7273. self.loop = self.loop.analyse_expressions(env)
  7274. return self
  7275. def may_be_none(self):
  7276. return False
  7277. def generate_result_code(self, code):
  7278. self.generate_operation_code(code)
  7279. def generate_operation_code(self, code):
  7280. if self.type is Builtin.list_type:
  7281. create_code = 'PyList_New(0)'
  7282. elif self.type is Builtin.set_type:
  7283. create_code = 'PySet_New(NULL)'
  7284. elif self.type is Builtin.dict_type:
  7285. create_code = 'PyDict_New()'
  7286. else:
  7287. raise InternalError("illegal type for comprehension: %s" % self.type)
  7288. code.putln('%s = %s; %s' % (
  7289. self.result(), create_code,
  7290. code.error_goto_if_null(self.result(), self.pos)))
  7291. code.put_gotref(self.result())
  7292. self.loop.generate_execution_code(code)
  7293. def annotate(self, code):
  7294. self.loop.annotate(code)
  7295. class ComprehensionAppendNode(Node):
  7296. # Need to be careful to avoid infinite recursion:
  7297. # target must not be in child_attrs/subexprs
  7298. child_attrs = ['expr']
  7299. target = None
  7300. type = PyrexTypes.c_int_type
  7301. def analyse_expressions(self, env):
  7302. self.expr = self.expr.analyse_expressions(env)
  7303. if not self.expr.type.is_pyobject:
  7304. self.expr = self.expr.coerce_to_pyobject(env)
  7305. return self
  7306. def generate_execution_code(self, code):
  7307. if self.target.type is list_type:
  7308. code.globalstate.use_utility_code(
  7309. UtilityCode.load_cached("ListCompAppend", "Optimize.c"))
  7310. function = "__Pyx_ListComp_Append"
  7311. elif self.target.type is set_type:
  7312. function = "PySet_Add"
  7313. else:
  7314. raise InternalError(
  7315. "Invalid type for comprehension node: %s" % self.target.type)
  7316. self.expr.generate_evaluation_code(code)
  7317. code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
  7318. function,
  7319. self.target.result(),
  7320. self.expr.result()
  7321. ), self.pos))
  7322. self.expr.generate_disposal_code(code)
  7323. self.expr.free_temps(code)
  7324. def generate_function_definitions(self, env, code):
  7325. self.expr.generate_function_definitions(env, code)
  7326. def annotate(self, code):
  7327. self.expr.annotate(code)
  7328. class DictComprehensionAppendNode(ComprehensionAppendNode):
  7329. child_attrs = ['key_expr', 'value_expr']
  7330. def analyse_expressions(self, env):
  7331. self.key_expr = self.key_expr.analyse_expressions(env)
  7332. if not self.key_expr.type.is_pyobject:
  7333. self.key_expr = self.key_expr.coerce_to_pyobject(env)
  7334. self.value_expr = self.value_expr.analyse_expressions(env)
  7335. if not self.value_expr.type.is_pyobject:
  7336. self.value_expr = self.value_expr.coerce_to_pyobject(env)
  7337. return self
  7338. def generate_execution_code(self, code):
  7339. self.key_expr.generate_evaluation_code(code)
  7340. self.value_expr.generate_evaluation_code(code)
  7341. code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
  7342. self.target.result(),
  7343. self.key_expr.result(),
  7344. self.value_expr.result()
  7345. ), self.pos))
  7346. self.key_expr.generate_disposal_code(code)
  7347. self.key_expr.free_temps(code)
  7348. self.value_expr.generate_disposal_code(code)
  7349. self.value_expr.free_temps(code)
  7350. def generate_function_definitions(self, env, code):
  7351. self.key_expr.generate_function_definitions(env, code)
  7352. self.value_expr.generate_function_definitions(env, code)
  7353. def annotate(self, code):
  7354. self.key_expr.annotate(code)
  7355. self.value_expr.annotate(code)
  7356. class InlinedGeneratorExpressionNode(ExprNode):
  7357. # An inlined generator expression for which the result is calculated
  7358. # inside of the loop and returned as a single, first and only Generator
  7359. # return value.
  7360. # This will only be created by transforms when replacing safe builtin
  7361. # calls on generator expressions.
  7362. #
  7363. # gen GeneratorExpressionNode the generator, not containing any YieldExprNodes
  7364. # orig_func String the name of the builtin function this node replaces
  7365. # target ExprNode or None a 'target' for a ComprehensionAppend node
  7366. subexprs = ["gen"]
  7367. orig_func = None
  7368. target = None
  7369. is_temp = True
  7370. type = py_object_type
  7371. def __init__(self, pos, gen, comprehension_type=None, **kwargs):
  7372. gbody = gen.def_node.gbody
  7373. gbody.is_inlined = True
  7374. if comprehension_type is not None:
  7375. assert comprehension_type in (list_type, set_type, dict_type), comprehension_type
  7376. gbody.inlined_comprehension_type = comprehension_type
  7377. kwargs.update(
  7378. target=RawCNameExprNode(pos, comprehension_type, Naming.retval_cname),
  7379. type=comprehension_type,
  7380. )
  7381. super(InlinedGeneratorExpressionNode, self).__init__(pos, gen=gen, **kwargs)
  7382. def may_be_none(self):
  7383. return self.orig_func not in ('any', 'all', 'sorted')
  7384. def infer_type(self, env):
  7385. return self.type
  7386. def analyse_types(self, env):
  7387. self.gen = self.gen.analyse_expressions(env)
  7388. return self
  7389. def generate_result_code(self, code):
  7390. code.putln("%s = __Pyx_Generator_Next(%s); %s" % (
  7391. self.result(), self.gen.result(),
  7392. code.error_goto_if_null(self.result(), self.pos)))
  7393. code.put_gotref(self.result())
  7394. class MergedSequenceNode(ExprNode):
  7395. """
  7396. Merge a sequence of iterables into a set/list/tuple.
  7397. The target collection is determined by self.type, which must be set externally.
  7398. args [ExprNode]
  7399. """
  7400. subexprs = ['args']
  7401. is_temp = True
  7402. gil_message = "Constructing Python collection"
  7403. def __init__(self, pos, args, type):
  7404. if type in (list_type, tuple_type) and args and args[0].is_sequence_constructor:
  7405. # construct a list directly from the first argument that we can then extend
  7406. if args[0].type is not list_type:
  7407. args[0] = ListNode(args[0].pos, args=args[0].args, is_temp=True, mult_factor=args[0].mult_factor)
  7408. ExprNode.__init__(self, pos, args=args, type=type)
  7409. def calculate_constant_result(self):
  7410. result = []
  7411. for item in self.args:
  7412. if item.is_sequence_constructor and item.mult_factor:
  7413. if item.mult_factor.constant_result <= 0:
  7414. continue
  7415. # otherwise, adding each item once should be enough
  7416. if item.is_set_literal or item.is_sequence_constructor:
  7417. # process items in order
  7418. items = (arg.constant_result for arg in item.args)
  7419. else:
  7420. items = item.constant_result
  7421. result.extend(items)
  7422. if self.type is set_type:
  7423. result = set(result)
  7424. elif self.type is tuple_type:
  7425. result = tuple(result)
  7426. else:
  7427. assert self.type is list_type
  7428. self.constant_result = result
  7429. def compile_time_value(self, denv):
  7430. result = []
  7431. for item in self.args:
  7432. if item.is_sequence_constructor and item.mult_factor:
  7433. if item.mult_factor.compile_time_value(denv) <= 0:
  7434. continue
  7435. if item.is_set_literal or item.is_sequence_constructor:
  7436. # process items in order
  7437. items = (arg.compile_time_value(denv) for arg in item.args)
  7438. else:
  7439. items = item.compile_time_value(denv)
  7440. result.extend(items)
  7441. if self.type is set_type:
  7442. try:
  7443. result = set(result)
  7444. except Exception as e:
  7445. self.compile_time_value_error(e)
  7446. elif self.type is tuple_type:
  7447. result = tuple(result)
  7448. else:
  7449. assert self.type is list_type
  7450. return result
  7451. def type_dependencies(self, env):
  7452. return ()
  7453. def infer_type(self, env):
  7454. return self.type
  7455. def analyse_types(self, env):
  7456. args = [
  7457. arg.analyse_types(env).coerce_to_pyobject(env).as_none_safe_node(
  7458. # FIXME: CPython's error message starts with the runtime function name
  7459. 'argument after * must be an iterable, not NoneType')
  7460. for arg in self.args
  7461. ]
  7462. if len(args) == 1 and args[0].type is self.type:
  7463. # strip this intermediate node and use the bare collection
  7464. return args[0]
  7465. assert self.type in (set_type, list_type, tuple_type)
  7466. self.args = args
  7467. return self
  7468. def may_be_none(self):
  7469. return False
  7470. def generate_evaluation_code(self, code):
  7471. code.mark_pos(self.pos)
  7472. self.allocate_temp_result(code)
  7473. is_set = self.type is set_type
  7474. args = iter(self.args)
  7475. item = next(args)
  7476. item.generate_evaluation_code(code)
  7477. if (is_set and item.is_set_literal or
  7478. not is_set and item.is_sequence_constructor and item.type is list_type):
  7479. code.putln("%s = %s;" % (self.result(), item.py_result()))
  7480. item.generate_post_assignment_code(code)
  7481. else:
  7482. code.putln("%s = %s(%s); %s" % (
  7483. self.result(),
  7484. 'PySet_New' if is_set else 'PySequence_List',
  7485. item.py_result(),
  7486. code.error_goto_if_null(self.result(), self.pos)))
  7487. code.put_gotref(self.py_result())
  7488. item.generate_disposal_code(code)
  7489. item.free_temps(code)
  7490. helpers = set()
  7491. if is_set:
  7492. add_func = "PySet_Add"
  7493. extend_func = "__Pyx_PySet_Update"
  7494. else:
  7495. add_func = "__Pyx_ListComp_Append"
  7496. extend_func = "__Pyx_PyList_Extend"
  7497. for item in args:
  7498. if (is_set and (item.is_set_literal or item.is_sequence_constructor) or
  7499. (item.is_sequence_constructor and not item.mult_factor)):
  7500. if not is_set and item.args:
  7501. helpers.add(("ListCompAppend", "Optimize.c"))
  7502. for arg in item.args:
  7503. arg.generate_evaluation_code(code)
  7504. code.put_error_if_neg(arg.pos, "%s(%s, %s)" % (
  7505. add_func,
  7506. self.result(),
  7507. arg.py_result()))
  7508. arg.generate_disposal_code(code)
  7509. arg.free_temps(code)
  7510. continue
  7511. if is_set:
  7512. helpers.add(("PySet_Update", "Builtins.c"))
  7513. else:
  7514. helpers.add(("ListExtend", "Optimize.c"))
  7515. item.generate_evaluation_code(code)
  7516. code.put_error_if_neg(item.pos, "%s(%s, %s)" % (
  7517. extend_func,
  7518. self.result(),
  7519. item.py_result()))
  7520. item.generate_disposal_code(code)
  7521. item.free_temps(code)
  7522. if self.type is tuple_type:
  7523. code.putln("{")
  7524. code.putln("PyObject *%s = PyList_AsTuple(%s);" % (
  7525. Naming.quick_temp_cname,
  7526. self.result()))
  7527. code.put_decref(self.result(), py_object_type)
  7528. code.putln("%s = %s; %s" % (
  7529. self.result(),
  7530. Naming.quick_temp_cname,
  7531. code.error_goto_if_null(self.result(), self.pos)))
  7532. code.put_gotref(self.result())
  7533. code.putln("}")
  7534. for helper in sorted(helpers):
  7535. code.globalstate.use_utility_code(UtilityCode.load_cached(*helper))
  7536. def annotate(self, code):
  7537. for item in self.args:
  7538. item.annotate(code)
  7539. class SetNode(ExprNode):
  7540. """
  7541. Set constructor.
  7542. """
  7543. subexprs = ['args']
  7544. type = set_type
  7545. is_set_literal = True
  7546. gil_message = "Constructing Python set"
  7547. def analyse_types(self, env):
  7548. for i in range(len(self.args)):
  7549. arg = self.args[i]
  7550. arg = arg.analyse_types(env)
  7551. self.args[i] = arg.coerce_to_pyobject(env)
  7552. self.type = set_type
  7553. self.is_temp = 1
  7554. return self
  7555. def may_be_none(self):
  7556. return False
  7557. def calculate_constant_result(self):
  7558. self.constant_result = set([arg.constant_result for arg in self.args])
  7559. def compile_time_value(self, denv):
  7560. values = [arg.compile_time_value(denv) for arg in self.args]
  7561. try:
  7562. return set(values)
  7563. except Exception as e:
  7564. self.compile_time_value_error(e)
  7565. def generate_evaluation_code(self, code):
  7566. for arg in self.args:
  7567. arg.generate_evaluation_code(code)
  7568. self.allocate_temp_result(code)
  7569. code.putln(
  7570. "%s = PySet_New(0); %s" % (
  7571. self.result(),
  7572. code.error_goto_if_null(self.result(), self.pos)))
  7573. code.put_gotref(self.py_result())
  7574. for arg in self.args:
  7575. code.put_error_if_neg(
  7576. self.pos,
  7577. "PySet_Add(%s, %s)" % (self.result(), arg.py_result()))
  7578. arg.generate_disposal_code(code)
  7579. arg.free_temps(code)
  7580. class DictNode(ExprNode):
  7581. # Dictionary constructor.
  7582. #
  7583. # key_value_pairs [DictItemNode]
  7584. # exclude_null_values [boolean] Do not add NULL values to dict
  7585. #
  7586. # obj_conversion_errors [PyrexError] used internally
  7587. subexprs = ['key_value_pairs']
  7588. is_temp = 1
  7589. exclude_null_values = False
  7590. type = dict_type
  7591. is_dict_literal = True
  7592. reject_duplicates = False
  7593. obj_conversion_errors = []
  7594. @classmethod
  7595. def from_pairs(cls, pos, pairs):
  7596. return cls(pos, key_value_pairs=[
  7597. DictItemNode(pos, key=k, value=v) for k, v in pairs])
  7598. def calculate_constant_result(self):
  7599. self.constant_result = dict([
  7600. item.constant_result for item in self.key_value_pairs])
  7601. def compile_time_value(self, denv):
  7602. pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
  7603. for item in self.key_value_pairs]
  7604. try:
  7605. return dict(pairs)
  7606. except Exception as e:
  7607. self.compile_time_value_error(e)
  7608. def type_dependencies(self, env):
  7609. return ()
  7610. def infer_type(self, env):
  7611. # TODO: Infer struct constructors.
  7612. return dict_type
  7613. def analyse_types(self, env):
  7614. with local_errors(ignore=True) as errors:
  7615. self.key_value_pairs = [
  7616. item.analyse_types(env)
  7617. for item in self.key_value_pairs
  7618. ]
  7619. self.obj_conversion_errors = errors
  7620. return self
  7621. def may_be_none(self):
  7622. return False
  7623. def coerce_to(self, dst_type, env):
  7624. if dst_type.is_pyobject:
  7625. self.release_errors()
  7626. if self.type.is_struct_or_union:
  7627. if not dict_type.subtype_of(dst_type):
  7628. error(self.pos, "Cannot interpret struct as non-dict type '%s'" % dst_type)
  7629. return DictNode(self.pos, key_value_pairs=[
  7630. DictItemNode(item.pos, key=item.key.coerce_to_pyobject(env),
  7631. value=item.value.coerce_to_pyobject(env))
  7632. for item in self.key_value_pairs])
  7633. if not self.type.subtype_of(dst_type):
  7634. error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
  7635. elif dst_type.is_struct_or_union:
  7636. self.type = dst_type
  7637. if not dst_type.is_struct and len(self.key_value_pairs) != 1:
  7638. error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
  7639. elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
  7640. warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
  7641. for item in self.key_value_pairs:
  7642. if isinstance(item.key, CoerceToPyTypeNode):
  7643. item.key = item.key.arg
  7644. if not item.key.is_string_literal:
  7645. error(item.key.pos, "Invalid struct field identifier")
  7646. item.key = StringNode(item.key.pos, value="<error>")
  7647. else:
  7648. key = str(item.key.value) # converts string literals to unicode in Py3
  7649. member = dst_type.scope.lookup_here(key)
  7650. if not member:
  7651. error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
  7652. else:
  7653. value = item.value
  7654. if isinstance(value, CoerceToPyTypeNode):
  7655. value = value.arg
  7656. item.value = value.coerce_to(member.type, env)
  7657. else:
  7658. self.type = error_type
  7659. error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
  7660. return self
  7661. def release_errors(self):
  7662. for err in self.obj_conversion_errors:
  7663. report_error(err)
  7664. self.obj_conversion_errors = []
  7665. gil_message = "Constructing Python dict"
  7666. def generate_evaluation_code(self, code):
  7667. # Custom method used here because key-value
  7668. # pairs are evaluated and used one at a time.
  7669. code.mark_pos(self.pos)
  7670. self.allocate_temp_result(code)
  7671. is_dict = self.type.is_pyobject
  7672. if is_dict:
  7673. self.release_errors()
  7674. code.putln(
  7675. "%s = __Pyx_PyDict_NewPresized(%d); %s" % (
  7676. self.result(),
  7677. len(self.key_value_pairs),
  7678. code.error_goto_if_null(self.result(), self.pos)))
  7679. code.put_gotref(self.py_result())
  7680. keys_seen = set()
  7681. key_type = None
  7682. needs_error_helper = False
  7683. for item in self.key_value_pairs:
  7684. item.generate_evaluation_code(code)
  7685. if is_dict:
  7686. if self.exclude_null_values:
  7687. code.putln('if (%s) {' % item.value.py_result())
  7688. key = item.key
  7689. if self.reject_duplicates:
  7690. if keys_seen is not None:
  7691. # avoid runtime 'in' checks for literals that we can do at compile time
  7692. if not key.is_string_literal:
  7693. keys_seen = None
  7694. elif key.value in keys_seen:
  7695. # FIXME: this could be a compile time error, at least in Cython code
  7696. keys_seen = None
  7697. elif key_type is not type(key.value):
  7698. if key_type is None:
  7699. key_type = type(key.value)
  7700. keys_seen.add(key.value)
  7701. else:
  7702. # different types => may not be able to compare at compile time
  7703. keys_seen = None
  7704. else:
  7705. keys_seen.add(key.value)
  7706. if keys_seen is None:
  7707. code.putln('if (unlikely(PyDict_Contains(%s, %s))) {' % (
  7708. self.result(), key.py_result()))
  7709. # currently only used in function calls
  7710. needs_error_helper = True
  7711. code.putln('__Pyx_RaiseDoubleKeywordsError("function", %s); %s' % (
  7712. key.py_result(),
  7713. code.error_goto(item.pos)))
  7714. code.putln("} else {")
  7715. code.put_error_if_neg(self.pos, "PyDict_SetItem(%s, %s, %s)" % (
  7716. self.result(),
  7717. item.key.py_result(),
  7718. item.value.py_result()))
  7719. if self.reject_duplicates and keys_seen is None:
  7720. code.putln('}')
  7721. if self.exclude_null_values:
  7722. code.putln('}')
  7723. else:
  7724. code.putln("%s.%s = %s;" % (
  7725. self.result(),
  7726. item.key.value,
  7727. item.value.result()))
  7728. item.generate_disposal_code(code)
  7729. item.free_temps(code)
  7730. if needs_error_helper:
  7731. code.globalstate.use_utility_code(
  7732. UtilityCode.load_cached("RaiseDoubleKeywords", "FunctionArguments.c"))
  7733. def annotate(self, code):
  7734. for item in self.key_value_pairs:
  7735. item.annotate(code)
  7736. class DictItemNode(ExprNode):
  7737. # Represents a single item in a DictNode
  7738. #
  7739. # key ExprNode
  7740. # value ExprNode
  7741. subexprs = ['key', 'value']
  7742. nogil_check = None # Parent DictNode takes care of it
  7743. def calculate_constant_result(self):
  7744. self.constant_result = (
  7745. self.key.constant_result, self.value.constant_result)
  7746. def analyse_types(self, env):
  7747. self.key = self.key.analyse_types(env)
  7748. self.value = self.value.analyse_types(env)
  7749. self.key = self.key.coerce_to_pyobject(env)
  7750. self.value = self.value.coerce_to_pyobject(env)
  7751. return self
  7752. def generate_evaluation_code(self, code):
  7753. self.key.generate_evaluation_code(code)
  7754. self.value.generate_evaluation_code(code)
  7755. def generate_disposal_code(self, code):
  7756. self.key.generate_disposal_code(code)
  7757. self.value.generate_disposal_code(code)
  7758. def free_temps(self, code):
  7759. self.key.free_temps(code)
  7760. self.value.free_temps(code)
  7761. def __iter__(self):
  7762. return iter([self.key, self.value])
  7763. class SortedDictKeysNode(ExprNode):
  7764. # build sorted list of dict keys, e.g. for dir()
  7765. subexprs = ['arg']
  7766. is_temp = True
  7767. def __init__(self, arg):
  7768. ExprNode.__init__(self, arg.pos, arg=arg)
  7769. self.type = Builtin.list_type
  7770. def analyse_types(self, env):
  7771. arg = self.arg.analyse_types(env)
  7772. if arg.type is Builtin.dict_type:
  7773. arg = arg.as_none_safe_node(
  7774. "'NoneType' object is not iterable")
  7775. self.arg = arg
  7776. return self
  7777. def may_be_none(self):
  7778. return False
  7779. def generate_result_code(self, code):
  7780. dict_result = self.arg.py_result()
  7781. if self.arg.type is Builtin.dict_type:
  7782. code.putln('%s = PyDict_Keys(%s); %s' % (
  7783. self.result(), dict_result,
  7784. code.error_goto_if_null(self.result(), self.pos)))
  7785. code.put_gotref(self.py_result())
  7786. else:
  7787. # originally used PyMapping_Keys() here, but that may return a tuple
  7788. code.globalstate.use_utility_code(UtilityCode.load_cached(
  7789. 'PyObjectCallMethod0', 'ObjectHandling.c'))
  7790. keys_cname = code.intern_identifier(StringEncoding.EncodedString("keys"))
  7791. code.putln('%s = __Pyx_PyObject_CallMethod0(%s, %s); %s' % (
  7792. self.result(), dict_result, keys_cname,
  7793. code.error_goto_if_null(self.result(), self.pos)))
  7794. code.put_gotref(self.py_result())
  7795. code.putln("if (unlikely(!PyList_Check(%s))) {" % self.result())
  7796. code.put_decref_set(self.result(), "PySequence_List(%s)" % self.result())
  7797. code.putln(code.error_goto_if_null(self.result(), self.pos))
  7798. code.put_gotref(self.py_result())
  7799. code.putln("}")
  7800. code.put_error_if_neg(
  7801. self.pos, 'PyList_Sort(%s)' % self.py_result())
  7802. class ModuleNameMixin(object):
  7803. def get_py_mod_name(self, code):
  7804. return code.get_py_string_const(
  7805. self.module_name, identifier=True)
  7806. def get_py_qualified_name(self, code):
  7807. return code.get_py_string_const(
  7808. self.qualname, identifier=True)
  7809. class ClassNode(ExprNode, ModuleNameMixin):
  7810. # Helper class used in the implementation of Python
  7811. # class definitions. Constructs a class object given
  7812. # a name, tuple of bases and class dictionary.
  7813. #
  7814. # name EncodedString Name of the class
  7815. # class_def_node PyClassDefNode PyClassDefNode defining this class
  7816. # doc ExprNode or None Doc string
  7817. # module_name EncodedString Name of defining module
  7818. subexprs = ['doc']
  7819. type = py_object_type
  7820. is_temp = True
  7821. def infer_type(self, env):
  7822. # TODO: could return 'type' in some cases
  7823. return py_object_type
  7824. def analyse_types(self, env):
  7825. if self.doc:
  7826. self.doc = self.doc.analyse_types(env)
  7827. self.doc = self.doc.coerce_to_pyobject(env)
  7828. env.use_utility_code(UtilityCode.load_cached("CreateClass", "ObjectHandling.c"))
  7829. return self
  7830. def may_be_none(self):
  7831. return True
  7832. gil_message = "Constructing Python class"
  7833. def generate_result_code(self, code):
  7834. class_def_node = self.class_def_node
  7835. cname = code.intern_identifier(self.name)
  7836. if self.doc:
  7837. code.put_error_if_neg(self.pos,
  7838. 'PyDict_SetItem(%s, %s, %s)' % (
  7839. class_def_node.dict.py_result(),
  7840. code.intern_identifier(
  7841. StringEncoding.EncodedString("__doc__")),
  7842. self.doc.py_result()))
  7843. py_mod_name = self.get_py_mod_name(code)
  7844. qualname = self.get_py_qualified_name(code)
  7845. code.putln(
  7846. '%s = __Pyx_CreateClass(%s, %s, %s, %s, %s); %s' % (
  7847. self.result(),
  7848. class_def_node.bases.py_result(),
  7849. class_def_node.dict.py_result(),
  7850. cname,
  7851. qualname,
  7852. py_mod_name,
  7853. code.error_goto_if_null(self.result(), self.pos)))
  7854. code.put_gotref(self.py_result())
  7855. class Py3ClassNode(ExprNode):
  7856. # Helper class used in the implementation of Python3+
  7857. # class definitions. Constructs a class object given
  7858. # a name, tuple of bases and class dictionary.
  7859. #
  7860. # name EncodedString Name of the class
  7861. # module_name EncodedString Name of defining module
  7862. # class_def_node PyClassDefNode PyClassDefNode defining this class
  7863. # calculate_metaclass bool should call CalculateMetaclass()
  7864. # allow_py2_metaclass bool should look for Py2 metaclass
  7865. subexprs = []
  7866. type = py_object_type
  7867. is_temp = True
  7868. def infer_type(self, env):
  7869. # TODO: could return 'type' in some cases
  7870. return py_object_type
  7871. def analyse_types(self, env):
  7872. return self
  7873. def may_be_none(self):
  7874. return True
  7875. gil_message = "Constructing Python class"
  7876. def generate_result_code(self, code):
  7877. code.globalstate.use_utility_code(UtilityCode.load_cached("Py3ClassCreate", "ObjectHandling.c"))
  7878. cname = code.intern_identifier(self.name)
  7879. class_def_node = self.class_def_node
  7880. mkw = class_def_node.mkw.py_result() if class_def_node.mkw else 'NULL'
  7881. if class_def_node.metaclass:
  7882. metaclass = class_def_node.metaclass.py_result()
  7883. else:
  7884. metaclass = "((PyObject*)&__Pyx_DefaultClassType)"
  7885. code.putln(
  7886. '%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s, %d, %d); %s' % (
  7887. self.result(),
  7888. metaclass,
  7889. cname,
  7890. class_def_node.bases.py_result(),
  7891. class_def_node.dict.py_result(),
  7892. mkw,
  7893. self.calculate_metaclass,
  7894. self.allow_py2_metaclass,
  7895. code.error_goto_if_null(self.result(), self.pos)))
  7896. code.put_gotref(self.py_result())
  7897. class PyClassMetaclassNode(ExprNode):
  7898. # Helper class holds Python3 metaclass object
  7899. #
  7900. # class_def_node PyClassDefNode PyClassDefNode defining this class
  7901. subexprs = []
  7902. def analyse_types(self, env):
  7903. self.type = py_object_type
  7904. self.is_temp = True
  7905. return self
  7906. def may_be_none(self):
  7907. return True
  7908. def generate_result_code(self, code):
  7909. bases = self.class_def_node.bases
  7910. mkw = self.class_def_node.mkw
  7911. if mkw:
  7912. code.globalstate.use_utility_code(
  7913. UtilityCode.load_cached("Py3MetaclassGet", "ObjectHandling.c"))
  7914. call = "__Pyx_Py3MetaclassGet(%s, %s)" % (
  7915. bases.result(),
  7916. mkw.result())
  7917. else:
  7918. code.globalstate.use_utility_code(
  7919. UtilityCode.load_cached("CalculateMetaclass", "ObjectHandling.c"))
  7920. call = "__Pyx_CalculateMetaclass(NULL, %s)" % (
  7921. bases.result())
  7922. code.putln(
  7923. "%s = %s; %s" % (
  7924. self.result(), call,
  7925. code.error_goto_if_null(self.result(), self.pos)))
  7926. code.put_gotref(self.py_result())
  7927. class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
  7928. # Helper class holds Python3 namespace object
  7929. #
  7930. # All this are not owned by this node
  7931. # class_def_node PyClassDefNode PyClassDefNode defining this class
  7932. # doc ExprNode or None Doc string (owned)
  7933. subexprs = ['doc']
  7934. def analyse_types(self, env):
  7935. if self.doc:
  7936. self.doc = self.doc.analyse_types(env).coerce_to_pyobject(env)
  7937. self.type = py_object_type
  7938. self.is_temp = 1
  7939. return self
  7940. def may_be_none(self):
  7941. return True
  7942. def generate_result_code(self, code):
  7943. cname = code.intern_identifier(self.name)
  7944. py_mod_name = self.get_py_mod_name(code)
  7945. qualname = self.get_py_qualified_name(code)
  7946. class_def_node = self.class_def_node
  7947. null = "(PyObject *) NULL"
  7948. doc_code = self.doc.result() if self.doc else null
  7949. mkw = class_def_node.mkw.py_result() if class_def_node.mkw else null
  7950. metaclass = class_def_node.metaclass.py_result() if class_def_node.metaclass else null
  7951. code.putln(
  7952. "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s, %s); %s" % (
  7953. self.result(),
  7954. metaclass,
  7955. class_def_node.bases.result(),
  7956. cname,
  7957. qualname,
  7958. mkw,
  7959. py_mod_name,
  7960. doc_code,
  7961. code.error_goto_if_null(self.result(), self.pos)))
  7962. code.put_gotref(self.py_result())
  7963. class ClassCellInjectorNode(ExprNode):
  7964. # Initialize CyFunction.func_classobj
  7965. is_temp = True
  7966. type = py_object_type
  7967. subexprs = []
  7968. is_active = False
  7969. def analyse_expressions(self, env):
  7970. return self
  7971. def generate_result_code(self, code):
  7972. assert self.is_active
  7973. code.putln(
  7974. '%s = PyList_New(0); %s' % (
  7975. self.result(),
  7976. code.error_goto_if_null(self.result(), self.pos)))
  7977. code.put_gotref(self.result())
  7978. def generate_injection_code(self, code, classobj_cname):
  7979. assert self.is_active
  7980. code.globalstate.use_utility_code(
  7981. UtilityCode.load_cached("CyFunctionClassCell", "CythonFunction.c"))
  7982. code.put_error_if_neg(self.pos, '__Pyx_CyFunction_InitClassCell(%s, %s)' % (
  7983. self.result(), classobj_cname))
  7984. class ClassCellNode(ExprNode):
  7985. # Class Cell for noargs super()
  7986. subexprs = []
  7987. is_temp = True
  7988. is_generator = False
  7989. type = py_object_type
  7990. def analyse_types(self, env):
  7991. return self
  7992. def generate_result_code(self, code):
  7993. if not self.is_generator:
  7994. code.putln('%s = __Pyx_CyFunction_GetClassObj(%s);' % (
  7995. self.result(),
  7996. Naming.self_cname))
  7997. else:
  7998. code.putln('%s = %s->classobj;' % (
  7999. self.result(), Naming.generator_cname))
  8000. code.putln(
  8001. 'if (!%s) { PyErr_SetString(PyExc_SystemError, '
  8002. '"super(): empty __class__ cell"); %s }' % (
  8003. self.result(),
  8004. code.error_goto(self.pos)))
  8005. code.put_incref(self.result(), py_object_type)
  8006. class PyCFunctionNode(ExprNode, ModuleNameMixin):
  8007. # Helper class used in the implementation of Python
  8008. # functions. Constructs a PyCFunction object
  8009. # from a PyMethodDef struct.
  8010. #
  8011. # pymethdef_cname string PyMethodDef structure
  8012. # self_object ExprNode or None
  8013. # binding bool
  8014. # def_node DefNode the Python function node
  8015. # module_name EncodedString Name of defining module
  8016. # code_object CodeObjectNode the PyCodeObject creator node
  8017. subexprs = ['code_object', 'defaults_tuple', 'defaults_kwdict',
  8018. 'annotations_dict']
  8019. self_object = None
  8020. code_object = None
  8021. binding = False
  8022. def_node = None
  8023. defaults = None
  8024. defaults_struct = None
  8025. defaults_pyobjects = 0
  8026. defaults_tuple = None
  8027. defaults_kwdict = None
  8028. annotations_dict = None
  8029. type = py_object_type
  8030. is_temp = 1
  8031. specialized_cpdefs = None
  8032. is_specialization = False
  8033. @classmethod
  8034. def from_defnode(cls, node, binding):
  8035. return cls(node.pos,
  8036. def_node=node,
  8037. pymethdef_cname=node.entry.pymethdef_cname,
  8038. binding=binding or node.specialized_cpdefs,
  8039. specialized_cpdefs=node.specialized_cpdefs,
  8040. code_object=CodeObjectNode(node))
  8041. def analyse_types(self, env):
  8042. if self.binding:
  8043. self.analyse_default_args(env)
  8044. return self
  8045. def analyse_default_args(self, env):
  8046. """
  8047. Handle non-literal function's default arguments.
  8048. """
  8049. nonliteral_objects = []
  8050. nonliteral_other = []
  8051. default_args = []
  8052. default_kwargs = []
  8053. annotations = []
  8054. # For global cpdef functions and def/cpdef methods in cdef classes, we must use global constants
  8055. # for default arguments to avoid the dependency on the CyFunction object as 'self' argument
  8056. # in the underlying C function. Basically, cpdef functions/methods are static C functions,
  8057. # so their optional arguments must be static, too.
  8058. # TODO: change CyFunction implementation to pass both function object and owning object for method calls
  8059. must_use_constants = env.is_c_class_scope or (self.def_node.is_wrapper and env.is_module_scope)
  8060. for arg in self.def_node.args:
  8061. if arg.default and not must_use_constants:
  8062. if not arg.default.is_literal:
  8063. arg.is_dynamic = True
  8064. if arg.type.is_pyobject:
  8065. nonliteral_objects.append(arg)
  8066. else:
  8067. nonliteral_other.append(arg)
  8068. else:
  8069. arg.default = DefaultLiteralArgNode(arg.pos, arg.default)
  8070. if arg.kw_only:
  8071. default_kwargs.append(arg)
  8072. else:
  8073. default_args.append(arg)
  8074. if arg.annotation:
  8075. arg.annotation = self.analyse_annotation(env, arg.annotation)
  8076. annotations.append((arg.pos, arg.name, arg.annotation))
  8077. for arg in (self.def_node.star_arg, self.def_node.starstar_arg):
  8078. if arg and arg.annotation:
  8079. arg.annotation = self.analyse_annotation(env, arg.annotation)
  8080. annotations.append((arg.pos, arg.name, arg.annotation))
  8081. annotation = self.def_node.return_type_annotation
  8082. if annotation:
  8083. annotation = self.analyse_annotation(env, annotation)
  8084. self.def_node.return_type_annotation = annotation
  8085. annotations.append((annotation.pos, StringEncoding.EncodedString("return"), annotation))
  8086. if nonliteral_objects or nonliteral_other:
  8087. module_scope = env.global_scope()
  8088. cname = module_scope.next_id(Naming.defaults_struct_prefix)
  8089. scope = Symtab.StructOrUnionScope(cname)
  8090. self.defaults = []
  8091. for arg in nonliteral_objects:
  8092. entry = scope.declare_var(arg.name, arg.type, None,
  8093. Naming.arg_prefix + arg.name,
  8094. allow_pyobject=True)
  8095. self.defaults.append((arg, entry))
  8096. for arg in nonliteral_other:
  8097. entry = scope.declare_var(arg.name, arg.type, None,
  8098. Naming.arg_prefix + arg.name,
  8099. allow_pyobject=False, allow_memoryview=True)
  8100. self.defaults.append((arg, entry))
  8101. entry = module_scope.declare_struct_or_union(
  8102. None, 'struct', scope, 1, None, cname=cname)
  8103. self.defaults_struct = scope
  8104. self.defaults_pyobjects = len(nonliteral_objects)
  8105. for arg, entry in self.defaults:
  8106. arg.default_value = '%s->%s' % (
  8107. Naming.dynamic_args_cname, entry.cname)
  8108. self.def_node.defaults_struct = self.defaults_struct.name
  8109. if default_args or default_kwargs:
  8110. if self.defaults_struct is None:
  8111. if default_args:
  8112. defaults_tuple = TupleNode(self.pos, args=[
  8113. arg.default for arg in default_args])
  8114. self.defaults_tuple = defaults_tuple.analyse_types(env).coerce_to_pyobject(env)
  8115. if default_kwargs:
  8116. defaults_kwdict = DictNode(self.pos, key_value_pairs=[
  8117. DictItemNode(
  8118. arg.pos,
  8119. key=IdentifierStringNode(arg.pos, value=arg.name),
  8120. value=arg.default)
  8121. for arg in default_kwargs])
  8122. self.defaults_kwdict = defaults_kwdict.analyse_types(env)
  8123. else:
  8124. if default_args:
  8125. defaults_tuple = DefaultsTupleNode(
  8126. self.pos, default_args, self.defaults_struct)
  8127. else:
  8128. defaults_tuple = NoneNode(self.pos)
  8129. if default_kwargs:
  8130. defaults_kwdict = DefaultsKwDictNode(
  8131. self.pos, default_kwargs, self.defaults_struct)
  8132. else:
  8133. defaults_kwdict = NoneNode(self.pos)
  8134. defaults_getter = Nodes.DefNode(
  8135. self.pos, args=[], star_arg=None, starstar_arg=None,
  8136. body=Nodes.ReturnStatNode(
  8137. self.pos, return_type=py_object_type,
  8138. value=TupleNode(
  8139. self.pos, args=[defaults_tuple, defaults_kwdict])),
  8140. decorators=None,
  8141. name=StringEncoding.EncodedString("__defaults__"))
  8142. # defaults getter must never live in class scopes, it's always a module function
  8143. module_scope = env.global_scope()
  8144. defaults_getter.analyse_declarations(module_scope)
  8145. defaults_getter = defaults_getter.analyse_expressions(module_scope)
  8146. defaults_getter.body = defaults_getter.body.analyse_expressions(
  8147. defaults_getter.local_scope)
  8148. defaults_getter.py_wrapper_required = False
  8149. defaults_getter.pymethdef_required = False
  8150. self.def_node.defaults_getter = defaults_getter
  8151. if annotations:
  8152. annotations_dict = DictNode(self.pos, key_value_pairs=[
  8153. DictItemNode(
  8154. pos, key=IdentifierStringNode(pos, value=name),
  8155. value=value)
  8156. for pos, name, value in annotations])
  8157. self.annotations_dict = annotations_dict.analyse_types(env)
  8158. def analyse_annotation(self, env, annotation):
  8159. if annotation is None:
  8160. return None
  8161. atype = annotation.analyse_as_type(env)
  8162. if atype is not None:
  8163. # Keep parsed types as strings as they might not be Python representable.
  8164. annotation = UnicodeNode(
  8165. annotation.pos,
  8166. value=StringEncoding.EncodedString(atype.declaration_code('', for_display=True)))
  8167. annotation = annotation.analyse_types(env)
  8168. if not annotation.type.is_pyobject:
  8169. annotation = annotation.coerce_to_pyobject(env)
  8170. return annotation
  8171. def may_be_none(self):
  8172. return False
  8173. gil_message = "Constructing Python function"
  8174. def self_result_code(self):
  8175. if self.self_object is None:
  8176. self_result = "NULL"
  8177. else:
  8178. self_result = self.self_object.py_result()
  8179. return self_result
  8180. def generate_result_code(self, code):
  8181. if self.binding:
  8182. self.generate_cyfunction_code(code)
  8183. else:
  8184. self.generate_pycfunction_code(code)
  8185. def generate_pycfunction_code(self, code):
  8186. py_mod_name = self.get_py_mod_name(code)
  8187. code.putln(
  8188. '%s = PyCFunction_NewEx(&%s, %s, %s); %s' % (
  8189. self.result(),
  8190. self.pymethdef_cname,
  8191. self.self_result_code(),
  8192. py_mod_name,
  8193. code.error_goto_if_null(self.result(), self.pos)))
  8194. code.put_gotref(self.py_result())
  8195. def generate_cyfunction_code(self, code):
  8196. if self.specialized_cpdefs:
  8197. def_node = self.specialized_cpdefs[0]
  8198. else:
  8199. def_node = self.def_node
  8200. if self.specialized_cpdefs or self.is_specialization:
  8201. code.globalstate.use_utility_code(
  8202. UtilityCode.load_cached("FusedFunction", "CythonFunction.c"))
  8203. constructor = "__pyx_FusedFunction_New"
  8204. else:
  8205. code.globalstate.use_utility_code(
  8206. UtilityCode.load_cached("CythonFunction", "CythonFunction.c"))
  8207. constructor = "__Pyx_CyFunction_New"
  8208. if self.code_object:
  8209. code_object_result = self.code_object.py_result()
  8210. else:
  8211. code_object_result = 'NULL'
  8212. flags = []
  8213. if def_node.is_staticmethod:
  8214. flags.append('__Pyx_CYFUNCTION_STATICMETHOD')
  8215. elif def_node.is_classmethod:
  8216. flags.append('__Pyx_CYFUNCTION_CLASSMETHOD')
  8217. if def_node.local_scope.parent_scope.is_c_class_scope and not def_node.entry.is_anonymous:
  8218. flags.append('__Pyx_CYFUNCTION_CCLASS')
  8219. if flags:
  8220. flags = ' | '.join(flags)
  8221. else:
  8222. flags = '0'
  8223. code.putln(
  8224. '%s = %s(&%s, %s, %s, %s, %s, %s, %s); %s' % (
  8225. self.result(),
  8226. constructor,
  8227. self.pymethdef_cname,
  8228. flags,
  8229. self.get_py_qualified_name(code),
  8230. self.self_result_code(),
  8231. self.get_py_mod_name(code),
  8232. Naming.moddict_cname,
  8233. code_object_result,
  8234. code.error_goto_if_null(self.result(), self.pos)))
  8235. code.put_gotref(self.py_result())
  8236. if def_node.requires_classobj:
  8237. assert code.pyclass_stack, "pyclass_stack is empty"
  8238. class_node = code.pyclass_stack[-1]
  8239. code.put_incref(self.py_result(), py_object_type)
  8240. code.putln(
  8241. 'PyList_Append(%s, %s);' % (
  8242. class_node.class_cell.result(),
  8243. self.result()))
  8244. code.put_giveref(self.py_result())
  8245. if self.defaults:
  8246. code.putln(
  8247. 'if (!__Pyx_CyFunction_InitDefaults(%s, sizeof(%s), %d)) %s' % (
  8248. self.result(), self.defaults_struct.name,
  8249. self.defaults_pyobjects, code.error_goto(self.pos)))
  8250. defaults = '__Pyx_CyFunction_Defaults(%s, %s)' % (
  8251. self.defaults_struct.name, self.result())
  8252. for arg, entry in self.defaults:
  8253. arg.generate_assignment_code(code, target='%s->%s' % (
  8254. defaults, entry.cname))
  8255. if self.defaults_tuple:
  8256. code.putln('__Pyx_CyFunction_SetDefaultsTuple(%s, %s);' % (
  8257. self.result(), self.defaults_tuple.py_result()))
  8258. if self.defaults_kwdict:
  8259. code.putln('__Pyx_CyFunction_SetDefaultsKwDict(%s, %s);' % (
  8260. self.result(), self.defaults_kwdict.py_result()))
  8261. if def_node.defaults_getter and not self.specialized_cpdefs:
  8262. # Fused functions do not support dynamic defaults, only their specialisations can have them for now.
  8263. code.putln('__Pyx_CyFunction_SetDefaultsGetter(%s, %s);' % (
  8264. self.result(), def_node.defaults_getter.entry.pyfunc_cname))
  8265. if self.annotations_dict:
  8266. code.putln('__Pyx_CyFunction_SetAnnotationsDict(%s, %s);' % (
  8267. self.result(), self.annotations_dict.py_result()))
  8268. class InnerFunctionNode(PyCFunctionNode):
  8269. # Special PyCFunctionNode that depends on a closure class
  8270. #
  8271. binding = True
  8272. needs_self_code = True
  8273. def self_result_code(self):
  8274. if self.needs_self_code:
  8275. return "((PyObject*)%s)" % Naming.cur_scope_cname
  8276. return "NULL"
  8277. class CodeObjectNode(ExprNode):
  8278. # Create a PyCodeObject for a CyFunction instance.
  8279. #
  8280. # def_node DefNode the Python function node
  8281. # varnames TupleNode a tuple with all local variable names
  8282. subexprs = ['varnames']
  8283. is_temp = False
  8284. result_code = None
  8285. def __init__(self, def_node):
  8286. ExprNode.__init__(self, def_node.pos, def_node=def_node)
  8287. args = list(def_node.args)
  8288. # if we have args/kwargs, then the first two in var_entries are those
  8289. local_vars = [arg for arg in def_node.local_scope.var_entries if arg.name]
  8290. self.varnames = TupleNode(
  8291. def_node.pos,
  8292. args=[IdentifierStringNode(arg.pos, value=arg.name)
  8293. for arg in args + local_vars],
  8294. is_temp=0,
  8295. is_literal=1)
  8296. def may_be_none(self):
  8297. return False
  8298. def calculate_result_code(self, code=None):
  8299. if self.result_code is None:
  8300. self.result_code = code.get_py_const(py_object_type, 'codeobj', cleanup_level=2)
  8301. return self.result_code
  8302. def generate_result_code(self, code):
  8303. if self.result_code is None:
  8304. self.result_code = code.get_py_const(py_object_type, 'codeobj', cleanup_level=2)
  8305. code = code.get_cached_constants_writer(self.result_code)
  8306. if code is None:
  8307. return # already initialised
  8308. code.mark_pos(self.pos)
  8309. func = self.def_node
  8310. func_name = code.get_py_string_const(
  8311. func.name, identifier=True, is_str=False, unicode_value=func.name)
  8312. # FIXME: better way to get the module file path at module init time? Encoding to use?
  8313. file_path = StringEncoding.bytes_literal(func.pos[0].get_filenametable_entry().encode('utf8'), 'utf8')
  8314. # XXX Use get_description() to set arcadia root relative filename
  8315. file_path = StringEncoding.bytes_literal(func.pos[0].get_description().encode('utf8'), 'utf8')
  8316. file_path_const = code.get_py_string_const(file_path, identifier=False, is_str=True)
  8317. # This combination makes CPython create a new dict for "frame.f_locals" (see GH #1836).
  8318. flags = ['CO_OPTIMIZED', 'CO_NEWLOCALS']
  8319. if self.def_node.star_arg:
  8320. flags.append('CO_VARARGS')
  8321. if self.def_node.starstar_arg:
  8322. flags.append('CO_VARKEYWORDS')
  8323. code.putln("%s = (PyObject*)__Pyx_PyCode_New(%d, %d, %d, 0, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d, %s); %s" % (
  8324. self.result_code,
  8325. len(func.args) - func.num_kwonly_args, # argcount
  8326. func.num_kwonly_args, # kwonlyargcount (Py3 only)
  8327. len(self.varnames.args), # nlocals
  8328. '|'.join(flags) or '0', # flags
  8329. Naming.empty_bytes, # code
  8330. Naming.empty_tuple, # consts
  8331. Naming.empty_tuple, # names (FIXME)
  8332. self.varnames.result(), # varnames
  8333. Naming.empty_tuple, # freevars (FIXME)
  8334. Naming.empty_tuple, # cellvars (FIXME)
  8335. file_path_const, # filename
  8336. func_name, # name
  8337. self.pos[1], # firstlineno
  8338. Naming.empty_bytes, # lnotab
  8339. code.error_goto_if_null(self.result_code, self.pos),
  8340. ))
  8341. class DefaultLiteralArgNode(ExprNode):
  8342. # CyFunction's literal argument default value
  8343. #
  8344. # Evaluate literal only once.
  8345. subexprs = []
  8346. is_literal = True
  8347. is_temp = False
  8348. def __init__(self, pos, arg):
  8349. super(DefaultLiteralArgNode, self).__init__(pos)
  8350. self.arg = arg
  8351. self.type = self.arg.type
  8352. self.evaluated = False
  8353. def analyse_types(self, env):
  8354. return self
  8355. def generate_result_code(self, code):
  8356. pass
  8357. def generate_evaluation_code(self, code):
  8358. if not self.evaluated:
  8359. self.arg.generate_evaluation_code(code)
  8360. self.evaluated = True
  8361. def result(self):
  8362. return self.type.cast_code(self.arg.result())
  8363. class DefaultNonLiteralArgNode(ExprNode):
  8364. # CyFunction's non-literal argument default value
  8365. subexprs = []
  8366. def __init__(self, pos, arg, defaults_struct):
  8367. super(DefaultNonLiteralArgNode, self).__init__(pos)
  8368. self.arg = arg
  8369. self.defaults_struct = defaults_struct
  8370. def analyse_types(self, env):
  8371. self.type = self.arg.type
  8372. self.is_temp = False
  8373. return self
  8374. def generate_result_code(self, code):
  8375. pass
  8376. def result(self):
  8377. return '__Pyx_CyFunction_Defaults(%s, %s)->%s' % (
  8378. self.defaults_struct.name, Naming.self_cname,
  8379. self.defaults_struct.lookup(self.arg.name).cname)
  8380. class DefaultsTupleNode(TupleNode):
  8381. # CyFunction's __defaults__ tuple
  8382. def __init__(self, pos, defaults, defaults_struct):
  8383. args = []
  8384. for arg in defaults:
  8385. if not arg.default.is_literal:
  8386. arg = DefaultNonLiteralArgNode(pos, arg, defaults_struct)
  8387. else:
  8388. arg = arg.default
  8389. args.append(arg)
  8390. super(DefaultsTupleNode, self).__init__(pos, args=args)
  8391. def analyse_types(self, env, skip_children=False):
  8392. return super(DefaultsTupleNode, self).analyse_types(env, skip_children).coerce_to_pyobject(env)
  8393. class DefaultsKwDictNode(DictNode):
  8394. # CyFunction's __kwdefaults__ dict
  8395. def __init__(self, pos, defaults, defaults_struct):
  8396. items = []
  8397. for arg in defaults:
  8398. name = IdentifierStringNode(arg.pos, value=arg.name)
  8399. if not arg.default.is_literal:
  8400. arg = DefaultNonLiteralArgNode(pos, arg, defaults_struct)
  8401. else:
  8402. arg = arg.default
  8403. items.append(DictItemNode(arg.pos, key=name, value=arg))
  8404. super(DefaultsKwDictNode, self).__init__(pos, key_value_pairs=items)
  8405. class LambdaNode(InnerFunctionNode):
  8406. # Lambda expression node (only used as a function reference)
  8407. #
  8408. # args [CArgDeclNode] formal arguments
  8409. # star_arg PyArgDeclNode or None * argument
  8410. # starstar_arg PyArgDeclNode or None ** argument
  8411. # lambda_name string a module-globally unique lambda name
  8412. # result_expr ExprNode
  8413. # def_node DefNode the underlying function 'def' node
  8414. child_attrs = ['def_node']
  8415. name = StringEncoding.EncodedString('<lambda>')
  8416. def analyse_declarations(self, env):
  8417. self.lambda_name = self.def_node.lambda_name = env.next_id('lambda')
  8418. self.def_node.no_assignment_synthesis = True
  8419. self.def_node.pymethdef_required = True
  8420. self.def_node.analyse_declarations(env)
  8421. self.def_node.is_cyfunction = True
  8422. self.pymethdef_cname = self.def_node.entry.pymethdef_cname
  8423. env.add_lambda_def(self.def_node)
  8424. def analyse_types(self, env):
  8425. self.def_node = self.def_node.analyse_expressions(env)
  8426. return super(LambdaNode, self).analyse_types(env)
  8427. def generate_result_code(self, code):
  8428. self.def_node.generate_execution_code(code)
  8429. super(LambdaNode, self).generate_result_code(code)
  8430. class GeneratorExpressionNode(LambdaNode):
  8431. # A generator expression, e.g. (i for i in range(10))
  8432. #
  8433. # Result is a generator.
  8434. #
  8435. # loop ForStatNode the for-loop, containing a YieldExprNode
  8436. # def_node DefNode the underlying generator 'def' node
  8437. name = StringEncoding.EncodedString('genexpr')
  8438. binding = False
  8439. def analyse_declarations(self, env):
  8440. self.genexpr_name = env.next_id('genexpr')
  8441. super(GeneratorExpressionNode, self).analyse_declarations(env)
  8442. # No pymethdef required
  8443. self.def_node.pymethdef_required = False
  8444. self.def_node.py_wrapper_required = False
  8445. self.def_node.is_cyfunction = False
  8446. # Force genexpr signature
  8447. self.def_node.entry.signature = TypeSlots.pyfunction_noargs
  8448. def generate_result_code(self, code):
  8449. code.putln(
  8450. '%s = %s(%s); %s' % (
  8451. self.result(),
  8452. self.def_node.entry.pyfunc_cname,
  8453. self.self_result_code(),
  8454. code.error_goto_if_null(self.result(), self.pos)))
  8455. code.put_gotref(self.py_result())
  8456. class YieldExprNode(ExprNode):
  8457. # Yield expression node
  8458. #
  8459. # arg ExprNode the value to return from the generator
  8460. # label_num integer yield label number
  8461. # is_yield_from boolean is a YieldFromExprNode to delegate to another generator
  8462. subexprs = ['arg']
  8463. type = py_object_type
  8464. label_num = 0
  8465. is_yield_from = False
  8466. is_await = False
  8467. in_async_gen = False
  8468. expr_keyword = 'yield'
  8469. def analyse_types(self, env):
  8470. if not self.label_num or (self.is_yield_from and self.in_async_gen):
  8471. error(self.pos, "'%s' not supported here" % self.expr_keyword)
  8472. self.is_temp = 1
  8473. if self.arg is not None:
  8474. self.arg = self.arg.analyse_types(env)
  8475. if not self.arg.type.is_pyobject:
  8476. self.coerce_yield_argument(env)
  8477. return self
  8478. def coerce_yield_argument(self, env):
  8479. self.arg = self.arg.coerce_to_pyobject(env)
  8480. def generate_evaluation_code(self, code):
  8481. if self.arg:
  8482. self.arg.generate_evaluation_code(code)
  8483. self.arg.make_owned_reference(code)
  8484. code.putln(
  8485. "%s = %s;" % (
  8486. Naming.retval_cname,
  8487. self.arg.result_as(py_object_type)))
  8488. self.arg.generate_post_assignment_code(code)
  8489. self.arg.free_temps(code)
  8490. else:
  8491. code.put_init_to_py_none(Naming.retval_cname, py_object_type)
  8492. self.generate_yield_code(code)
  8493. def generate_yield_code(self, code):
  8494. """
  8495. Generate the code to return the argument in 'Naming.retval_cname'
  8496. and to continue at the yield label.
  8497. """
  8498. label_num, label_name = code.new_yield_label(
  8499. self.expr_keyword.replace(' ', '_'))
  8500. code.use_label(label_name)
  8501. saved = []
  8502. code.funcstate.closure_temps.reset()
  8503. for cname, type, manage_ref in code.funcstate.temps_in_use():
  8504. save_cname = code.funcstate.closure_temps.allocate_temp(type)
  8505. saved.append((cname, save_cname, type))
  8506. if type.is_pyobject:
  8507. code.put_xgiveref(cname)
  8508. code.putln('%s->%s = %s;' % (Naming.cur_scope_cname, save_cname, cname))
  8509. code.put_xgiveref(Naming.retval_cname)
  8510. profile = code.globalstate.directives['profile']
  8511. linetrace = code.globalstate.directives['linetrace']
  8512. if profile or linetrace:
  8513. code.put_trace_return(Naming.retval_cname,
  8514. nogil=not code.funcstate.gil_owned)
  8515. code.put_finish_refcount_context()
  8516. if code.funcstate.current_except is not None:
  8517. # inside of an except block => save away currently handled exception
  8518. code.putln("__Pyx_Coroutine_SwapException(%s);" % Naming.generator_cname)
  8519. else:
  8520. # no exceptions being handled => restore exception state of caller
  8521. code.putln("__Pyx_Coroutine_ResetAndClearException(%s);" % Naming.generator_cname)
  8522. code.putln("/* return from %sgenerator, %sing value */" % (
  8523. 'async ' if self.in_async_gen else '',
  8524. 'await' if self.is_await else 'yield'))
  8525. code.putln("%s->resume_label = %d;" % (
  8526. Naming.generator_cname, label_num))
  8527. if self.in_async_gen and not self.is_await:
  8528. # __Pyx__PyAsyncGenValueWrapperNew() steals a reference to the return value
  8529. code.putln("return __Pyx__PyAsyncGenValueWrapperNew(%s);" % Naming.retval_cname)
  8530. else:
  8531. code.putln("return %s;" % Naming.retval_cname)
  8532. code.put_label(label_name)
  8533. for cname, save_cname, type in saved:
  8534. code.putln('%s = %s->%s;' % (cname, Naming.cur_scope_cname, save_cname))
  8535. if type.is_pyobject:
  8536. code.putln('%s->%s = 0;' % (Naming.cur_scope_cname, save_cname))
  8537. code.put_xgotref(cname)
  8538. self.generate_sent_value_handling_code(code, Naming.sent_value_cname)
  8539. if self.result_is_used:
  8540. self.allocate_temp_result(code)
  8541. code.put('%s = %s; ' % (self.result(), Naming.sent_value_cname))
  8542. code.put_incref(self.result(), py_object_type)
  8543. def generate_sent_value_handling_code(self, code, value_cname):
  8544. code.putln(code.error_goto_if_null(value_cname, self.pos))
  8545. class _YieldDelegationExprNode(YieldExprNode):
  8546. def yield_from_func(self, code):
  8547. raise NotImplementedError()
  8548. def generate_evaluation_code(self, code, source_cname=None, decref_source=False):
  8549. if source_cname is None:
  8550. self.arg.generate_evaluation_code(code)
  8551. code.putln("%s = %s(%s, %s);" % (
  8552. Naming.retval_cname,
  8553. self.yield_from_func(code),
  8554. Naming.generator_cname,
  8555. self.arg.py_result() if source_cname is None else source_cname))
  8556. if source_cname is None:
  8557. self.arg.generate_disposal_code(code)
  8558. self.arg.free_temps(code)
  8559. elif decref_source:
  8560. code.put_decref_clear(source_cname, py_object_type)
  8561. code.put_xgotref(Naming.retval_cname)
  8562. code.putln("if (likely(%s)) {" % Naming.retval_cname)
  8563. self.generate_yield_code(code)
  8564. code.putln("} else {")
  8565. # either error or sub-generator has normally terminated: return value => node result
  8566. if self.result_is_used:
  8567. self.fetch_iteration_result(code)
  8568. else:
  8569. self.handle_iteration_exception(code)
  8570. code.putln("}")
  8571. def fetch_iteration_result(self, code):
  8572. # YieldExprNode has allocated the result temp for us
  8573. code.putln("%s = NULL;" % self.result())
  8574. code.put_error_if_neg(self.pos, "__Pyx_PyGen_FetchStopIterationValue(&%s)" % self.result())
  8575. code.put_gotref(self.result())
  8576. def handle_iteration_exception(self, code):
  8577. code.putln("PyObject* exc_type = __Pyx_PyErr_Occurred();")
  8578. code.putln("if (exc_type) {")
  8579. code.putln("if (likely(exc_type == PyExc_StopIteration || (exc_type != PyExc_GeneratorExit &&"
  8580. " __Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)))) PyErr_Clear();")
  8581. code.putln("else %s" % code.error_goto(self.pos))
  8582. code.putln("}")
  8583. class YieldFromExprNode(_YieldDelegationExprNode):
  8584. # "yield from GEN" expression
  8585. is_yield_from = True
  8586. expr_keyword = 'yield from'
  8587. def coerce_yield_argument(self, env):
  8588. if not self.arg.type.is_string:
  8589. # FIXME: support C arrays and C++ iterators?
  8590. error(self.pos, "yielding from non-Python object not supported")
  8591. self.arg = self.arg.coerce_to_pyobject(env)
  8592. def yield_from_func(self, code):
  8593. code.globalstate.use_utility_code(UtilityCode.load_cached("GeneratorYieldFrom", "Coroutine.c"))
  8594. return "__Pyx_Generator_Yield_From"
  8595. class AwaitExprNode(_YieldDelegationExprNode):
  8596. # 'await' expression node
  8597. #
  8598. # arg ExprNode the Awaitable value to await
  8599. # label_num integer yield label number
  8600. is_await = True
  8601. expr_keyword = 'await'
  8602. def coerce_yield_argument(self, env):
  8603. if self.arg is not None:
  8604. # FIXME: use same check as in YieldFromExprNode.coerce_yield_argument() ?
  8605. self.arg = self.arg.coerce_to_pyobject(env)
  8606. def yield_from_func(self, code):
  8607. code.globalstate.use_utility_code(UtilityCode.load_cached("CoroutineYieldFrom", "Coroutine.c"))
  8608. return "__Pyx_Coroutine_Yield_From"
  8609. class AwaitIterNextExprNode(AwaitExprNode):
  8610. # 'await' expression node as part of 'async for' iteration
  8611. #
  8612. # Breaks out of loop on StopAsyncIteration exception.
  8613. def _generate_break(self, code):
  8614. code.globalstate.use_utility_code(UtilityCode.load_cached("StopAsyncIteration", "Coroutine.c"))
  8615. code.putln("PyObject* exc_type = __Pyx_PyErr_Occurred();")
  8616. code.putln("if (unlikely(exc_type && (exc_type == __Pyx_PyExc_StopAsyncIteration || ("
  8617. " exc_type != PyExc_StopIteration && exc_type != PyExc_GeneratorExit &&"
  8618. " __Pyx_PyErr_GivenExceptionMatches(exc_type, __Pyx_PyExc_StopAsyncIteration))))) {")
  8619. code.putln("PyErr_Clear();")
  8620. code.putln("break;")
  8621. code.putln("}")
  8622. def fetch_iteration_result(self, code):
  8623. assert code.break_label, "AwaitIterNextExprNode outside of 'async for' loop"
  8624. self._generate_break(code)
  8625. super(AwaitIterNextExprNode, self).fetch_iteration_result(code)
  8626. def generate_sent_value_handling_code(self, code, value_cname):
  8627. assert code.break_label, "AwaitIterNextExprNode outside of 'async for' loop"
  8628. code.putln("if (unlikely(!%s)) {" % value_cname)
  8629. self._generate_break(code)
  8630. # all non-break exceptions are errors, as in parent class
  8631. code.putln(code.error_goto(self.pos))
  8632. code.putln("}")
  8633. class GlobalsExprNode(AtomicExprNode):
  8634. type = dict_type
  8635. is_temp = 1
  8636. def analyse_types(self, env):
  8637. env.use_utility_code(Builtin.globals_utility_code)
  8638. return self
  8639. gil_message = "Constructing globals dict"
  8640. def may_be_none(self):
  8641. return False
  8642. def generate_result_code(self, code):
  8643. code.putln('%s = __Pyx_Globals(); %s' % (
  8644. self.result(),
  8645. code.error_goto_if_null(self.result(), self.pos)))
  8646. code.put_gotref(self.result())
  8647. class LocalsDictItemNode(DictItemNode):
  8648. def analyse_types(self, env):
  8649. self.key = self.key.analyse_types(env)
  8650. self.value = self.value.analyse_types(env)
  8651. self.key = self.key.coerce_to_pyobject(env)
  8652. if self.value.type.can_coerce_to_pyobject(env):
  8653. self.value = self.value.coerce_to_pyobject(env)
  8654. else:
  8655. self.value = None
  8656. return self
  8657. class FuncLocalsExprNode(DictNode):
  8658. def __init__(self, pos, env):
  8659. local_vars = sorted([
  8660. entry.name for entry in env.entries.values() if entry.name])
  8661. items = [LocalsDictItemNode(
  8662. pos, key=IdentifierStringNode(pos, value=var),
  8663. value=NameNode(pos, name=var, allow_null=True))
  8664. for var in local_vars]
  8665. DictNode.__init__(self, pos, key_value_pairs=items,
  8666. exclude_null_values=True)
  8667. def analyse_types(self, env):
  8668. node = super(FuncLocalsExprNode, self).analyse_types(env)
  8669. node.key_value_pairs = [ i for i in node.key_value_pairs
  8670. if i.value is not None ]
  8671. return node
  8672. class PyClassLocalsExprNode(AtomicExprNode):
  8673. def __init__(self, pos, pyclass_dict):
  8674. AtomicExprNode.__init__(self, pos)
  8675. self.pyclass_dict = pyclass_dict
  8676. def analyse_types(self, env):
  8677. self.type = self.pyclass_dict.type
  8678. self.is_temp = False
  8679. return self
  8680. def may_be_none(self):
  8681. return False
  8682. def result(self):
  8683. return self.pyclass_dict.result()
  8684. def generate_result_code(self, code):
  8685. pass
  8686. def LocalsExprNode(pos, scope_node, env):
  8687. if env.is_module_scope:
  8688. return GlobalsExprNode(pos)
  8689. if env.is_py_class_scope:
  8690. return PyClassLocalsExprNode(pos, scope_node.dict)
  8691. return FuncLocalsExprNode(pos, env)
  8692. #-------------------------------------------------------------------
  8693. #
  8694. # Unary operator nodes
  8695. #
  8696. #-------------------------------------------------------------------
  8697. compile_time_unary_operators = {
  8698. 'not': operator.not_,
  8699. '~': operator.inv,
  8700. '-': operator.neg,
  8701. '+': operator.pos,
  8702. }
  8703. class UnopNode(ExprNode):
  8704. # operator string
  8705. # operand ExprNode
  8706. #
  8707. # Processing during analyse_expressions phase:
  8708. #
  8709. # analyse_c_operation
  8710. # Called when the operand is not a pyobject.
  8711. # - Check operand type and coerce if needed.
  8712. # - Determine result type and result code fragment.
  8713. # - Allocate temporary for result if needed.
  8714. subexprs = ['operand']
  8715. infix = True
  8716. def calculate_constant_result(self):
  8717. func = compile_time_unary_operators[self.operator]
  8718. self.constant_result = func(self.operand.constant_result)
  8719. def compile_time_value(self, denv):
  8720. func = compile_time_unary_operators.get(self.operator)
  8721. if not func:
  8722. error(self.pos,
  8723. "Unary '%s' not supported in compile-time expression"
  8724. % self.operator)
  8725. operand = self.operand.compile_time_value(denv)
  8726. try:
  8727. return func(operand)
  8728. except Exception as e:
  8729. self.compile_time_value_error(e)
  8730. def infer_type(self, env):
  8731. operand_type = self.operand.infer_type(env)
  8732. if operand_type.is_cpp_class or operand_type.is_ptr:
  8733. cpp_type = operand_type.find_cpp_operation_type(self.operator)
  8734. if cpp_type is not None:
  8735. return cpp_type
  8736. return self.infer_unop_type(env, operand_type)
  8737. def infer_unop_type(self, env, operand_type):
  8738. if operand_type.is_pyobject:
  8739. return py_object_type
  8740. else:
  8741. return operand_type
  8742. def may_be_none(self):
  8743. if self.operand.type and self.operand.type.is_builtin_type:
  8744. if self.operand.type is not type_type:
  8745. return False
  8746. return ExprNode.may_be_none(self)
  8747. def analyse_types(self, env):
  8748. self.operand = self.operand.analyse_types(env)
  8749. if self.is_pythran_operation(env):
  8750. self.type = PythranExpr(pythran_unaryop_type(self.operator, self.operand.type))
  8751. self.is_temp = 1
  8752. elif self.is_py_operation():
  8753. self.coerce_operand_to_pyobject(env)
  8754. self.type = py_object_type
  8755. self.is_temp = 1
  8756. elif self.is_cpp_operation():
  8757. self.analyse_cpp_operation(env)
  8758. else:
  8759. self.analyse_c_operation(env)
  8760. return self
  8761. def check_const(self):
  8762. return self.operand.check_const()
  8763. def is_py_operation(self):
  8764. return self.operand.type.is_pyobject or self.operand.type.is_ctuple
  8765. def is_pythran_operation(self, env):
  8766. np_pythran = has_np_pythran(env)
  8767. op_type = self.operand.type
  8768. return np_pythran and (op_type.is_buffer or op_type.is_pythran_expr)
  8769. def nogil_check(self, env):
  8770. if self.is_py_operation():
  8771. self.gil_error()
  8772. def is_cpp_operation(self):
  8773. type = self.operand.type
  8774. return type.is_cpp_class
  8775. def coerce_operand_to_pyobject(self, env):
  8776. self.operand = self.operand.coerce_to_pyobject(env)
  8777. def generate_result_code(self, code):
  8778. if self.type.is_pythran_expr:
  8779. code.putln("// Pythran unaryop")
  8780. code.putln("__Pyx_call_destructor(%s);" % self.result())
  8781. code.putln("new (&%s) decltype(%s){%s%s};" % (
  8782. self.result(),
  8783. self.result(),
  8784. self.operator,
  8785. self.operand.pythran_result()))
  8786. elif self.operand.type.is_pyobject:
  8787. self.generate_py_operation_code(code)
  8788. elif self.is_temp:
  8789. if self.is_cpp_operation() and self.exception_check == '+':
  8790. translate_cpp_exception(code, self.pos,
  8791. "%s = %s %s;" % (self.result(), self.operator, self.operand.result()),
  8792. self.result() if self.type.is_pyobject else None,
  8793. self.exception_value, self.in_nogil_context)
  8794. else:
  8795. code.putln("%s = %s %s;" % (self.result(), self.operator, self.operand.result()))
  8796. def generate_py_operation_code(self, code):
  8797. function = self.py_operation_function(code)
  8798. code.putln(
  8799. "%s = %s(%s); %s" % (
  8800. self.result(),
  8801. function,
  8802. self.operand.py_result(),
  8803. code.error_goto_if_null(self.result(), self.pos)))
  8804. code.put_gotref(self.py_result())
  8805. def type_error(self):
  8806. if not self.operand.type.is_error:
  8807. error(self.pos, "Invalid operand type for '%s' (%s)" %
  8808. (self.operator, self.operand.type))
  8809. self.type = PyrexTypes.error_type
  8810. def analyse_cpp_operation(self, env, overload_check=True):
  8811. entry = env.lookup_operator(self.operator, [self.operand])
  8812. if overload_check and not entry:
  8813. self.type_error()
  8814. return
  8815. if entry:
  8816. self.exception_check = entry.type.exception_check
  8817. self.exception_value = entry.type.exception_value
  8818. if self.exception_check == '+':
  8819. self.is_temp = True
  8820. if self.exception_value is None:
  8821. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  8822. else:
  8823. self.exception_check = ''
  8824. self.exception_value = ''
  8825. cpp_type = self.operand.type.find_cpp_operation_type(self.operator)
  8826. if overload_check and cpp_type is None:
  8827. error(self.pos, "'%s' operator not defined for %s" % (
  8828. self.operator, type))
  8829. self.type_error()
  8830. return
  8831. self.type = cpp_type
  8832. class NotNode(UnopNode):
  8833. # 'not' operator
  8834. #
  8835. # operand ExprNode
  8836. operator = '!'
  8837. type = PyrexTypes.c_bint_type
  8838. def calculate_constant_result(self):
  8839. self.constant_result = not self.operand.constant_result
  8840. def compile_time_value(self, denv):
  8841. operand = self.operand.compile_time_value(denv)
  8842. try:
  8843. return not operand
  8844. except Exception as e:
  8845. self.compile_time_value_error(e)
  8846. def infer_unop_type(self, env, operand_type):
  8847. return PyrexTypes.c_bint_type
  8848. def analyse_types(self, env):
  8849. self.operand = self.operand.analyse_types(env)
  8850. operand_type = self.operand.type
  8851. if operand_type.is_cpp_class:
  8852. self.analyse_cpp_operation(env)
  8853. else:
  8854. self.operand = self.operand.coerce_to_boolean(env)
  8855. return self
  8856. def calculate_result_code(self):
  8857. return "(!%s)" % self.operand.result()
  8858. class UnaryPlusNode(UnopNode):
  8859. # unary '+' operator
  8860. operator = '+'
  8861. def analyse_c_operation(self, env):
  8862. self.type = PyrexTypes.widest_numeric_type(
  8863. self.operand.type, PyrexTypes.c_int_type)
  8864. def py_operation_function(self, code):
  8865. return "PyNumber_Positive"
  8866. def calculate_result_code(self):
  8867. if self.is_cpp_operation():
  8868. return "(+%s)" % self.operand.result()
  8869. else:
  8870. return self.operand.result()
  8871. class UnaryMinusNode(UnopNode):
  8872. # unary '-' operator
  8873. operator = '-'
  8874. def analyse_c_operation(self, env):
  8875. if self.operand.type.is_numeric:
  8876. self.type = PyrexTypes.widest_numeric_type(
  8877. self.operand.type, PyrexTypes.c_int_type)
  8878. elif self.operand.type.is_enum:
  8879. self.type = PyrexTypes.c_int_type
  8880. else:
  8881. self.type_error()
  8882. if self.type.is_complex:
  8883. self.infix = False
  8884. def py_operation_function(self, code):
  8885. return "PyNumber_Negative"
  8886. def calculate_result_code(self):
  8887. if self.infix:
  8888. return "(-%s)" % self.operand.result()
  8889. else:
  8890. return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
  8891. def get_constant_c_result_code(self):
  8892. value = self.operand.get_constant_c_result_code()
  8893. if value:
  8894. return "(-%s)" % value
  8895. class TildeNode(UnopNode):
  8896. # unary '~' operator
  8897. def analyse_c_operation(self, env):
  8898. if self.operand.type.is_int:
  8899. self.type = PyrexTypes.widest_numeric_type(
  8900. self.operand.type, PyrexTypes.c_int_type)
  8901. elif self.operand.type.is_enum:
  8902. self.type = PyrexTypes.c_int_type
  8903. else:
  8904. self.type_error()
  8905. def py_operation_function(self, code):
  8906. return "PyNumber_Invert"
  8907. def calculate_result_code(self):
  8908. return "(~%s)" % self.operand.result()
  8909. class CUnopNode(UnopNode):
  8910. def is_py_operation(self):
  8911. return False
  8912. class DereferenceNode(CUnopNode):
  8913. # unary * operator
  8914. operator = '*'
  8915. def infer_unop_type(self, env, operand_type):
  8916. if operand_type.is_ptr:
  8917. return operand_type.base_type
  8918. else:
  8919. return PyrexTypes.error_type
  8920. def analyse_c_operation(self, env):
  8921. if self.operand.type.is_ptr:
  8922. self.type = self.operand.type.base_type
  8923. else:
  8924. self.type_error()
  8925. def calculate_result_code(self):
  8926. return "(*%s)" % self.operand.result()
  8927. class DecrementIncrementNode(CUnopNode):
  8928. # unary ++/-- operator
  8929. def analyse_c_operation(self, env):
  8930. if self.operand.type.is_numeric:
  8931. self.type = PyrexTypes.widest_numeric_type(
  8932. self.operand.type, PyrexTypes.c_int_type)
  8933. elif self.operand.type.is_ptr:
  8934. self.type = self.operand.type
  8935. else:
  8936. self.type_error()
  8937. def calculate_result_code(self):
  8938. if self.is_prefix:
  8939. return "(%s%s)" % (self.operator, self.operand.result())
  8940. else:
  8941. return "(%s%s)" % (self.operand.result(), self.operator)
  8942. def inc_dec_constructor(is_prefix, operator):
  8943. return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
  8944. class AmpersandNode(CUnopNode):
  8945. # The C address-of operator.
  8946. #
  8947. # operand ExprNode
  8948. operator = '&'
  8949. def infer_unop_type(self, env, operand_type):
  8950. return PyrexTypes.c_ptr_type(operand_type)
  8951. def analyse_types(self, env):
  8952. self.operand = self.operand.analyse_types(env)
  8953. argtype = self.operand.type
  8954. if argtype.is_cpp_class:
  8955. self.analyse_cpp_operation(env, overload_check=False)
  8956. if not (argtype.is_cfunction or argtype.is_reference or self.operand.is_addressable()):
  8957. if argtype.is_memoryviewslice:
  8958. self.error("Cannot take address of memoryview slice")
  8959. else:
  8960. self.error("Taking address of non-lvalue (type %s)" % argtype)
  8961. return self
  8962. if argtype.is_pyobject:
  8963. self.error("Cannot take address of Python %s" % (
  8964. "variable '%s'" % self.operand.name if self.operand.is_name else
  8965. "object attribute '%s'" % self.operand.attribute if self.operand.is_attribute else
  8966. "object"))
  8967. return self
  8968. if not argtype.is_cpp_class or not self.type:
  8969. self.type = PyrexTypes.c_ptr_type(argtype)
  8970. return self
  8971. def check_const(self):
  8972. return self.operand.check_const_addr()
  8973. def error(self, mess):
  8974. error(self.pos, mess)
  8975. self.type = PyrexTypes.error_type
  8976. self.result_code = "<error>"
  8977. def calculate_result_code(self):
  8978. return "(&%s)" % self.operand.result()
  8979. def generate_result_code(self, code):
  8980. if (self.operand.type.is_cpp_class and self.exception_check == '+'):
  8981. translate_cpp_exception(code, self.pos,
  8982. "%s = %s %s;" % (self.result(), self.operator, self.operand.result()),
  8983. self.result() if self.type.is_pyobject else None,
  8984. self.exception_value, self.in_nogil_context)
  8985. unop_node_classes = {
  8986. "+": UnaryPlusNode,
  8987. "-": UnaryMinusNode,
  8988. "~": TildeNode,
  8989. }
  8990. def unop_node(pos, operator, operand):
  8991. # Construct unnop node of appropriate class for
  8992. # given operator.
  8993. if isinstance(operand, IntNode) and operator == '-':
  8994. return IntNode(pos = operand.pos, value = str(-Utils.str_to_number(operand.value)),
  8995. longness=operand.longness, unsigned=operand.unsigned)
  8996. elif isinstance(operand, UnopNode) and operand.operator == operator in '+-':
  8997. warning(pos, "Python has no increment/decrement operator: %s%sx == %s(%sx) == x" % ((operator,)*4), 5)
  8998. return unop_node_classes[operator](pos,
  8999. operator = operator,
  9000. operand = operand)
  9001. class TypecastNode(ExprNode):
  9002. # C type cast
  9003. #
  9004. # operand ExprNode
  9005. # base_type CBaseTypeNode
  9006. # declarator CDeclaratorNode
  9007. # typecheck boolean
  9008. #
  9009. # If used from a transform, one can if wanted specify the attribute
  9010. # "type" directly and leave base_type and declarator to None
  9011. subexprs = ['operand']
  9012. base_type = declarator = type = None
  9013. def type_dependencies(self, env):
  9014. return ()
  9015. def infer_type(self, env):
  9016. if self.type is None:
  9017. base_type = self.base_type.analyse(env)
  9018. _, self.type = self.declarator.analyse(base_type, env)
  9019. return self.type
  9020. def analyse_types(self, env):
  9021. if self.type is None:
  9022. base_type = self.base_type.analyse(env)
  9023. _, self.type = self.declarator.analyse(base_type, env)
  9024. if self.operand.has_constant_result():
  9025. # Must be done after self.type is resolved.
  9026. self.calculate_constant_result()
  9027. if self.type.is_cfunction:
  9028. error(self.pos,
  9029. "Cannot cast to a function type")
  9030. self.type = PyrexTypes.error_type
  9031. self.operand = self.operand.analyse_types(env)
  9032. if self.type is PyrexTypes.c_bint_type:
  9033. # short circuit this to a coercion
  9034. return self.operand.coerce_to_boolean(env)
  9035. to_py = self.type.is_pyobject
  9036. from_py = self.operand.type.is_pyobject
  9037. if from_py and not to_py and self.operand.is_ephemeral():
  9038. if not self.type.is_numeric and not self.type.is_cpp_class:
  9039. error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
  9040. if to_py and not from_py:
  9041. if self.type is bytes_type and self.operand.type.is_int:
  9042. return CoerceIntToBytesNode(self.operand, env)
  9043. elif self.operand.type.can_coerce_to_pyobject(env):
  9044. self.result_ctype = py_object_type
  9045. self.operand = self.operand.coerce_to(self.type, env)
  9046. else:
  9047. if self.operand.type.is_ptr:
  9048. if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
  9049. error(self.pos, "Python objects cannot be cast from pointers of primitive types")
  9050. else:
  9051. # Should this be an error?
  9052. warning(self.pos, "No conversion from %s to %s, python object pointer used." % (
  9053. self.operand.type, self.type))
  9054. self.operand = self.operand.coerce_to_simple(env)
  9055. elif from_py and not to_py:
  9056. if self.type.create_from_py_utility_code(env):
  9057. self.operand = self.operand.coerce_to(self.type, env)
  9058. elif self.type.is_ptr:
  9059. if not (self.type.base_type.is_void or self.type.base_type.is_struct):
  9060. error(self.pos, "Python objects cannot be cast to pointers of primitive types")
  9061. else:
  9062. warning(self.pos, "No conversion from %s to %s, python object pointer used." % (
  9063. self.type, self.operand.type))
  9064. elif from_py and to_py:
  9065. if self.typecheck:
  9066. self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
  9067. elif isinstance(self.operand, SliceIndexNode):
  9068. # This cast can influence the created type of string slices.
  9069. self.operand = self.operand.coerce_to(self.type, env)
  9070. elif self.type.is_complex and self.operand.type.is_complex:
  9071. self.operand = self.operand.coerce_to_simple(env)
  9072. elif self.operand.type.is_fused:
  9073. self.operand = self.operand.coerce_to(self.type, env)
  9074. #self.type = self.operand.type
  9075. if self.type.is_ptr and self.type.base_type.is_cfunction and self.type.base_type.nogil:
  9076. op_type = self.operand.type
  9077. if op_type.is_ptr:
  9078. op_type = op_type.base_type
  9079. if op_type.is_cfunction and not op_type.nogil:
  9080. warning(self.pos,
  9081. "Casting a GIL-requiring function into a nogil function circumvents GIL validation", 1)
  9082. return self
  9083. def is_simple(self):
  9084. # either temp or a C cast => no side effects other than the operand's
  9085. return self.operand.is_simple()
  9086. def is_ephemeral(self):
  9087. # either temp or a C cast => no side effects other than the operand's
  9088. return self.operand.is_ephemeral()
  9089. def nonlocally_immutable(self):
  9090. return self.is_temp or self.operand.nonlocally_immutable()
  9091. def nogil_check(self, env):
  9092. if self.type and self.type.is_pyobject and self.is_temp:
  9093. self.gil_error()
  9094. def check_const(self):
  9095. return self.operand.check_const()
  9096. def calculate_constant_result(self):
  9097. self.constant_result = self.calculate_result_code(self.operand.constant_result)
  9098. def calculate_result_code(self, operand_result = None):
  9099. if operand_result is None:
  9100. operand_result = self.operand.result()
  9101. if self.type.is_complex:
  9102. operand_result = self.operand.result()
  9103. if self.operand.type.is_complex:
  9104. real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
  9105. imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
  9106. else:
  9107. real_part = self.type.real_type.cast_code(operand_result)
  9108. imag_part = "0"
  9109. return "%s(%s, %s)" % (
  9110. self.type.from_parts,
  9111. real_part,
  9112. imag_part)
  9113. else:
  9114. return self.type.cast_code(operand_result)
  9115. def get_constant_c_result_code(self):
  9116. operand_result = self.operand.get_constant_c_result_code()
  9117. if operand_result:
  9118. return self.type.cast_code(operand_result)
  9119. def result_as(self, type):
  9120. if self.type.is_pyobject and not self.is_temp:
  9121. # Optimise away some unnecessary casting
  9122. return self.operand.result_as(type)
  9123. else:
  9124. return ExprNode.result_as(self, type)
  9125. def generate_result_code(self, code):
  9126. if self.is_temp:
  9127. code.putln(
  9128. "%s = (PyObject *)%s;" % (
  9129. self.result(),
  9130. self.operand.result()))
  9131. code.put_incref(self.result(), self.ctype())
  9132. ERR_START = "Start may not be given"
  9133. ERR_NOT_STOP = "Stop must be provided to indicate shape"
  9134. ERR_STEPS = ("Strides may only be given to indicate contiguity. "
  9135. "Consider slicing it after conversion")
  9136. ERR_NOT_POINTER = "Can only create cython.array from pointer or array"
  9137. ERR_BASE_TYPE = "Pointer base type does not match cython.array base type"
  9138. class CythonArrayNode(ExprNode):
  9139. """
  9140. Used when a pointer of base_type is cast to a memoryviewslice with that
  9141. base type. i.e.
  9142. <int[:M:1, :N]> p
  9143. creates a fortran-contiguous cython.array.
  9144. We leave the type set to object so coercions to object are more efficient
  9145. and less work. Acquiring a memoryviewslice from this will be just as
  9146. efficient. ExprNode.coerce_to() will do the additional typecheck on
  9147. self.compile_time_type
  9148. This also handles <int[:, :]> my_c_array
  9149. operand ExprNode the thing we're casting
  9150. base_type_node MemoryViewSliceTypeNode the cast expression node
  9151. """
  9152. subexprs = ['operand', 'shapes']
  9153. shapes = None
  9154. is_temp = True
  9155. mode = "c"
  9156. array_dtype = None
  9157. shape_type = PyrexTypes.c_py_ssize_t_type
  9158. def analyse_types(self, env):
  9159. from . import MemoryView
  9160. self.operand = self.operand.analyse_types(env)
  9161. if self.array_dtype:
  9162. array_dtype = self.array_dtype
  9163. else:
  9164. array_dtype = self.base_type_node.base_type_node.analyse(env)
  9165. axes = self.base_type_node.axes
  9166. self.type = error_type
  9167. self.shapes = []
  9168. ndim = len(axes)
  9169. # Base type of the pointer or C array we are converting
  9170. base_type = self.operand.type
  9171. if not self.operand.type.is_ptr and not self.operand.type.is_array:
  9172. error(self.operand.pos, ERR_NOT_POINTER)
  9173. return self
  9174. # Dimension sizes of C array
  9175. array_dimension_sizes = []
  9176. if base_type.is_array:
  9177. while base_type.is_array:
  9178. array_dimension_sizes.append(base_type.size)
  9179. base_type = base_type.base_type
  9180. elif base_type.is_ptr:
  9181. base_type = base_type.base_type
  9182. else:
  9183. error(self.pos, "unexpected base type %s found" % base_type)
  9184. return self
  9185. if not (base_type.same_as(array_dtype) or base_type.is_void):
  9186. error(self.operand.pos, ERR_BASE_TYPE)
  9187. return self
  9188. elif self.operand.type.is_array and len(array_dimension_sizes) != ndim:
  9189. error(self.operand.pos,
  9190. "Expected %d dimensions, array has %d dimensions" %
  9191. (ndim, len(array_dimension_sizes)))
  9192. return self
  9193. # Verify the start, stop and step values
  9194. # In case of a C array, use the size of C array in each dimension to
  9195. # get an automatic cast
  9196. for axis_no, axis in enumerate(axes):
  9197. if not axis.start.is_none:
  9198. error(axis.start.pos, ERR_START)
  9199. return self
  9200. if axis.stop.is_none:
  9201. if array_dimension_sizes:
  9202. dimsize = array_dimension_sizes[axis_no]
  9203. axis.stop = IntNode(self.pos, value=str(dimsize),
  9204. constant_result=dimsize,
  9205. type=PyrexTypes.c_int_type)
  9206. else:
  9207. error(axis.pos, ERR_NOT_STOP)
  9208. return self
  9209. axis.stop = axis.stop.analyse_types(env)
  9210. shape = axis.stop.coerce_to(self.shape_type, env)
  9211. if not shape.is_literal:
  9212. shape.coerce_to_temp(env)
  9213. self.shapes.append(shape)
  9214. first_or_last = axis_no in (0, ndim - 1)
  9215. if not axis.step.is_none and first_or_last:
  9216. # '1' in the first or last dimension denotes F or C contiguity
  9217. axis.step = axis.step.analyse_types(env)
  9218. if (not axis.step.type.is_int and axis.step.is_literal and not
  9219. axis.step.type.is_error):
  9220. error(axis.step.pos, "Expected an integer literal")
  9221. return self
  9222. if axis.step.compile_time_value(env) != 1:
  9223. error(axis.step.pos, ERR_STEPS)
  9224. return self
  9225. if axis_no == 0:
  9226. self.mode = "fortran"
  9227. elif not axis.step.is_none and not first_or_last:
  9228. # step provided in some other dimension
  9229. error(axis.step.pos, ERR_STEPS)
  9230. return self
  9231. if not self.operand.is_name:
  9232. self.operand = self.operand.coerce_to_temp(env)
  9233. axes = [('direct', 'follow')] * len(axes)
  9234. if self.mode == "fortran":
  9235. axes[0] = ('direct', 'contig')
  9236. else:
  9237. axes[-1] = ('direct', 'contig')
  9238. self.coercion_type = PyrexTypes.MemoryViewSliceType(array_dtype, axes)
  9239. self.coercion_type.validate_memslice_dtype(self.pos)
  9240. self.type = self.get_cython_array_type(env)
  9241. MemoryView.use_cython_array_utility_code(env)
  9242. env.use_utility_code(MemoryView.typeinfo_to_format_code)
  9243. return self
  9244. def allocate_temp_result(self, code):
  9245. if self.temp_code:
  9246. raise RuntimeError("temp allocated multiple times")
  9247. self.temp_code = code.funcstate.allocate_temp(self.type, True)
  9248. def infer_type(self, env):
  9249. return self.get_cython_array_type(env)
  9250. def get_cython_array_type(self, env):
  9251. cython_scope = env.global_scope().context.cython_scope
  9252. cython_scope.load_cythonscope()
  9253. return cython_scope.viewscope.lookup("array").type
  9254. def generate_result_code(self, code):
  9255. from . import Buffer
  9256. shapes = [self.shape_type.cast_code(shape.result())
  9257. for shape in self.shapes]
  9258. dtype = self.coercion_type.dtype
  9259. shapes_temp = code.funcstate.allocate_temp(py_object_type, True)
  9260. format_temp = code.funcstate.allocate_temp(py_object_type, True)
  9261. itemsize = "sizeof(%s)" % dtype.empty_declaration_code()
  9262. type_info = Buffer.get_type_information_cname(code, dtype)
  9263. if self.operand.type.is_ptr:
  9264. code.putln("if (!%s) {" % self.operand.result())
  9265. code.putln( 'PyErr_SetString(PyExc_ValueError,'
  9266. '"Cannot create cython.array from NULL pointer");')
  9267. code.putln(code.error_goto(self.operand.pos))
  9268. code.putln("}")
  9269. code.putln("%s = __pyx_format_from_typeinfo(&%s); %s" % (
  9270. format_temp,
  9271. type_info,
  9272. code.error_goto_if_null(format_temp, self.pos),
  9273. ))
  9274. code.put_gotref(format_temp)
  9275. buildvalue_fmt = " __PYX_BUILD_PY_SSIZE_T " * len(shapes)
  9276. code.putln('%s = Py_BuildValue((char*) "(" %s ")", %s); %s' % (
  9277. shapes_temp,
  9278. buildvalue_fmt,
  9279. ", ".join(shapes),
  9280. code.error_goto_if_null(shapes_temp, self.pos),
  9281. ))
  9282. code.put_gotref(shapes_temp)
  9283. tup = (self.result(), shapes_temp, itemsize, format_temp,
  9284. self.mode, self.operand.result())
  9285. code.putln('%s = __pyx_array_new('
  9286. '%s, %s, PyBytes_AS_STRING(%s), '
  9287. '(char *) "%s", (char *) %s);' % tup)
  9288. code.putln(code.error_goto_if_null(self.result(), self.pos))
  9289. code.put_gotref(self.result())
  9290. def dispose(temp):
  9291. code.put_decref_clear(temp, py_object_type)
  9292. code.funcstate.release_temp(temp)
  9293. dispose(shapes_temp)
  9294. dispose(format_temp)
  9295. @classmethod
  9296. def from_carray(cls, src_node, env):
  9297. """
  9298. Given a C array type, return a CythonArrayNode
  9299. """
  9300. pos = src_node.pos
  9301. base_type = src_node.type
  9302. none_node = NoneNode(pos)
  9303. axes = []
  9304. while base_type.is_array:
  9305. axes.append(SliceNode(pos, start=none_node, stop=none_node,
  9306. step=none_node))
  9307. base_type = base_type.base_type
  9308. axes[-1].step = IntNode(pos, value="1", is_c_literal=True)
  9309. memslicenode = Nodes.MemoryViewSliceTypeNode(pos, axes=axes,
  9310. base_type_node=base_type)
  9311. result = CythonArrayNode(pos, base_type_node=memslicenode,
  9312. operand=src_node, array_dtype=base_type)
  9313. result = result.analyse_types(env)
  9314. return result
  9315. class SizeofNode(ExprNode):
  9316. # Abstract base class for sizeof(x) expression nodes.
  9317. type = PyrexTypes.c_size_t_type
  9318. def check_const(self):
  9319. return True
  9320. def generate_result_code(self, code):
  9321. pass
  9322. class SizeofTypeNode(SizeofNode):
  9323. # C sizeof function applied to a type
  9324. #
  9325. # base_type CBaseTypeNode
  9326. # declarator CDeclaratorNode
  9327. subexprs = []
  9328. arg_type = None
  9329. def analyse_types(self, env):
  9330. # we may have incorrectly interpreted a dotted name as a type rather than an attribute
  9331. # this could be better handled by more uniformly treating types as runtime-available objects
  9332. if 0 and self.base_type.module_path:
  9333. path = self.base_type.module_path
  9334. obj = env.lookup(path[0])
  9335. if obj.as_module is None:
  9336. operand = NameNode(pos=self.pos, name=path[0])
  9337. for attr in path[1:]:
  9338. operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
  9339. operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
  9340. node = SizeofVarNode(self.pos, operand=operand).analyse_types(env)
  9341. return node
  9342. if self.arg_type is None:
  9343. base_type = self.base_type.analyse(env)
  9344. _, arg_type = self.declarator.analyse(base_type, env)
  9345. self.arg_type = arg_type
  9346. self.check_type()
  9347. return self
  9348. def check_type(self):
  9349. arg_type = self.arg_type
  9350. if not arg_type:
  9351. return
  9352. if arg_type.is_pyobject and not arg_type.is_extension_type:
  9353. error(self.pos, "Cannot take sizeof Python object")
  9354. elif arg_type.is_void:
  9355. error(self.pos, "Cannot take sizeof void")
  9356. elif not arg_type.is_complete():
  9357. error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
  9358. def calculate_result_code(self):
  9359. if self.arg_type.is_extension_type:
  9360. # the size of the pointer is boring
  9361. # we want the size of the actual struct
  9362. arg_code = self.arg_type.declaration_code("", deref=1)
  9363. else:
  9364. arg_code = self.arg_type.empty_declaration_code()
  9365. return "(sizeof(%s))" % arg_code
  9366. class SizeofVarNode(SizeofNode):
  9367. # C sizeof function applied to a variable
  9368. #
  9369. # operand ExprNode
  9370. subexprs = ['operand']
  9371. def analyse_types(self, env):
  9372. # We may actually be looking at a type rather than a variable...
  9373. # If we are, traditional analysis would fail...
  9374. operand_as_type = self.operand.analyse_as_type(env)
  9375. if operand_as_type:
  9376. self.arg_type = operand_as_type
  9377. if self.arg_type.is_fused:
  9378. self.arg_type = self.arg_type.specialize(env.fused_to_specific)
  9379. self.__class__ = SizeofTypeNode
  9380. self.check_type()
  9381. else:
  9382. self.operand = self.operand.analyse_types(env)
  9383. return self
  9384. def calculate_result_code(self):
  9385. return "(sizeof(%s))" % self.operand.result()
  9386. def generate_result_code(self, code):
  9387. pass
  9388. class TypeidNode(ExprNode):
  9389. # C++ typeid operator applied to a type or variable
  9390. #
  9391. # operand ExprNode
  9392. # arg_type ExprNode
  9393. # is_variable boolean
  9394. type = PyrexTypes.error_type
  9395. subexprs = ['operand']
  9396. arg_type = None
  9397. is_variable = None
  9398. is_temp = 1
  9399. def get_type_info_type(self, env):
  9400. env_module = env
  9401. while not env_module.is_module_scope:
  9402. env_module = env_module.outer_scope
  9403. typeinfo_module = env_module.find_module('libcpp.typeinfo', self.pos)
  9404. typeinfo_entry = typeinfo_module.lookup('type_info')
  9405. return PyrexTypes.CFakeReferenceType(PyrexTypes.c_const_type(typeinfo_entry.type))
  9406. cpp_message = 'typeid operator'
  9407. def analyse_types(self, env):
  9408. self.cpp_check(env)
  9409. type_info = self.get_type_info_type(env)
  9410. if not type_info:
  9411. self.error("The 'libcpp.typeinfo' module must be cimported to use the typeid() operator")
  9412. return self
  9413. self.type = type_info
  9414. as_type = self.operand.analyse_as_type(env)
  9415. if as_type:
  9416. self.arg_type = as_type
  9417. self.is_type = True
  9418. else:
  9419. self.arg_type = self.operand.analyse_types(env)
  9420. self.is_type = False
  9421. if self.arg_type.type.is_pyobject:
  9422. self.error("Cannot use typeid on a Python object")
  9423. return self
  9424. elif self.arg_type.type.is_void:
  9425. self.error("Cannot use typeid on void")
  9426. return self
  9427. elif not self.arg_type.type.is_complete():
  9428. self.error("Cannot use typeid on incomplete type '%s'" % self.arg_type.type)
  9429. return self
  9430. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  9431. return self
  9432. def error(self, mess):
  9433. error(self.pos, mess)
  9434. self.type = PyrexTypes.error_type
  9435. self.result_code = "<error>"
  9436. def check_const(self):
  9437. return True
  9438. def calculate_result_code(self):
  9439. return self.temp_code
  9440. def generate_result_code(self, code):
  9441. if self.is_type:
  9442. arg_code = self.arg_type.empty_declaration_code()
  9443. else:
  9444. arg_code = self.arg_type.result()
  9445. translate_cpp_exception(code, self.pos,
  9446. "%s = typeid(%s);" % (self.temp_code, arg_code),
  9447. None, None, self.in_nogil_context)
  9448. class TypeofNode(ExprNode):
  9449. # Compile-time type of an expression, as a string.
  9450. #
  9451. # operand ExprNode
  9452. # literal StringNode # internal
  9453. literal = None
  9454. type = py_object_type
  9455. subexprs = ['literal'] # 'operand' will be ignored after type analysis!
  9456. def analyse_types(self, env):
  9457. self.operand = self.operand.analyse_types(env)
  9458. value = StringEncoding.EncodedString(str(self.operand.type)) #self.operand.type.typeof_name())
  9459. literal = StringNode(self.pos, value=value)
  9460. literal = literal.analyse_types(env)
  9461. self.literal = literal.coerce_to_pyobject(env)
  9462. return self
  9463. def analyse_as_type(self, env):
  9464. self.operand = self.operand.analyse_types(env)
  9465. return self.operand.type
  9466. def may_be_none(self):
  9467. return False
  9468. def generate_evaluation_code(self, code):
  9469. self.literal.generate_evaluation_code(code)
  9470. def calculate_result_code(self):
  9471. return self.literal.calculate_result_code()
  9472. #-------------------------------------------------------------------
  9473. #
  9474. # Binary operator nodes
  9475. #
  9476. #-------------------------------------------------------------------
  9477. try:
  9478. matmul_operator = operator.matmul
  9479. except AttributeError:
  9480. def matmul_operator(a, b):
  9481. try:
  9482. func = a.__matmul__
  9483. except AttributeError:
  9484. func = b.__rmatmul__
  9485. return func(a, b)
  9486. compile_time_binary_operators = {
  9487. '<': operator.lt,
  9488. '<=': operator.le,
  9489. '==': operator.eq,
  9490. '!=': operator.ne,
  9491. '>=': operator.ge,
  9492. '>': operator.gt,
  9493. 'is': operator.is_,
  9494. 'is_not': operator.is_not,
  9495. '+': operator.add,
  9496. '&': operator.and_,
  9497. '/': operator.truediv,
  9498. '//': operator.floordiv,
  9499. '<<': operator.lshift,
  9500. '%': operator.mod,
  9501. '*': operator.mul,
  9502. '|': operator.or_,
  9503. '**': operator.pow,
  9504. '>>': operator.rshift,
  9505. '-': operator.sub,
  9506. '^': operator.xor,
  9507. '@': matmul_operator,
  9508. 'in': lambda x, seq: x in seq,
  9509. 'not_in': lambda x, seq: x not in seq,
  9510. }
  9511. def get_compile_time_binop(node):
  9512. func = compile_time_binary_operators.get(node.operator)
  9513. if not func:
  9514. error(node.pos,
  9515. "Binary '%s' not supported in compile-time expression"
  9516. % node.operator)
  9517. return func
  9518. class BinopNode(ExprNode):
  9519. # operator string
  9520. # operand1 ExprNode
  9521. # operand2 ExprNode
  9522. #
  9523. # Processing during analyse_expressions phase:
  9524. #
  9525. # analyse_c_operation
  9526. # Called when neither operand is a pyobject.
  9527. # - Check operand types and coerce if needed.
  9528. # - Determine result type and result code fragment.
  9529. # - Allocate temporary for result if needed.
  9530. subexprs = ['operand1', 'operand2']
  9531. inplace = False
  9532. def calculate_constant_result(self):
  9533. func = compile_time_binary_operators[self.operator]
  9534. self.constant_result = func(
  9535. self.operand1.constant_result,
  9536. self.operand2.constant_result)
  9537. def compile_time_value(self, denv):
  9538. func = get_compile_time_binop(self)
  9539. operand1 = self.operand1.compile_time_value(denv)
  9540. operand2 = self.operand2.compile_time_value(denv)
  9541. try:
  9542. return func(operand1, operand2)
  9543. except Exception as e:
  9544. self.compile_time_value_error(e)
  9545. def infer_type(self, env):
  9546. return self.result_type(self.operand1.infer_type(env),
  9547. self.operand2.infer_type(env), env)
  9548. def analyse_types(self, env):
  9549. self.operand1 = self.operand1.analyse_types(env)
  9550. self.operand2 = self.operand2.analyse_types(env)
  9551. self.analyse_operation(env)
  9552. return self
  9553. def analyse_operation(self, env):
  9554. if self.is_pythran_operation(env):
  9555. self.type = self.result_type(self.operand1.type,
  9556. self.operand2.type, env)
  9557. assert self.type.is_pythran_expr
  9558. self.is_temp = 1
  9559. elif self.is_py_operation():
  9560. self.coerce_operands_to_pyobjects(env)
  9561. self.type = self.result_type(self.operand1.type,
  9562. self.operand2.type, env)
  9563. assert self.type.is_pyobject
  9564. self.is_temp = 1
  9565. elif self.is_cpp_operation():
  9566. self.analyse_cpp_operation(env)
  9567. else:
  9568. self.analyse_c_operation(env)
  9569. def is_py_operation(self):
  9570. return self.is_py_operation_types(self.operand1.type, self.operand2.type)
  9571. def is_py_operation_types(self, type1, type2):
  9572. return type1.is_pyobject or type2.is_pyobject or type1.is_ctuple or type2.is_ctuple
  9573. def is_pythran_operation(self, env):
  9574. return self.is_pythran_operation_types(self.operand1.type, self.operand2.type, env)
  9575. def is_pythran_operation_types(self, type1, type2, env):
  9576. # Support only expr op supported_type, or supported_type op expr
  9577. return has_np_pythran(env) and \
  9578. (is_pythran_supported_operation_type(type1) and is_pythran_supported_operation_type(type2)) and \
  9579. (is_pythran_expr(type1) or is_pythran_expr(type2))
  9580. def is_cpp_operation(self):
  9581. return (self.operand1.type.is_cpp_class
  9582. or self.operand2.type.is_cpp_class)
  9583. def analyse_cpp_operation(self, env):
  9584. entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
  9585. if not entry:
  9586. self.type_error()
  9587. return
  9588. func_type = entry.type
  9589. self.exception_check = func_type.exception_check
  9590. self.exception_value = func_type.exception_value
  9591. if self.exception_check == '+':
  9592. # Used by NumBinopNodes to break up expressions involving multiple
  9593. # operators so that exceptions can be handled properly.
  9594. self.is_temp = 1
  9595. if self.exception_value is None:
  9596. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  9597. if func_type.is_ptr:
  9598. func_type = func_type.base_type
  9599. if len(func_type.args) == 1:
  9600. self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
  9601. else:
  9602. self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
  9603. self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
  9604. self.type = func_type.return_type
  9605. def result_type(self, type1, type2, env):
  9606. if self.is_pythran_operation_types(type1, type2, env):
  9607. return PythranExpr(pythran_binop_type(self.operator, type1, type2))
  9608. if self.is_py_operation_types(type1, type2):
  9609. if type2.is_string:
  9610. type2 = Builtin.bytes_type
  9611. elif type2.is_pyunicode_ptr:
  9612. type2 = Builtin.unicode_type
  9613. if type1.is_string:
  9614. type1 = Builtin.bytes_type
  9615. elif type1.is_pyunicode_ptr:
  9616. type1 = Builtin.unicode_type
  9617. if type1.is_builtin_type or type2.is_builtin_type:
  9618. if type1 is type2 and self.operator in '**%+|&^':
  9619. # FIXME: at least these operators should be safe - others?
  9620. return type1
  9621. result_type = self.infer_builtin_types_operation(type1, type2)
  9622. if result_type is not None:
  9623. return result_type
  9624. return py_object_type
  9625. elif type1.is_error or type2.is_error:
  9626. return PyrexTypes.error_type
  9627. else:
  9628. return self.compute_c_result_type(type1, type2)
  9629. def infer_builtin_types_operation(self, type1, type2):
  9630. return None
  9631. def nogil_check(self, env):
  9632. if self.is_py_operation():
  9633. self.gil_error()
  9634. def coerce_operands_to_pyobjects(self, env):
  9635. self.operand1 = self.operand1.coerce_to_pyobject(env)
  9636. self.operand2 = self.operand2.coerce_to_pyobject(env)
  9637. def check_const(self):
  9638. return self.operand1.check_const() and self.operand2.check_const()
  9639. def is_ephemeral(self):
  9640. return (super(BinopNode, self).is_ephemeral() or
  9641. self.operand1.is_ephemeral() or self.operand2.is_ephemeral())
  9642. def generate_result_code(self, code):
  9643. if self.type.is_pythran_expr:
  9644. code.putln("// Pythran binop")
  9645. code.putln("__Pyx_call_destructor(%s);" % self.result())
  9646. if self.operator == '**':
  9647. code.putln("new (&%s) decltype(%s){pythonic::numpy::functor::power{}(%s, %s)};" % (
  9648. self.result(),
  9649. self.result(),
  9650. self.operand1.pythran_result(),
  9651. self.operand2.pythran_result()))
  9652. else:
  9653. code.putln("new (&%s) decltype(%s){%s %s %s};" % (
  9654. self.result(),
  9655. self.result(),
  9656. self.operand1.pythran_result(),
  9657. self.operator,
  9658. self.operand2.pythran_result()))
  9659. elif self.operand1.type.is_pyobject:
  9660. function = self.py_operation_function(code)
  9661. if self.operator == '**':
  9662. extra_args = ", Py_None"
  9663. else:
  9664. extra_args = ""
  9665. code.putln(
  9666. "%s = %s(%s, %s%s); %s" % (
  9667. self.result(),
  9668. function,
  9669. self.operand1.py_result(),
  9670. self.operand2.py_result(),
  9671. extra_args,
  9672. code.error_goto_if_null(self.result(), self.pos)))
  9673. code.put_gotref(self.py_result())
  9674. elif self.is_temp:
  9675. # C++ overloaded operators with exception values are currently all
  9676. # handled through temporaries.
  9677. if self.is_cpp_operation() and self.exception_check == '+':
  9678. translate_cpp_exception(code, self.pos,
  9679. "%s = %s;" % (self.result(), self.calculate_result_code()),
  9680. self.result() if self.type.is_pyobject else None,
  9681. self.exception_value, self.in_nogil_context)
  9682. else:
  9683. code.putln("%s = %s;" % (self.result(), self.calculate_result_code()))
  9684. def type_error(self):
  9685. if not (self.operand1.type.is_error
  9686. or self.operand2.type.is_error):
  9687. error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
  9688. (self.operator, self.operand1.type,
  9689. self.operand2.type))
  9690. self.type = PyrexTypes.error_type
  9691. class CBinopNode(BinopNode):
  9692. def analyse_types(self, env):
  9693. node = BinopNode.analyse_types(self, env)
  9694. if node.is_py_operation():
  9695. node.type = PyrexTypes.error_type
  9696. return node
  9697. def py_operation_function(self, code):
  9698. return ""
  9699. def calculate_result_code(self):
  9700. return "(%s %s %s)" % (
  9701. self.operand1.result(),
  9702. self.operator,
  9703. self.operand2.result())
  9704. def compute_c_result_type(self, type1, type2):
  9705. cpp_type = None
  9706. if type1.is_cpp_class or type1.is_ptr:
  9707. cpp_type = type1.find_cpp_operation_type(self.operator, type2)
  9708. if cpp_type is None and (type2.is_cpp_class or type2.is_ptr):
  9709. cpp_type = type2.find_cpp_operation_type(self.operator, type1)
  9710. # FIXME: do we need to handle other cases here?
  9711. return cpp_type
  9712. def c_binop_constructor(operator):
  9713. def make_binop_node(pos, **operands):
  9714. return CBinopNode(pos, operator=operator, **operands)
  9715. return make_binop_node
  9716. class NumBinopNode(BinopNode):
  9717. # Binary operation taking numeric arguments.
  9718. infix = True
  9719. overflow_check = False
  9720. overflow_bit_node = None
  9721. def analyse_c_operation(self, env):
  9722. type1 = self.operand1.type
  9723. type2 = self.operand2.type
  9724. self.type = self.compute_c_result_type(type1, type2)
  9725. if not self.type:
  9726. self.type_error()
  9727. return
  9728. if self.type.is_complex:
  9729. self.infix = False
  9730. if (self.type.is_int
  9731. and env.directives['overflowcheck']
  9732. and self.operator in self.overflow_op_names):
  9733. if (self.operator in ('+', '*')
  9734. and self.operand1.has_constant_result()
  9735. and not self.operand2.has_constant_result()):
  9736. self.operand1, self.operand2 = self.operand2, self.operand1
  9737. self.overflow_check = True
  9738. self.overflow_fold = env.directives['overflowcheck.fold']
  9739. self.func = self.type.overflow_check_binop(
  9740. self.overflow_op_names[self.operator],
  9741. env,
  9742. const_rhs = self.operand2.has_constant_result())
  9743. self.is_temp = True
  9744. if not self.infix or (type1.is_numeric and type2.is_numeric):
  9745. self.operand1 = self.operand1.coerce_to(self.type, env)
  9746. self.operand2 = self.operand2.coerce_to(self.type, env)
  9747. def compute_c_result_type(self, type1, type2):
  9748. if self.c_types_okay(type1, type2):
  9749. widest_type = PyrexTypes.widest_numeric_type(type1, type2)
  9750. if widest_type is PyrexTypes.c_bint_type:
  9751. if self.operator not in '|^&':
  9752. # False + False == 0 # not False!
  9753. widest_type = PyrexTypes.c_int_type
  9754. else:
  9755. widest_type = PyrexTypes.widest_numeric_type(
  9756. widest_type, PyrexTypes.c_int_type)
  9757. return widest_type
  9758. else:
  9759. return None
  9760. def may_be_none(self):
  9761. if self.type and self.type.is_builtin_type:
  9762. # if we know the result type, we know the operation, so it can't be None
  9763. return False
  9764. type1 = self.operand1.type
  9765. type2 = self.operand2.type
  9766. if type1 and type1.is_builtin_type and type2 and type2.is_builtin_type:
  9767. # XXX: I can't think of any case where a binary operation
  9768. # on builtin types evaluates to None - add a special case
  9769. # here if there is one.
  9770. return False
  9771. return super(NumBinopNode, self).may_be_none()
  9772. def get_constant_c_result_code(self):
  9773. value1 = self.operand1.get_constant_c_result_code()
  9774. value2 = self.operand2.get_constant_c_result_code()
  9775. if value1 and value2:
  9776. return "(%s %s %s)" % (value1, self.operator, value2)
  9777. else:
  9778. return None
  9779. def c_types_okay(self, type1, type2):
  9780. #print "NumBinopNode.c_types_okay:", type1, type2 ###
  9781. return (type1.is_numeric or type1.is_enum) \
  9782. and (type2.is_numeric or type2.is_enum)
  9783. def generate_evaluation_code(self, code):
  9784. if self.overflow_check:
  9785. self.overflow_bit_node = self
  9786. self.overflow_bit = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
  9787. code.putln("%s = 0;" % self.overflow_bit)
  9788. super(NumBinopNode, self).generate_evaluation_code(code)
  9789. if self.overflow_check:
  9790. code.putln("if (unlikely(%s)) {" % self.overflow_bit)
  9791. code.putln('PyErr_SetString(PyExc_OverflowError, "value too large");')
  9792. code.putln(code.error_goto(self.pos))
  9793. code.putln("}")
  9794. code.funcstate.release_temp(self.overflow_bit)
  9795. def calculate_result_code(self):
  9796. if self.overflow_bit_node is not None:
  9797. return "%s(%s, %s, &%s)" % (
  9798. self.func,
  9799. self.operand1.result(),
  9800. self.operand2.result(),
  9801. self.overflow_bit_node.overflow_bit)
  9802. elif self.type.is_cpp_class or self.infix:
  9803. if is_pythran_expr(self.type):
  9804. result1, result2 = self.operand1.pythran_result(), self.operand2.pythran_result()
  9805. else:
  9806. result1, result2 = self.operand1.result(), self.operand2.result()
  9807. return "(%s %s %s)" % (result1, self.operator, result2)
  9808. else:
  9809. func = self.type.binary_op(self.operator)
  9810. if func is None:
  9811. error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
  9812. return "%s(%s, %s)" % (
  9813. func,
  9814. self.operand1.result(),
  9815. self.operand2.result())
  9816. def is_py_operation_types(self, type1, type2):
  9817. return (type1.is_unicode_char or
  9818. type2.is_unicode_char or
  9819. BinopNode.is_py_operation_types(self, type1, type2))
  9820. def py_operation_function(self, code):
  9821. function_name = self.py_functions[self.operator]
  9822. if self.inplace:
  9823. function_name = function_name.replace('PyNumber_', 'PyNumber_InPlace')
  9824. return function_name
  9825. py_functions = {
  9826. "|": "PyNumber_Or",
  9827. "^": "PyNumber_Xor",
  9828. "&": "PyNumber_And",
  9829. "<<": "PyNumber_Lshift",
  9830. ">>": "PyNumber_Rshift",
  9831. "+": "PyNumber_Add",
  9832. "-": "PyNumber_Subtract",
  9833. "*": "PyNumber_Multiply",
  9834. "@": "__Pyx_PyNumber_MatrixMultiply",
  9835. "/": "__Pyx_PyNumber_Divide",
  9836. "//": "PyNumber_FloorDivide",
  9837. "%": "PyNumber_Remainder",
  9838. "**": "PyNumber_Power",
  9839. }
  9840. overflow_op_names = {
  9841. "+": "add",
  9842. "-": "sub",
  9843. "*": "mul",
  9844. "<<": "lshift",
  9845. }
  9846. class IntBinopNode(NumBinopNode):
  9847. # Binary operation taking integer arguments.
  9848. def c_types_okay(self, type1, type2):
  9849. #print "IntBinopNode.c_types_okay:", type1, type2 ###
  9850. return (type1.is_int or type1.is_enum) \
  9851. and (type2.is_int or type2.is_enum)
  9852. class AddNode(NumBinopNode):
  9853. # '+' operator.
  9854. def is_py_operation_types(self, type1, type2):
  9855. if type1.is_string and type2.is_string or type1.is_pyunicode_ptr and type2.is_pyunicode_ptr:
  9856. return 1
  9857. else:
  9858. return NumBinopNode.is_py_operation_types(self, type1, type2)
  9859. def infer_builtin_types_operation(self, type1, type2):
  9860. # b'abc' + 'abc' raises an exception in Py3,
  9861. # so we can safely infer the Py2 type for bytes here
  9862. string_types = (bytes_type, bytearray_type, str_type, basestring_type, unicode_type)
  9863. if type1 in string_types and type2 in string_types:
  9864. return string_types[max(string_types.index(type1),
  9865. string_types.index(type2))]
  9866. return None
  9867. def compute_c_result_type(self, type1, type2):
  9868. #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
  9869. if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
  9870. return type1
  9871. elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
  9872. return type2
  9873. else:
  9874. return NumBinopNode.compute_c_result_type(
  9875. self, type1, type2)
  9876. def py_operation_function(self, code):
  9877. type1, type2 = self.operand1.type, self.operand2.type
  9878. if type1 is unicode_type or type2 is unicode_type:
  9879. if type1 in (unicode_type, str_type) and type2 in (unicode_type, str_type):
  9880. is_unicode_concat = True
  9881. elif isinstance(self.operand1, FormattedValueNode) or isinstance(self.operand2, FormattedValueNode):
  9882. # Assume that even if we don't know the second type, it's going to be a string.
  9883. is_unicode_concat = True
  9884. else:
  9885. # Operation depends on the second type.
  9886. is_unicode_concat = False
  9887. if is_unicode_concat:
  9888. if self.operand1.may_be_none() or self.operand2.may_be_none():
  9889. return '__Pyx_PyUnicode_ConcatSafe'
  9890. else:
  9891. return '__Pyx_PyUnicode_Concat'
  9892. return super(AddNode, self).py_operation_function(code)
  9893. class SubNode(NumBinopNode):
  9894. # '-' operator.
  9895. def compute_c_result_type(self, type1, type2):
  9896. if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
  9897. return type1
  9898. elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
  9899. return PyrexTypes.c_ptrdiff_t_type
  9900. else:
  9901. return NumBinopNode.compute_c_result_type(
  9902. self, type1, type2)
  9903. class MulNode(NumBinopNode):
  9904. # '*' operator.
  9905. def is_py_operation_types(self, type1, type2):
  9906. if ((type1.is_string and type2.is_int) or
  9907. (type2.is_string and type1.is_int)):
  9908. return 1
  9909. else:
  9910. return NumBinopNode.is_py_operation_types(self, type1, type2)
  9911. def infer_builtin_types_operation(self, type1, type2):
  9912. # let's assume that whatever builtin type you multiply a string with
  9913. # will either return a string of the same type or fail with an exception
  9914. string_types = (bytes_type, bytearray_type, str_type, basestring_type, unicode_type)
  9915. if type1 in string_types and type2.is_builtin_type:
  9916. return type1
  9917. if type2 in string_types and type1.is_builtin_type:
  9918. return type2
  9919. # multiplication of containers/numbers with an integer value
  9920. # always (?) returns the same type
  9921. if type1.is_int:
  9922. return type2
  9923. if type2.is_int:
  9924. return type1
  9925. return None
  9926. class MatMultNode(NumBinopNode):
  9927. # '@' operator.
  9928. def is_py_operation_types(self, type1, type2):
  9929. return True
  9930. def generate_evaluation_code(self, code):
  9931. code.globalstate.use_utility_code(UtilityCode.load_cached("MatrixMultiply", "ObjectHandling.c"))
  9932. super(MatMultNode, self).generate_evaluation_code(code)
  9933. class DivNode(NumBinopNode):
  9934. # '/' or '//' operator.
  9935. cdivision = None
  9936. truedivision = None # == "unknown" if operator == '/'
  9937. ctruedivision = False
  9938. cdivision_warnings = False
  9939. zerodivision_check = None
  9940. def find_compile_time_binary_operator(self, op1, op2):
  9941. func = compile_time_binary_operators[self.operator]
  9942. if self.operator == '/' and self.truedivision is None:
  9943. # => true div for floats, floor div for integers
  9944. if isinstance(op1, _py_int_types) and isinstance(op2, _py_int_types):
  9945. func = compile_time_binary_operators['//']
  9946. return func
  9947. def calculate_constant_result(self):
  9948. op1 = self.operand1.constant_result
  9949. op2 = self.operand2.constant_result
  9950. func = self.find_compile_time_binary_operator(op1, op2)
  9951. self.constant_result = func(
  9952. self.operand1.constant_result,
  9953. self.operand2.constant_result)
  9954. def compile_time_value(self, denv):
  9955. operand1 = self.operand1.compile_time_value(denv)
  9956. operand2 = self.operand2.compile_time_value(denv)
  9957. try:
  9958. func = self.find_compile_time_binary_operator(
  9959. operand1, operand2)
  9960. return func(operand1, operand2)
  9961. except Exception as e:
  9962. self.compile_time_value_error(e)
  9963. def _check_truedivision(self, env):
  9964. if self.cdivision or env.directives['cdivision']:
  9965. self.ctruedivision = False
  9966. else:
  9967. self.ctruedivision = self.truedivision
  9968. def infer_type(self, env):
  9969. self._check_truedivision(env)
  9970. return self.result_type(
  9971. self.operand1.infer_type(env),
  9972. self.operand2.infer_type(env), env)
  9973. def analyse_operation(self, env):
  9974. self._check_truedivision(env)
  9975. NumBinopNode.analyse_operation(self, env)
  9976. if self.is_cpp_operation():
  9977. self.cdivision = True
  9978. if not self.type.is_pyobject:
  9979. self.zerodivision_check = (
  9980. self.cdivision is None and not env.directives['cdivision']
  9981. and (not self.operand2.has_constant_result() or
  9982. self.operand2.constant_result == 0))
  9983. if self.zerodivision_check or env.directives['cdivision_warnings']:
  9984. # Need to check ahead of time to warn or raise zero division error
  9985. self.operand1 = self.operand1.coerce_to_simple(env)
  9986. self.operand2 = self.operand2.coerce_to_simple(env)
  9987. def compute_c_result_type(self, type1, type2):
  9988. if self.operator == '/' and self.ctruedivision and not type1.is_cpp_class and not type2.is_cpp_class:
  9989. if not type1.is_float and not type2.is_float:
  9990. widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
  9991. widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
  9992. return widest_type
  9993. return NumBinopNode.compute_c_result_type(self, type1, type2)
  9994. def zero_division_message(self):
  9995. if self.type.is_int:
  9996. return "integer division or modulo by zero"
  9997. else:
  9998. return "float division"
  9999. def generate_evaluation_code(self, code):
  10000. if not self.type.is_pyobject and not self.type.is_complex:
  10001. if self.cdivision is None:
  10002. self.cdivision = (
  10003. code.globalstate.directives['cdivision']
  10004. or self.type.is_float
  10005. or ((self.type.is_numeric or self.type.is_enum) and not self.type.signed)
  10006. )
  10007. if not self.cdivision:
  10008. code.globalstate.use_utility_code(
  10009. UtilityCode.load_cached("DivInt", "CMath.c").specialize(self.type))
  10010. NumBinopNode.generate_evaluation_code(self, code)
  10011. self.generate_div_warning_code(code)
  10012. def generate_div_warning_code(self, code):
  10013. in_nogil = self.in_nogil_context
  10014. if not self.type.is_pyobject:
  10015. if self.zerodivision_check:
  10016. if not self.infix:
  10017. zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
  10018. else:
  10019. zero_test = "%s == 0" % self.operand2.result()
  10020. code.putln("if (unlikely(%s)) {" % zero_test)
  10021. if in_nogil:
  10022. code.put_ensure_gil()
  10023. code.putln('PyErr_SetString(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
  10024. if in_nogil:
  10025. code.put_release_ensured_gil()
  10026. code.putln(code.error_goto(self.pos))
  10027. code.putln("}")
  10028. if self.type.is_int and self.type.signed and self.operator != '%':
  10029. code.globalstate.use_utility_code(UtilityCode.load_cached("UnaryNegOverflows", "Overflow.c"))
  10030. if self.operand2.type.signed == 2:
  10031. # explicitly signed, no runtime check needed
  10032. minus1_check = 'unlikely(%s == -1)' % self.operand2.result()
  10033. else:
  10034. type_of_op2 = self.operand2.type.empty_declaration_code()
  10035. minus1_check = '(!(((%s)-1) > 0)) && unlikely(%s == (%s)-1)' % (
  10036. type_of_op2, self.operand2.result(), type_of_op2)
  10037. code.putln("else if (sizeof(%s) == sizeof(long) && %s "
  10038. " && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
  10039. self.type.empty_declaration_code(),
  10040. minus1_check,
  10041. self.operand1.result()))
  10042. if in_nogil:
  10043. code.put_ensure_gil()
  10044. code.putln('PyErr_SetString(PyExc_OverflowError, "value too large to perform division");')
  10045. if in_nogil:
  10046. code.put_release_ensured_gil()
  10047. code.putln(code.error_goto(self.pos))
  10048. code.putln("}")
  10049. if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
  10050. code.globalstate.use_utility_code(
  10051. UtilityCode.load_cached("CDivisionWarning", "CMath.c"))
  10052. code.putln("if (unlikely((%s < 0) ^ (%s < 0))) {" % (
  10053. self.operand1.result(),
  10054. self.operand2.result()))
  10055. warning_code = "__Pyx_cdivision_warning(%(FILENAME)s, %(LINENO)s)" % {
  10056. 'FILENAME': Naming.filename_cname,
  10057. 'LINENO': Naming.lineno_cname,
  10058. }
  10059. if in_nogil:
  10060. result_code = 'result'
  10061. code.putln("int %s;" % result_code)
  10062. code.put_ensure_gil()
  10063. code.putln(code.set_error_info(self.pos, used=True))
  10064. code.putln("%s = %s;" % (result_code, warning_code))
  10065. code.put_release_ensured_gil()
  10066. else:
  10067. result_code = warning_code
  10068. code.putln(code.set_error_info(self.pos, used=True))
  10069. code.put("if (unlikely(%s)) " % result_code)
  10070. code.put_goto(code.error_label)
  10071. code.putln("}")
  10072. def calculate_result_code(self):
  10073. if self.type.is_complex or self.is_cpp_operation():
  10074. return NumBinopNode.calculate_result_code(self)
  10075. elif self.type.is_float and self.operator == '//':
  10076. return "floor(%s / %s)" % (
  10077. self.operand1.result(),
  10078. self.operand2.result())
  10079. elif self.truedivision or self.cdivision:
  10080. op1 = self.operand1.result()
  10081. op2 = self.operand2.result()
  10082. if self.truedivision:
  10083. if self.type != self.operand1.type:
  10084. op1 = self.type.cast_code(op1)
  10085. if self.type != self.operand2.type:
  10086. op2 = self.type.cast_code(op2)
  10087. return "(%s / %s)" % (op1, op2)
  10088. else:
  10089. return "__Pyx_div_%s(%s, %s)" % (
  10090. self.type.specialization_name(),
  10091. self.operand1.result(),
  10092. self.operand2.result())
  10093. _find_formatting_types = re.compile(
  10094. br"%"
  10095. br"(?:%|" # %%
  10096. br"(?:\([^)]+\))?" # %(name)
  10097. br"[-+#,0-9 ]*([a-z])" # %.2f etc.
  10098. br")").findall
  10099. # These format conversion types can never trigger a Unicode string conversion in Py2.
  10100. _safe_bytes_formats = set([
  10101. # Excludes 's' and 'r', which can generate non-bytes strings.
  10102. 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',
  10103. ])
  10104. class ModNode(DivNode):
  10105. # '%' operator.
  10106. def is_py_operation_types(self, type1, type2):
  10107. return (type1.is_string
  10108. or type2.is_string
  10109. or NumBinopNode.is_py_operation_types(self, type1, type2))
  10110. def infer_builtin_types_operation(self, type1, type2):
  10111. # b'%s' % xyz raises an exception in Py3<3.5, so it's safe to infer the type for Py2 and later Py3's.
  10112. if type1 is unicode_type:
  10113. # None + xyz may be implemented by RHS
  10114. if type2.is_builtin_type or not self.operand1.may_be_none():
  10115. return type1
  10116. elif type1 in (bytes_type, str_type, basestring_type):
  10117. if type2 is unicode_type:
  10118. return type2
  10119. elif type2.is_numeric:
  10120. return type1
  10121. elif self.operand1.is_string_literal:
  10122. if type1 is str_type or type1 is bytes_type:
  10123. if set(_find_formatting_types(self.operand1.value)) <= _safe_bytes_formats:
  10124. return type1
  10125. return basestring_type
  10126. elif type1 is bytes_type and not type2.is_builtin_type:
  10127. return None # RHS might implement '% operator differently in Py3
  10128. else:
  10129. return basestring_type # either str or unicode, can't tell
  10130. return None
  10131. def zero_division_message(self):
  10132. if self.type.is_int:
  10133. return "integer division or modulo by zero"
  10134. else:
  10135. return "float divmod()"
  10136. def analyse_operation(self, env):
  10137. DivNode.analyse_operation(self, env)
  10138. if not self.type.is_pyobject:
  10139. if self.cdivision is None:
  10140. self.cdivision = env.directives['cdivision'] or not self.type.signed
  10141. if not self.cdivision and not self.type.is_int and not self.type.is_float:
  10142. error(self.pos, "mod operator not supported for type '%s'" % self.type)
  10143. def generate_evaluation_code(self, code):
  10144. if not self.type.is_pyobject and not self.cdivision:
  10145. if self.type.is_int:
  10146. code.globalstate.use_utility_code(
  10147. UtilityCode.load_cached("ModInt", "CMath.c").specialize(self.type))
  10148. else: # float
  10149. code.globalstate.use_utility_code(
  10150. UtilityCode.load_cached("ModFloat", "CMath.c").specialize(
  10151. self.type, math_h_modifier=self.type.math_h_modifier))
  10152. # NOTE: skipping over DivNode here
  10153. NumBinopNode.generate_evaluation_code(self, code)
  10154. self.generate_div_warning_code(code)
  10155. def calculate_result_code(self):
  10156. if self.cdivision:
  10157. if self.type.is_float:
  10158. return "fmod%s(%s, %s)" % (
  10159. self.type.math_h_modifier,
  10160. self.operand1.result(),
  10161. self.operand2.result())
  10162. else:
  10163. return "(%s %% %s)" % (
  10164. self.operand1.result(),
  10165. self.operand2.result())
  10166. else:
  10167. return "__Pyx_mod_%s(%s, %s)" % (
  10168. self.type.specialization_name(),
  10169. self.operand1.result(),
  10170. self.operand2.result())
  10171. def py_operation_function(self, code):
  10172. type1, type2 = self.operand1.type, self.operand2.type
  10173. # ("..." % x) must call "x.__rmod__()" for string subtypes.
  10174. if type1 is unicode_type:
  10175. if self.operand1.may_be_none() or (
  10176. type2.is_extension_type and type2.subtype_of(type1) or
  10177. type2 is py_object_type and not isinstance(self.operand2, CoerceToPyTypeNode)):
  10178. return '__Pyx_PyUnicode_FormatSafe'
  10179. else:
  10180. return 'PyUnicode_Format'
  10181. elif type1 is str_type:
  10182. if self.operand1.may_be_none() or (
  10183. type2.is_extension_type and type2.subtype_of(type1) or
  10184. type2 is py_object_type and not isinstance(self.operand2, CoerceToPyTypeNode)):
  10185. return '__Pyx_PyString_FormatSafe'
  10186. else:
  10187. return '__Pyx_PyString_Format'
  10188. return super(ModNode, self).py_operation_function(code)
  10189. class PowNode(NumBinopNode):
  10190. # '**' operator.
  10191. def analyse_types(self, env):
  10192. if not env.directives['cpow']:
  10193. # Note - the check here won't catch cpow directives that don't use '**'
  10194. # but that's probably OK for a placeholder forward compatibility directive
  10195. error(self.pos, "The 'cpow' directive is provided for forward compatibility "
  10196. "and must be True")
  10197. return super(PowNode, self).analyse_types(env)
  10198. def analyse_c_operation(self, env):
  10199. NumBinopNode.analyse_c_operation(self, env)
  10200. if self.type.is_complex:
  10201. if self.type.real_type.is_float:
  10202. self.operand1 = self.operand1.coerce_to(self.type, env)
  10203. self.operand2 = self.operand2.coerce_to(self.type, env)
  10204. self.pow_func = self.type.binary_op('**')
  10205. else:
  10206. error(self.pos, "complex int powers not supported")
  10207. self.pow_func = "<error>"
  10208. elif self.type.is_float:
  10209. self.pow_func = "pow" + self.type.math_h_modifier
  10210. elif self.type.is_int:
  10211. self.pow_func = "__Pyx_pow_%s" % self.type.empty_declaration_code().replace(' ', '_')
  10212. env.use_utility_code(
  10213. UtilityCode.load_cached("IntPow", "CMath.c").specialize(
  10214. func_name=self.pow_func,
  10215. type=self.type.empty_declaration_code(),
  10216. signed=self.type.signed and 1 or 0))
  10217. elif not self.type.is_error:
  10218. error(self.pos, "got unexpected types for C power operator: %s, %s" %
  10219. (self.operand1.type, self.operand2.type))
  10220. def calculate_result_code(self):
  10221. # Work around MSVC overloading ambiguity.
  10222. def typecast(operand):
  10223. if self.type == operand.type:
  10224. return operand.result()
  10225. else:
  10226. return self.type.cast_code(operand.result())
  10227. return "%s(%s, %s)" % (
  10228. self.pow_func,
  10229. typecast(self.operand1),
  10230. typecast(self.operand2))
  10231. def py_operation_function(self, code):
  10232. if (self.type.is_pyobject and
  10233. self.operand1.constant_result == 2 and
  10234. isinstance(self.operand1.constant_result, _py_int_types) and
  10235. self.operand2.type is py_object_type):
  10236. code.globalstate.use_utility_code(UtilityCode.load_cached('PyNumberPow2', 'Optimize.c'))
  10237. if self.inplace:
  10238. return '__Pyx_PyNumber_InPlacePowerOf2'
  10239. else:
  10240. return '__Pyx_PyNumber_PowerOf2'
  10241. return super(PowNode, self).py_operation_function(code)
  10242. class BoolBinopNode(ExprNode):
  10243. """
  10244. Short-circuiting boolean operation.
  10245. Note that this node provides the same code generation method as
  10246. BoolBinopResultNode to simplify expression nesting.
  10247. operator string "and"/"or"
  10248. operand1 BoolBinopNode/BoolBinopResultNode left operand
  10249. operand2 BoolBinopNode/BoolBinopResultNode right operand
  10250. """
  10251. subexprs = ['operand1', 'operand2']
  10252. is_temp = True
  10253. operator = None
  10254. operand1 = None
  10255. operand2 = None
  10256. def infer_type(self, env):
  10257. type1 = self.operand1.infer_type(env)
  10258. type2 = self.operand2.infer_type(env)
  10259. return PyrexTypes.independent_spanning_type(type1, type2)
  10260. def may_be_none(self):
  10261. if self.operator == 'or':
  10262. return self.operand2.may_be_none()
  10263. else:
  10264. return self.operand1.may_be_none() or self.operand2.may_be_none()
  10265. def calculate_constant_result(self):
  10266. operand1 = self.operand1.constant_result
  10267. operand2 = self.operand2.constant_result
  10268. if self.operator == 'and':
  10269. self.constant_result = operand1 and operand2
  10270. else:
  10271. self.constant_result = operand1 or operand2
  10272. def compile_time_value(self, denv):
  10273. operand1 = self.operand1.compile_time_value(denv)
  10274. operand2 = self.operand2.compile_time_value(denv)
  10275. if self.operator == 'and':
  10276. return operand1 and operand2
  10277. else:
  10278. return operand1 or operand2
  10279. def is_ephemeral(self):
  10280. return self.operand1.is_ephemeral() or self.operand2.is_ephemeral()
  10281. def analyse_types(self, env):
  10282. # Note: we do not do any coercion here as we most likely do not know the final type anyway.
  10283. # We even accept to set self.type to ErrorType if both operands do not have a spanning type.
  10284. # The coercion to the final type and to a "simple" value is left to coerce_to().
  10285. operand1 = self.operand1.analyse_types(env)
  10286. operand2 = self.operand2.analyse_types(env)
  10287. self.type = PyrexTypes.independent_spanning_type(
  10288. operand1.type, operand2.type)
  10289. self.operand1 = self._wrap_operand(operand1, env)
  10290. self.operand2 = self._wrap_operand(operand2, env)
  10291. return self
  10292. def _wrap_operand(self, operand, env):
  10293. if not isinstance(operand, (BoolBinopNode, BoolBinopResultNode)):
  10294. operand = BoolBinopResultNode(operand, self.type, env)
  10295. return operand
  10296. def wrap_operands(self, env):
  10297. """
  10298. Must get called by transforms that want to create a correct BoolBinopNode
  10299. after the type analysis phase.
  10300. """
  10301. self.operand1 = self._wrap_operand(self.operand1, env)
  10302. self.operand2 = self._wrap_operand(self.operand2, env)
  10303. def coerce_to_boolean(self, env):
  10304. return self.coerce_to(PyrexTypes.c_bint_type, env)
  10305. def coerce_to(self, dst_type, env):
  10306. operand1 = self.operand1.coerce_to(dst_type, env)
  10307. operand2 = self.operand2.coerce_to(dst_type, env)
  10308. return BoolBinopNode.from_node(
  10309. self, type=dst_type,
  10310. operator=self.operator,
  10311. operand1=operand1, operand2=operand2)
  10312. def generate_bool_evaluation_code(self, code, final_result_temp, final_result_type, and_label, or_label, end_label, fall_through):
  10313. code.mark_pos(self.pos)
  10314. outer_labels = (and_label, or_label)
  10315. if self.operator == 'and':
  10316. my_label = and_label = code.new_label('next_and')
  10317. else:
  10318. my_label = or_label = code.new_label('next_or')
  10319. self.operand1.generate_bool_evaluation_code(
  10320. code, final_result_temp, final_result_type, and_label, or_label, end_label, my_label)
  10321. and_label, or_label = outer_labels
  10322. code.put_label(my_label)
  10323. self.operand2.generate_bool_evaluation_code(
  10324. code, final_result_temp, final_result_type, and_label, or_label, end_label, fall_through)
  10325. def generate_evaluation_code(self, code):
  10326. self.allocate_temp_result(code)
  10327. result_type = PyrexTypes.py_object_type if self.type.is_pyobject else self.type
  10328. or_label = and_label = None
  10329. end_label = code.new_label('bool_binop_done')
  10330. self.generate_bool_evaluation_code(code, self.result(), result_type, and_label, or_label, end_label, end_label)
  10331. code.put_label(end_label)
  10332. gil_message = "Truth-testing Python object"
  10333. def check_const(self):
  10334. return self.operand1.check_const() and self.operand2.check_const()
  10335. def generate_subexpr_disposal_code(self, code):
  10336. pass # nothing to do here, all done in generate_evaluation_code()
  10337. def free_subexpr_temps(self, code):
  10338. pass # nothing to do here, all done in generate_evaluation_code()
  10339. def generate_operand1_test(self, code):
  10340. # Generate code to test the truth of the first operand.
  10341. if self.type.is_pyobject:
  10342. test_result = code.funcstate.allocate_temp(
  10343. PyrexTypes.c_bint_type, manage_ref=False)
  10344. code.putln(
  10345. "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
  10346. test_result,
  10347. self.operand1.py_result(),
  10348. code.error_goto_if_neg(test_result, self.pos)))
  10349. else:
  10350. test_result = self.operand1.result()
  10351. return (test_result, self.type.is_pyobject)
  10352. class BoolBinopResultNode(ExprNode):
  10353. """
  10354. Intermediate result of a short-circuiting and/or expression.
  10355. Tests the result for 'truthiness' and takes care of coercing the final result
  10356. of the overall expression to the target type.
  10357. Note that this node provides the same code generation method as
  10358. BoolBinopNode to simplify expression nesting.
  10359. arg ExprNode the argument to test
  10360. value ExprNode the coerced result value node
  10361. """
  10362. subexprs = ['arg', 'value']
  10363. is_temp = True
  10364. arg = None
  10365. value = None
  10366. def __init__(self, arg, result_type, env):
  10367. # using 'arg' multiple times, so it must be a simple/temp value
  10368. arg = arg.coerce_to_simple(env)
  10369. # wrap in ProxyNode, in case a transform wants to replace self.arg later
  10370. arg = ProxyNode(arg)
  10371. super(BoolBinopResultNode, self).__init__(
  10372. arg.pos, arg=arg, type=result_type,
  10373. value=CloneNode(arg).coerce_to(result_type, env))
  10374. def coerce_to_boolean(self, env):
  10375. return self.coerce_to(PyrexTypes.c_bint_type, env)
  10376. def coerce_to(self, dst_type, env):
  10377. # unwrap, coerce, rewrap
  10378. arg = self.arg.arg
  10379. if dst_type is PyrexTypes.c_bint_type:
  10380. arg = arg.coerce_to_boolean(env)
  10381. # TODO: unwrap more coercion nodes?
  10382. return BoolBinopResultNode(arg, dst_type, env)
  10383. def nogil_check(self, env):
  10384. # let's leave all errors to BoolBinopNode
  10385. pass
  10386. def generate_operand_test(self, code):
  10387. # Generate code to test the truth of the first operand.
  10388. if self.arg.type.is_pyobject:
  10389. test_result = code.funcstate.allocate_temp(
  10390. PyrexTypes.c_bint_type, manage_ref=False)
  10391. code.putln(
  10392. "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
  10393. test_result,
  10394. self.arg.py_result(),
  10395. code.error_goto_if_neg(test_result, self.pos)))
  10396. else:
  10397. test_result = self.arg.result()
  10398. return (test_result, self.arg.type.is_pyobject)
  10399. def generate_bool_evaluation_code(self, code, final_result_temp, final_result_type, and_label, or_label, end_label, fall_through):
  10400. code.mark_pos(self.pos)
  10401. # x => x
  10402. # x and ... or ... => next 'and' / 'or'
  10403. # False ... or x => next 'or'
  10404. # True and x => next 'and'
  10405. # True or x => True (operand)
  10406. self.arg.generate_evaluation_code(code)
  10407. if and_label or or_label:
  10408. test_result, uses_temp = self.generate_operand_test(code)
  10409. if uses_temp and (and_label and or_label):
  10410. # cannot become final result => free early
  10411. # disposal: uses_temp and (and_label and or_label)
  10412. self.arg.generate_disposal_code(code)
  10413. sense = '!' if or_label else ''
  10414. code.putln("if (%s%s) {" % (sense, test_result))
  10415. if uses_temp:
  10416. code.funcstate.release_temp(test_result)
  10417. if not uses_temp or not (and_label and or_label):
  10418. # disposal: (not uses_temp) or {not (and_label and or_label) [if]}
  10419. self.arg.generate_disposal_code(code)
  10420. if or_label and or_label != fall_through:
  10421. # value is false => short-circuit to next 'or'
  10422. code.put_goto(or_label)
  10423. if and_label:
  10424. # value is true => go to next 'and'
  10425. if or_label:
  10426. code.putln("} else {")
  10427. if not uses_temp:
  10428. # disposal: (not uses_temp) and {(and_label and or_label) [else]}
  10429. self.arg.generate_disposal_code(code)
  10430. if and_label != fall_through:
  10431. code.put_goto(and_label)
  10432. if not and_label or not or_label:
  10433. # if no next 'and' or 'or', we provide the result
  10434. if and_label or or_label:
  10435. code.putln("} else {")
  10436. self.value.generate_evaluation_code(code)
  10437. self.value.make_owned_reference(code)
  10438. code.putln("%s = %s;" % (final_result_temp, self.value.result_as(final_result_type)))
  10439. self.value.generate_post_assignment_code(code)
  10440. # disposal: {not (and_label and or_label) [else]}
  10441. self.arg.generate_disposal_code(code)
  10442. self.value.free_temps(code)
  10443. if end_label != fall_through:
  10444. code.put_goto(end_label)
  10445. if and_label or or_label:
  10446. code.putln("}")
  10447. self.arg.free_temps(code)
  10448. class CondExprNode(ExprNode):
  10449. # Short-circuiting conditional expression.
  10450. #
  10451. # test ExprNode
  10452. # true_val ExprNode
  10453. # false_val ExprNode
  10454. true_val = None
  10455. false_val = None
  10456. is_temp = True
  10457. subexprs = ['test', 'true_val', 'false_val']
  10458. def type_dependencies(self, env):
  10459. return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
  10460. def infer_type(self, env):
  10461. return PyrexTypes.independent_spanning_type(
  10462. self.true_val.infer_type(env),
  10463. self.false_val.infer_type(env))
  10464. def calculate_constant_result(self):
  10465. if self.test.constant_result:
  10466. self.constant_result = self.true_val.constant_result
  10467. else:
  10468. self.constant_result = self.false_val.constant_result
  10469. def is_ephemeral(self):
  10470. return self.true_val.is_ephemeral() or self.false_val.is_ephemeral()
  10471. def analyse_types(self, env):
  10472. self.test = self.test.analyse_types(env).coerce_to_boolean(env)
  10473. self.true_val = self.true_val.analyse_types(env)
  10474. self.false_val = self.false_val.analyse_types(env)
  10475. return self.analyse_result_type(env)
  10476. def analyse_result_type(self, env):
  10477. true_val_type = self.true_val.type
  10478. false_val_type = self.false_val.type
  10479. self.type = PyrexTypes.independent_spanning_type(true_val_type, false_val_type)
  10480. if self.type.is_reference:
  10481. self.type = PyrexTypes.CFakeReferenceType(self.type.ref_base_type)
  10482. if self.type.is_pyobject:
  10483. self.result_ctype = py_object_type
  10484. elif self.true_val.is_ephemeral() or self.false_val.is_ephemeral():
  10485. error(self.pos, "Unsafe C derivative of temporary Python reference used in conditional expression")
  10486. if true_val_type.is_pyobject or false_val_type.is_pyobject:
  10487. if true_val_type != self.type:
  10488. self.true_val = self.true_val.coerce_to(self.type, env)
  10489. if false_val_type != self.type:
  10490. self.false_val = self.false_val.coerce_to(self.type, env)
  10491. if self.type.is_error:
  10492. self.type_error()
  10493. return self
  10494. def coerce_to_integer(self, env):
  10495. if not self.true_val.type.is_int:
  10496. self.true_val = self.true_val.coerce_to_integer(env)
  10497. if not self.false_val.type.is_int:
  10498. self.false_val = self.false_val.coerce_to_integer(env)
  10499. self.result_ctype = None
  10500. return self.analyse_result_type(env)
  10501. def coerce_to(self, dst_type, env):
  10502. if self.true_val.type != dst_type:
  10503. self.true_val = self.true_val.coerce_to(dst_type, env)
  10504. if self.false_val.type != dst_type:
  10505. self.false_val = self.false_val.coerce_to(dst_type, env)
  10506. self.result_ctype = None
  10507. return self.analyse_result_type(env)
  10508. def type_error(self):
  10509. if not (self.true_val.type.is_error or self.false_val.type.is_error):
  10510. error(self.pos, "Incompatible types in conditional expression (%s; %s)" %
  10511. (self.true_val.type, self.false_val.type))
  10512. self.type = PyrexTypes.error_type
  10513. def check_const(self):
  10514. return (self.test.check_const()
  10515. and self.true_val.check_const()
  10516. and self.false_val.check_const())
  10517. def generate_evaluation_code(self, code):
  10518. # Because subexprs may not be evaluated we can use a more optimal
  10519. # subexpr allocation strategy than the default, so override evaluation_code.
  10520. code.mark_pos(self.pos)
  10521. self.allocate_temp_result(code)
  10522. self.test.generate_evaluation_code(code)
  10523. code.putln("if (%s) {" % self.test.result())
  10524. self.eval_and_get(code, self.true_val)
  10525. code.putln("} else {")
  10526. self.eval_and_get(code, self.false_val)
  10527. code.putln("}")
  10528. self.test.generate_disposal_code(code)
  10529. self.test.free_temps(code)
  10530. def eval_and_get(self, code, expr):
  10531. expr.generate_evaluation_code(code)
  10532. if self.type.is_memoryviewslice:
  10533. expr.make_owned_memoryviewslice(code)
  10534. else:
  10535. expr.make_owned_reference(code)
  10536. code.putln('%s = %s;' % (self.result(), expr.result_as(self.ctype())))
  10537. expr.generate_post_assignment_code(code)
  10538. expr.free_temps(code)
  10539. def generate_subexpr_disposal_code(self, code):
  10540. pass # done explicitly above (cleanup must separately happen within the if/else blocks)
  10541. def free_subexpr_temps(self, code):
  10542. pass # done explicitly above (cleanup must separately happen within the if/else blocks)
  10543. richcmp_constants = {
  10544. "<" : "Py_LT",
  10545. "<=": "Py_LE",
  10546. "==": "Py_EQ",
  10547. "!=": "Py_NE",
  10548. "<>": "Py_NE",
  10549. ">" : "Py_GT",
  10550. ">=": "Py_GE",
  10551. # the following are faked by special compare functions
  10552. "in" : "Py_EQ",
  10553. "not_in": "Py_NE",
  10554. }
  10555. class CmpNode(object):
  10556. # Mixin class containing code common to PrimaryCmpNodes
  10557. # and CascadedCmpNodes.
  10558. special_bool_cmp_function = None
  10559. special_bool_cmp_utility_code = None
  10560. def infer_type(self, env):
  10561. # TODO: Actually implement this (after merging with -unstable).
  10562. return py_object_type
  10563. def calculate_cascaded_constant_result(self, operand1_result):
  10564. func = compile_time_binary_operators[self.operator]
  10565. operand2_result = self.operand2.constant_result
  10566. if (isinstance(operand1_result, any_string_type) and
  10567. isinstance(operand2_result, any_string_type) and
  10568. type(operand1_result) != type(operand2_result)):
  10569. # string comparison of different types isn't portable
  10570. return
  10571. if self.operator in ('in', 'not_in'):
  10572. if isinstance(self.operand2, (ListNode, TupleNode, SetNode)):
  10573. if not self.operand2.args:
  10574. self.constant_result = self.operator == 'not_in'
  10575. return
  10576. elif isinstance(self.operand2, ListNode) and not self.cascade:
  10577. # tuples are more efficient to store than lists
  10578. self.operand2 = self.operand2.as_tuple()
  10579. elif isinstance(self.operand2, DictNode):
  10580. if not self.operand2.key_value_pairs:
  10581. self.constant_result = self.operator == 'not_in'
  10582. return
  10583. self.constant_result = func(operand1_result, operand2_result)
  10584. def cascaded_compile_time_value(self, operand1, denv):
  10585. func = get_compile_time_binop(self)
  10586. operand2 = self.operand2.compile_time_value(denv)
  10587. try:
  10588. result = func(operand1, operand2)
  10589. except Exception as e:
  10590. self.compile_time_value_error(e)
  10591. result = None
  10592. if result:
  10593. cascade = self.cascade
  10594. if cascade:
  10595. result = result and cascade.cascaded_compile_time_value(operand2, denv)
  10596. return result
  10597. def is_cpp_comparison(self):
  10598. return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
  10599. def find_common_int_type(self, env, op, operand1, operand2):
  10600. # type1 != type2 and at least one of the types is not a C int
  10601. type1 = operand1.type
  10602. type2 = operand2.type
  10603. type1_can_be_int = False
  10604. type2_can_be_int = False
  10605. if operand1.is_string_literal and operand1.can_coerce_to_char_literal():
  10606. type1_can_be_int = True
  10607. if operand2.is_string_literal and operand2.can_coerce_to_char_literal():
  10608. type2_can_be_int = True
  10609. if type1.is_int:
  10610. if type2_can_be_int:
  10611. return type1
  10612. elif type2.is_int:
  10613. if type1_can_be_int:
  10614. return type2
  10615. elif type1_can_be_int:
  10616. if type2_can_be_int:
  10617. if Builtin.unicode_type in (type1, type2):
  10618. return PyrexTypes.c_py_ucs4_type
  10619. else:
  10620. return PyrexTypes.c_uchar_type
  10621. return None
  10622. def find_common_type(self, env, op, operand1, common_type=None):
  10623. operand2 = self.operand2
  10624. type1 = operand1.type
  10625. type2 = operand2.type
  10626. new_common_type = None
  10627. # catch general errors
  10628. if (type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or
  10629. type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type))):
  10630. error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
  10631. new_common_type = error_type
  10632. # try to use numeric comparisons where possible
  10633. elif type1.is_complex or type2.is_complex:
  10634. if (op not in ('==', '!=')
  10635. and (type1.is_complex or type1.is_numeric)
  10636. and (type2.is_complex or type2.is_numeric)):
  10637. error(self.pos, "complex types are unordered")
  10638. new_common_type = error_type
  10639. elif type1.is_pyobject:
  10640. new_common_type = Builtin.complex_type if type1.subtype_of(Builtin.complex_type) else py_object_type
  10641. elif type2.is_pyobject:
  10642. new_common_type = Builtin.complex_type if type2.subtype_of(Builtin.complex_type) else py_object_type
  10643. else:
  10644. new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
  10645. elif type1.is_numeric and type2.is_numeric:
  10646. new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
  10647. elif common_type is None or not common_type.is_pyobject:
  10648. new_common_type = self.find_common_int_type(env, op, operand1, operand2)
  10649. if new_common_type is None:
  10650. # fall back to generic type compatibility tests
  10651. if type1.is_ctuple or type2.is_ctuple:
  10652. new_common_type = py_object_type
  10653. elif type1 == type2:
  10654. new_common_type = type1
  10655. elif type1.is_pyobject or type2.is_pyobject:
  10656. if type2.is_numeric or type2.is_string:
  10657. if operand2.check_for_coercion_error(type1, env):
  10658. new_common_type = error_type
  10659. else:
  10660. new_common_type = py_object_type
  10661. elif type1.is_numeric or type1.is_string:
  10662. if operand1.check_for_coercion_error(type2, env):
  10663. new_common_type = error_type
  10664. else:
  10665. new_common_type = py_object_type
  10666. elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
  10667. new_common_type = py_object_type
  10668. else:
  10669. # one Python type and one non-Python type, not assignable
  10670. self.invalid_types_error(operand1, op, operand2)
  10671. new_common_type = error_type
  10672. elif type1.assignable_from(type2):
  10673. new_common_type = type1
  10674. elif type2.assignable_from(type1):
  10675. new_common_type = type2
  10676. else:
  10677. # C types that we couldn't handle up to here are an error
  10678. self.invalid_types_error(operand1, op, operand2)
  10679. new_common_type = error_type
  10680. if new_common_type.is_string and (isinstance(operand1, BytesNode) or
  10681. isinstance(operand2, BytesNode)):
  10682. # special case when comparing char* to bytes literal: must
  10683. # compare string values!
  10684. new_common_type = bytes_type
  10685. # recursively merge types
  10686. if common_type is None or new_common_type.is_error:
  10687. common_type = new_common_type
  10688. else:
  10689. # we could do a lot better by splitting the comparison
  10690. # into a non-Python part and a Python part, but this is
  10691. # safer for now
  10692. common_type = PyrexTypes.spanning_type(common_type, new_common_type)
  10693. if self.cascade:
  10694. common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
  10695. return common_type
  10696. def invalid_types_error(self, operand1, op, operand2):
  10697. error(self.pos, "Invalid types for '%s' (%s, %s)" %
  10698. (op, operand1.type, operand2.type))
  10699. def is_python_comparison(self):
  10700. return (not self.is_ptr_contains()
  10701. and not self.is_c_string_contains()
  10702. and (self.has_python_operands()
  10703. or (self.cascade and self.cascade.is_python_comparison())
  10704. or self.operator in ('in', 'not_in')))
  10705. def coerce_operands_to(self, dst_type, env):
  10706. operand2 = self.operand2
  10707. if operand2.type != dst_type:
  10708. self.operand2 = operand2.coerce_to(dst_type, env)
  10709. if self.cascade:
  10710. self.cascade.coerce_operands_to(dst_type, env)
  10711. def is_python_result(self):
  10712. return ((self.has_python_operands() and
  10713. self.special_bool_cmp_function is None and
  10714. self.operator not in ('is', 'is_not', 'in', 'not_in') and
  10715. not self.is_c_string_contains() and
  10716. not self.is_ptr_contains())
  10717. or (self.cascade and self.cascade.is_python_result()))
  10718. def is_c_string_contains(self):
  10719. return self.operator in ('in', 'not_in') and \
  10720. ((self.operand1.type.is_int
  10721. and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
  10722. (self.operand1.type.is_unicode_char
  10723. and self.operand2.type is unicode_type))
  10724. def is_ptr_contains(self):
  10725. if self.operator in ('in', 'not_in'):
  10726. container_type = self.operand2.type
  10727. return (container_type.is_ptr or container_type.is_array) \
  10728. and not container_type.is_string
  10729. def find_special_bool_compare_function(self, env, operand1, result_is_bool=False):
  10730. # note: currently operand1 must get coerced to a Python object if we succeed here!
  10731. if self.operator in ('==', '!='):
  10732. type1, type2 = operand1.type, self.operand2.type
  10733. if result_is_bool or (type1.is_builtin_type and type2.is_builtin_type):
  10734. if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
  10735. self.special_bool_cmp_utility_code = UtilityCode.load_cached("UnicodeEquals", "StringTools.c")
  10736. self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
  10737. return True
  10738. elif type1 is Builtin.bytes_type or type2 is Builtin.bytes_type:
  10739. self.special_bool_cmp_utility_code = UtilityCode.load_cached("BytesEquals", "StringTools.c")
  10740. self.special_bool_cmp_function = "__Pyx_PyBytes_Equals"
  10741. return True
  10742. elif type1 is Builtin.basestring_type or type2 is Builtin.basestring_type:
  10743. self.special_bool_cmp_utility_code = UtilityCode.load_cached("UnicodeEquals", "StringTools.c")
  10744. self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
  10745. return True
  10746. elif type1 is Builtin.str_type or type2 is Builtin.str_type:
  10747. self.special_bool_cmp_utility_code = UtilityCode.load_cached("StrEquals", "StringTools.c")
  10748. self.special_bool_cmp_function = "__Pyx_PyString_Equals"
  10749. return True
  10750. elif self.operator in ('in', 'not_in'):
  10751. if self.operand2.type is Builtin.dict_type:
  10752. self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
  10753. self.special_bool_cmp_utility_code = UtilityCode.load_cached("PyDictContains", "ObjectHandling.c")
  10754. self.special_bool_cmp_function = "__Pyx_PyDict_ContainsTF"
  10755. return True
  10756. elif self.operand2.type is Builtin.set_type:
  10757. self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
  10758. self.special_bool_cmp_utility_code = UtilityCode.load_cached("PySetContains", "ObjectHandling.c")
  10759. self.special_bool_cmp_function = "__Pyx_PySet_ContainsTF"
  10760. return True
  10761. elif self.operand2.type is Builtin.unicode_type:
  10762. self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
  10763. self.special_bool_cmp_utility_code = UtilityCode.load_cached("PyUnicodeContains", "StringTools.c")
  10764. self.special_bool_cmp_function = "__Pyx_PyUnicode_ContainsTF"
  10765. return True
  10766. else:
  10767. if not self.operand2.type.is_pyobject:
  10768. self.operand2 = self.operand2.coerce_to_pyobject(env)
  10769. self.special_bool_cmp_utility_code = UtilityCode.load_cached("PySequenceContains", "ObjectHandling.c")
  10770. self.special_bool_cmp_function = "__Pyx_PySequence_ContainsTF"
  10771. return True
  10772. return False
  10773. def generate_operation_code(self, code, result_code,
  10774. operand1, op , operand2):
  10775. if self.type.is_pyobject:
  10776. error_clause = code.error_goto_if_null
  10777. got_ref = "__Pyx_XGOTREF(%s); " % result_code
  10778. if self.special_bool_cmp_function:
  10779. code.globalstate.use_utility_code(
  10780. UtilityCode.load_cached("PyBoolOrNullFromLong", "ObjectHandling.c"))
  10781. coerce_result = "__Pyx_PyBoolOrNull_FromLong"
  10782. else:
  10783. coerce_result = "__Pyx_PyBool_FromLong"
  10784. else:
  10785. error_clause = code.error_goto_if_neg
  10786. got_ref = ""
  10787. coerce_result = ""
  10788. if self.special_bool_cmp_function:
  10789. if operand1.type.is_pyobject:
  10790. result1 = operand1.py_result()
  10791. else:
  10792. result1 = operand1.result()
  10793. if operand2.type.is_pyobject:
  10794. result2 = operand2.py_result()
  10795. else:
  10796. result2 = operand2.result()
  10797. if self.special_bool_cmp_utility_code:
  10798. code.globalstate.use_utility_code(self.special_bool_cmp_utility_code)
  10799. code.putln(
  10800. "%s = %s(%s(%s, %s, %s)); %s%s" % (
  10801. result_code,
  10802. coerce_result,
  10803. self.special_bool_cmp_function,
  10804. result1, result2, richcmp_constants[op],
  10805. got_ref,
  10806. error_clause(result_code, self.pos)))
  10807. elif operand1.type.is_pyobject and op not in ('is', 'is_not'):
  10808. assert op not in ('in', 'not_in'), op
  10809. code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s%s" % (
  10810. result_code,
  10811. operand1.py_result(),
  10812. operand2.py_result(),
  10813. richcmp_constants[op],
  10814. got_ref,
  10815. error_clause(result_code, self.pos)))
  10816. elif operand1.type.is_complex:
  10817. code.putln("%s = %s(%s%s(%s, %s));" % (
  10818. result_code,
  10819. coerce_result,
  10820. op == "!=" and "!" or "",
  10821. operand1.type.unary_op('eq'),
  10822. operand1.result(),
  10823. operand2.result()))
  10824. else:
  10825. type1 = operand1.type
  10826. type2 = operand2.type
  10827. if (type1.is_extension_type or type2.is_extension_type) \
  10828. and not type1.same_as(type2):
  10829. common_type = py_object_type
  10830. elif type1.is_numeric:
  10831. common_type = PyrexTypes.widest_numeric_type(type1, type2)
  10832. else:
  10833. common_type = type1
  10834. code1 = operand1.result_as(common_type)
  10835. code2 = operand2.result_as(common_type)
  10836. statement = "%s = %s(%s %s %s);" % (
  10837. result_code,
  10838. coerce_result,
  10839. code1,
  10840. self.c_operator(op),
  10841. code2)
  10842. if self.is_cpp_comparison() and self.exception_check == '+':
  10843. translate_cpp_exception(
  10844. code,
  10845. self.pos,
  10846. statement,
  10847. result_code if self.type.is_pyobject else None,
  10848. self.exception_value,
  10849. self.in_nogil_context)
  10850. else:
  10851. code.putln(statement)
  10852. def c_operator(self, op):
  10853. if op == 'is':
  10854. return "=="
  10855. elif op == 'is_not':
  10856. return "!="
  10857. else:
  10858. return op
  10859. class PrimaryCmpNode(ExprNode, CmpNode):
  10860. # Non-cascaded comparison or first comparison of
  10861. # a cascaded sequence.
  10862. #
  10863. # operator string
  10864. # operand1 ExprNode
  10865. # operand2 ExprNode
  10866. # cascade CascadedCmpNode
  10867. # We don't use the subexprs mechanism, because
  10868. # things here are too complicated for it to handle.
  10869. # Instead, we override all the framework methods
  10870. # which use it.
  10871. child_attrs = ['operand1', 'operand2', 'coerced_operand2', 'cascade']
  10872. cascade = None
  10873. coerced_operand2 = None
  10874. is_memslice_nonecheck = False
  10875. def infer_type(self, env):
  10876. type1 = self.operand1.infer_type(env)
  10877. type2 = self.operand2.infer_type(env)
  10878. if is_pythran_expr(type1) or is_pythran_expr(type2):
  10879. if is_pythran_supported_type(type1) and is_pythran_supported_type(type2):
  10880. return PythranExpr(pythran_binop_type(self.operator, type1, type2))
  10881. # TODO: implement this for other types.
  10882. return py_object_type
  10883. def type_dependencies(self, env):
  10884. return ()
  10885. def calculate_constant_result(self):
  10886. assert not self.cascade
  10887. self.calculate_cascaded_constant_result(self.operand1.constant_result)
  10888. def compile_time_value(self, denv):
  10889. operand1 = self.operand1.compile_time_value(denv)
  10890. return self.cascaded_compile_time_value(operand1, denv)
  10891. def analyse_types(self, env):
  10892. self.operand1 = self.operand1.analyse_types(env)
  10893. self.operand2 = self.operand2.analyse_types(env)
  10894. if self.is_cpp_comparison():
  10895. self.analyse_cpp_comparison(env)
  10896. if self.cascade:
  10897. error(self.pos, "Cascading comparison not yet supported for cpp types.")
  10898. return self
  10899. type1 = self.operand1.type
  10900. type2 = self.operand2.type
  10901. if is_pythran_expr(type1) or is_pythran_expr(type2):
  10902. if is_pythran_supported_type(type1) and is_pythran_supported_type(type2):
  10903. self.type = PythranExpr(pythran_binop_type(self.operator, type1, type2))
  10904. self.is_pycmp = False
  10905. return self
  10906. if self.analyse_memoryviewslice_comparison(env):
  10907. return self
  10908. if self.cascade:
  10909. self.cascade = self.cascade.analyse_types(env)
  10910. if self.operator in ('in', 'not_in'):
  10911. if self.is_c_string_contains():
  10912. self.is_pycmp = False
  10913. common_type = None
  10914. if self.cascade:
  10915. error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
  10916. return self
  10917. if self.operand2.type is unicode_type:
  10918. env.use_utility_code(UtilityCode.load_cached("PyUCS4InUnicode", "StringTools.c"))
  10919. else:
  10920. if self.operand1.type is PyrexTypes.c_uchar_type:
  10921. self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
  10922. if self.operand2.type is not bytes_type:
  10923. self.operand2 = self.operand2.coerce_to(bytes_type, env)
  10924. env.use_utility_code(UtilityCode.load_cached("BytesContains", "StringTools.c"))
  10925. self.operand2 = self.operand2.as_none_safe_node(
  10926. "argument of type 'NoneType' is not iterable")
  10927. elif self.is_ptr_contains():
  10928. if self.cascade:
  10929. error(self.pos, "Cascading comparison not supported for 'val in sliced pointer'.")
  10930. self.type = PyrexTypes.c_bint_type
  10931. # Will be transformed by IterationTransform
  10932. return self
  10933. elif self.find_special_bool_compare_function(env, self.operand1):
  10934. if not self.operand1.type.is_pyobject:
  10935. self.operand1 = self.operand1.coerce_to_pyobject(env)
  10936. common_type = None # if coercion needed, the method call above has already done it
  10937. self.is_pycmp = False # result is bint
  10938. else:
  10939. common_type = py_object_type
  10940. self.is_pycmp = True
  10941. elif self.find_special_bool_compare_function(env, self.operand1):
  10942. if not self.operand1.type.is_pyobject:
  10943. self.operand1 = self.operand1.coerce_to_pyobject(env)
  10944. common_type = None # if coercion needed, the method call above has already done it
  10945. self.is_pycmp = False # result is bint
  10946. else:
  10947. common_type = self.find_common_type(env, self.operator, self.operand1)
  10948. self.is_pycmp = common_type.is_pyobject
  10949. if common_type is not None and not common_type.is_error:
  10950. if self.operand1.type != common_type:
  10951. self.operand1 = self.operand1.coerce_to(common_type, env)
  10952. self.coerce_operands_to(common_type, env)
  10953. if self.cascade:
  10954. self.operand2 = self.operand2.coerce_to_simple(env)
  10955. self.cascade.coerce_cascaded_operands_to_temp(env)
  10956. operand2 = self.cascade.optimise_comparison(self.operand2, env)
  10957. if operand2 is not self.operand2:
  10958. self.coerced_operand2 = operand2
  10959. if self.is_python_result():
  10960. self.type = PyrexTypes.py_object_type
  10961. else:
  10962. self.type = PyrexTypes.c_bint_type
  10963. cdr = self.cascade
  10964. while cdr:
  10965. cdr.type = self.type
  10966. cdr = cdr.cascade
  10967. if self.is_pycmp or self.cascade or self.special_bool_cmp_function:
  10968. # 1) owned reference, 2) reused value, 3) potential function error return value
  10969. self.is_temp = 1
  10970. return self
  10971. def analyse_cpp_comparison(self, env):
  10972. type1 = self.operand1.type
  10973. type2 = self.operand2.type
  10974. self.is_pycmp = False
  10975. entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
  10976. if entry is None:
  10977. error(self.pos, "Invalid types for '%s' (%s, %s)" %
  10978. (self.operator, type1, type2))
  10979. self.type = PyrexTypes.error_type
  10980. self.result_code = "<error>"
  10981. return
  10982. func_type = entry.type
  10983. if func_type.is_ptr:
  10984. func_type = func_type.base_type
  10985. self.exception_check = func_type.exception_check
  10986. self.exception_value = func_type.exception_value
  10987. if self.exception_check == '+':
  10988. self.is_temp = True
  10989. if self.exception_value is None:
  10990. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  10991. if len(func_type.args) == 1:
  10992. self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
  10993. else:
  10994. self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
  10995. self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
  10996. self.type = func_type.return_type
  10997. def analyse_memoryviewslice_comparison(self, env):
  10998. have_none = self.operand1.is_none or self.operand2.is_none
  10999. have_slice = (self.operand1.type.is_memoryviewslice or
  11000. self.operand2.type.is_memoryviewslice)
  11001. ops = ('==', '!=', 'is', 'is_not')
  11002. if have_slice and have_none and self.operator in ops:
  11003. self.is_pycmp = False
  11004. self.type = PyrexTypes.c_bint_type
  11005. self.is_memslice_nonecheck = True
  11006. return True
  11007. return False
  11008. def coerce_to_boolean(self, env):
  11009. if self.is_pycmp:
  11010. # coercing to bool => may allow for more efficient comparison code
  11011. if self.find_special_bool_compare_function(
  11012. env, self.operand1, result_is_bool=True):
  11013. self.is_pycmp = False
  11014. self.type = PyrexTypes.c_bint_type
  11015. self.is_temp = 1
  11016. if self.cascade:
  11017. operand2 = self.cascade.optimise_comparison(
  11018. self.operand2, env, result_is_bool=True)
  11019. if operand2 is not self.operand2:
  11020. self.coerced_operand2 = operand2
  11021. return self
  11022. # TODO: check if we can optimise parts of the cascade here
  11023. return ExprNode.coerce_to_boolean(self, env)
  11024. def has_python_operands(self):
  11025. return (self.operand1.type.is_pyobject
  11026. or self.operand2.type.is_pyobject)
  11027. def check_const(self):
  11028. if self.cascade:
  11029. self.not_const()
  11030. return False
  11031. else:
  11032. return self.operand1.check_const() and self.operand2.check_const()
  11033. def calculate_result_code(self):
  11034. operand1, operand2 = self.operand1, self.operand2
  11035. if operand1.type.is_complex:
  11036. if self.operator == "!=":
  11037. negation = "!"
  11038. else:
  11039. negation = ""
  11040. return "(%s%s(%s, %s))" % (
  11041. negation,
  11042. operand1.type.binary_op('=='),
  11043. operand1.result(),
  11044. operand2.result())
  11045. elif self.is_c_string_contains():
  11046. if operand2.type is unicode_type:
  11047. method = "__Pyx_UnicodeContainsUCS4"
  11048. else:
  11049. method = "__Pyx_BytesContains"
  11050. if self.operator == "not_in":
  11051. negation = "!"
  11052. else:
  11053. negation = ""
  11054. return "(%s%s(%s, %s))" % (
  11055. negation,
  11056. method,
  11057. operand2.result(),
  11058. operand1.result())
  11059. else:
  11060. if is_pythran_expr(self.type):
  11061. result1, result2 = operand1.pythran_result(), operand2.pythran_result()
  11062. else:
  11063. result1, result2 = operand1.result(), operand2.result()
  11064. if self.is_memslice_nonecheck:
  11065. if operand1.type.is_memoryviewslice:
  11066. result1 = "((PyObject *) %s.memview)" % result1
  11067. else:
  11068. result2 = "((PyObject *) %s.memview)" % result2
  11069. return "(%s %s %s)" % (
  11070. result1,
  11071. self.c_operator(self.operator),
  11072. result2)
  11073. def generate_evaluation_code(self, code):
  11074. self.operand1.generate_evaluation_code(code)
  11075. self.operand2.generate_evaluation_code(code)
  11076. if self.is_temp:
  11077. self.allocate_temp_result(code)
  11078. self.generate_operation_code(code, self.result(),
  11079. self.operand1, self.operator, self.operand2)
  11080. if self.cascade:
  11081. self.cascade.generate_evaluation_code(
  11082. code, self.result(), self.coerced_operand2 or self.operand2,
  11083. needs_evaluation=self.coerced_operand2 is not None)
  11084. self.operand1.generate_disposal_code(code)
  11085. self.operand1.free_temps(code)
  11086. self.operand2.generate_disposal_code(code)
  11087. self.operand2.free_temps(code)
  11088. def generate_subexpr_disposal_code(self, code):
  11089. # If this is called, it is a non-cascaded cmp,
  11090. # so only need to dispose of the two main operands.
  11091. self.operand1.generate_disposal_code(code)
  11092. self.operand2.generate_disposal_code(code)
  11093. def free_subexpr_temps(self, code):
  11094. # If this is called, it is a non-cascaded cmp,
  11095. # so only need to dispose of the two main operands.
  11096. self.operand1.free_temps(code)
  11097. self.operand2.free_temps(code)
  11098. def annotate(self, code):
  11099. self.operand1.annotate(code)
  11100. self.operand2.annotate(code)
  11101. if self.cascade:
  11102. self.cascade.annotate(code)
  11103. class CascadedCmpNode(Node, CmpNode):
  11104. # A CascadedCmpNode is not a complete expression node. It
  11105. # hangs off the side of another comparison node, shares
  11106. # its left operand with that node, and shares its result
  11107. # with the PrimaryCmpNode at the head of the chain.
  11108. #
  11109. # operator string
  11110. # operand2 ExprNode
  11111. # cascade CascadedCmpNode
  11112. child_attrs = ['operand2', 'coerced_operand2', 'cascade']
  11113. cascade = None
  11114. coerced_operand2 = None
  11115. constant_result = constant_value_not_set # FIXME: where to calculate this?
  11116. def infer_type(self, env):
  11117. # TODO: Actually implement this (after merging with -unstable).
  11118. return py_object_type
  11119. def type_dependencies(self, env):
  11120. return ()
  11121. def has_constant_result(self):
  11122. return self.constant_result is not constant_value_not_set and \
  11123. self.constant_result is not not_a_constant
  11124. def analyse_types(self, env):
  11125. self.operand2 = self.operand2.analyse_types(env)
  11126. if self.cascade:
  11127. self.cascade = self.cascade.analyse_types(env)
  11128. return self
  11129. def has_python_operands(self):
  11130. return self.operand2.type.is_pyobject
  11131. def is_cpp_comparison(self):
  11132. # cascaded comparisons aren't currently implemented for c++ classes.
  11133. return False
  11134. def optimise_comparison(self, operand1, env, result_is_bool=False):
  11135. if self.find_special_bool_compare_function(env, operand1, result_is_bool):
  11136. self.is_pycmp = False
  11137. self.type = PyrexTypes.c_bint_type
  11138. if not operand1.type.is_pyobject:
  11139. operand1 = operand1.coerce_to_pyobject(env)
  11140. if self.cascade:
  11141. operand2 = self.cascade.optimise_comparison(self.operand2, env, result_is_bool)
  11142. if operand2 is not self.operand2:
  11143. self.coerced_operand2 = operand2
  11144. return operand1
  11145. def coerce_operands_to_pyobjects(self, env):
  11146. self.operand2 = self.operand2.coerce_to_pyobject(env)
  11147. if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
  11148. self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
  11149. if self.cascade:
  11150. self.cascade.coerce_operands_to_pyobjects(env)
  11151. def coerce_cascaded_operands_to_temp(self, env):
  11152. if self.cascade:
  11153. #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
  11154. self.operand2 = self.operand2.coerce_to_simple(env)
  11155. self.cascade.coerce_cascaded_operands_to_temp(env)
  11156. def generate_evaluation_code(self, code, result, operand1, needs_evaluation=False):
  11157. if self.type.is_pyobject:
  11158. code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
  11159. code.put_decref(result, self.type)
  11160. else:
  11161. code.putln("if (%s) {" % result)
  11162. if needs_evaluation:
  11163. operand1.generate_evaluation_code(code)
  11164. self.operand2.generate_evaluation_code(code)
  11165. self.generate_operation_code(code, result,
  11166. operand1, self.operator, self.operand2)
  11167. if self.cascade:
  11168. self.cascade.generate_evaluation_code(
  11169. code, result, self.coerced_operand2 or self.operand2,
  11170. needs_evaluation=self.coerced_operand2 is not None)
  11171. if needs_evaluation:
  11172. operand1.generate_disposal_code(code)
  11173. operand1.free_temps(code)
  11174. # Cascaded cmp result is always temp
  11175. self.operand2.generate_disposal_code(code)
  11176. self.operand2.free_temps(code)
  11177. code.putln("}")
  11178. def annotate(self, code):
  11179. self.operand2.annotate(code)
  11180. if self.cascade:
  11181. self.cascade.annotate(code)
  11182. binop_node_classes = {
  11183. "or": BoolBinopNode,
  11184. "and": BoolBinopNode,
  11185. "|": IntBinopNode,
  11186. "^": IntBinopNode,
  11187. "&": IntBinopNode,
  11188. "<<": IntBinopNode,
  11189. ">>": IntBinopNode,
  11190. "+": AddNode,
  11191. "-": SubNode,
  11192. "*": MulNode,
  11193. "@": MatMultNode,
  11194. "/": DivNode,
  11195. "//": DivNode,
  11196. "%": ModNode,
  11197. "**": PowNode,
  11198. }
  11199. def binop_node(pos, operator, operand1, operand2, inplace=False, **kwargs):
  11200. # Construct binop node of appropriate class for
  11201. # given operator.
  11202. return binop_node_classes[operator](
  11203. pos,
  11204. operator=operator,
  11205. operand1=operand1,
  11206. operand2=operand2,
  11207. inplace=inplace,
  11208. **kwargs)
  11209. #-------------------------------------------------------------------
  11210. #
  11211. # Coercion nodes
  11212. #
  11213. # Coercion nodes are special in that they are created during
  11214. # the analyse_types phase of parse tree processing.
  11215. # Their __init__ methods consequently incorporate some aspects
  11216. # of that phase.
  11217. #
  11218. #-------------------------------------------------------------------
  11219. class CoercionNode(ExprNode):
  11220. # Abstract base class for coercion nodes.
  11221. #
  11222. # arg ExprNode node being coerced
  11223. subexprs = ['arg']
  11224. constant_result = not_a_constant
  11225. def __init__(self, arg):
  11226. super(CoercionNode, self).__init__(arg.pos)
  11227. self.arg = arg
  11228. if debug_coercion:
  11229. print("%s Coercing %s" % (self, self.arg))
  11230. def calculate_constant_result(self):
  11231. # constant folding can break type coercion, so this is disabled
  11232. pass
  11233. def annotate(self, code):
  11234. self.arg.annotate(code)
  11235. if self.arg.type != self.type:
  11236. file, line, col = self.pos
  11237. code.annotate((file, line, col-1), AnnotationItem(
  11238. style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
  11239. class CoerceToMemViewSliceNode(CoercionNode):
  11240. """
  11241. Coerce an object to a memoryview slice. This holds a new reference in
  11242. a managed temp.
  11243. """
  11244. def __init__(self, arg, dst_type, env):
  11245. assert dst_type.is_memoryviewslice
  11246. assert not arg.type.is_memoryviewslice
  11247. CoercionNode.__init__(self, arg)
  11248. self.type = dst_type
  11249. self.is_temp = 1
  11250. self.use_managed_ref = True
  11251. self.arg = arg
  11252. self.type.create_from_py_utility_code(env)
  11253. def generate_result_code(self, code):
  11254. code.putln(self.type.from_py_call_code(
  11255. self.arg.py_result(),
  11256. self.result(),
  11257. self.pos,
  11258. code
  11259. ))
  11260. class CastNode(CoercionNode):
  11261. # Wrap a node in a C type cast.
  11262. def __init__(self, arg, new_type):
  11263. CoercionNode.__init__(self, arg)
  11264. self.type = new_type
  11265. def may_be_none(self):
  11266. return self.arg.may_be_none()
  11267. def calculate_result_code(self):
  11268. return self.arg.result_as(self.type)
  11269. def generate_result_code(self, code):
  11270. self.arg.generate_result_code(code)
  11271. class PyTypeTestNode(CoercionNode):
  11272. # This node is used to check that a generic Python
  11273. # object is an instance of a particular extension type.
  11274. # This node borrows the result of its argument node.
  11275. exact_builtin_type = True
  11276. def __init__(self, arg, dst_type, env, notnone=False):
  11277. # The arg is know to be a Python object, and
  11278. # the dst_type is known to be an extension type.
  11279. assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
  11280. CoercionNode.__init__(self, arg)
  11281. self.type = dst_type
  11282. self.result_ctype = arg.ctype()
  11283. self.notnone = notnone
  11284. nogil_check = Node.gil_error
  11285. gil_message = "Python type test"
  11286. def analyse_types(self, env):
  11287. return self
  11288. def may_be_none(self):
  11289. if self.notnone:
  11290. return False
  11291. return self.arg.may_be_none()
  11292. def is_simple(self):
  11293. return self.arg.is_simple()
  11294. def result_in_temp(self):
  11295. return self.arg.result_in_temp()
  11296. def is_ephemeral(self):
  11297. return self.arg.is_ephemeral()
  11298. def nonlocally_immutable(self):
  11299. return self.arg.nonlocally_immutable()
  11300. def reanalyse(self):
  11301. if self.type != self.arg.type or not self.arg.is_temp:
  11302. return self
  11303. if not self.type.typeobj_is_available():
  11304. return self
  11305. if self.arg.may_be_none() and self.notnone:
  11306. return self.arg.as_none_safe_node("Cannot convert NoneType to %.200s" % self.type.name)
  11307. return self.arg
  11308. def calculate_constant_result(self):
  11309. # FIXME
  11310. pass
  11311. def calculate_result_code(self):
  11312. return self.arg.result()
  11313. def generate_result_code(self, code):
  11314. if self.type.typeobj_is_available():
  11315. if self.type.is_builtin_type:
  11316. type_test = self.type.type_test_code(
  11317. self.arg.py_result(),
  11318. self.notnone, exact=self.exact_builtin_type)
  11319. else:
  11320. type_test = self.type.type_test_code(
  11321. self.arg.py_result(), self.notnone)
  11322. code.globalstate.use_utility_code(
  11323. UtilityCode.load_cached("ExtTypeTest", "ObjectHandling.c"))
  11324. code.putln("if (!(%s)) %s" % (
  11325. type_test, code.error_goto(self.pos)))
  11326. else:
  11327. error(self.pos, "Cannot test type of extern C class "
  11328. "without type object name specification")
  11329. def generate_post_assignment_code(self, code):
  11330. self.arg.generate_post_assignment_code(code)
  11331. def allocate_temp_result(self, code):
  11332. pass
  11333. def release_temp_result(self, code):
  11334. pass
  11335. def free_temps(self, code):
  11336. self.arg.free_temps(code)
  11337. def free_subexpr_temps(self, code):
  11338. self.arg.free_subexpr_temps(code)
  11339. class NoneCheckNode(CoercionNode):
  11340. # This node is used to check that a Python object is not None and
  11341. # raises an appropriate exception (as specified by the creating
  11342. # transform).
  11343. is_nonecheck = True
  11344. def __init__(self, arg, exception_type_cname, exception_message,
  11345. exception_format_args=()):
  11346. CoercionNode.__init__(self, arg)
  11347. self.type = arg.type
  11348. self.result_ctype = arg.ctype()
  11349. self.exception_type_cname = exception_type_cname
  11350. self.exception_message = exception_message
  11351. self.exception_format_args = tuple(exception_format_args or ())
  11352. nogil_check = None # this node only guards an operation that would fail already
  11353. def analyse_types(self, env):
  11354. return self
  11355. def may_be_none(self):
  11356. return False
  11357. def is_simple(self):
  11358. return self.arg.is_simple()
  11359. def result_in_temp(self):
  11360. return self.arg.result_in_temp()
  11361. def nonlocally_immutable(self):
  11362. return self.arg.nonlocally_immutable()
  11363. def calculate_result_code(self):
  11364. return self.arg.result()
  11365. def condition(self):
  11366. if self.type.is_pyobject:
  11367. return self.arg.py_result()
  11368. elif self.type.is_memoryviewslice:
  11369. return "((PyObject *) %s.memview)" % self.arg.result()
  11370. else:
  11371. raise Exception("unsupported type")
  11372. @classmethod
  11373. def generate(cls, arg, code, exception_message,
  11374. exception_type_cname="PyExc_TypeError", exception_format_args=(), in_nogil_context=False):
  11375. node = cls(arg, exception_type_cname, exception_message, exception_format_args)
  11376. node.in_nogil_context = in_nogil_context
  11377. node.put_nonecheck(code)
  11378. @classmethod
  11379. def generate_if_needed(cls, arg, code, exception_message,
  11380. exception_type_cname="PyExc_TypeError", exception_format_args=(), in_nogil_context=False):
  11381. if arg.may_be_none():
  11382. cls.generate(arg, code, exception_message, exception_type_cname, exception_format_args, in_nogil_context)
  11383. def put_nonecheck(self, code):
  11384. code.putln(
  11385. "if (unlikely(%s == Py_None)) {" % self.condition())
  11386. if self.in_nogil_context:
  11387. code.put_ensure_gil()
  11388. escape = StringEncoding.escape_byte_string
  11389. if self.exception_format_args:
  11390. code.putln('PyErr_Format(%s, "%s", %s);' % (
  11391. self.exception_type_cname,
  11392. StringEncoding.escape_byte_string(
  11393. self.exception_message.encode('UTF-8')),
  11394. ', '.join([ '"%s"' % escape(str(arg).encode('UTF-8'))
  11395. for arg in self.exception_format_args ])))
  11396. else:
  11397. code.putln('PyErr_SetString(%s, "%s");' % (
  11398. self.exception_type_cname,
  11399. escape(self.exception_message.encode('UTF-8'))))
  11400. if self.in_nogil_context:
  11401. code.put_release_ensured_gil()
  11402. code.putln(code.error_goto(self.pos))
  11403. code.putln("}")
  11404. def generate_result_code(self, code):
  11405. self.put_nonecheck(code)
  11406. def generate_post_assignment_code(self, code):
  11407. self.arg.generate_post_assignment_code(code)
  11408. def free_temps(self, code):
  11409. self.arg.free_temps(code)
  11410. class CoerceToPyTypeNode(CoercionNode):
  11411. # This node is used to convert a C data type
  11412. # to a Python object.
  11413. type = py_object_type
  11414. target_type = py_object_type
  11415. is_temp = 1
  11416. def __init__(self, arg, env, type=py_object_type):
  11417. if not arg.type.create_to_py_utility_code(env):
  11418. error(arg.pos, "Cannot convert '%s' to Python object" % arg.type)
  11419. elif arg.type.is_complex:
  11420. # special case: complex coercion is so complex that it
  11421. # uses a macro ("__pyx_PyComplex_FromComplex()"), for
  11422. # which the argument must be simple
  11423. arg = arg.coerce_to_simple(env)
  11424. CoercionNode.__init__(self, arg)
  11425. if type is py_object_type:
  11426. # be specific about some known types
  11427. if arg.type.is_string or arg.type.is_cpp_string:
  11428. self.type = default_str_type(env)
  11429. elif arg.type.is_pyunicode_ptr or arg.type.is_unicode_char:
  11430. self.type = unicode_type
  11431. elif arg.type.is_complex:
  11432. self.type = Builtin.complex_type
  11433. self.target_type = self.type
  11434. elif arg.type.is_string or arg.type.is_cpp_string:
  11435. if (type not in (bytes_type, bytearray_type)
  11436. and not env.directives['c_string_encoding']):
  11437. error(arg.pos,
  11438. "default encoding required for conversion from '%s' to '%s'" %
  11439. (arg.type, type))
  11440. self.type = self.target_type = type
  11441. else:
  11442. # FIXME: check that the target type and the resulting type are compatible
  11443. self.target_type = type
  11444. gil_message = "Converting to Python object"
  11445. def may_be_none(self):
  11446. # FIXME: is this always safe?
  11447. return False
  11448. def coerce_to_boolean(self, env):
  11449. arg_type = self.arg.type
  11450. if (arg_type == PyrexTypes.c_bint_type or
  11451. (arg_type.is_pyobject and arg_type.name == 'bool')):
  11452. return self.arg.coerce_to_temp(env)
  11453. else:
  11454. return CoerceToBooleanNode(self, env)
  11455. def coerce_to_integer(self, env):
  11456. # If not already some C integer type, coerce to longint.
  11457. if self.arg.type.is_int:
  11458. return self.arg
  11459. else:
  11460. return self.arg.coerce_to(PyrexTypes.c_long_type, env)
  11461. def analyse_types(self, env):
  11462. # The arg is always already analysed
  11463. return self
  11464. def generate_result_code(self, code):
  11465. code.putln('%s; %s' % (
  11466. self.arg.type.to_py_call_code(
  11467. self.arg.result(),
  11468. self.result(),
  11469. self.target_type),
  11470. code.error_goto_if_null(self.result(), self.pos)))
  11471. code.put_gotref(self.py_result())
  11472. class CoerceIntToBytesNode(CoerceToPyTypeNode):
  11473. # This node is used to convert a C int type to a Python bytes
  11474. # object.
  11475. is_temp = 1
  11476. def __init__(self, arg, env):
  11477. arg = arg.coerce_to_simple(env)
  11478. CoercionNode.__init__(self, arg)
  11479. self.type = Builtin.bytes_type
  11480. def generate_result_code(self, code):
  11481. arg = self.arg
  11482. arg_result = arg.result()
  11483. if arg.type not in (PyrexTypes.c_char_type,
  11484. PyrexTypes.c_uchar_type,
  11485. PyrexTypes.c_schar_type):
  11486. if arg.type.signed:
  11487. code.putln("if ((%s < 0) || (%s > 255)) {" % (
  11488. arg_result, arg_result))
  11489. else:
  11490. code.putln("if (%s > 255) {" % arg_result)
  11491. code.putln('PyErr_SetString(PyExc_OverflowError, '
  11492. '"value too large to pack into a byte"); %s' % (
  11493. code.error_goto(self.pos)))
  11494. code.putln('}')
  11495. temp = None
  11496. if arg.type is not PyrexTypes.c_char_type:
  11497. temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
  11498. code.putln("%s = (char)%s;" % (temp, arg_result))
  11499. arg_result = temp
  11500. code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
  11501. self.result(),
  11502. arg_result,
  11503. code.error_goto_if_null(self.result(), self.pos)))
  11504. if temp is not None:
  11505. code.funcstate.release_temp(temp)
  11506. code.put_gotref(self.py_result())
  11507. class CoerceFromPyTypeNode(CoercionNode):
  11508. # This node is used to convert a Python object
  11509. # to a C data type.
  11510. def __init__(self, result_type, arg, env):
  11511. CoercionNode.__init__(self, arg)
  11512. self.type = result_type
  11513. self.is_temp = 1
  11514. if not result_type.create_from_py_utility_code(env):
  11515. error(arg.pos,
  11516. "Cannot convert Python object to '%s'" % result_type)
  11517. if self.type.is_string or self.type.is_pyunicode_ptr:
  11518. if self.arg.is_name and self.arg.entry and self.arg.entry.is_pyglobal:
  11519. warning(arg.pos,
  11520. "Obtaining '%s' from externally modifiable global Python value" % result_type,
  11521. level=1)
  11522. def analyse_types(self, env):
  11523. # The arg is always already analysed
  11524. return self
  11525. def is_ephemeral(self):
  11526. return (self.type.is_ptr and not self.type.is_array) and self.arg.is_ephemeral()
  11527. def generate_result_code(self, code):
  11528. from_py_function = None
  11529. # for certain source types, we can do better than the generic coercion
  11530. if self.type.is_string and self.arg.type is bytes_type:
  11531. if self.type.from_py_function.startswith('__Pyx_PyObject_As'):
  11532. from_py_function = '__Pyx_PyBytes' + self.type.from_py_function[len('__Pyx_PyObject'):]
  11533. NoneCheckNode.generate_if_needed(self.arg, code, "expected bytes, NoneType found")
  11534. code.putln(self.type.from_py_call_code(
  11535. self.arg.py_result(), self.result(), self.pos, code, from_py_function=from_py_function))
  11536. if self.type.is_pyobject:
  11537. code.put_gotref(self.py_result())
  11538. def nogil_check(self, env):
  11539. error(self.pos, "Coercion from Python not allowed without the GIL")
  11540. class CoerceToBooleanNode(CoercionNode):
  11541. # This node is used when a result needs to be used
  11542. # in a boolean context.
  11543. type = PyrexTypes.c_bint_type
  11544. _special_builtins = {
  11545. Builtin.list_type: 'PyList_GET_SIZE',
  11546. Builtin.tuple_type: 'PyTuple_GET_SIZE',
  11547. Builtin.set_type: 'PySet_GET_SIZE',
  11548. Builtin.frozenset_type: 'PySet_GET_SIZE',
  11549. Builtin.bytes_type: 'PyBytes_GET_SIZE',
  11550. Builtin.bytearray_type: 'PyByteArray_GET_SIZE',
  11551. Builtin.unicode_type: '__Pyx_PyUnicode_IS_TRUE',
  11552. }
  11553. def __init__(self, arg, env):
  11554. CoercionNode.__init__(self, arg)
  11555. if arg.type.is_pyobject:
  11556. self.is_temp = 1
  11557. def nogil_check(self, env):
  11558. if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
  11559. self.gil_error()
  11560. gil_message = "Truth-testing Python object"
  11561. def check_const(self):
  11562. if self.is_temp:
  11563. self.not_const()
  11564. return False
  11565. return self.arg.check_const()
  11566. def calculate_result_code(self):
  11567. return "(%s != 0)" % self.arg.result()
  11568. def generate_result_code(self, code):
  11569. if not self.is_temp:
  11570. return
  11571. test_func = self._special_builtins.get(self.arg.type)
  11572. if test_func is not None:
  11573. checks = ["(%s != Py_None)" % self.arg.py_result()] if self.arg.may_be_none() else []
  11574. checks.append("(%s(%s) != 0)" % (test_func, self.arg.py_result()))
  11575. code.putln("%s = %s;" % (self.result(), '&&'.join(checks)))
  11576. else:
  11577. code.putln(
  11578. "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
  11579. self.result(),
  11580. self.arg.py_result(),
  11581. code.error_goto_if_neg(self.result(), self.pos)))
  11582. class CoerceToComplexNode(CoercionNode):
  11583. def __init__(self, arg, dst_type, env):
  11584. if arg.type.is_complex:
  11585. arg = arg.coerce_to_simple(env)
  11586. self.type = dst_type
  11587. CoercionNode.__init__(self, arg)
  11588. dst_type.create_declaration_utility_code(env)
  11589. def calculate_result_code(self):
  11590. if self.arg.type.is_complex:
  11591. real_part = "__Pyx_CREAL(%s)" % self.arg.result()
  11592. imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
  11593. else:
  11594. real_part = self.arg.result()
  11595. imag_part = "0"
  11596. return "%s(%s, %s)" % (
  11597. self.type.from_parts,
  11598. real_part,
  11599. imag_part)
  11600. def generate_result_code(self, code):
  11601. pass
  11602. class CoerceToTempNode(CoercionNode):
  11603. # This node is used to force the result of another node
  11604. # to be stored in a temporary. It is only used if the
  11605. # argument node's result is not already in a temporary.
  11606. def __init__(self, arg, env):
  11607. CoercionNode.__init__(self, arg)
  11608. self.type = self.arg.type.as_argument_type()
  11609. self.constant_result = self.arg.constant_result
  11610. self.is_temp = 1
  11611. if self.type.is_pyobject:
  11612. self.result_ctype = py_object_type
  11613. gil_message = "Creating temporary Python reference"
  11614. def analyse_types(self, env):
  11615. # The arg is always already analysed
  11616. return self
  11617. def coerce_to_boolean(self, env):
  11618. self.arg = self.arg.coerce_to_boolean(env)
  11619. if self.arg.is_simple():
  11620. return self.arg
  11621. self.type = self.arg.type
  11622. self.result_ctype = self.type
  11623. return self
  11624. def generate_result_code(self, code):
  11625. #self.arg.generate_evaluation_code(code) # Already done
  11626. # by generic generate_subexpr_evaluation_code!
  11627. code.putln("%s = %s;" % (
  11628. self.result(), self.arg.result_as(self.ctype())))
  11629. if self.use_managed_ref:
  11630. if self.type.is_pyobject:
  11631. code.put_incref(self.result(), self.ctype())
  11632. elif self.type.is_memoryviewslice:
  11633. code.put_incref_memoryviewslice(self.result(),
  11634. not self.in_nogil_context)
  11635. class ProxyNode(CoercionNode):
  11636. """
  11637. A node that should not be replaced by transforms or other means,
  11638. and hence can be useful to wrap the argument to a clone node
  11639. MyNode -> ProxyNode -> ArgNode
  11640. CloneNode -^
  11641. """
  11642. nogil_check = None
  11643. def __init__(self, arg):
  11644. super(ProxyNode, self).__init__(arg)
  11645. self.constant_result = arg.constant_result
  11646. self._proxy_type()
  11647. def analyse_types(self, env):
  11648. self.arg = self.arg.analyse_expressions(env)
  11649. self._proxy_type()
  11650. return self
  11651. def infer_type(self, env):
  11652. return self.arg.infer_type(env)
  11653. def _proxy_type(self):
  11654. if hasattr(self.arg, 'type'):
  11655. self.type = self.arg.type
  11656. self.result_ctype = self.arg.result_ctype
  11657. if hasattr(self.arg, 'entry'):
  11658. self.entry = self.arg.entry
  11659. def generate_result_code(self, code):
  11660. self.arg.generate_result_code(code)
  11661. def result(self):
  11662. return self.arg.result()
  11663. def is_simple(self):
  11664. return self.arg.is_simple()
  11665. def may_be_none(self):
  11666. return self.arg.may_be_none()
  11667. def generate_evaluation_code(self, code):
  11668. self.arg.generate_evaluation_code(code)
  11669. def generate_disposal_code(self, code):
  11670. self.arg.generate_disposal_code(code)
  11671. def free_temps(self, code):
  11672. self.arg.free_temps(code)
  11673. class CloneNode(CoercionNode):
  11674. # This node is employed when the result of another node needs
  11675. # to be used multiple times. The argument node's result must
  11676. # be in a temporary. This node "borrows" the result from the
  11677. # argument node, and does not generate any evaluation or
  11678. # disposal code for it. The original owner of the argument
  11679. # node is responsible for doing those things.
  11680. subexprs = [] # Arg is not considered a subexpr
  11681. nogil_check = None
  11682. def __init__(self, arg):
  11683. CoercionNode.__init__(self, arg)
  11684. self.constant_result = arg.constant_result
  11685. if hasattr(arg, 'type'):
  11686. self.type = arg.type
  11687. self.result_ctype = arg.result_ctype
  11688. if hasattr(arg, 'entry'):
  11689. self.entry = arg.entry
  11690. def result(self):
  11691. return self.arg.result()
  11692. def may_be_none(self):
  11693. return self.arg.may_be_none()
  11694. def type_dependencies(self, env):
  11695. return self.arg.type_dependencies(env)
  11696. def infer_type(self, env):
  11697. return self.arg.infer_type(env)
  11698. def analyse_types(self, env):
  11699. self.type = self.arg.type
  11700. self.result_ctype = self.arg.result_ctype
  11701. self.is_temp = 1
  11702. if hasattr(self.arg, 'entry'):
  11703. self.entry = self.arg.entry
  11704. return self
  11705. def coerce_to(self, dest_type, env):
  11706. if self.arg.is_literal:
  11707. return self.arg.coerce_to(dest_type, env)
  11708. return super(CloneNode, self).coerce_to(dest_type, env)
  11709. def is_simple(self):
  11710. return True # result is always in a temp (or a name)
  11711. def generate_evaluation_code(self, code):
  11712. pass
  11713. def generate_result_code(self, code):
  11714. pass
  11715. def generate_disposal_code(self, code):
  11716. pass
  11717. def free_temps(self, code):
  11718. pass
  11719. class CMethodSelfCloneNode(CloneNode):
  11720. # Special CloneNode for the self argument of builtin C methods
  11721. # that accepts subtypes of the builtin type. This is safe only
  11722. # for 'final' subtypes, as subtypes of the declared type may
  11723. # override the C method.
  11724. def coerce_to(self, dst_type, env):
  11725. if dst_type.is_builtin_type and self.type.subtype_of(dst_type):
  11726. return self
  11727. return CloneNode.coerce_to(self, dst_type, env)
  11728. class ModuleRefNode(ExprNode):
  11729. # Simple returns the module object
  11730. type = py_object_type
  11731. is_temp = False
  11732. subexprs = []
  11733. def analyse_types(self, env):
  11734. return self
  11735. def may_be_none(self):
  11736. return False
  11737. def calculate_result_code(self):
  11738. return Naming.module_cname
  11739. def generate_result_code(self, code):
  11740. pass
  11741. class DocstringRefNode(ExprNode):
  11742. # Extracts the docstring of the body element
  11743. subexprs = ['body']
  11744. type = py_object_type
  11745. is_temp = True
  11746. def __init__(self, pos, body):
  11747. ExprNode.__init__(self, pos)
  11748. assert body.type.is_pyobject
  11749. self.body = body
  11750. def analyse_types(self, env):
  11751. return self
  11752. def generate_result_code(self, code):
  11753. code.putln('%s = __Pyx_GetAttr(%s, %s); %s' % (
  11754. self.result(), self.body.result(),
  11755. code.intern_identifier(StringEncoding.EncodedString("__doc__")),
  11756. code.error_goto_if_null(self.result(), self.pos)))
  11757. code.put_gotref(self.result())
  11758. #------------------------------------------------------------------------------------
  11759. #
  11760. # Runtime support code
  11761. #
  11762. #------------------------------------------------------------------------------------
  11763. pyerr_occurred_withgil_utility_code= UtilityCode(
  11764. proto = """
  11765. static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
  11766. """,
  11767. impl = """
  11768. static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
  11769. int err;
  11770. #ifdef WITH_THREAD
  11771. PyGILState_STATE _save = PyGILState_Ensure();
  11772. #endif
  11773. err = !!PyErr_Occurred();
  11774. #ifdef WITH_THREAD
  11775. PyGILState_Release(_save);
  11776. #endif
  11777. return err;
  11778. }
  11779. """
  11780. )
  11781. #------------------------------------------------------------------------------------
  11782. raise_unbound_local_error_utility_code = UtilityCode(
  11783. proto = """
  11784. static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
  11785. """,
  11786. impl = """
  11787. static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
  11788. PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
  11789. }
  11790. """)
  11791. raise_closure_name_error_utility_code = UtilityCode(
  11792. proto = """
  11793. static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname);
  11794. """,
  11795. impl = """
  11796. static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname) {
  11797. PyErr_Format(PyExc_NameError, "free variable '%s' referenced before assignment in enclosing scope", varname);
  11798. }
  11799. """)
  11800. # Don't inline the function, it should really never be called in production
  11801. raise_unbound_memoryview_utility_code_nogil = UtilityCode(
  11802. proto = """
  11803. static void __Pyx_RaiseUnboundMemoryviewSliceNogil(const char *varname);
  11804. """,
  11805. impl = """
  11806. static void __Pyx_RaiseUnboundMemoryviewSliceNogil(const char *varname) {
  11807. #ifdef WITH_THREAD
  11808. PyGILState_STATE gilstate = PyGILState_Ensure();
  11809. #endif
  11810. __Pyx_RaiseUnboundLocalError(varname);
  11811. #ifdef WITH_THREAD
  11812. PyGILState_Release(gilstate);
  11813. #endif
  11814. }
  11815. """,
  11816. requires = [raise_unbound_local_error_utility_code])
  11817. #------------------------------------------------------------------------------------
  11818. raise_too_many_values_to_unpack = UtilityCode.load_cached("RaiseTooManyValuesToUnpack", "ObjectHandling.c")
  11819. raise_need_more_values_to_unpack = UtilityCode.load_cached("RaiseNeedMoreValuesToUnpack", "ObjectHandling.c")
  11820. tuple_unpacking_error_code = UtilityCode.load_cached("UnpackTupleError", "ObjectHandling.c")