ExprNodes.py 536 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694
  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. # is_numpy_attribute boolean Is a Numpy module attribute
  279. # result_code/temp_result can safely be set to None
  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 iterator_type.is_cpp_class:
  2508. item_type = env.lookup_operator_for_types(self.pos, "*", [iterator_type]).type.return_type
  2509. if item_type.is_reference:
  2510. item_type = item_type.ref_base_type
  2511. if item_type.is_const:
  2512. item_type = item_type.const_base_type
  2513. return item_type
  2514. else:
  2515. # Avoid duplication of complicated logic.
  2516. fake_index_node = IndexNode(
  2517. self.pos,
  2518. base=self.iterator.sequence,
  2519. index=IntNode(self.pos, value='PY_SSIZE_T_MAX',
  2520. type=PyrexTypes.c_py_ssize_t_type))
  2521. return fake_index_node.infer_type(env)
  2522. def analyse_types(self, env):
  2523. self.type = self.infer_type(env, self.iterator.type)
  2524. self.is_temp = 1
  2525. return self
  2526. def generate_result_code(self, code):
  2527. self.iterator.generate_iter_next_result_code(self.result(), code)
  2528. class AsyncIteratorNode(ExprNode):
  2529. # Used as part of 'async for' statement implementation.
  2530. #
  2531. # Implements result = sequence.__aiter__()
  2532. #
  2533. # sequence ExprNode
  2534. subexprs = ['sequence']
  2535. is_async = True
  2536. type = py_object_type
  2537. is_temp = 1
  2538. def infer_type(self, env):
  2539. return py_object_type
  2540. def analyse_types(self, env):
  2541. self.sequence = self.sequence.analyse_types(env)
  2542. if not self.sequence.type.is_pyobject:
  2543. error(self.pos, "async for loops not allowed on C/C++ types")
  2544. self.sequence = self.sequence.coerce_to_pyobject(env)
  2545. return self
  2546. def generate_result_code(self, code):
  2547. code.globalstate.use_utility_code(UtilityCode.load_cached("AsyncIter", "Coroutine.c"))
  2548. code.putln("%s = __Pyx_Coroutine_GetAsyncIter(%s); %s" % (
  2549. self.result(),
  2550. self.sequence.py_result(),
  2551. code.error_goto_if_null(self.result(), self.pos)))
  2552. code.put_gotref(self.result())
  2553. class AsyncNextNode(AtomicExprNode):
  2554. # Used as part of 'async for' statement implementation.
  2555. # Implements result = iterator.__anext__()
  2556. # Created during analyse_types phase.
  2557. # The iterator is not owned by this node.
  2558. #
  2559. # iterator IteratorNode
  2560. type = py_object_type
  2561. is_temp = 1
  2562. def __init__(self, iterator):
  2563. AtomicExprNode.__init__(self, iterator.pos)
  2564. self.iterator = iterator
  2565. def infer_type(self, env):
  2566. return py_object_type
  2567. def analyse_types(self, env):
  2568. return self
  2569. def generate_result_code(self, code):
  2570. code.globalstate.use_utility_code(UtilityCode.load_cached("AsyncIter", "Coroutine.c"))
  2571. code.putln("%s = __Pyx_Coroutine_AsyncIterNext(%s); %s" % (
  2572. self.result(),
  2573. self.iterator.py_result(),
  2574. code.error_goto_if_null(self.result(), self.pos)))
  2575. code.put_gotref(self.result())
  2576. class WithExitCallNode(ExprNode):
  2577. # The __exit__() call of a 'with' statement. Used in both the
  2578. # except and finally clauses.
  2579. # with_stat WithStatNode the surrounding 'with' statement
  2580. # args TupleNode or ResultStatNode the exception info tuple
  2581. # await_expr AwaitExprNode the await expression of an 'async with' statement
  2582. subexprs = ['args', 'await_expr']
  2583. test_if_run = True
  2584. await_expr = None
  2585. def analyse_types(self, env):
  2586. self.args = self.args.analyse_types(env)
  2587. if self.await_expr:
  2588. self.await_expr = self.await_expr.analyse_types(env)
  2589. self.type = PyrexTypes.c_bint_type
  2590. self.is_temp = True
  2591. return self
  2592. def generate_evaluation_code(self, code):
  2593. if self.test_if_run:
  2594. # call only if it was not already called (and decref-cleared)
  2595. code.putln("if (%s) {" % self.with_stat.exit_var)
  2596. self.args.generate_evaluation_code(code)
  2597. result_var = code.funcstate.allocate_temp(py_object_type, manage_ref=False)
  2598. code.mark_pos(self.pos)
  2599. code.globalstate.use_utility_code(UtilityCode.load_cached(
  2600. "PyObjectCall", "ObjectHandling.c"))
  2601. code.putln("%s = __Pyx_PyObject_Call(%s, %s, NULL);" % (
  2602. result_var,
  2603. self.with_stat.exit_var,
  2604. self.args.result()))
  2605. code.put_decref_clear(self.with_stat.exit_var, type=py_object_type)
  2606. self.args.generate_disposal_code(code)
  2607. self.args.free_temps(code)
  2608. code.putln(code.error_goto_if_null(result_var, self.pos))
  2609. code.put_gotref(result_var)
  2610. if self.await_expr:
  2611. # FIXME: result_var temp currently leaks into the closure
  2612. self.await_expr.generate_evaluation_code(code, source_cname=result_var, decref_source=True)
  2613. code.putln("%s = %s;" % (result_var, self.await_expr.py_result()))
  2614. self.await_expr.generate_post_assignment_code(code)
  2615. self.await_expr.free_temps(code)
  2616. if self.result_is_used:
  2617. self.allocate_temp_result(code)
  2618. code.putln("%s = __Pyx_PyObject_IsTrue(%s);" % (self.result(), result_var))
  2619. code.put_decref_clear(result_var, type=py_object_type)
  2620. if self.result_is_used:
  2621. code.put_error_if_neg(self.pos, self.result())
  2622. code.funcstate.release_temp(result_var)
  2623. if self.test_if_run:
  2624. code.putln("}")
  2625. class ExcValueNode(AtomicExprNode):
  2626. # Node created during analyse_types phase
  2627. # of an ExceptClauseNode to fetch the current
  2628. # exception value.
  2629. type = py_object_type
  2630. def __init__(self, pos):
  2631. ExprNode.__init__(self, pos)
  2632. def set_var(self, var):
  2633. self.var = var
  2634. def calculate_result_code(self):
  2635. return self.var
  2636. def generate_result_code(self, code):
  2637. pass
  2638. def analyse_types(self, env):
  2639. return self
  2640. class TempNode(ExprNode):
  2641. # Node created during analyse_types phase
  2642. # of some nodes to hold a temporary value.
  2643. #
  2644. # Note: One must call "allocate" and "release" on
  2645. # the node during code generation to get/release the temp.
  2646. # This is because the temp result is often used outside of
  2647. # the regular cycle.
  2648. subexprs = []
  2649. def __init__(self, pos, type, env=None):
  2650. ExprNode.__init__(self, pos)
  2651. self.type = type
  2652. if type.is_pyobject:
  2653. self.result_ctype = py_object_type
  2654. self.is_temp = 1
  2655. def analyse_types(self, env):
  2656. return self
  2657. def analyse_target_declaration(self, env):
  2658. pass
  2659. def generate_result_code(self, code):
  2660. pass
  2661. def allocate(self, code):
  2662. self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
  2663. def release(self, code):
  2664. code.funcstate.release_temp(self.temp_cname)
  2665. self.temp_cname = None
  2666. def result(self):
  2667. try:
  2668. return self.temp_cname
  2669. except:
  2670. assert False, "Remember to call allocate/release on TempNode"
  2671. raise
  2672. # Do not participate in normal temp alloc/dealloc:
  2673. def allocate_temp_result(self, code):
  2674. pass
  2675. def release_temp_result(self, code):
  2676. pass
  2677. class PyTempNode(TempNode):
  2678. # TempNode holding a Python value.
  2679. def __init__(self, pos, env):
  2680. TempNode.__init__(self, pos, PyrexTypes.py_object_type, env)
  2681. class RawCNameExprNode(ExprNode):
  2682. subexprs = []
  2683. def __init__(self, pos, type=None, cname=None):
  2684. ExprNode.__init__(self, pos, type=type)
  2685. if cname is not None:
  2686. self.cname = cname
  2687. def analyse_types(self, env):
  2688. return self
  2689. def set_cname(self, cname):
  2690. self.cname = cname
  2691. def result(self):
  2692. return self.cname
  2693. def generate_result_code(self, code):
  2694. pass
  2695. #-------------------------------------------------------------------
  2696. #
  2697. # F-strings
  2698. #
  2699. #-------------------------------------------------------------------
  2700. class JoinedStrNode(ExprNode):
  2701. # F-strings
  2702. #
  2703. # values [UnicodeNode|FormattedValueNode] Substrings of the f-string
  2704. #
  2705. type = unicode_type
  2706. is_temp = True
  2707. subexprs = ['values']
  2708. def analyse_types(self, env):
  2709. self.values = [v.analyse_types(env).coerce_to_pyobject(env) for v in self.values]
  2710. return self
  2711. def may_be_none(self):
  2712. # PyUnicode_Join() always returns a Unicode string or raises an exception
  2713. return False
  2714. def generate_evaluation_code(self, code):
  2715. code.mark_pos(self.pos)
  2716. num_items = len(self.values)
  2717. list_var = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  2718. ulength_var = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
  2719. max_char_var = code.funcstate.allocate_temp(PyrexTypes.c_py_ucs4_type, manage_ref=False)
  2720. code.putln('%s = PyTuple_New(%s); %s' % (
  2721. list_var,
  2722. num_items,
  2723. code.error_goto_if_null(list_var, self.pos)))
  2724. code.put_gotref(list_var)
  2725. code.putln("%s = 0;" % ulength_var)
  2726. code.putln("%s = 127;" % max_char_var) # at least ASCII character range
  2727. for i, node in enumerate(self.values):
  2728. node.generate_evaluation_code(code)
  2729. node.make_owned_reference(code)
  2730. ulength = "__Pyx_PyUnicode_GET_LENGTH(%s)" % node.py_result()
  2731. max_char_value = "__Pyx_PyUnicode_MAX_CHAR_VALUE(%s)" % node.py_result()
  2732. is_ascii = False
  2733. if isinstance(node, UnicodeNode):
  2734. try:
  2735. # most strings will be ASCII or at least Latin-1
  2736. node.value.encode('iso8859-1')
  2737. max_char_value = '255'
  2738. node.value.encode('us-ascii')
  2739. is_ascii = True
  2740. except UnicodeEncodeError:
  2741. if max_char_value != '255':
  2742. # not ISO8859-1 => check BMP limit
  2743. max_char = max(map(ord, node.value))
  2744. if max_char < 0xD800:
  2745. # BMP-only, no surrogate pairs used
  2746. max_char_value = '65535'
  2747. ulength = str(len(node.value))
  2748. elif max_char >= 65536:
  2749. # cleary outside of BMP, and not on a 16-bit Unicode system
  2750. max_char_value = '1114111'
  2751. ulength = str(len(node.value))
  2752. else:
  2753. # not really worth implementing a check for surrogate pairs here
  2754. # drawback: C code can differ when generating on Py2 with 2-byte Unicode
  2755. pass
  2756. else:
  2757. ulength = str(len(node.value))
  2758. elif isinstance(node, FormattedValueNode) and node.value.type.is_numeric:
  2759. is_ascii = True # formatted C numbers are always ASCII
  2760. if not is_ascii:
  2761. code.putln("%s = (%s > %s) ? %s : %s;" % (
  2762. max_char_var, max_char_value, max_char_var, max_char_value, max_char_var))
  2763. code.putln("%s += %s;" % (ulength_var, ulength))
  2764. code.put_giveref(node.py_result())
  2765. code.putln('PyTuple_SET_ITEM(%s, %s, %s);' % (list_var, i, node.py_result()))
  2766. node.generate_post_assignment_code(code)
  2767. node.free_temps(code)
  2768. code.mark_pos(self.pos)
  2769. self.allocate_temp_result(code)
  2770. code.globalstate.use_utility_code(UtilityCode.load_cached("JoinPyUnicode", "StringTools.c"))
  2771. code.putln('%s = __Pyx_PyUnicode_Join(%s, %d, %s, %s); %s' % (
  2772. self.result(),
  2773. list_var,
  2774. num_items,
  2775. ulength_var,
  2776. max_char_var,
  2777. code.error_goto_if_null(self.py_result(), self.pos)))
  2778. code.put_gotref(self.py_result())
  2779. code.put_decref_clear(list_var, py_object_type)
  2780. code.funcstate.release_temp(list_var)
  2781. code.funcstate.release_temp(ulength_var)
  2782. code.funcstate.release_temp(max_char_var)
  2783. class FormattedValueNode(ExprNode):
  2784. # {}-delimited portions of an f-string
  2785. #
  2786. # value ExprNode The expression itself
  2787. # conversion_char str or None Type conversion (!s, !r, !a, or none, or 'd' for integer conversion)
  2788. # format_spec JoinedStrNode or None Format string passed to __format__
  2789. # c_format_spec str or None If not None, formatting can be done at the C level
  2790. subexprs = ['value', 'format_spec']
  2791. type = unicode_type
  2792. is_temp = True
  2793. c_format_spec = None
  2794. find_conversion_func = {
  2795. 's': 'PyObject_Unicode',
  2796. 'r': 'PyObject_Repr',
  2797. 'a': 'PyObject_ASCII', # NOTE: mapped to PyObject_Repr() in Py2
  2798. 'd': '__Pyx_PyNumber_IntOrLong', # NOTE: internal mapping for '%d' formatting
  2799. }.get
  2800. def may_be_none(self):
  2801. # PyObject_Format() always returns a Unicode string or raises an exception
  2802. return False
  2803. def analyse_types(self, env):
  2804. self.value = self.value.analyse_types(env)
  2805. if not self.format_spec or self.format_spec.is_string_literal:
  2806. c_format_spec = self.format_spec.value if self.format_spec else self.value.type.default_format_spec
  2807. if self.value.type.can_coerce_to_pystring(env, format_spec=c_format_spec):
  2808. self.c_format_spec = c_format_spec
  2809. if self.format_spec:
  2810. self.format_spec = self.format_spec.analyse_types(env).coerce_to_pyobject(env)
  2811. if self.c_format_spec is None:
  2812. self.value = self.value.coerce_to_pyobject(env)
  2813. if not self.format_spec and (not self.conversion_char or self.conversion_char == 's'):
  2814. if self.value.type is unicode_type and not self.value.may_be_none():
  2815. # value is definitely a unicode string and we don't format it any special
  2816. return self.value
  2817. return self
  2818. def generate_result_code(self, code):
  2819. if self.c_format_spec is not None and not self.value.type.is_pyobject:
  2820. convert_func_call = self.value.type.convert_to_pystring(
  2821. self.value.result(), code, self.c_format_spec)
  2822. code.putln("%s = %s; %s" % (
  2823. self.result(),
  2824. convert_func_call,
  2825. code.error_goto_if_null(self.result(), self.pos)))
  2826. code.put_gotref(self.py_result())
  2827. return
  2828. value_result = self.value.py_result()
  2829. value_is_unicode = self.value.type is unicode_type and not self.value.may_be_none()
  2830. if self.format_spec:
  2831. format_func = '__Pyx_PyObject_Format'
  2832. format_spec = self.format_spec.py_result()
  2833. else:
  2834. # common case: expect simple Unicode pass-through if no format spec
  2835. format_func = '__Pyx_PyObject_FormatSimple'
  2836. # passing a Unicode format string in Py2 forces PyObject_Format() to also return a Unicode string
  2837. format_spec = Naming.empty_unicode
  2838. conversion_char = self.conversion_char
  2839. if conversion_char == 's' and value_is_unicode:
  2840. # no need to pipe unicode strings through str()
  2841. conversion_char = None
  2842. if conversion_char:
  2843. fn = self.find_conversion_func(conversion_char)
  2844. assert fn is not None, "invalid conversion character found: '%s'" % conversion_char
  2845. value_result = '%s(%s)' % (fn, value_result)
  2846. code.globalstate.use_utility_code(
  2847. UtilityCode.load_cached("PyObjectFormatAndDecref", "StringTools.c"))
  2848. format_func += 'AndDecref'
  2849. elif self.format_spec:
  2850. code.globalstate.use_utility_code(
  2851. UtilityCode.load_cached("PyObjectFormat", "StringTools.c"))
  2852. else:
  2853. code.globalstate.use_utility_code(
  2854. UtilityCode.load_cached("PyObjectFormatSimple", "StringTools.c"))
  2855. code.putln("%s = %s(%s, %s); %s" % (
  2856. self.result(),
  2857. format_func,
  2858. value_result,
  2859. format_spec,
  2860. code.error_goto_if_null(self.result(), self.pos)))
  2861. code.put_gotref(self.py_result())
  2862. #-------------------------------------------------------------------
  2863. #
  2864. # Parallel nodes (cython.parallel.thread(savailable|id))
  2865. #
  2866. #-------------------------------------------------------------------
  2867. class ParallelThreadsAvailableNode(AtomicExprNode):
  2868. """
  2869. Note: this is disabled and not a valid directive at this moment
  2870. Implements cython.parallel.threadsavailable(). If we are called from the
  2871. sequential part of the application, we need to call omp_get_max_threads(),
  2872. and in the parallel part we can just call omp_get_num_threads()
  2873. """
  2874. type = PyrexTypes.c_int_type
  2875. def analyse_types(self, env):
  2876. self.is_temp = True
  2877. # env.add_include_file("omp.h")
  2878. return self
  2879. def generate_result_code(self, code):
  2880. code.putln("#ifdef _OPENMP")
  2881. code.putln("if (omp_in_parallel()) %s = omp_get_max_threads();" %
  2882. self.temp_code)
  2883. code.putln("else %s = omp_get_num_threads();" % self.temp_code)
  2884. code.putln("#else")
  2885. code.putln("%s = 1;" % self.temp_code)
  2886. code.putln("#endif")
  2887. def result(self):
  2888. return self.temp_code
  2889. class ParallelThreadIdNode(AtomicExprNode): #, Nodes.ParallelNode):
  2890. """
  2891. Implements cython.parallel.threadid()
  2892. """
  2893. type = PyrexTypes.c_int_type
  2894. def analyse_types(self, env):
  2895. self.is_temp = True
  2896. # env.add_include_file("omp.h")
  2897. return self
  2898. def generate_result_code(self, code):
  2899. code.putln("#ifdef _OPENMP")
  2900. code.putln("%s = omp_get_thread_num();" % self.temp_code)
  2901. code.putln("#else")
  2902. code.putln("%s = 0;" % self.temp_code)
  2903. code.putln("#endif")
  2904. def result(self):
  2905. return self.temp_code
  2906. #-------------------------------------------------------------------
  2907. #
  2908. # Trailer nodes
  2909. #
  2910. #-------------------------------------------------------------------
  2911. class _IndexingBaseNode(ExprNode):
  2912. # Base class for indexing nodes.
  2913. #
  2914. # base ExprNode the value being indexed
  2915. def is_ephemeral(self):
  2916. # in most cases, indexing will return a safe reference to an object in a container,
  2917. # so we consider the result safe if the base object is
  2918. return self.base.is_ephemeral() or self.base.type in (
  2919. basestring_type, str_type, bytes_type, bytearray_type, unicode_type)
  2920. def check_const_addr(self):
  2921. return self.base.check_const_addr() and self.index.check_const()
  2922. def is_lvalue(self):
  2923. # NOTE: references currently have both is_reference and is_ptr
  2924. # set. Since pointers and references have different lvalue
  2925. # rules, we must be careful to separate the two.
  2926. if self.type.is_reference:
  2927. if self.type.ref_base_type.is_array:
  2928. # fixed-sized arrays aren't l-values
  2929. return False
  2930. elif self.type.is_ptr:
  2931. # non-const pointers can always be reassigned
  2932. return True
  2933. # Just about everything else returned by the index operator
  2934. # can be an lvalue.
  2935. return True
  2936. class IndexNode(_IndexingBaseNode):
  2937. # Sequence indexing.
  2938. #
  2939. # base ExprNode
  2940. # index ExprNode
  2941. # type_indices [PyrexType]
  2942. #
  2943. # is_fused_index boolean Whether the index is used to specialize a
  2944. # c(p)def function
  2945. subexprs = ['base', 'index']
  2946. type_indices = None
  2947. is_subscript = True
  2948. is_fused_index = False
  2949. def calculate_constant_result(self):
  2950. self.constant_result = self.base.constant_result[self.index.constant_result]
  2951. def compile_time_value(self, denv):
  2952. base = self.base.compile_time_value(denv)
  2953. index = self.index.compile_time_value(denv)
  2954. try:
  2955. return base[index]
  2956. except Exception as e:
  2957. self.compile_time_value_error(e)
  2958. def is_simple(self):
  2959. base = self.base
  2960. return (base.is_simple() and self.index.is_simple()
  2961. and base.type and (base.type.is_ptr or base.type.is_array))
  2962. def may_be_none(self):
  2963. base_type = self.base.type
  2964. if base_type:
  2965. if base_type.is_string:
  2966. return False
  2967. if isinstance(self.index, SliceNode):
  2968. # slicing!
  2969. if base_type in (bytes_type, bytearray_type, str_type, unicode_type,
  2970. basestring_type, list_type, tuple_type):
  2971. return False
  2972. return ExprNode.may_be_none(self)
  2973. def analyse_target_declaration(self, env):
  2974. pass
  2975. def analyse_as_type(self, env):
  2976. base_type = self.base.analyse_as_type(env)
  2977. if base_type and not base_type.is_pyobject:
  2978. if base_type.is_cpp_class:
  2979. if isinstance(self.index, TupleNode):
  2980. template_values = self.index.args
  2981. else:
  2982. template_values = [self.index]
  2983. type_node = Nodes.TemplatedTypeNode(
  2984. pos=self.pos,
  2985. positional_args=template_values,
  2986. keyword_args=None)
  2987. return type_node.analyse(env, base_type=base_type)
  2988. elif self.index.is_slice or self.index.is_sequence_constructor:
  2989. # memory view
  2990. from . import MemoryView
  2991. env.use_utility_code(MemoryView.view_utility_code)
  2992. axes = [self.index] if self.index.is_slice else list(self.index.args)
  2993. return PyrexTypes.MemoryViewSliceType(base_type, MemoryView.get_axes_specs(env, axes))
  2994. else:
  2995. # C array
  2996. index = self.index.compile_time_value(env)
  2997. if index is not None:
  2998. try:
  2999. index = int(index)
  3000. except (ValueError, TypeError):
  3001. pass
  3002. else:
  3003. return PyrexTypes.CArrayType(base_type, index)
  3004. error(self.pos, "Array size must be a compile time constant")
  3005. return None
  3006. def type_dependencies(self, env):
  3007. return self.base.type_dependencies(env) + self.index.type_dependencies(env)
  3008. def infer_type(self, env):
  3009. base_type = self.base.infer_type(env)
  3010. if self.index.is_slice:
  3011. # slicing!
  3012. if base_type.is_string:
  3013. # sliced C strings must coerce to Python
  3014. return bytes_type
  3015. elif base_type.is_pyunicode_ptr:
  3016. # sliced Py_UNICODE* strings must coerce to Python
  3017. return unicode_type
  3018. elif base_type in (unicode_type, bytes_type, str_type,
  3019. bytearray_type, list_type, tuple_type):
  3020. # slicing these returns the same type
  3021. return base_type
  3022. else:
  3023. # TODO: Handle buffers (hopefully without too much redundancy).
  3024. return py_object_type
  3025. index_type = self.index.infer_type(env)
  3026. if index_type and index_type.is_int or isinstance(self.index, IntNode):
  3027. # indexing!
  3028. if base_type is unicode_type:
  3029. # Py_UCS4 will automatically coerce to a unicode string
  3030. # if required, so this is safe. We only infer Py_UCS4
  3031. # when the index is a C integer type. Otherwise, we may
  3032. # need to use normal Python item access, in which case
  3033. # it's faster to return the one-char unicode string than
  3034. # to receive it, throw it away, and potentially rebuild it
  3035. # on a subsequent PyObject coercion.
  3036. return PyrexTypes.c_py_ucs4_type
  3037. elif base_type is str_type:
  3038. # always returns str - Py2: bytes, Py3: unicode
  3039. return base_type
  3040. elif base_type is bytearray_type:
  3041. return PyrexTypes.c_uchar_type
  3042. elif isinstance(self.base, BytesNode):
  3043. #if env.global_scope().context.language_level >= 3:
  3044. # # inferring 'char' can be made to work in Python 3 mode
  3045. # return PyrexTypes.c_char_type
  3046. # Py2/3 return different types on indexing bytes objects
  3047. return py_object_type
  3048. elif base_type in (tuple_type, list_type):
  3049. # if base is a literal, take a look at its values
  3050. item_type = infer_sequence_item_type(
  3051. env, self.base, self.index, seq_type=base_type)
  3052. if item_type is not None:
  3053. return item_type
  3054. elif base_type.is_ptr or base_type.is_array:
  3055. return base_type.base_type
  3056. elif base_type.is_ctuple and isinstance(self.index, IntNode):
  3057. if self.index.has_constant_result():
  3058. index = self.index.constant_result
  3059. if index < 0:
  3060. index += base_type.size
  3061. if 0 <= index < base_type.size:
  3062. return base_type.components[index]
  3063. if base_type.is_cpp_class:
  3064. class FakeOperand:
  3065. def __init__(self, **kwds):
  3066. self.__dict__.update(kwds)
  3067. operands = [
  3068. FakeOperand(pos=self.pos, type=base_type),
  3069. FakeOperand(pos=self.pos, type=index_type),
  3070. ]
  3071. index_func = env.lookup_operator('[]', operands)
  3072. if index_func is not None:
  3073. return index_func.type.return_type
  3074. if is_pythran_expr(base_type) and is_pythran_expr(index_type):
  3075. index_with_type = (self.index, index_type)
  3076. return PythranExpr(pythran_indexing_type(base_type, [index_with_type]))
  3077. # may be slicing or indexing, we don't know
  3078. if base_type in (unicode_type, str_type):
  3079. # these types always returns their own type on Python indexing/slicing
  3080. return base_type
  3081. else:
  3082. # TODO: Handle buffers (hopefully without too much redundancy).
  3083. return py_object_type
  3084. def analyse_types(self, env):
  3085. return self.analyse_base_and_index_types(env, getting=True)
  3086. def analyse_target_types(self, env):
  3087. node = self.analyse_base_and_index_types(env, setting=True)
  3088. if node.type.is_const:
  3089. error(self.pos, "Assignment to const dereference")
  3090. if node is self and not node.is_lvalue():
  3091. error(self.pos, "Assignment to non-lvalue of type '%s'" % node.type)
  3092. return node
  3093. def analyse_base_and_index_types(self, env, getting=False, setting=False,
  3094. analyse_base=True):
  3095. # Note: This might be cleaned up by having IndexNode
  3096. # parsed in a saner way and only construct the tuple if
  3097. # needed.
  3098. if analyse_base:
  3099. self.base = self.base.analyse_types(env)
  3100. if self.base.type.is_error:
  3101. # Do not visit child tree if base is undeclared to avoid confusing
  3102. # error messages
  3103. self.type = PyrexTypes.error_type
  3104. return self
  3105. is_slice = self.index.is_slice
  3106. if not env.directives['wraparound']:
  3107. if is_slice:
  3108. check_negative_indices(self.index.start, self.index.stop)
  3109. else:
  3110. check_negative_indices(self.index)
  3111. # Potentially overflowing index value.
  3112. if not is_slice and isinstance(self.index, IntNode) and Utils.long_literal(self.index.value):
  3113. self.index = self.index.coerce_to_pyobject(env)
  3114. is_memslice = self.base.type.is_memoryviewslice
  3115. # Handle the case where base is a literal char* (and we expect a string, not an int)
  3116. if not is_memslice and (isinstance(self.base, BytesNode) or is_slice):
  3117. if self.base.type.is_string or not (self.base.type.is_ptr or self.base.type.is_array):
  3118. self.base = self.base.coerce_to_pyobject(env)
  3119. replacement_node = self.analyse_as_buffer_operation(env, getting)
  3120. if replacement_node is not None:
  3121. return replacement_node
  3122. self.nogil = env.nogil
  3123. base_type = self.base.type
  3124. if not base_type.is_cfunction:
  3125. self.index = self.index.analyse_types(env)
  3126. self.original_index_type = self.index.type
  3127. if base_type.is_unicode_char:
  3128. # we infer Py_UNICODE/Py_UCS4 for unicode strings in some
  3129. # cases, but indexing must still work for them
  3130. if setting:
  3131. warning(self.pos, "cannot assign to Unicode string index", level=1)
  3132. elif self.index.constant_result in (0, -1):
  3133. # uchar[0] => uchar
  3134. return self.base
  3135. self.base = self.base.coerce_to_pyobject(env)
  3136. base_type = self.base.type
  3137. if base_type.is_pyobject:
  3138. return self.analyse_as_pyobject(env, is_slice, getting, setting)
  3139. elif base_type.is_ptr or base_type.is_array:
  3140. return self.analyse_as_c_array(env, is_slice)
  3141. elif base_type.is_cpp_class:
  3142. return self.analyse_as_cpp(env, setting)
  3143. elif base_type.is_cfunction:
  3144. return self.analyse_as_c_function(env)
  3145. elif base_type.is_ctuple:
  3146. return self.analyse_as_c_tuple(env, getting, setting)
  3147. else:
  3148. error(self.pos,
  3149. "Attempting to index non-array type '%s'" %
  3150. base_type)
  3151. self.type = PyrexTypes.error_type
  3152. return self
  3153. def analyse_as_pyobject(self, env, is_slice, getting, setting):
  3154. base_type = self.base.type
  3155. if self.index.type.is_unicode_char and base_type is not dict_type:
  3156. # TODO: eventually fold into case below and remove warning, once people have adapted their code
  3157. warning(self.pos,
  3158. "Item lookup of unicode character codes now always converts to a Unicode string. "
  3159. "Use an explicit C integer cast to get back the previous integer lookup behaviour.", level=1)
  3160. self.index = self.index.coerce_to_pyobject(env)
  3161. self.is_temp = 1
  3162. elif self.index.type.is_int and base_type is not dict_type:
  3163. if (getting
  3164. and (base_type in (list_type, tuple_type, bytearray_type))
  3165. and (not self.index.type.signed
  3166. or not env.directives['wraparound']
  3167. or (isinstance(self.index, IntNode) and
  3168. self.index.has_constant_result() and self.index.constant_result >= 0))
  3169. and not env.directives['boundscheck']):
  3170. self.is_temp = 0
  3171. else:
  3172. self.is_temp = 1
  3173. self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env).coerce_to_simple(env)
  3174. self.original_index_type.create_to_py_utility_code(env)
  3175. else:
  3176. self.index = self.index.coerce_to_pyobject(env)
  3177. self.is_temp = 1
  3178. if self.index.type.is_int and base_type is unicode_type:
  3179. # Py_UNICODE/Py_UCS4 will automatically coerce to a unicode string
  3180. # if required, so this is fast and safe
  3181. self.type = PyrexTypes.c_py_ucs4_type
  3182. elif self.index.type.is_int and base_type is bytearray_type:
  3183. if setting:
  3184. self.type = PyrexTypes.c_uchar_type
  3185. else:
  3186. # not using 'uchar' to enable fast and safe error reporting as '-1'
  3187. self.type = PyrexTypes.c_int_type
  3188. elif is_slice and base_type in (bytes_type, bytearray_type, str_type, unicode_type, list_type, tuple_type):
  3189. self.type = base_type
  3190. else:
  3191. item_type = None
  3192. if base_type in (list_type, tuple_type) and self.index.type.is_int:
  3193. item_type = infer_sequence_item_type(
  3194. env, self.base, self.index, seq_type=base_type)
  3195. if item_type is None:
  3196. item_type = py_object_type
  3197. self.type = item_type
  3198. if base_type in (list_type, tuple_type, dict_type):
  3199. # do the None check explicitly (not in a helper) to allow optimising it away
  3200. self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
  3201. self.wrap_in_nonecheck_node(env, getting)
  3202. return self
  3203. def analyse_as_c_array(self, env, is_slice):
  3204. base_type = self.base.type
  3205. self.type = base_type.base_type
  3206. if is_slice:
  3207. self.type = base_type
  3208. elif self.index.type.is_pyobject:
  3209. self.index = self.index.coerce_to(PyrexTypes.c_py_ssize_t_type, env)
  3210. elif not self.index.type.is_int:
  3211. error(self.pos, "Invalid index type '%s'" % self.index.type)
  3212. return self
  3213. def analyse_as_cpp(self, env, setting):
  3214. base_type = self.base.type
  3215. function = env.lookup_operator("[]", [self.base, self.index])
  3216. if function is None:
  3217. error(self.pos, "Indexing '%s' not supported for index type '%s'" % (base_type, self.index.type))
  3218. self.type = PyrexTypes.error_type
  3219. self.result_code = "<error>"
  3220. return self
  3221. func_type = function.type
  3222. if func_type.is_ptr:
  3223. func_type = func_type.base_type
  3224. self.exception_check = func_type.exception_check
  3225. self.exception_value = func_type.exception_value
  3226. if self.exception_check:
  3227. if not setting:
  3228. self.is_temp = True
  3229. if self.exception_value is None:
  3230. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  3231. self.index = self.index.coerce_to(func_type.args[0].type, env)
  3232. self.type = func_type.return_type
  3233. if setting and not func_type.return_type.is_reference:
  3234. error(self.pos, "Can't set non-reference result '%s'" % self.type)
  3235. return self
  3236. def analyse_as_c_function(self, env):
  3237. base_type = self.base.type
  3238. if base_type.is_fused:
  3239. self.parse_indexed_fused_cdef(env)
  3240. else:
  3241. self.type_indices = self.parse_index_as_types(env)
  3242. self.index = None # FIXME: use a dedicated Node class instead of generic IndexNode
  3243. if base_type.templates is None:
  3244. error(self.pos, "Can only parameterize template functions.")
  3245. self.type = error_type
  3246. elif self.type_indices is None:
  3247. # Error recorded earlier.
  3248. self.type = error_type
  3249. elif len(base_type.templates) != len(self.type_indices):
  3250. error(self.pos, "Wrong number of template arguments: expected %s, got %s" % (
  3251. (len(base_type.templates), len(self.type_indices))))
  3252. self.type = error_type
  3253. else:
  3254. self.type = base_type.specialize(dict(zip(base_type.templates, self.type_indices)))
  3255. # FIXME: use a dedicated Node class instead of generic IndexNode
  3256. return self
  3257. def analyse_as_c_tuple(self, env, getting, setting):
  3258. base_type = self.base.type
  3259. if isinstance(self.index, IntNode) and self.index.has_constant_result():
  3260. index = self.index.constant_result
  3261. if -base_type.size <= index < base_type.size:
  3262. if index < 0:
  3263. index += base_type.size
  3264. self.type = base_type.components[index]
  3265. else:
  3266. error(self.pos,
  3267. "Index %s out of bounds for '%s'" %
  3268. (index, base_type))
  3269. self.type = PyrexTypes.error_type
  3270. return self
  3271. else:
  3272. self.base = self.base.coerce_to_pyobject(env)
  3273. return self.analyse_base_and_index_types(env, getting=getting, setting=setting, analyse_base=False)
  3274. def analyse_as_buffer_operation(self, env, getting):
  3275. """
  3276. Analyse buffer indexing and memoryview indexing/slicing
  3277. """
  3278. if isinstance(self.index, TupleNode):
  3279. indices = self.index.args
  3280. else:
  3281. indices = [self.index]
  3282. base = self.base
  3283. base_type = base.type
  3284. replacement_node = None
  3285. if base_type.is_memoryviewslice:
  3286. # memoryviewslice indexing or slicing
  3287. from . import MemoryView
  3288. if base.is_memview_slice:
  3289. # For memory views, "view[i][j]" is the same as "view[i, j]" => use the latter for speed.
  3290. merged_indices = base.merged_indices(indices)
  3291. if merged_indices is not None:
  3292. base = base.base
  3293. base_type = base.type
  3294. indices = merged_indices
  3295. have_slices, indices, newaxes = MemoryView.unellipsify(indices, base_type.ndim)
  3296. if have_slices:
  3297. replacement_node = MemoryViewSliceNode(self.pos, indices=indices, base=base)
  3298. else:
  3299. replacement_node = MemoryViewIndexNode(self.pos, indices=indices, base=base)
  3300. elif base_type.is_buffer or base_type.is_pythran_expr:
  3301. if base_type.is_pythran_expr or len(indices) == base_type.ndim:
  3302. # Buffer indexing
  3303. is_buffer_access = True
  3304. indices = [index.analyse_types(env) for index in indices]
  3305. if base_type.is_pythran_expr:
  3306. do_replacement = all(
  3307. index.type.is_int or index.is_slice or index.type.is_pythran_expr
  3308. for index in indices)
  3309. if do_replacement:
  3310. for i,index in enumerate(indices):
  3311. if index.is_slice:
  3312. index = SliceIntNode(index.pos, start=index.start, stop=index.stop, step=index.step)
  3313. index = index.analyse_types(env)
  3314. indices[i] = index
  3315. else:
  3316. do_replacement = all(index.type.is_int for index in indices)
  3317. if do_replacement:
  3318. replacement_node = BufferIndexNode(self.pos, indices=indices, base=base)
  3319. # On cloning, indices is cloned. Otherwise, unpack index into indices.
  3320. assert not isinstance(self.index, CloneNode)
  3321. if replacement_node is not None:
  3322. replacement_node = replacement_node.analyse_types(env, getting)
  3323. return replacement_node
  3324. def wrap_in_nonecheck_node(self, env, getting):
  3325. if not env.directives['nonecheck'] or not self.base.may_be_none():
  3326. return
  3327. self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
  3328. def parse_index_as_types(self, env, required=True):
  3329. if isinstance(self.index, TupleNode):
  3330. indices = self.index.args
  3331. else:
  3332. indices = [self.index]
  3333. type_indices = []
  3334. for index in indices:
  3335. type_indices.append(index.analyse_as_type(env))
  3336. if type_indices[-1] is None:
  3337. if required:
  3338. error(index.pos, "not parsable as a type")
  3339. return None
  3340. return type_indices
  3341. def parse_indexed_fused_cdef(self, env):
  3342. """
  3343. Interpret fused_cdef_func[specific_type1, ...]
  3344. Note that if this method is called, we are an indexed cdef function
  3345. with fused argument types, and this IndexNode will be replaced by the
  3346. NameNode with specific entry just after analysis of expressions by
  3347. AnalyseExpressionsTransform.
  3348. """
  3349. self.type = PyrexTypes.error_type
  3350. self.is_fused_index = True
  3351. base_type = self.base.type
  3352. positions = []
  3353. if self.index.is_name or self.index.is_attribute:
  3354. positions.append(self.index.pos)
  3355. elif isinstance(self.index, TupleNode):
  3356. for arg in self.index.args:
  3357. positions.append(arg.pos)
  3358. specific_types = self.parse_index_as_types(env, required=False)
  3359. if specific_types is None:
  3360. self.index = self.index.analyse_types(env)
  3361. if not self.base.entry.as_variable:
  3362. error(self.pos, "Can only index fused functions with types")
  3363. else:
  3364. # A cpdef function indexed with Python objects
  3365. self.base.entry = self.entry = self.base.entry.as_variable
  3366. self.base.type = self.type = self.entry.type
  3367. self.base.is_temp = True
  3368. self.is_temp = True
  3369. self.entry.used = True
  3370. self.is_fused_index = False
  3371. return
  3372. for i, type in enumerate(specific_types):
  3373. specific_types[i] = type.specialize_fused(env)
  3374. fused_types = base_type.get_fused_types()
  3375. if len(specific_types) > len(fused_types):
  3376. return error(self.pos, "Too many types specified")
  3377. elif len(specific_types) < len(fused_types):
  3378. t = fused_types[len(specific_types)]
  3379. return error(self.pos, "Not enough types specified to specialize "
  3380. "the function, %s is still fused" % t)
  3381. # See if our index types form valid specializations
  3382. for pos, specific_type, fused_type in zip(positions,
  3383. specific_types,
  3384. fused_types):
  3385. if not any([specific_type.same_as(t) for t in fused_type.types]):
  3386. return error(pos, "Type not in fused type")
  3387. if specific_type is None or specific_type.is_error:
  3388. return
  3389. fused_to_specific = dict(zip(fused_types, specific_types))
  3390. type = base_type.specialize(fused_to_specific)
  3391. if type.is_fused:
  3392. # Only partially specific, this is invalid
  3393. error(self.pos,
  3394. "Index operation makes function only partially specific")
  3395. else:
  3396. # Fully specific, find the signature with the specialized entry
  3397. for signature in self.base.type.get_all_specialized_function_types():
  3398. if type.same_as(signature):
  3399. self.type = signature
  3400. if self.base.is_attribute:
  3401. # Pretend to be a normal attribute, for cdef extension
  3402. # methods
  3403. self.entry = signature.entry
  3404. self.is_attribute = True
  3405. self.obj = self.base.obj
  3406. self.type.entry.used = True
  3407. self.base.type = signature
  3408. self.base.entry = signature.entry
  3409. break
  3410. else:
  3411. # This is a bug
  3412. raise InternalError("Couldn't find the right signature")
  3413. gil_message = "Indexing Python object"
  3414. def calculate_result_code(self):
  3415. if self.base.type in (list_type, tuple_type, bytearray_type):
  3416. if self.base.type is list_type:
  3417. index_code = "PyList_GET_ITEM(%s, %s)"
  3418. elif self.base.type is tuple_type:
  3419. index_code = "PyTuple_GET_ITEM(%s, %s)"
  3420. elif self.base.type is bytearray_type:
  3421. index_code = "((unsigned char)(PyByteArray_AS_STRING(%s)[%s]))"
  3422. else:
  3423. assert False, "unexpected base type in indexing: %s" % self.base.type
  3424. elif self.base.type.is_cfunction:
  3425. return "%s<%s>" % (
  3426. self.base.result(),
  3427. ",".join([param.empty_declaration_code() for param in self.type_indices]))
  3428. elif self.base.type.is_ctuple:
  3429. index = self.index.constant_result
  3430. if index < 0:
  3431. index += self.base.type.size
  3432. return "%s.f%s" % (self.base.result(), index)
  3433. else:
  3434. if (self.type.is_ptr or self.type.is_array) and self.type == self.base.type:
  3435. error(self.pos, "Invalid use of pointer slice")
  3436. return
  3437. index_code = "(%s[%s])"
  3438. return index_code % (self.base.result(), self.index.result())
  3439. def extra_index_params(self, code):
  3440. if self.index.type.is_int:
  3441. is_list = self.base.type is list_type
  3442. wraparound = (
  3443. bool(code.globalstate.directives['wraparound']) and
  3444. self.original_index_type.signed and
  3445. not (isinstance(self.index.constant_result, _py_int_types)
  3446. and self.index.constant_result >= 0))
  3447. boundscheck = bool(code.globalstate.directives['boundscheck'])
  3448. return ", %s, %d, %s, %d, %d, %d" % (
  3449. self.original_index_type.empty_declaration_code(),
  3450. self.original_index_type.signed and 1 or 0,
  3451. self.original_index_type.to_py_function,
  3452. is_list, wraparound, boundscheck)
  3453. else:
  3454. return ""
  3455. def generate_result_code(self, code):
  3456. if not self.is_temp:
  3457. # all handled in self.calculate_result_code()
  3458. return
  3459. utility_code = None
  3460. if self.type.is_pyobject:
  3461. error_value = 'NULL'
  3462. if self.index.type.is_int:
  3463. if self.base.type is list_type:
  3464. function = "__Pyx_GetItemInt_List"
  3465. elif self.base.type is tuple_type:
  3466. function = "__Pyx_GetItemInt_Tuple"
  3467. else:
  3468. function = "__Pyx_GetItemInt"
  3469. utility_code = TempitaUtilityCode.load_cached("GetItemInt", "ObjectHandling.c")
  3470. else:
  3471. if self.base.type is dict_type:
  3472. function = "__Pyx_PyDict_GetItem"
  3473. utility_code = UtilityCode.load_cached("DictGetItem", "ObjectHandling.c")
  3474. elif self.base.type is py_object_type and self.index.type in (str_type, unicode_type):
  3475. # obj[str] is probably doing a dict lookup
  3476. function = "__Pyx_PyObject_Dict_GetItem"
  3477. utility_code = UtilityCode.load_cached("DictGetItem", "ObjectHandling.c")
  3478. else:
  3479. function = "__Pyx_PyObject_GetItem"
  3480. code.globalstate.use_utility_code(
  3481. TempitaUtilityCode.load_cached("GetItemInt", "ObjectHandling.c"))
  3482. utility_code = UtilityCode.load_cached("ObjectGetItem", "ObjectHandling.c")
  3483. elif self.type.is_unicode_char and self.base.type is unicode_type:
  3484. assert self.index.type.is_int
  3485. function = "__Pyx_GetItemInt_Unicode"
  3486. error_value = '(Py_UCS4)-1'
  3487. utility_code = UtilityCode.load_cached("GetItemIntUnicode", "StringTools.c")
  3488. elif self.base.type is bytearray_type:
  3489. assert self.index.type.is_int
  3490. assert self.type.is_int
  3491. function = "__Pyx_GetItemInt_ByteArray"
  3492. error_value = '-1'
  3493. utility_code = UtilityCode.load_cached("GetItemIntByteArray", "StringTools.c")
  3494. elif not (self.base.type.is_cpp_class and self.exception_check):
  3495. assert False, "unexpected type %s and base type %s for indexing" % (
  3496. self.type, self.base.type)
  3497. if utility_code is not None:
  3498. code.globalstate.use_utility_code(utility_code)
  3499. if self.index.type.is_int:
  3500. index_code = self.index.result()
  3501. else:
  3502. index_code = self.index.py_result()
  3503. if self.base.type.is_cpp_class and self.exception_check:
  3504. translate_cpp_exception(code, self.pos,
  3505. "%s = %s[%s];" % (self.result(), self.base.result(),
  3506. self.index.result()),
  3507. self.result() if self.type.is_pyobject else None,
  3508. self.exception_value, self.in_nogil_context)
  3509. else:
  3510. error_check = '!%s' if error_value == 'NULL' else '%%s == %s' % error_value
  3511. code.putln(
  3512. "%s = %s(%s, %s%s); %s" % (
  3513. self.result(),
  3514. function,
  3515. self.base.py_result(),
  3516. index_code,
  3517. self.extra_index_params(code),
  3518. code.error_goto_if(error_check % self.result(), self.pos)))
  3519. if self.type.is_pyobject:
  3520. code.put_gotref(self.py_result())
  3521. def generate_setitem_code(self, value_code, code):
  3522. if self.index.type.is_int:
  3523. if self.base.type is bytearray_type:
  3524. code.globalstate.use_utility_code(
  3525. UtilityCode.load_cached("SetItemIntByteArray", "StringTools.c"))
  3526. function = "__Pyx_SetItemInt_ByteArray"
  3527. else:
  3528. code.globalstate.use_utility_code(
  3529. UtilityCode.load_cached("SetItemInt", "ObjectHandling.c"))
  3530. function = "__Pyx_SetItemInt"
  3531. index_code = self.index.result()
  3532. else:
  3533. index_code = self.index.py_result()
  3534. if self.base.type is dict_type:
  3535. function = "PyDict_SetItem"
  3536. # It would seem that we could specialized lists/tuples, but that
  3537. # shouldn't happen here.
  3538. # Both PyList_SetItem() and PyTuple_SetItem() take a Py_ssize_t as
  3539. # index instead of an object, and bad conversion here would give
  3540. # the wrong exception. Also, tuples are supposed to be immutable,
  3541. # and raise a TypeError when trying to set their entries
  3542. # (PyTuple_SetItem() is for creating new tuples from scratch).
  3543. else:
  3544. function = "PyObject_SetItem"
  3545. code.putln(code.error_goto_if_neg(
  3546. "%s(%s, %s, %s%s)" % (
  3547. function,
  3548. self.base.py_result(),
  3549. index_code,
  3550. value_code,
  3551. self.extra_index_params(code)),
  3552. self.pos))
  3553. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  3554. exception_check=None, exception_value=None):
  3555. self.generate_subexpr_evaluation_code(code)
  3556. if self.type.is_pyobject:
  3557. self.generate_setitem_code(rhs.py_result(), code)
  3558. elif self.base.type is bytearray_type:
  3559. value_code = self._check_byte_value(code, rhs)
  3560. self.generate_setitem_code(value_code, code)
  3561. elif self.base.type.is_cpp_class and self.exception_check and self.exception_check == '+':
  3562. if overloaded_assignment and exception_check and \
  3563. self.exception_value != exception_value:
  3564. # Handle the case that both the index operator and the assignment
  3565. # operator have a c++ exception handler and they are not the same.
  3566. translate_double_cpp_exception(code, self.pos, self.type,
  3567. self.result(), rhs.result(), self.exception_value,
  3568. exception_value, self.in_nogil_context)
  3569. else:
  3570. # Handle the case that only the index operator has a
  3571. # c++ exception handler, or that
  3572. # both exception handlers are the same.
  3573. translate_cpp_exception(code, self.pos,
  3574. "%s = %s;" % (self.result(), rhs.result()),
  3575. self.result() if self.type.is_pyobject else None,
  3576. self.exception_value, self.in_nogil_context)
  3577. else:
  3578. code.putln(
  3579. "%s = %s;" % (self.result(), rhs.result()))
  3580. self.generate_subexpr_disposal_code(code)
  3581. self.free_subexpr_temps(code)
  3582. rhs.generate_disposal_code(code)
  3583. rhs.free_temps(code)
  3584. def _check_byte_value(self, code, rhs):
  3585. # TODO: should we do this generally on downcasts, or just here?
  3586. assert rhs.type.is_int, repr(rhs.type)
  3587. value_code = rhs.result()
  3588. if rhs.has_constant_result():
  3589. if 0 <= rhs.constant_result < 256:
  3590. return value_code
  3591. needs_cast = True # make at least the C compiler happy
  3592. warning(rhs.pos,
  3593. "value outside of range(0, 256)"
  3594. " when assigning to byte: %s" % rhs.constant_result,
  3595. level=1)
  3596. else:
  3597. needs_cast = rhs.type != PyrexTypes.c_uchar_type
  3598. if not self.nogil:
  3599. conditions = []
  3600. if rhs.is_literal or rhs.type.signed:
  3601. conditions.append('%s < 0' % value_code)
  3602. if (rhs.is_literal or not
  3603. (rhs.is_temp and rhs.type in (
  3604. PyrexTypes.c_uchar_type, PyrexTypes.c_char_type,
  3605. PyrexTypes.c_schar_type))):
  3606. conditions.append('%s > 255' % value_code)
  3607. if conditions:
  3608. code.putln("if (unlikely(%s)) {" % ' || '.join(conditions))
  3609. code.putln(
  3610. 'PyErr_SetString(PyExc_ValueError,'
  3611. ' "byte must be in range(0, 256)"); %s' %
  3612. code.error_goto(self.pos))
  3613. code.putln("}")
  3614. if needs_cast:
  3615. value_code = '((unsigned char)%s)' % value_code
  3616. return value_code
  3617. def generate_deletion_code(self, code, ignore_nonexisting=False):
  3618. self.generate_subexpr_evaluation_code(code)
  3619. #if self.type.is_pyobject:
  3620. if self.index.type.is_int:
  3621. function = "__Pyx_DelItemInt"
  3622. index_code = self.index.result()
  3623. code.globalstate.use_utility_code(
  3624. UtilityCode.load_cached("DelItemInt", "ObjectHandling.c"))
  3625. else:
  3626. index_code = self.index.py_result()
  3627. if self.base.type is dict_type:
  3628. function = "PyDict_DelItem"
  3629. else:
  3630. function = "PyObject_DelItem"
  3631. code.putln(code.error_goto_if_neg(
  3632. "%s(%s, %s%s)" % (
  3633. function,
  3634. self.base.py_result(),
  3635. index_code,
  3636. self.extra_index_params(code)),
  3637. self.pos))
  3638. self.generate_subexpr_disposal_code(code)
  3639. self.free_subexpr_temps(code)
  3640. class BufferIndexNode(_IndexingBaseNode):
  3641. """
  3642. Indexing of buffers and memoryviews. This node is created during type
  3643. analysis from IndexNode and replaces it.
  3644. Attributes:
  3645. base - base node being indexed
  3646. indices - list of indexing expressions
  3647. """
  3648. subexprs = ['base', 'indices']
  3649. is_buffer_access = True
  3650. # Whether we're assigning to a buffer (in that case it needs to be writable)
  3651. writable_needed = False
  3652. # Any indexing temp variables that we need to clean up.
  3653. index_temps = ()
  3654. def analyse_target_types(self, env):
  3655. self.analyse_types(env, getting=False)
  3656. def analyse_types(self, env, getting=True):
  3657. """
  3658. Analyse types for buffer indexing only. Overridden by memoryview
  3659. indexing and slicing subclasses
  3660. """
  3661. # self.indices are already analyzed
  3662. if not self.base.is_name and not is_pythran_expr(self.base.type):
  3663. error(self.pos, "Can only index buffer variables")
  3664. self.type = error_type
  3665. return self
  3666. if not getting:
  3667. if not self.base.entry.type.writable:
  3668. error(self.pos, "Writing to readonly buffer")
  3669. else:
  3670. self.writable_needed = True
  3671. if self.base.type.is_buffer:
  3672. self.base.entry.buffer_aux.writable_needed = True
  3673. self.none_error_message = "'NoneType' object is not subscriptable"
  3674. self.analyse_buffer_index(env, getting)
  3675. self.wrap_in_nonecheck_node(env)
  3676. return self
  3677. def analyse_buffer_index(self, env, getting):
  3678. if is_pythran_expr(self.base.type):
  3679. index_with_type_list = [(idx, idx.type) for idx in self.indices]
  3680. self.type = PythranExpr(pythran_indexing_type(self.base.type, index_with_type_list))
  3681. else:
  3682. self.base = self.base.coerce_to_simple(env)
  3683. self.type = self.base.type.dtype
  3684. self.buffer_type = self.base.type
  3685. if getting and (self.type.is_pyobject or self.type.is_pythran_expr):
  3686. self.is_temp = True
  3687. def analyse_assignment(self, rhs):
  3688. """
  3689. Called by IndexNode when this node is assigned to,
  3690. with the rhs of the assignment
  3691. """
  3692. def wrap_in_nonecheck_node(self, env):
  3693. if not env.directives['nonecheck'] or not self.base.may_be_none():
  3694. return
  3695. self.base = self.base.as_none_safe_node(self.none_error_message)
  3696. def nogil_check(self, env):
  3697. if self.is_buffer_access or self.is_memview_index:
  3698. if self.type.is_pyobject:
  3699. error(self.pos, "Cannot access buffer with object dtype without gil")
  3700. self.type = error_type
  3701. def calculate_result_code(self):
  3702. return "(*%s)" % self.buffer_ptr_code
  3703. def buffer_entry(self):
  3704. base = self.base
  3705. if self.base.is_nonecheck:
  3706. base = base.arg
  3707. return base.type.get_entry(base)
  3708. def get_index_in_temp(self, code, ivar):
  3709. ret = code.funcstate.allocate_temp(
  3710. PyrexTypes.widest_numeric_type(
  3711. ivar.type,
  3712. PyrexTypes.c_ssize_t_type if ivar.type.signed else PyrexTypes.c_size_t_type),
  3713. manage_ref=False)
  3714. code.putln("%s = %s;" % (ret, ivar.result()))
  3715. return ret
  3716. def buffer_lookup_code(self, code):
  3717. """
  3718. ndarray[1, 2, 3] and memslice[1, 2, 3]
  3719. """
  3720. if self.in_nogil_context:
  3721. if self.is_buffer_access or self.is_memview_index:
  3722. if code.globalstate.directives['boundscheck']:
  3723. warning(self.pos, "Use boundscheck(False) for faster access", level=1)
  3724. # Assign indices to temps of at least (s)size_t to allow further index calculations.
  3725. self.index_temps = index_temps = [self.get_index_in_temp(code,ivar) for ivar in self.indices]
  3726. # Generate buffer access code using these temps
  3727. from . import Buffer
  3728. buffer_entry = self.buffer_entry()
  3729. if buffer_entry.type.is_buffer:
  3730. negative_indices = buffer_entry.type.negative_indices
  3731. else:
  3732. negative_indices = Buffer.buffer_defaults['negative_indices']
  3733. return buffer_entry, Buffer.put_buffer_lookup_code(
  3734. entry=buffer_entry,
  3735. index_signeds=[ivar.type.signed for ivar in self.indices],
  3736. index_cnames=index_temps,
  3737. directives=code.globalstate.directives,
  3738. pos=self.pos, code=code,
  3739. negative_indices=negative_indices,
  3740. in_nogil_context=self.in_nogil_context)
  3741. def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
  3742. self.generate_subexpr_evaluation_code(code)
  3743. self.generate_buffer_setitem_code(rhs, code)
  3744. self.generate_subexpr_disposal_code(code)
  3745. self.free_subexpr_temps(code)
  3746. rhs.generate_disposal_code(code)
  3747. rhs.free_temps(code)
  3748. def generate_buffer_setitem_code(self, rhs, code, op=""):
  3749. base_type = self.base.type
  3750. if is_pythran_expr(base_type) and is_pythran_supported_type(rhs.type):
  3751. obj = code.funcstate.allocate_temp(PythranExpr(pythran_type(self.base.type)), manage_ref=False)
  3752. # We have got to do this because we have to declare pythran objects
  3753. # at the beginning of the functions.
  3754. # Indeed, Cython uses "goto" statement for error management, and
  3755. # RAII doesn't work with that kind of construction.
  3756. # Moreover, the way Pythran expressions are made is that they don't
  3757. # support move-assignation easily.
  3758. # This, we explicitly destroy then in-place new objects in this
  3759. # case.
  3760. code.putln("__Pyx_call_destructor(%s);" % obj)
  3761. code.putln("new (&%s) decltype(%s){%s};" % (obj, obj, self.base.pythran_result()))
  3762. code.putln("%s%s %s= %s;" % (
  3763. obj,
  3764. pythran_indexing_code(self.indices),
  3765. op,
  3766. rhs.pythran_result()))
  3767. code.funcstate.release_temp(obj)
  3768. return
  3769. # Used from generate_assignment_code and InPlaceAssignmentNode
  3770. buffer_entry, ptrexpr = self.buffer_lookup_code(code)
  3771. if self.buffer_type.dtype.is_pyobject:
  3772. # Must manage refcounts. Decref what is already there
  3773. # and incref what we put in.
  3774. ptr = code.funcstate.allocate_temp(buffer_entry.buf_ptr_type,
  3775. manage_ref=False)
  3776. rhs_code = rhs.result()
  3777. code.putln("%s = %s;" % (ptr, ptrexpr))
  3778. code.put_gotref("*%s" % ptr)
  3779. code.putln("__Pyx_INCREF(%s); __Pyx_DECREF(*%s);" % (
  3780. rhs_code, ptr))
  3781. code.putln("*%s %s= %s;" % (ptr, op, rhs_code))
  3782. code.put_giveref("*%s" % ptr)
  3783. code.funcstate.release_temp(ptr)
  3784. else:
  3785. # Simple case
  3786. code.putln("*%s %s= %s;" % (ptrexpr, op, rhs.result()))
  3787. def generate_result_code(self, code):
  3788. if is_pythran_expr(self.base.type):
  3789. res = self.result()
  3790. code.putln("__Pyx_call_destructor(%s);" % res)
  3791. code.putln("new (&%s) decltype(%s){%s%s};" % (
  3792. res,
  3793. res,
  3794. self.base.pythran_result(),
  3795. pythran_indexing_code(self.indices)))
  3796. return
  3797. buffer_entry, self.buffer_ptr_code = self.buffer_lookup_code(code)
  3798. if self.type.is_pyobject:
  3799. # is_temp is True, so must pull out value and incref it.
  3800. # NOTE: object temporary results for nodes are declared
  3801. # as PyObject *, so we need a cast
  3802. code.putln("%s = (PyObject *) *%s;" % (self.result(), self.buffer_ptr_code))
  3803. code.putln("__Pyx_INCREF((PyObject*)%s);" % self.result())
  3804. def free_subexpr_temps(self, code):
  3805. for temp in self.index_temps:
  3806. code.funcstate.release_temp(temp)
  3807. self.index_temps = ()
  3808. super(BufferIndexNode, self).free_subexpr_temps(code)
  3809. class MemoryViewIndexNode(BufferIndexNode):
  3810. is_memview_index = True
  3811. is_buffer_access = False
  3812. warned_untyped_idx = False
  3813. def analyse_types(self, env, getting=True):
  3814. # memoryviewslice indexing or slicing
  3815. from . import MemoryView
  3816. self.is_pythran_mode = has_np_pythran(env)
  3817. indices = self.indices
  3818. have_slices, indices, newaxes = MemoryView.unellipsify(indices, self.base.type.ndim)
  3819. if not getting:
  3820. self.writable_needed = True
  3821. if self.base.is_name or self.base.is_attribute:
  3822. self.base.entry.type.writable_needed = True
  3823. self.memslice_index = (not newaxes and len(indices) == self.base.type.ndim)
  3824. axes = []
  3825. index_type = PyrexTypes.c_py_ssize_t_type
  3826. new_indices = []
  3827. if len(indices) - len(newaxes) > self.base.type.ndim:
  3828. self.type = error_type
  3829. error(indices[self.base.type.ndim].pos,
  3830. "Too many indices specified for type %s" % self.base.type)
  3831. return self
  3832. axis_idx = 0
  3833. for i, index in enumerate(indices[:]):
  3834. index = index.analyse_types(env)
  3835. if index.is_none:
  3836. self.is_memview_slice = True
  3837. new_indices.append(index)
  3838. axes.append(('direct', 'strided'))
  3839. continue
  3840. access, packing = self.base.type.axes[axis_idx]
  3841. axis_idx += 1
  3842. if index.is_slice:
  3843. self.is_memview_slice = True
  3844. if index.step.is_none:
  3845. axes.append((access, packing))
  3846. else:
  3847. axes.append((access, 'strided'))
  3848. # Coerce start, stop and step to temps of the right type
  3849. for attr in ('start', 'stop', 'step'):
  3850. value = getattr(index, attr)
  3851. if not value.is_none:
  3852. value = value.coerce_to(index_type, env)
  3853. #value = value.coerce_to_temp(env)
  3854. setattr(index, attr, value)
  3855. new_indices.append(value)
  3856. elif index.type.is_int or index.type.is_pyobject:
  3857. if index.type.is_pyobject and not self.warned_untyped_idx:
  3858. warning(index.pos, "Index should be typed for more efficient access", level=2)
  3859. MemoryViewIndexNode.warned_untyped_idx = True
  3860. self.is_memview_index = True
  3861. index = index.coerce_to(index_type, env)
  3862. indices[i] = index
  3863. new_indices.append(index)
  3864. else:
  3865. self.type = error_type
  3866. error(index.pos, "Invalid index for memoryview specified, type %s" % index.type)
  3867. return self
  3868. ### FIXME: replace by MemoryViewSliceNode if is_memview_slice ?
  3869. self.is_memview_index = self.is_memview_index and not self.is_memview_slice
  3870. self.indices = new_indices
  3871. # All indices with all start/stop/step for slices.
  3872. # We need to keep this around.
  3873. self.original_indices = indices
  3874. self.nogil = env.nogil
  3875. self.analyse_operation(env, getting, axes)
  3876. self.wrap_in_nonecheck_node(env)
  3877. return self
  3878. def analyse_operation(self, env, getting, axes):
  3879. self.none_error_message = "Cannot index None memoryview slice"
  3880. self.analyse_buffer_index(env, getting)
  3881. def analyse_broadcast_operation(self, rhs):
  3882. """
  3883. Support broadcasting for slice assignment.
  3884. E.g.
  3885. m_2d[...] = m_1d # or,
  3886. m_1d[...] = m_2d # if the leading dimension has extent 1
  3887. """
  3888. if self.type.is_memoryviewslice:
  3889. lhs = self
  3890. if lhs.is_memview_broadcast or rhs.is_memview_broadcast:
  3891. lhs.is_memview_broadcast = True
  3892. rhs.is_memview_broadcast = True
  3893. def analyse_as_memview_scalar_assignment(self, rhs):
  3894. lhs = self.analyse_assignment(rhs)
  3895. if lhs:
  3896. rhs.is_memview_copy_assignment = lhs.is_memview_copy_assignment
  3897. return lhs
  3898. return self
  3899. class MemoryViewSliceNode(MemoryViewIndexNode):
  3900. is_memview_slice = True
  3901. # No-op slicing operation, this node will be replaced
  3902. is_ellipsis_noop = False
  3903. is_memview_scalar_assignment = False
  3904. is_memview_index = False
  3905. is_memview_broadcast = False
  3906. def analyse_ellipsis_noop(self, env, getting):
  3907. """Slicing operations needing no evaluation, i.e. m[...] or m[:, :]"""
  3908. ### FIXME: replace directly
  3909. self.is_ellipsis_noop = all(
  3910. index.is_slice and index.start.is_none and index.stop.is_none and index.step.is_none
  3911. for index in self.indices)
  3912. if self.is_ellipsis_noop:
  3913. self.type = self.base.type
  3914. def analyse_operation(self, env, getting, axes):
  3915. from . import MemoryView
  3916. if not getting:
  3917. self.is_memview_broadcast = True
  3918. self.none_error_message = "Cannot assign to None memoryview slice"
  3919. else:
  3920. self.none_error_message = "Cannot slice None memoryview slice"
  3921. self.analyse_ellipsis_noop(env, getting)
  3922. if self.is_ellipsis_noop:
  3923. return
  3924. self.index = None
  3925. self.is_temp = True
  3926. self.use_managed_ref = True
  3927. if not MemoryView.validate_axes(self.pos, axes):
  3928. self.type = error_type
  3929. return
  3930. self.type = PyrexTypes.MemoryViewSliceType(self.base.type.dtype, axes)
  3931. if not (self.base.is_simple() or self.base.result_in_temp()):
  3932. self.base = self.base.coerce_to_temp(env)
  3933. def analyse_assignment(self, rhs):
  3934. if not rhs.type.is_memoryviewslice and (
  3935. self.type.dtype.assignable_from(rhs.type) or
  3936. rhs.type.is_pyobject):
  3937. # scalar assignment
  3938. return MemoryCopyScalar(self.pos, self)
  3939. else:
  3940. return MemoryCopySlice(self.pos, self)
  3941. def merged_indices(self, indices):
  3942. """Return a new list of indices/slices with 'indices' merged into the current ones
  3943. according to slicing rules.
  3944. Is used to implement "view[i][j]" => "view[i, j]".
  3945. Return None if the indices cannot (easily) be merged at compile time.
  3946. """
  3947. if not indices:
  3948. return None
  3949. # NOTE: Need to evaluate "self.original_indices" here as they might differ from "self.indices".
  3950. new_indices = self.original_indices[:]
  3951. indices = indices[:]
  3952. for i, s in enumerate(self.original_indices):
  3953. if s.is_slice:
  3954. if s.start.is_none and s.stop.is_none and s.step.is_none:
  3955. # Full slice found, replace by index.
  3956. new_indices[i] = indices[0]
  3957. indices.pop(0)
  3958. if not indices:
  3959. return new_indices
  3960. else:
  3961. # Found something non-trivial, e.g. a partial slice.
  3962. return None
  3963. elif not s.type.is_int:
  3964. # Not a slice, not an integer index => could be anything...
  3965. return None
  3966. if indices:
  3967. if len(new_indices) + len(indices) > self.base.type.ndim:
  3968. return None
  3969. new_indices += indices
  3970. return new_indices
  3971. def is_simple(self):
  3972. if self.is_ellipsis_noop:
  3973. # TODO: fix SimpleCallNode.is_simple()
  3974. return self.base.is_simple() or self.base.result_in_temp()
  3975. return self.result_in_temp()
  3976. def calculate_result_code(self):
  3977. """This is called in case this is a no-op slicing node"""
  3978. return self.base.result()
  3979. def generate_result_code(self, code):
  3980. if self.is_ellipsis_noop:
  3981. return ### FIXME: remove
  3982. buffer_entry = self.buffer_entry()
  3983. have_gil = not self.in_nogil_context
  3984. # TODO Mark: this is insane, do it better
  3985. have_slices = False
  3986. it = iter(self.indices)
  3987. for index in self.original_indices:
  3988. if index.is_slice:
  3989. have_slices = True
  3990. if not index.start.is_none:
  3991. index.start = next(it)
  3992. if not index.stop.is_none:
  3993. index.stop = next(it)
  3994. if not index.step.is_none:
  3995. index.step = next(it)
  3996. else:
  3997. next(it)
  3998. assert not list(it)
  3999. buffer_entry.generate_buffer_slice_code(
  4000. code, self.original_indices, self.result(),
  4001. have_gil=have_gil, have_slices=have_slices,
  4002. directives=code.globalstate.directives)
  4003. def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
  4004. if self.is_ellipsis_noop:
  4005. self.generate_subexpr_evaluation_code(code)
  4006. else:
  4007. self.generate_evaluation_code(code)
  4008. if self.is_memview_scalar_assignment:
  4009. self.generate_memoryviewslice_assign_scalar_code(rhs, code)
  4010. else:
  4011. self.generate_memoryviewslice_setslice_code(rhs, code)
  4012. if self.is_ellipsis_noop:
  4013. self.generate_subexpr_disposal_code(code)
  4014. else:
  4015. self.generate_disposal_code(code)
  4016. rhs.generate_disposal_code(code)
  4017. rhs.free_temps(code)
  4018. class MemoryCopyNode(ExprNode):
  4019. """
  4020. Wraps a memoryview slice for slice assignment.
  4021. dst: destination mememoryview slice
  4022. """
  4023. subexprs = ['dst']
  4024. def __init__(self, pos, dst):
  4025. super(MemoryCopyNode, self).__init__(pos)
  4026. self.dst = dst
  4027. self.type = dst.type
  4028. def generate_assignment_code(self, rhs, code, overloaded_assignment=False):
  4029. self.dst.generate_evaluation_code(code)
  4030. self._generate_assignment_code(rhs, code)
  4031. self.dst.generate_disposal_code(code)
  4032. self.dst.free_temps(code)
  4033. rhs.generate_disposal_code(code)
  4034. rhs.free_temps(code)
  4035. class MemoryCopySlice(MemoryCopyNode):
  4036. """
  4037. Copy the contents of slice src to slice dst. Does not support indirect
  4038. slices.
  4039. memslice1[...] = memslice2
  4040. memslice1[:] = memslice2
  4041. """
  4042. is_memview_copy_assignment = True
  4043. copy_slice_cname = "__pyx_memoryview_copy_contents"
  4044. def _generate_assignment_code(self, src, code):
  4045. dst = self.dst
  4046. src.type.assert_direct_dims(src.pos)
  4047. dst.type.assert_direct_dims(dst.pos)
  4048. code.putln(code.error_goto_if_neg(
  4049. "%s(%s, %s, %d, %d, %d)" % (self.copy_slice_cname,
  4050. src.result(), dst.result(),
  4051. src.type.ndim, dst.type.ndim,
  4052. dst.type.dtype.is_pyobject),
  4053. dst.pos))
  4054. class MemoryCopyScalar(MemoryCopyNode):
  4055. """
  4056. Assign a scalar to a slice. dst must be simple, scalar will be assigned
  4057. to a correct type and not just something assignable.
  4058. memslice1[...] = 0.0
  4059. memslice1[:] = 0.0
  4060. """
  4061. def __init__(self, pos, dst):
  4062. super(MemoryCopyScalar, self).__init__(pos, dst)
  4063. self.type = dst.type.dtype
  4064. def _generate_assignment_code(self, scalar, code):
  4065. from . import MemoryView
  4066. self.dst.type.assert_direct_dims(self.dst.pos)
  4067. dtype = self.dst.type.dtype
  4068. type_decl = dtype.declaration_code("")
  4069. slice_decl = self.dst.type.declaration_code("")
  4070. code.begin_block()
  4071. code.putln("%s __pyx_temp_scalar = %s;" % (type_decl, scalar.result()))
  4072. if self.dst.result_in_temp() or self.dst.is_simple():
  4073. dst_temp = self.dst.result()
  4074. else:
  4075. code.putln("%s __pyx_temp_slice = %s;" % (slice_decl, self.dst.result()))
  4076. dst_temp = "__pyx_temp_slice"
  4077. slice_iter_obj = MemoryView.slice_iter(self.dst.type, dst_temp,
  4078. self.dst.type.ndim, code)
  4079. p = slice_iter_obj.start_loops()
  4080. if dtype.is_pyobject:
  4081. code.putln("Py_DECREF(*(PyObject **) %s);" % p)
  4082. code.putln("*((%s *) %s) = __pyx_temp_scalar;" % (type_decl, p))
  4083. if dtype.is_pyobject:
  4084. code.putln("Py_INCREF(__pyx_temp_scalar);")
  4085. slice_iter_obj.end_loops()
  4086. code.end_block()
  4087. class SliceIndexNode(ExprNode):
  4088. # 2-element slice indexing
  4089. #
  4090. # base ExprNode
  4091. # start ExprNode or None
  4092. # stop ExprNode or None
  4093. # slice ExprNode or None constant slice object
  4094. subexprs = ['base', 'start', 'stop', 'slice']
  4095. slice = None
  4096. def infer_type(self, env):
  4097. base_type = self.base.infer_type(env)
  4098. if base_type.is_string or base_type.is_cpp_class:
  4099. return bytes_type
  4100. elif base_type.is_pyunicode_ptr:
  4101. return unicode_type
  4102. elif base_type in (bytes_type, bytearray_type, str_type, unicode_type,
  4103. basestring_type, list_type, tuple_type):
  4104. return base_type
  4105. elif base_type.is_ptr or base_type.is_array:
  4106. return PyrexTypes.c_array_type(base_type.base_type, None)
  4107. return py_object_type
  4108. def inferable_item_node(self, index=0):
  4109. # slicing shouldn't change the result type of the base, but the index might
  4110. if index is not not_a_constant and self.start:
  4111. if self.start.has_constant_result():
  4112. index += self.start.constant_result
  4113. else:
  4114. index = not_a_constant
  4115. return self.base.inferable_item_node(index)
  4116. def may_be_none(self):
  4117. base_type = self.base.type
  4118. if base_type:
  4119. if base_type.is_string:
  4120. return False
  4121. if base_type in (bytes_type, str_type, unicode_type,
  4122. basestring_type, list_type, tuple_type):
  4123. return False
  4124. return ExprNode.may_be_none(self)
  4125. def calculate_constant_result(self):
  4126. if self.start is None:
  4127. start = None
  4128. else:
  4129. start = self.start.constant_result
  4130. if self.stop is None:
  4131. stop = None
  4132. else:
  4133. stop = self.stop.constant_result
  4134. self.constant_result = self.base.constant_result[start:stop]
  4135. def compile_time_value(self, denv):
  4136. base = self.base.compile_time_value(denv)
  4137. if self.start is None:
  4138. start = 0
  4139. else:
  4140. start = self.start.compile_time_value(denv)
  4141. if self.stop is None:
  4142. stop = None
  4143. else:
  4144. stop = self.stop.compile_time_value(denv)
  4145. try:
  4146. return base[start:stop]
  4147. except Exception as e:
  4148. self.compile_time_value_error(e)
  4149. def analyse_target_declaration(self, env):
  4150. pass
  4151. def analyse_target_types(self, env):
  4152. node = self.analyse_types(env, getting=False)
  4153. # when assigning, we must accept any Python type
  4154. if node.type.is_pyobject:
  4155. node.type = py_object_type
  4156. return node
  4157. def analyse_types(self, env, getting=True):
  4158. self.base = self.base.analyse_types(env)
  4159. if self.base.type.is_buffer or self.base.type.is_pythran_expr or self.base.type.is_memoryviewslice:
  4160. none_node = NoneNode(self.pos)
  4161. index = SliceNode(self.pos,
  4162. start=self.start or none_node,
  4163. stop=self.stop or none_node,
  4164. step=none_node)
  4165. index_node = IndexNode(self.pos, index=index, base=self.base)
  4166. return index_node.analyse_base_and_index_types(
  4167. env, getting=getting, setting=not getting,
  4168. analyse_base=False)
  4169. if self.start:
  4170. self.start = self.start.analyse_types(env)
  4171. if self.stop:
  4172. self.stop = self.stop.analyse_types(env)
  4173. if not env.directives['wraparound']:
  4174. check_negative_indices(self.start, self.stop)
  4175. base_type = self.base.type
  4176. if base_type.is_array and not getting:
  4177. # cannot assign directly to C array => try to assign by making a copy
  4178. if not self.start and not self.stop:
  4179. self.type = base_type
  4180. else:
  4181. self.type = PyrexTypes.CPtrType(base_type.base_type)
  4182. elif base_type.is_string or base_type.is_cpp_string:
  4183. self.type = default_str_type(env)
  4184. elif base_type.is_pyunicode_ptr:
  4185. self.type = unicode_type
  4186. elif base_type.is_ptr:
  4187. self.type = base_type
  4188. elif base_type.is_array:
  4189. # we need a ptr type here instead of an array type, as
  4190. # array types can result in invalid type casts in the C
  4191. # code
  4192. self.type = PyrexTypes.CPtrType(base_type.base_type)
  4193. else:
  4194. self.base = self.base.coerce_to_pyobject(env)
  4195. self.type = py_object_type
  4196. if base_type.is_builtin_type:
  4197. # slicing builtin types returns something of the same type
  4198. self.type = base_type
  4199. self.base = self.base.as_none_safe_node("'NoneType' object is not subscriptable")
  4200. if self.type is py_object_type:
  4201. if (not self.start or self.start.is_literal) and \
  4202. (not self.stop or self.stop.is_literal):
  4203. # cache the constant slice object, in case we need it
  4204. none_node = NoneNode(self.pos)
  4205. self.slice = SliceNode(
  4206. self.pos,
  4207. start=copy.deepcopy(self.start or none_node),
  4208. stop=copy.deepcopy(self.stop or none_node),
  4209. step=none_node
  4210. ).analyse_types(env)
  4211. else:
  4212. c_int = PyrexTypes.c_py_ssize_t_type
  4213. def allow_none(node, default_value, env):
  4214. # Coerce to Py_ssize_t, but allow None as meaning the default slice bound.
  4215. from .UtilNodes import EvalWithTempExprNode, ResultRefNode
  4216. node_ref = ResultRefNode(node)
  4217. new_expr = CondExprNode(
  4218. node.pos,
  4219. true_val=IntNode(
  4220. node.pos,
  4221. type=c_int,
  4222. value=default_value,
  4223. constant_result=int(default_value) if default_value.isdigit() else not_a_constant,
  4224. ),
  4225. false_val=node_ref.coerce_to(c_int, env),
  4226. test=PrimaryCmpNode(
  4227. node.pos,
  4228. operand1=node_ref,
  4229. operator='is',
  4230. operand2=NoneNode(node.pos),
  4231. ).analyse_types(env)
  4232. ).analyse_result_type(env)
  4233. return EvalWithTempExprNode(node_ref, new_expr)
  4234. if self.start:
  4235. if self.start.type.is_pyobject:
  4236. self.start = allow_none(self.start, '0', env)
  4237. self.start = self.start.coerce_to(c_int, env)
  4238. if self.stop:
  4239. if self.stop.type.is_pyobject:
  4240. self.stop = allow_none(self.stop, 'PY_SSIZE_T_MAX', env)
  4241. self.stop = self.stop.coerce_to(c_int, env)
  4242. self.is_temp = 1
  4243. return self
  4244. def analyse_as_type(self, env):
  4245. base_type = self.base.analyse_as_type(env)
  4246. if base_type and not base_type.is_pyobject:
  4247. if not self.start and not self.stop:
  4248. # memory view
  4249. from . import MemoryView
  4250. env.use_utility_code(MemoryView.view_utility_code)
  4251. none_node = NoneNode(self.pos)
  4252. slice_node = SliceNode(
  4253. self.pos,
  4254. start=none_node,
  4255. stop=none_node,
  4256. step=none_node,
  4257. )
  4258. return PyrexTypes.MemoryViewSliceType(
  4259. base_type, MemoryView.get_axes_specs(env, [slice_node]))
  4260. return None
  4261. nogil_check = Node.gil_error
  4262. gil_message = "Slicing Python object"
  4263. get_slice_utility_code = TempitaUtilityCode.load(
  4264. "SliceObject", "ObjectHandling.c", context={'access': 'Get'})
  4265. set_slice_utility_code = TempitaUtilityCode.load(
  4266. "SliceObject", "ObjectHandling.c", context={'access': 'Set'})
  4267. def coerce_to(self, dst_type, env):
  4268. if ((self.base.type.is_string or self.base.type.is_cpp_string)
  4269. and dst_type in (bytes_type, bytearray_type, str_type, unicode_type)):
  4270. if (dst_type not in (bytes_type, bytearray_type)
  4271. and not env.directives['c_string_encoding']):
  4272. error(self.pos,
  4273. "default encoding required for conversion from '%s' to '%s'" %
  4274. (self.base.type, dst_type))
  4275. self.type = dst_type
  4276. if dst_type.is_array and self.base.type.is_array:
  4277. if not self.start and not self.stop:
  4278. # redundant slice building, copy C arrays directly
  4279. return self.base.coerce_to(dst_type, env)
  4280. # else: check array size if possible
  4281. return super(SliceIndexNode, self).coerce_to(dst_type, env)
  4282. def generate_result_code(self, code):
  4283. if not self.type.is_pyobject:
  4284. error(self.pos,
  4285. "Slicing is not currently supported for '%s'." % self.type)
  4286. return
  4287. base_result = self.base.result()
  4288. result = self.result()
  4289. start_code = self.start_code()
  4290. stop_code = self.stop_code()
  4291. if self.base.type.is_string:
  4292. base_result = self.base.result()
  4293. if self.base.type not in (PyrexTypes.c_char_ptr_type, PyrexTypes.c_const_char_ptr_type):
  4294. base_result = '((const char*)%s)' % base_result
  4295. if self.type is bytearray_type:
  4296. type_name = 'ByteArray'
  4297. else:
  4298. type_name = self.type.name.title()
  4299. if self.stop is None:
  4300. code.putln(
  4301. "%s = __Pyx_Py%s_FromString(%s + %s); %s" % (
  4302. result,
  4303. type_name,
  4304. base_result,
  4305. start_code,
  4306. code.error_goto_if_null(result, self.pos)))
  4307. else:
  4308. code.putln(
  4309. "%s = __Pyx_Py%s_FromStringAndSize(%s + %s, %s - %s); %s" % (
  4310. result,
  4311. type_name,
  4312. base_result,
  4313. start_code,
  4314. stop_code,
  4315. start_code,
  4316. code.error_goto_if_null(result, self.pos)))
  4317. elif self.base.type.is_pyunicode_ptr:
  4318. base_result = self.base.result()
  4319. if self.base.type != PyrexTypes.c_py_unicode_ptr_type:
  4320. base_result = '((const Py_UNICODE*)%s)' % base_result
  4321. if self.stop is None:
  4322. code.putln(
  4323. "%s = __Pyx_PyUnicode_FromUnicode(%s + %s); %s" % (
  4324. result,
  4325. base_result,
  4326. start_code,
  4327. code.error_goto_if_null(result, self.pos)))
  4328. else:
  4329. code.putln(
  4330. "%s = __Pyx_PyUnicode_FromUnicodeAndLength(%s + %s, %s - %s); %s" % (
  4331. result,
  4332. base_result,
  4333. start_code,
  4334. stop_code,
  4335. start_code,
  4336. code.error_goto_if_null(result, self.pos)))
  4337. elif self.base.type is unicode_type:
  4338. code.globalstate.use_utility_code(
  4339. UtilityCode.load_cached("PyUnicode_Substring", "StringTools.c"))
  4340. code.putln(
  4341. "%s = __Pyx_PyUnicode_Substring(%s, %s, %s); %s" % (
  4342. result,
  4343. base_result,
  4344. start_code,
  4345. stop_code,
  4346. code.error_goto_if_null(result, self.pos)))
  4347. elif self.type is py_object_type:
  4348. code.globalstate.use_utility_code(self.get_slice_utility_code)
  4349. (has_c_start, has_c_stop, c_start, c_stop,
  4350. py_start, py_stop, py_slice) = self.get_slice_config()
  4351. code.putln(
  4352. "%s = __Pyx_PyObject_GetSlice(%s, %s, %s, %s, %s, %s, %d, %d, %d); %s" % (
  4353. result,
  4354. self.base.py_result(),
  4355. c_start, c_stop,
  4356. py_start, py_stop, py_slice,
  4357. has_c_start, has_c_stop,
  4358. bool(code.globalstate.directives['wraparound']),
  4359. code.error_goto_if_null(result, self.pos)))
  4360. else:
  4361. if self.base.type is list_type:
  4362. code.globalstate.use_utility_code(
  4363. TempitaUtilityCode.load_cached("SliceTupleAndList", "ObjectHandling.c"))
  4364. cfunc = '__Pyx_PyList_GetSlice'
  4365. elif self.base.type is tuple_type:
  4366. code.globalstate.use_utility_code(
  4367. TempitaUtilityCode.load_cached("SliceTupleAndList", "ObjectHandling.c"))
  4368. cfunc = '__Pyx_PyTuple_GetSlice'
  4369. else:
  4370. cfunc = 'PySequence_GetSlice'
  4371. code.putln(
  4372. "%s = %s(%s, %s, %s); %s" % (
  4373. result,
  4374. cfunc,
  4375. self.base.py_result(),
  4376. start_code,
  4377. stop_code,
  4378. code.error_goto_if_null(result, self.pos)))
  4379. code.put_gotref(self.py_result())
  4380. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  4381. exception_check=None, exception_value=None):
  4382. self.generate_subexpr_evaluation_code(code)
  4383. if self.type.is_pyobject:
  4384. code.globalstate.use_utility_code(self.set_slice_utility_code)
  4385. (has_c_start, has_c_stop, c_start, c_stop,
  4386. py_start, py_stop, py_slice) = self.get_slice_config()
  4387. code.put_error_if_neg(self.pos,
  4388. "__Pyx_PyObject_SetSlice(%s, %s, %s, %s, %s, %s, %s, %d, %d, %d)" % (
  4389. self.base.py_result(),
  4390. rhs.py_result(),
  4391. c_start, c_stop,
  4392. py_start, py_stop, py_slice,
  4393. has_c_start, has_c_stop,
  4394. bool(code.globalstate.directives['wraparound'])))
  4395. else:
  4396. start_offset = self.start_code() if self.start else '0'
  4397. if rhs.type.is_array:
  4398. array_length = rhs.type.size
  4399. self.generate_slice_guard_code(code, array_length)
  4400. else:
  4401. array_length = '%s - %s' % (self.stop_code(), start_offset)
  4402. code.globalstate.use_utility_code(UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
  4403. code.putln("memcpy(&(%s[%s]), %s, sizeof(%s[0]) * (%s));" % (
  4404. self.base.result(), start_offset,
  4405. rhs.result(),
  4406. self.base.result(), array_length
  4407. ))
  4408. self.generate_subexpr_disposal_code(code)
  4409. self.free_subexpr_temps(code)
  4410. rhs.generate_disposal_code(code)
  4411. rhs.free_temps(code)
  4412. def generate_deletion_code(self, code, ignore_nonexisting=False):
  4413. if not self.base.type.is_pyobject:
  4414. error(self.pos,
  4415. "Deleting slices is only supported for Python types, not '%s'." % self.type)
  4416. return
  4417. self.generate_subexpr_evaluation_code(code)
  4418. code.globalstate.use_utility_code(self.set_slice_utility_code)
  4419. (has_c_start, has_c_stop, c_start, c_stop,
  4420. py_start, py_stop, py_slice) = self.get_slice_config()
  4421. code.put_error_if_neg(self.pos,
  4422. "__Pyx_PyObject_DelSlice(%s, %s, %s, %s, %s, %s, %d, %d, %d)" % (
  4423. self.base.py_result(),
  4424. c_start, c_stop,
  4425. py_start, py_stop, py_slice,
  4426. has_c_start, has_c_stop,
  4427. bool(code.globalstate.directives['wraparound'])))
  4428. self.generate_subexpr_disposal_code(code)
  4429. self.free_subexpr_temps(code)
  4430. def get_slice_config(self):
  4431. has_c_start, c_start, py_start = False, '0', 'NULL'
  4432. if self.start:
  4433. has_c_start = not self.start.type.is_pyobject
  4434. if has_c_start:
  4435. c_start = self.start.result()
  4436. else:
  4437. py_start = '&%s' % self.start.py_result()
  4438. has_c_stop, c_stop, py_stop = False, '0', 'NULL'
  4439. if self.stop:
  4440. has_c_stop = not self.stop.type.is_pyobject
  4441. if has_c_stop:
  4442. c_stop = self.stop.result()
  4443. else:
  4444. py_stop = '&%s' % self.stop.py_result()
  4445. py_slice = self.slice and '&%s' % self.slice.py_result() or 'NULL'
  4446. return (has_c_start, has_c_stop, c_start, c_stop,
  4447. py_start, py_stop, py_slice)
  4448. def generate_slice_guard_code(self, code, target_size):
  4449. if not self.base.type.is_array:
  4450. return
  4451. slice_size = self.base.type.size
  4452. try:
  4453. total_length = slice_size = int(slice_size)
  4454. except ValueError:
  4455. total_length = None
  4456. start = stop = None
  4457. if self.stop:
  4458. stop = self.stop.result()
  4459. try:
  4460. stop = int(stop)
  4461. if stop < 0:
  4462. if total_length is None:
  4463. slice_size = '%s + %d' % (slice_size, stop)
  4464. else:
  4465. slice_size += stop
  4466. else:
  4467. slice_size = stop
  4468. stop = None
  4469. except ValueError:
  4470. pass
  4471. if self.start:
  4472. start = self.start.result()
  4473. try:
  4474. start = int(start)
  4475. if start < 0:
  4476. if total_length is None:
  4477. start = '%s + %d' % (self.base.type.size, start)
  4478. else:
  4479. start += total_length
  4480. if isinstance(slice_size, _py_int_types):
  4481. slice_size -= start
  4482. else:
  4483. slice_size = '%s - (%s)' % (slice_size, start)
  4484. start = None
  4485. except ValueError:
  4486. pass
  4487. runtime_check = None
  4488. compile_time_check = False
  4489. try:
  4490. int_target_size = int(target_size)
  4491. except ValueError:
  4492. int_target_size = None
  4493. else:
  4494. compile_time_check = isinstance(slice_size, _py_int_types)
  4495. if compile_time_check and slice_size < 0:
  4496. if int_target_size > 0:
  4497. error(self.pos, "Assignment to empty slice.")
  4498. elif compile_time_check and start is None and stop is None:
  4499. # we know the exact slice length
  4500. if int_target_size != slice_size:
  4501. error(self.pos, "Assignment to slice of wrong length, expected %s, got %s" % (
  4502. slice_size, target_size))
  4503. elif start is not None:
  4504. if stop is None:
  4505. stop = slice_size
  4506. runtime_check = "(%s)-(%s)" % (stop, start)
  4507. elif stop is not None:
  4508. runtime_check = stop
  4509. else:
  4510. runtime_check = slice_size
  4511. if runtime_check:
  4512. code.putln("if (unlikely((%s) != (%s))) {" % (runtime_check, target_size))
  4513. code.putln(
  4514. 'PyErr_Format(PyExc_ValueError, "Assignment to slice of wrong length,'
  4515. ' expected %%" CYTHON_FORMAT_SSIZE_T "d, got %%" CYTHON_FORMAT_SSIZE_T "d",'
  4516. ' (Py_ssize_t)(%s), (Py_ssize_t)(%s));' % (
  4517. target_size, runtime_check))
  4518. code.putln(code.error_goto(self.pos))
  4519. code.putln("}")
  4520. def start_code(self):
  4521. if self.start:
  4522. return self.start.result()
  4523. else:
  4524. return "0"
  4525. def stop_code(self):
  4526. if self.stop:
  4527. return self.stop.result()
  4528. elif self.base.type.is_array:
  4529. return self.base.type.size
  4530. else:
  4531. return "PY_SSIZE_T_MAX"
  4532. def calculate_result_code(self):
  4533. # self.result() is not used, but this method must exist
  4534. return "<unused>"
  4535. class SliceNode(ExprNode):
  4536. # start:stop:step in subscript list
  4537. #
  4538. # start ExprNode
  4539. # stop ExprNode
  4540. # step ExprNode
  4541. subexprs = ['start', 'stop', 'step']
  4542. is_slice = True
  4543. type = slice_type
  4544. is_temp = 1
  4545. def calculate_constant_result(self):
  4546. self.constant_result = slice(
  4547. self.start.constant_result,
  4548. self.stop.constant_result,
  4549. self.step.constant_result)
  4550. def compile_time_value(self, denv):
  4551. start = self.start.compile_time_value(denv)
  4552. stop = self.stop.compile_time_value(denv)
  4553. step = self.step.compile_time_value(denv)
  4554. try:
  4555. return slice(start, stop, step)
  4556. except Exception as e:
  4557. self.compile_time_value_error(e)
  4558. def may_be_none(self):
  4559. return False
  4560. def analyse_types(self, env):
  4561. start = self.start.analyse_types(env)
  4562. stop = self.stop.analyse_types(env)
  4563. step = self.step.analyse_types(env)
  4564. self.start = start.coerce_to_pyobject(env)
  4565. self.stop = stop.coerce_to_pyobject(env)
  4566. self.step = step.coerce_to_pyobject(env)
  4567. if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
  4568. self.is_literal = True
  4569. self.is_temp = False
  4570. return self
  4571. gil_message = "Constructing Python slice object"
  4572. def calculate_result_code(self):
  4573. return self.result_code
  4574. def generate_result_code(self, code):
  4575. if self.is_literal:
  4576. dedup_key = make_dedup_key(self.type, (self,))
  4577. self.result_code = code.get_py_const(py_object_type, 'slice', cleanup_level=2, dedup_key=dedup_key)
  4578. code = code.get_cached_constants_writer(self.result_code)
  4579. if code is None:
  4580. return # already initialised
  4581. code.mark_pos(self.pos)
  4582. code.putln(
  4583. "%s = PySlice_New(%s, %s, %s); %s" % (
  4584. self.result(),
  4585. self.start.py_result(),
  4586. self.stop.py_result(),
  4587. self.step.py_result(),
  4588. code.error_goto_if_null(self.result(), self.pos)))
  4589. code.put_gotref(self.py_result())
  4590. if self.is_literal:
  4591. code.put_giveref(self.py_result())
  4592. class SliceIntNode(SliceNode):
  4593. # start:stop:step in subscript list
  4594. # This is just a node to hold start,stop and step nodes that can be
  4595. # converted to integers. This does not generate a slice python object.
  4596. #
  4597. # start ExprNode
  4598. # stop ExprNode
  4599. # step ExprNode
  4600. is_temp = 0
  4601. def calculate_constant_result(self):
  4602. self.constant_result = slice(
  4603. self.start.constant_result,
  4604. self.stop.constant_result,
  4605. self.step.constant_result)
  4606. def compile_time_value(self, denv):
  4607. start = self.start.compile_time_value(denv)
  4608. stop = self.stop.compile_time_value(denv)
  4609. step = self.step.compile_time_value(denv)
  4610. try:
  4611. return slice(start, stop, step)
  4612. except Exception as e:
  4613. self.compile_time_value_error(e)
  4614. def may_be_none(self):
  4615. return False
  4616. def analyse_types(self, env):
  4617. self.start = self.start.analyse_types(env)
  4618. self.stop = self.stop.analyse_types(env)
  4619. self.step = self.step.analyse_types(env)
  4620. if not self.start.is_none:
  4621. self.start = self.start.coerce_to_integer(env)
  4622. if not self.stop.is_none:
  4623. self.stop = self.stop.coerce_to_integer(env)
  4624. if not self.step.is_none:
  4625. self.step = self.step.coerce_to_integer(env)
  4626. if self.start.is_literal and self.stop.is_literal and self.step.is_literal:
  4627. self.is_literal = True
  4628. self.is_temp = False
  4629. return self
  4630. def calculate_result_code(self):
  4631. pass
  4632. def generate_result_code(self, code):
  4633. for a in self.start,self.stop,self.step:
  4634. if isinstance(a, CloneNode):
  4635. a.arg.result()
  4636. class CallNode(ExprNode):
  4637. # allow overriding the default 'may_be_none' behaviour
  4638. may_return_none = None
  4639. def infer_type(self, env):
  4640. # TODO(robertwb): Reduce redundancy with analyse_types.
  4641. function = self.function
  4642. func_type = function.infer_type(env)
  4643. if isinstance(function, NewExprNode):
  4644. # note: needs call to infer_type() above
  4645. return PyrexTypes.CPtrType(function.class_type)
  4646. if func_type is py_object_type:
  4647. # function might have lied for safety => try to find better type
  4648. entry = getattr(function, 'entry', None)
  4649. if entry is not None:
  4650. func_type = entry.type or func_type
  4651. if func_type.is_ptr:
  4652. func_type = func_type.base_type
  4653. if func_type.is_cfunction:
  4654. if getattr(self.function, 'entry', None) and hasattr(self, 'args'):
  4655. alternatives = self.function.entry.all_alternatives()
  4656. arg_types = [arg.infer_type(env) for arg in self.args]
  4657. func_entry = PyrexTypes.best_match(arg_types, alternatives)
  4658. if func_entry:
  4659. func_type = func_entry.type
  4660. if func_type.is_ptr:
  4661. func_type = func_type.base_type
  4662. return func_type.return_type
  4663. return func_type.return_type
  4664. elif func_type is type_type:
  4665. if function.is_name and function.entry and function.entry.type:
  4666. result_type = function.entry.type
  4667. if result_type.is_extension_type:
  4668. return result_type
  4669. elif result_type.is_builtin_type:
  4670. if function.entry.name == 'float':
  4671. return PyrexTypes.c_double_type
  4672. elif function.entry.name in Builtin.types_that_construct_their_instance:
  4673. return result_type
  4674. return py_object_type
  4675. def type_dependencies(self, env):
  4676. # TODO: Update when Danilo's C++ code merged in to handle the
  4677. # the case of function overloading.
  4678. return self.function.type_dependencies(env)
  4679. def is_simple(self):
  4680. # C function calls could be considered simple, but they may
  4681. # have side-effects that may hit when multiple operations must
  4682. # be effected in order, e.g. when constructing the argument
  4683. # sequence for a function call or comparing values.
  4684. return False
  4685. def may_be_none(self):
  4686. if self.may_return_none is not None:
  4687. return self.may_return_none
  4688. func_type = self.function.type
  4689. if func_type is type_type and self.function.is_name:
  4690. entry = self.function.entry
  4691. if entry.type.is_extension_type:
  4692. return False
  4693. if (entry.type.is_builtin_type and
  4694. entry.name in Builtin.types_that_construct_their_instance):
  4695. return False
  4696. return ExprNode.may_be_none(self)
  4697. def set_py_result_type(self, function, func_type=None):
  4698. if func_type is None:
  4699. func_type = function.type
  4700. if func_type is Builtin.type_type and (
  4701. function.is_name and
  4702. function.entry and
  4703. function.entry.is_builtin and
  4704. function.entry.name in Builtin.types_that_construct_their_instance):
  4705. # calling a builtin type that returns a specific object type
  4706. if function.entry.name == 'float':
  4707. # the following will come true later on in a transform
  4708. self.type = PyrexTypes.c_double_type
  4709. self.result_ctype = PyrexTypes.c_double_type
  4710. else:
  4711. self.type = Builtin.builtin_types[function.entry.name]
  4712. self.result_ctype = py_object_type
  4713. self.may_return_none = False
  4714. elif function.is_name and function.type_entry:
  4715. # We are calling an extension type constructor. As long as we do not
  4716. # support __new__(), the result type is clear
  4717. self.type = function.type_entry.type
  4718. self.result_ctype = py_object_type
  4719. self.may_return_none = False
  4720. else:
  4721. self.type = py_object_type
  4722. def analyse_as_type_constructor(self, env):
  4723. type = self.function.analyse_as_type(env)
  4724. if type and type.is_struct_or_union:
  4725. args, kwds = self.explicit_args_kwds()
  4726. items = []
  4727. for arg, member in zip(args, type.scope.var_entries):
  4728. items.append(DictItemNode(pos=arg.pos, key=StringNode(pos=arg.pos, value=member.name), value=arg))
  4729. if kwds:
  4730. items += kwds.key_value_pairs
  4731. self.key_value_pairs = items
  4732. self.__class__ = DictNode
  4733. self.analyse_types(env) # FIXME
  4734. self.coerce_to(type, env)
  4735. return True
  4736. elif type and type.is_cpp_class:
  4737. self.args = [ arg.analyse_types(env) for arg in self.args ]
  4738. constructor = type.scope.lookup("<init>")
  4739. if not constructor:
  4740. error(self.function.pos, "no constructor found for C++ type '%s'" % self.function.name)
  4741. self.type = error_type
  4742. return self
  4743. self.function = RawCNameExprNode(self.function.pos, constructor.type)
  4744. self.function.entry = constructor
  4745. self.function.set_cname(type.empty_declaration_code())
  4746. self.analyse_c_function_call(env)
  4747. self.type = type
  4748. return True
  4749. def is_lvalue(self):
  4750. return self.type.is_reference
  4751. def nogil_check(self, env):
  4752. func_type = self.function_type()
  4753. if func_type.is_pyobject:
  4754. self.gil_error()
  4755. elif not func_type.is_error and not getattr(func_type, 'nogil', False):
  4756. self.gil_error()
  4757. gil_message = "Calling gil-requiring function"
  4758. class SimpleCallNode(CallNode):
  4759. # Function call without keyword, * or ** args.
  4760. #
  4761. # function ExprNode
  4762. # args [ExprNode]
  4763. # arg_tuple ExprNode or None used internally
  4764. # self ExprNode or None used internally
  4765. # coerced_self ExprNode or None used internally
  4766. # wrapper_call bool used internally
  4767. # has_optional_args bool used internally
  4768. # nogil bool used internally
  4769. subexprs = ['self', 'coerced_self', 'function', 'args', 'arg_tuple']
  4770. self = None
  4771. coerced_self = None
  4772. arg_tuple = None
  4773. wrapper_call = False
  4774. has_optional_args = False
  4775. nogil = False
  4776. analysed = False
  4777. overflowcheck = False
  4778. def compile_time_value(self, denv):
  4779. function = self.function.compile_time_value(denv)
  4780. args = [arg.compile_time_value(denv) for arg in self.args]
  4781. try:
  4782. return function(*args)
  4783. except Exception as e:
  4784. self.compile_time_value_error(e)
  4785. def analyse_as_type(self, env):
  4786. attr = self.function.as_cython_attribute()
  4787. if attr == 'pointer':
  4788. if len(self.args) != 1:
  4789. error(self.args.pos, "only one type allowed.")
  4790. else:
  4791. type = self.args[0].analyse_as_type(env)
  4792. if not type:
  4793. error(self.args[0].pos, "Unknown type")
  4794. else:
  4795. return PyrexTypes.CPtrType(type)
  4796. elif attr == 'typeof':
  4797. if len(self.args) != 1:
  4798. error(self.args.pos, "only one type allowed.")
  4799. operand = self.args[0].analyse_types(env)
  4800. return operand.type
  4801. def explicit_args_kwds(self):
  4802. return self.args, None
  4803. def analyse_types(self, env):
  4804. if self.analyse_as_type_constructor(env):
  4805. return self
  4806. if self.analysed:
  4807. return self
  4808. self.analysed = True
  4809. self.function.is_called = 1
  4810. self.function = self.function.analyse_types(env)
  4811. function = self.function
  4812. if function.is_attribute and function.entry and function.entry.is_cmethod:
  4813. # Take ownership of the object from which the attribute
  4814. # was obtained, because we need to pass it as 'self'.
  4815. self.self = function.obj
  4816. function.obj = CloneNode(self.self)
  4817. func_type = self.function_type()
  4818. self.is_numpy_call_with_exprs = False
  4819. if (has_np_pythran(env) and function.is_numpy_attribute and
  4820. pythran_is_numpy_func_supported(function)):
  4821. has_pythran_args = True
  4822. self.arg_tuple = TupleNode(self.pos, args = self.args)
  4823. self.arg_tuple = self.arg_tuple.analyse_types(env)
  4824. for arg in self.arg_tuple.args:
  4825. has_pythran_args &= is_pythran_supported_node_or_none(arg)
  4826. self.is_numpy_call_with_exprs = bool(has_pythran_args)
  4827. if self.is_numpy_call_with_exprs:
  4828. env.add_include_file(pythran_get_func_include_file(function))
  4829. return NumPyMethodCallNode.from_node(
  4830. self,
  4831. function_cname=pythran_functor(function),
  4832. arg_tuple=self.arg_tuple,
  4833. type=PythranExpr(pythran_func_type(function, self.arg_tuple.args)),
  4834. )
  4835. elif func_type.is_pyobject:
  4836. self.arg_tuple = TupleNode(self.pos, args = self.args)
  4837. self.arg_tuple = self.arg_tuple.analyse_types(env).coerce_to_pyobject(env)
  4838. self.args = None
  4839. self.set_py_result_type(function, func_type)
  4840. self.is_temp = 1
  4841. else:
  4842. self.args = [ arg.analyse_types(env) for arg in self.args ]
  4843. self.analyse_c_function_call(env)
  4844. if func_type.exception_check == '+':
  4845. self.is_temp = True
  4846. return self
  4847. def function_type(self):
  4848. # Return the type of the function being called, coercing a function
  4849. # pointer to a function if necessary. If the function has fused
  4850. # arguments, return the specific type.
  4851. func_type = self.function.type
  4852. if func_type.is_ptr:
  4853. func_type = func_type.base_type
  4854. return func_type
  4855. def analyse_c_function_call(self, env):
  4856. func_type = self.function.type
  4857. if func_type is error_type:
  4858. self.type = error_type
  4859. return
  4860. if func_type.is_cfunction and func_type.is_static_method:
  4861. if self.self and self.self.type.is_extension_type:
  4862. # To support this we'd need to pass self to determine whether
  4863. # it was overloaded in Python space (possibly via a Cython
  4864. # superclass turning a cdef method into a cpdef one).
  4865. error(self.pos, "Cannot call a static method on an instance variable.")
  4866. args = self.args
  4867. elif self.self:
  4868. args = [self.self] + self.args
  4869. else:
  4870. args = self.args
  4871. if func_type.is_cpp_class:
  4872. overloaded_entry = self.function.type.scope.lookup("operator()")
  4873. if overloaded_entry is None:
  4874. self.type = PyrexTypes.error_type
  4875. self.result_code = "<error>"
  4876. return
  4877. elif hasattr(self.function, 'entry'):
  4878. overloaded_entry = self.function.entry
  4879. elif self.function.is_subscript and self.function.is_fused_index:
  4880. overloaded_entry = self.function.type.entry
  4881. else:
  4882. overloaded_entry = None
  4883. if overloaded_entry:
  4884. if self.function.type.is_fused:
  4885. functypes = self.function.type.get_all_specialized_function_types()
  4886. alternatives = [f.entry for f in functypes]
  4887. else:
  4888. alternatives = overloaded_entry.all_alternatives()
  4889. entry = PyrexTypes.best_match(
  4890. [arg.type for arg in args], alternatives, self.pos, env, args)
  4891. if not entry:
  4892. self.type = PyrexTypes.error_type
  4893. self.result_code = "<error>"
  4894. return
  4895. entry.used = True
  4896. if not func_type.is_cpp_class:
  4897. self.function.entry = entry
  4898. self.function.type = entry.type
  4899. func_type = self.function_type()
  4900. else:
  4901. entry = None
  4902. func_type = self.function_type()
  4903. if not func_type.is_cfunction:
  4904. error(self.pos, "Calling non-function type '%s'" % func_type)
  4905. self.type = PyrexTypes.error_type
  4906. self.result_code = "<error>"
  4907. return
  4908. # Check no. of args
  4909. max_nargs = len(func_type.args)
  4910. expected_nargs = max_nargs - func_type.optional_arg_count
  4911. actual_nargs = len(args)
  4912. if func_type.optional_arg_count and expected_nargs != actual_nargs:
  4913. self.has_optional_args = 1
  4914. self.is_temp = 1
  4915. # check 'self' argument
  4916. if entry and entry.is_cmethod and func_type.args and not func_type.is_static_method:
  4917. formal_arg = func_type.args[0]
  4918. arg = args[0]
  4919. if formal_arg.not_none:
  4920. if self.self:
  4921. self.self = self.self.as_none_safe_node(
  4922. "'NoneType' object has no attribute '%{0}s'".format('.30' if len(entry.name) <= 30 else ''),
  4923. error='PyExc_AttributeError',
  4924. format_args=[entry.name])
  4925. else:
  4926. # unbound method
  4927. arg = arg.as_none_safe_node(
  4928. "descriptor '%s' requires a '%s' object but received a 'NoneType'",
  4929. format_args=[entry.name, formal_arg.type.name])
  4930. if self.self:
  4931. if formal_arg.accept_builtin_subtypes:
  4932. arg = CMethodSelfCloneNode(self.self)
  4933. else:
  4934. arg = CloneNode(self.self)
  4935. arg = self.coerced_self = arg.coerce_to(formal_arg.type, env)
  4936. elif formal_arg.type.is_builtin_type:
  4937. # special case: unbound methods of builtins accept subtypes
  4938. arg = arg.coerce_to(formal_arg.type, env)
  4939. if arg.type.is_builtin_type and isinstance(arg, PyTypeTestNode):
  4940. arg.exact_builtin_type = False
  4941. args[0] = arg
  4942. # Coerce arguments
  4943. some_args_in_temps = False
  4944. for i in range(min(max_nargs, actual_nargs)):
  4945. formal_arg = func_type.args[i]
  4946. formal_type = formal_arg.type
  4947. arg = args[i].coerce_to(formal_type, env)
  4948. if formal_arg.not_none:
  4949. # C methods must do the None checks at *call* time
  4950. arg = arg.as_none_safe_node(
  4951. "cannot pass None into a C function argument that is declared 'not None'")
  4952. if arg.is_temp:
  4953. if i > 0:
  4954. # first argument in temp doesn't impact subsequent arguments
  4955. some_args_in_temps = True
  4956. elif arg.type.is_pyobject and not env.nogil:
  4957. if i == 0 and self.self is not None:
  4958. # a method's cloned "self" argument is ok
  4959. pass
  4960. elif arg.nonlocally_immutable():
  4961. # plain local variables are ok
  4962. pass
  4963. else:
  4964. # we do not safely own the argument's reference,
  4965. # but we must make sure it cannot be collected
  4966. # before we return from the function, so we create
  4967. # an owned temp reference to it
  4968. if i > 0: # first argument doesn't matter
  4969. some_args_in_temps = True
  4970. arg = arg.coerce_to_temp(env)
  4971. args[i] = arg
  4972. # handle additional varargs parameters
  4973. for i in range(max_nargs, actual_nargs):
  4974. arg = args[i]
  4975. if arg.type.is_pyobject:
  4976. if arg.type is str_type:
  4977. arg_ctype = PyrexTypes.c_char_ptr_type
  4978. else:
  4979. arg_ctype = arg.type.default_coerced_ctype()
  4980. if arg_ctype is None:
  4981. error(self.args[i].pos,
  4982. "Python object cannot be passed as a varargs parameter")
  4983. else:
  4984. args[i] = arg = arg.coerce_to(arg_ctype, env)
  4985. if arg.is_temp and i > 0:
  4986. some_args_in_temps = True
  4987. if some_args_in_temps:
  4988. # if some args are temps and others are not, they may get
  4989. # constructed in the wrong order (temps first) => make
  4990. # sure they are either all temps or all not temps (except
  4991. # for the last argument, which is evaluated last in any
  4992. # case)
  4993. for i in range(actual_nargs-1):
  4994. if i == 0 and self.self is not None:
  4995. continue # self is ok
  4996. arg = args[i]
  4997. if arg.nonlocally_immutable():
  4998. # locals, C functions, unassignable types are safe.
  4999. pass
  5000. elif arg.type.is_cpp_class:
  5001. # Assignment has side effects, avoid.
  5002. pass
  5003. elif env.nogil and arg.type.is_pyobject:
  5004. # can't copy a Python reference into a temp in nogil
  5005. # env (this is safe: a construction would fail in
  5006. # nogil anyway)
  5007. pass
  5008. else:
  5009. #self.args[i] = arg.coerce_to_temp(env)
  5010. # instead: issue a warning
  5011. if i > 0 or i == 1 and self.self is not None: # skip first arg
  5012. warning(arg.pos, "Argument evaluation order in C function call is undefined and may not be as expected", 0)
  5013. break
  5014. self.args[:] = args
  5015. # Calc result type and code fragment
  5016. if isinstance(self.function, NewExprNode):
  5017. self.type = PyrexTypes.CPtrType(self.function.class_type)
  5018. else:
  5019. self.type = func_type.return_type
  5020. if self.function.is_name or self.function.is_attribute:
  5021. func_entry = self.function.entry
  5022. if func_entry and (func_entry.utility_code or func_entry.utility_code_definition):
  5023. self.is_temp = 1 # currently doesn't work for self.calculate_result_code()
  5024. if self.type.is_pyobject:
  5025. self.result_ctype = py_object_type
  5026. self.is_temp = 1
  5027. elif func_type.exception_value is not None or func_type.exception_check:
  5028. self.is_temp = 1
  5029. elif self.type.is_memoryviewslice:
  5030. self.is_temp = 1
  5031. # func_type.exception_check = True
  5032. if self.is_temp and self.type.is_reference:
  5033. self.type = PyrexTypes.CFakeReferenceType(self.type.ref_base_type)
  5034. # Called in 'nogil' context?
  5035. self.nogil = env.nogil
  5036. if (self.nogil and
  5037. func_type.exception_check and
  5038. func_type.exception_check != '+'):
  5039. env.use_utility_code(pyerr_occurred_withgil_utility_code)
  5040. # C++ exception handler
  5041. if func_type.exception_check == '+':
  5042. if func_type.exception_value is None:
  5043. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  5044. self.overflowcheck = env.directives['overflowcheck']
  5045. def calculate_result_code(self):
  5046. return self.c_call_code()
  5047. def c_call_code(self):
  5048. func_type = self.function_type()
  5049. if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
  5050. return "<error>"
  5051. formal_args = func_type.args
  5052. arg_list_code = []
  5053. args = list(zip(formal_args, self.args))
  5054. max_nargs = len(func_type.args)
  5055. expected_nargs = max_nargs - func_type.optional_arg_count
  5056. actual_nargs = len(self.args)
  5057. for formal_arg, actual_arg in args[:expected_nargs]:
  5058. arg_code = actual_arg.result_as(formal_arg.type)
  5059. arg_list_code.append(arg_code)
  5060. if func_type.is_overridable:
  5061. arg_list_code.append(str(int(self.wrapper_call or self.function.entry.is_unbound_cmethod)))
  5062. if func_type.optional_arg_count:
  5063. if expected_nargs == actual_nargs:
  5064. optional_args = 'NULL'
  5065. else:
  5066. optional_args = "&%s" % self.opt_arg_struct
  5067. arg_list_code.append(optional_args)
  5068. for actual_arg in self.args[len(formal_args):]:
  5069. arg_list_code.append(actual_arg.result())
  5070. result = "%s(%s)" % (self.function.result(), ', '.join(arg_list_code))
  5071. return result
  5072. def is_c_result_required(self):
  5073. func_type = self.function_type()
  5074. if not func_type.exception_value or func_type.exception_check == '+':
  5075. return False # skip allocation of unused result temp
  5076. return True
  5077. def generate_evaluation_code(self, code):
  5078. function = self.function
  5079. if function.is_name or function.is_attribute:
  5080. code.globalstate.use_entry_utility_code(function.entry)
  5081. abs_function_cnames = ('abs', 'labs', '__Pyx_abs_longlong')
  5082. is_signed_int = self.type.is_int and self.type.signed
  5083. if self.overflowcheck and is_signed_int and function.result() in abs_function_cnames:
  5084. code.globalstate.use_utility_code(UtilityCode.load_cached("Common", "Overflow.c"))
  5085. code.putln('if (unlikely(%s == __PYX_MIN(%s))) {\
  5086. PyErr_SetString(PyExc_OverflowError,\
  5087. "Trying to take the absolute value of the most negative integer is not defined."); %s; }' % (
  5088. self.args[0].result(),
  5089. self.args[0].type.empty_declaration_code(),
  5090. code.error_goto(self.pos)))
  5091. if not function.type.is_pyobject or len(self.arg_tuple.args) > 1 or (
  5092. self.arg_tuple.args and self.arg_tuple.is_literal):
  5093. super(SimpleCallNode, self).generate_evaluation_code(code)
  5094. return
  5095. # Special case 0-args and try to avoid explicit tuple creation for Python calls with 1 arg.
  5096. arg = self.arg_tuple.args[0] if self.arg_tuple.args else None
  5097. subexprs = (self.self, self.coerced_self, function, arg)
  5098. for subexpr in subexprs:
  5099. if subexpr is not None:
  5100. subexpr.generate_evaluation_code(code)
  5101. code.mark_pos(self.pos)
  5102. assert self.is_temp
  5103. self.allocate_temp_result(code)
  5104. if arg is None:
  5105. code.globalstate.use_utility_code(UtilityCode.load_cached(
  5106. "PyObjectCallNoArg", "ObjectHandling.c"))
  5107. code.putln(
  5108. "%s = __Pyx_PyObject_CallNoArg(%s); %s" % (
  5109. self.result(),
  5110. function.py_result(),
  5111. code.error_goto_if_null(self.result(), self.pos)))
  5112. else:
  5113. code.globalstate.use_utility_code(UtilityCode.load_cached(
  5114. "PyObjectCallOneArg", "ObjectHandling.c"))
  5115. code.putln(
  5116. "%s = __Pyx_PyObject_CallOneArg(%s, %s); %s" % (
  5117. self.result(),
  5118. function.py_result(),
  5119. arg.py_result(),
  5120. code.error_goto_if_null(self.result(), self.pos)))
  5121. code.put_gotref(self.py_result())
  5122. for subexpr in subexprs:
  5123. if subexpr is not None:
  5124. subexpr.generate_disposal_code(code)
  5125. subexpr.free_temps(code)
  5126. def generate_result_code(self, code):
  5127. func_type = self.function_type()
  5128. if func_type.is_pyobject:
  5129. arg_code = self.arg_tuple.py_result()
  5130. code.globalstate.use_utility_code(UtilityCode.load_cached(
  5131. "PyObjectCall", "ObjectHandling.c"))
  5132. code.putln(
  5133. "%s = __Pyx_PyObject_Call(%s, %s, NULL); %s" % (
  5134. self.result(),
  5135. self.function.py_result(),
  5136. arg_code,
  5137. code.error_goto_if_null(self.result(), self.pos)))
  5138. code.put_gotref(self.py_result())
  5139. elif func_type.is_cfunction:
  5140. if self.has_optional_args:
  5141. actual_nargs = len(self.args)
  5142. expected_nargs = len(func_type.args) - func_type.optional_arg_count
  5143. self.opt_arg_struct = code.funcstate.allocate_temp(
  5144. func_type.op_arg_struct.base_type, manage_ref=True)
  5145. code.putln("%s.%s = %s;" % (
  5146. self.opt_arg_struct,
  5147. Naming.pyrex_prefix + "n",
  5148. len(self.args) - expected_nargs))
  5149. args = list(zip(func_type.args, self.args))
  5150. for formal_arg, actual_arg in args[expected_nargs:actual_nargs]:
  5151. code.putln("%s.%s = %s;" % (
  5152. self.opt_arg_struct,
  5153. func_type.opt_arg_cname(formal_arg.name),
  5154. actual_arg.result_as(formal_arg.type)))
  5155. exc_checks = []
  5156. if self.type.is_pyobject and self.is_temp:
  5157. exc_checks.append("!%s" % self.result())
  5158. elif self.type.is_memoryviewslice:
  5159. assert self.is_temp
  5160. exc_checks.append(self.type.error_condition(self.result()))
  5161. elif func_type.exception_check != '+':
  5162. exc_val = func_type.exception_value
  5163. exc_check = func_type.exception_check
  5164. if exc_val is not None:
  5165. exc_checks.append("%s == %s" % (self.result(), func_type.return_type.cast_code(exc_val)))
  5166. if exc_check:
  5167. if self.nogil:
  5168. exc_checks.append("__Pyx_ErrOccurredWithGIL()")
  5169. else:
  5170. exc_checks.append("PyErr_Occurred()")
  5171. if self.is_temp or exc_checks:
  5172. rhs = self.c_call_code()
  5173. if self.result():
  5174. lhs = "%s = " % self.result()
  5175. if self.is_temp and self.type.is_pyobject:
  5176. #return_type = self.type # func_type.return_type
  5177. #print "SimpleCallNode.generate_result_code: casting", rhs, \
  5178. # "from", return_type, "to pyobject" ###
  5179. rhs = typecast(py_object_type, self.type, rhs)
  5180. else:
  5181. lhs = ""
  5182. if func_type.exception_check == '+':
  5183. translate_cpp_exception(code, self.pos, '%s%s;' % (lhs, rhs),
  5184. self.result() if self.type.is_pyobject else None,
  5185. func_type.exception_value, self.nogil)
  5186. else:
  5187. if exc_checks:
  5188. goto_error = code.error_goto_if(" && ".join(exc_checks), self.pos)
  5189. else:
  5190. goto_error = ""
  5191. code.putln("%s%s; %s" % (lhs, rhs, goto_error))
  5192. if self.type.is_pyobject and self.result():
  5193. code.put_gotref(self.py_result())
  5194. if self.has_optional_args:
  5195. code.funcstate.release_temp(self.opt_arg_struct)
  5196. class NumPyMethodCallNode(ExprNode):
  5197. # Pythran call to a NumPy function or method.
  5198. #
  5199. # function_cname string the function/method to call
  5200. # arg_tuple TupleNode the arguments as an args tuple
  5201. subexprs = ['arg_tuple']
  5202. is_temp = True
  5203. may_return_none = True
  5204. def generate_evaluation_code(self, code):
  5205. code.mark_pos(self.pos)
  5206. self.allocate_temp_result(code)
  5207. assert self.arg_tuple.mult_factor is None
  5208. args = self.arg_tuple.args
  5209. for arg in args:
  5210. arg.generate_evaluation_code(code)
  5211. code.putln("// function evaluation code for numpy function")
  5212. code.putln("__Pyx_call_destructor(%s);" % self.result())
  5213. code.putln("new (&%s) decltype(%s){%s{}(%s)};" % (
  5214. self.result(),
  5215. self.result(),
  5216. self.function_cname,
  5217. ", ".join(a.pythran_result() for a in args)))
  5218. class PyMethodCallNode(SimpleCallNode):
  5219. # Specialised call to a (potential) PyMethodObject with non-constant argument tuple.
  5220. # Allows the self argument to be injected directly instead of repacking a tuple for it.
  5221. #
  5222. # function ExprNode the function/method object to call
  5223. # arg_tuple TupleNode the arguments for the args tuple
  5224. subexprs = ['function', 'arg_tuple']
  5225. is_temp = True
  5226. def generate_evaluation_code(self, code):
  5227. code.mark_pos(self.pos)
  5228. self.allocate_temp_result(code)
  5229. self.function.generate_evaluation_code(code)
  5230. assert self.arg_tuple.mult_factor is None
  5231. args = self.arg_tuple.args
  5232. for arg in args:
  5233. arg.generate_evaluation_code(code)
  5234. # make sure function is in temp so that we can replace the reference below if it's a method
  5235. reuse_function_temp = self.function.is_temp
  5236. if reuse_function_temp:
  5237. function = self.function.result()
  5238. else:
  5239. function = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  5240. self.function.make_owned_reference(code)
  5241. code.put("%s = %s; " % (function, self.function.py_result()))
  5242. self.function.generate_disposal_code(code)
  5243. self.function.free_temps(code)
  5244. self_arg = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  5245. code.putln("%s = NULL;" % self_arg)
  5246. arg_offset_cname = None
  5247. if len(args) > 1:
  5248. arg_offset_cname = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
  5249. code.putln("%s = 0;" % arg_offset_cname)
  5250. def attribute_is_likely_method(attr):
  5251. obj = attr.obj
  5252. if obj.is_name and obj.entry.is_pyglobal:
  5253. return False # more likely to be a function
  5254. return True
  5255. if self.function.is_attribute:
  5256. likely_method = 'likely' if attribute_is_likely_method(self.function) else 'unlikely'
  5257. elif self.function.is_name and self.function.cf_state:
  5258. # not an attribute itself, but might have been assigned from one (e.g. bound method)
  5259. for assignment in self.function.cf_state:
  5260. value = assignment.rhs
  5261. if value and value.is_attribute and value.obj.type and value.obj.type.is_pyobject:
  5262. if attribute_is_likely_method(value):
  5263. likely_method = 'likely'
  5264. break
  5265. else:
  5266. likely_method = 'unlikely'
  5267. else:
  5268. likely_method = 'unlikely'
  5269. code.putln("if (CYTHON_UNPACK_METHODS && %s(PyMethod_Check(%s))) {" % (likely_method, function))
  5270. code.putln("%s = PyMethod_GET_SELF(%s);" % (self_arg, function))
  5271. # the following is always true in Py3 (kept only for safety),
  5272. # but is false for unbound methods in Py2
  5273. code.putln("if (likely(%s)) {" % self_arg)
  5274. code.putln("PyObject* function = PyMethod_GET_FUNCTION(%s);" % function)
  5275. code.put_incref(self_arg, py_object_type)
  5276. code.put_incref("function", py_object_type)
  5277. # free method object as early to possible to enable reuse from CPython's freelist
  5278. code.put_decref_set(function, "function")
  5279. if len(args) > 1:
  5280. code.putln("%s = 1;" % arg_offset_cname)
  5281. code.putln("}")
  5282. code.putln("}")
  5283. if not args:
  5284. # fastest special case: try to avoid tuple creation
  5285. code.globalstate.use_utility_code(
  5286. UtilityCode.load_cached("PyObjectCallNoArg", "ObjectHandling.c"))
  5287. code.globalstate.use_utility_code(
  5288. UtilityCode.load_cached("PyObjectCallOneArg", "ObjectHandling.c"))
  5289. code.putln(
  5290. "%s = (%s) ? __Pyx_PyObject_CallOneArg(%s, %s) : __Pyx_PyObject_CallNoArg(%s);" % (
  5291. self.result(), self_arg,
  5292. function, self_arg,
  5293. function))
  5294. code.put_xdecref_clear(self_arg, py_object_type)
  5295. code.funcstate.release_temp(self_arg)
  5296. code.putln(code.error_goto_if_null(self.result(), self.pos))
  5297. code.put_gotref(self.py_result())
  5298. elif len(args) == 1:
  5299. # fastest special case: try to avoid tuple creation
  5300. code.globalstate.use_utility_code(
  5301. UtilityCode.load_cached("PyObjectCall2Args", "ObjectHandling.c"))
  5302. code.globalstate.use_utility_code(
  5303. UtilityCode.load_cached("PyObjectCallOneArg", "ObjectHandling.c"))
  5304. arg = args[0]
  5305. code.putln(
  5306. "%s = (%s) ? __Pyx_PyObject_Call2Args(%s, %s, %s) : __Pyx_PyObject_CallOneArg(%s, %s);" % (
  5307. self.result(), self_arg,
  5308. function, self_arg, arg.py_result(),
  5309. function, arg.py_result()))
  5310. code.put_xdecref_clear(self_arg, py_object_type)
  5311. code.funcstate.release_temp(self_arg)
  5312. arg.generate_disposal_code(code)
  5313. arg.free_temps(code)
  5314. code.putln(code.error_goto_if_null(self.result(), self.pos))
  5315. code.put_gotref(self.py_result())
  5316. else:
  5317. code.globalstate.use_utility_code(
  5318. UtilityCode.load_cached("PyFunctionFastCall", "ObjectHandling.c"))
  5319. code.globalstate.use_utility_code(
  5320. UtilityCode.load_cached("PyCFunctionFastCall", "ObjectHandling.c"))
  5321. for test_func, call_prefix in [('PyFunction_Check', 'Py'), ('__Pyx_PyFastCFunction_Check', 'PyC')]:
  5322. code.putln("#if CYTHON_FAST_%sCALL" % call_prefix.upper())
  5323. code.putln("if (%s(%s)) {" % (test_func, function))
  5324. code.putln("PyObject *%s[%d] = {%s, %s};" % (
  5325. Naming.quick_temp_cname,
  5326. len(args)+1,
  5327. self_arg,
  5328. ', '.join(arg.py_result() for arg in args)))
  5329. code.putln("%s = __Pyx_%sFunction_FastCall(%s, %s+1-%s, %d+%s); %s" % (
  5330. self.result(),
  5331. call_prefix,
  5332. function,
  5333. Naming.quick_temp_cname,
  5334. arg_offset_cname,
  5335. len(args),
  5336. arg_offset_cname,
  5337. code.error_goto_if_null(self.result(), self.pos)))
  5338. code.put_xdecref_clear(self_arg, py_object_type)
  5339. code.put_gotref(self.py_result())
  5340. for arg in args:
  5341. arg.generate_disposal_code(code)
  5342. code.putln("} else")
  5343. code.putln("#endif")
  5344. code.putln("{")
  5345. args_tuple = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  5346. code.putln("%s = PyTuple_New(%d+%s); %s" % (
  5347. args_tuple, len(args), arg_offset_cname,
  5348. code.error_goto_if_null(args_tuple, self.pos)))
  5349. code.put_gotref(args_tuple)
  5350. if len(args) > 1:
  5351. code.putln("if (%s) {" % self_arg)
  5352. code.putln("__Pyx_GIVEREF(%s); PyTuple_SET_ITEM(%s, 0, %s); %s = NULL;" % (
  5353. self_arg, args_tuple, self_arg, self_arg)) # stealing owned ref in this case
  5354. code.funcstate.release_temp(self_arg)
  5355. if len(args) > 1:
  5356. code.putln("}")
  5357. for i, arg in enumerate(args):
  5358. arg.make_owned_reference(code)
  5359. code.put_giveref(arg.py_result())
  5360. code.putln("PyTuple_SET_ITEM(%s, %d+%s, %s);" % (
  5361. args_tuple, i, arg_offset_cname, arg.py_result()))
  5362. if len(args) > 1:
  5363. code.funcstate.release_temp(arg_offset_cname)
  5364. for arg in args:
  5365. arg.generate_post_assignment_code(code)
  5366. arg.free_temps(code)
  5367. code.globalstate.use_utility_code(
  5368. UtilityCode.load_cached("PyObjectCall", "ObjectHandling.c"))
  5369. code.putln(
  5370. "%s = __Pyx_PyObject_Call(%s, %s, NULL); %s" % (
  5371. self.result(),
  5372. function, args_tuple,
  5373. code.error_goto_if_null(self.result(), self.pos)))
  5374. code.put_gotref(self.py_result())
  5375. code.put_decref_clear(args_tuple, py_object_type)
  5376. code.funcstate.release_temp(args_tuple)
  5377. if len(args) == 1:
  5378. code.putln("}")
  5379. code.putln("}") # !CYTHON_FAST_PYCALL
  5380. if reuse_function_temp:
  5381. self.function.generate_disposal_code(code)
  5382. self.function.free_temps(code)
  5383. else:
  5384. code.put_decref_clear(function, py_object_type)
  5385. code.funcstate.release_temp(function)
  5386. class InlinedDefNodeCallNode(CallNode):
  5387. # Inline call to defnode
  5388. #
  5389. # function PyCFunctionNode
  5390. # function_name NameNode
  5391. # args [ExprNode]
  5392. subexprs = ['args', 'function_name']
  5393. is_temp = 1
  5394. type = py_object_type
  5395. function = None
  5396. function_name = None
  5397. def can_be_inlined(self):
  5398. func_type= self.function.def_node
  5399. if func_type.star_arg or func_type.starstar_arg:
  5400. return False
  5401. if len(func_type.args) != len(self.args):
  5402. return False
  5403. if func_type.num_kwonly_args:
  5404. return False # actually wrong number of arguments
  5405. return True
  5406. def analyse_types(self, env):
  5407. self.function_name = self.function_name.analyse_types(env)
  5408. self.args = [ arg.analyse_types(env) for arg in self.args ]
  5409. func_type = self.function.def_node
  5410. actual_nargs = len(self.args)
  5411. # Coerce arguments
  5412. some_args_in_temps = False
  5413. for i in range(actual_nargs):
  5414. formal_type = func_type.args[i].type
  5415. arg = self.args[i].coerce_to(formal_type, env)
  5416. if arg.is_temp:
  5417. if i > 0:
  5418. # first argument in temp doesn't impact subsequent arguments
  5419. some_args_in_temps = True
  5420. elif arg.type.is_pyobject and not env.nogil:
  5421. if arg.nonlocally_immutable():
  5422. # plain local variables are ok
  5423. pass
  5424. else:
  5425. # we do not safely own the argument's reference,
  5426. # but we must make sure it cannot be collected
  5427. # before we return from the function, so we create
  5428. # an owned temp reference to it
  5429. if i > 0: # first argument doesn't matter
  5430. some_args_in_temps = True
  5431. arg = arg.coerce_to_temp(env)
  5432. self.args[i] = arg
  5433. if some_args_in_temps:
  5434. # if some args are temps and others are not, they may get
  5435. # constructed in the wrong order (temps first) => make
  5436. # sure they are either all temps or all not temps (except
  5437. # for the last argument, which is evaluated last in any
  5438. # case)
  5439. for i in range(actual_nargs-1):
  5440. arg = self.args[i]
  5441. if arg.nonlocally_immutable():
  5442. # locals, C functions, unassignable types are safe.
  5443. pass
  5444. elif arg.type.is_cpp_class:
  5445. # Assignment has side effects, avoid.
  5446. pass
  5447. elif env.nogil and arg.type.is_pyobject:
  5448. # can't copy a Python reference into a temp in nogil
  5449. # env (this is safe: a construction would fail in
  5450. # nogil anyway)
  5451. pass
  5452. else:
  5453. #self.args[i] = arg.coerce_to_temp(env)
  5454. # instead: issue a warning
  5455. if i > 0:
  5456. warning(arg.pos, "Argument evaluation order in C function call is undefined and may not be as expected", 0)
  5457. break
  5458. return self
  5459. def generate_result_code(self, code):
  5460. arg_code = [self.function_name.py_result()]
  5461. func_type = self.function.def_node
  5462. for arg, proto_arg in zip(self.args, func_type.args):
  5463. if arg.type.is_pyobject:
  5464. arg_code.append(arg.result_as(proto_arg.type))
  5465. else:
  5466. arg_code.append(arg.result())
  5467. arg_code = ', '.join(arg_code)
  5468. code.putln(
  5469. "%s = %s(%s); %s" % (
  5470. self.result(),
  5471. self.function.def_node.entry.pyfunc_cname,
  5472. arg_code,
  5473. code.error_goto_if_null(self.result(), self.pos)))
  5474. code.put_gotref(self.py_result())
  5475. class PythonCapiFunctionNode(ExprNode):
  5476. subexprs = []
  5477. def __init__(self, pos, py_name, cname, func_type, utility_code = None):
  5478. ExprNode.__init__(self, pos, name=py_name, cname=cname,
  5479. type=func_type, utility_code=utility_code)
  5480. def analyse_types(self, env):
  5481. return self
  5482. def generate_result_code(self, code):
  5483. if self.utility_code:
  5484. code.globalstate.use_utility_code(self.utility_code)
  5485. def calculate_result_code(self):
  5486. return self.cname
  5487. class PythonCapiCallNode(SimpleCallNode):
  5488. # Python C-API Function call (only created in transforms)
  5489. # By default, we assume that the call never returns None, as this
  5490. # is true for most C-API functions in CPython. If this does not
  5491. # apply to a call, set the following to True (or None to inherit
  5492. # the default behaviour).
  5493. may_return_none = False
  5494. def __init__(self, pos, function_name, func_type,
  5495. utility_code = None, py_name=None, **kwargs):
  5496. self.type = func_type.return_type
  5497. self.result_ctype = self.type
  5498. self.function = PythonCapiFunctionNode(
  5499. pos, py_name, function_name, func_type,
  5500. utility_code = utility_code)
  5501. # call this last so that we can override the constructed
  5502. # attributes above with explicit keyword arguments if required
  5503. SimpleCallNode.__init__(self, pos, **kwargs)
  5504. class CachedBuiltinMethodCallNode(CallNode):
  5505. # Python call to a method of a known Python builtin (only created in transforms)
  5506. subexprs = ['obj', 'args']
  5507. is_temp = True
  5508. def __init__(self, call_node, obj, method_name, args):
  5509. super(CachedBuiltinMethodCallNode, self).__init__(
  5510. call_node.pos,
  5511. obj=obj, method_name=method_name, args=args,
  5512. may_return_none=call_node.may_return_none,
  5513. type=call_node.type)
  5514. def may_be_none(self):
  5515. if self.may_return_none is not None:
  5516. return self.may_return_none
  5517. return ExprNode.may_be_none(self)
  5518. def generate_result_code(self, code):
  5519. type_cname = self.obj.type.cname
  5520. obj_cname = self.obj.py_result()
  5521. args = [arg.py_result() for arg in self.args]
  5522. call_code = code.globalstate.cached_unbound_method_call_code(
  5523. obj_cname, type_cname, self.method_name, args)
  5524. code.putln("%s = %s; %s" % (
  5525. self.result(), call_code,
  5526. code.error_goto_if_null(self.result(), self.pos)
  5527. ))
  5528. code.put_gotref(self.result())
  5529. class GeneralCallNode(CallNode):
  5530. # General Python function call, including keyword,
  5531. # * and ** arguments.
  5532. #
  5533. # function ExprNode
  5534. # positional_args ExprNode Tuple of positional arguments
  5535. # keyword_args ExprNode or None Dict of keyword arguments
  5536. type = py_object_type
  5537. subexprs = ['function', 'positional_args', 'keyword_args']
  5538. nogil_check = Node.gil_error
  5539. def compile_time_value(self, denv):
  5540. function = self.function.compile_time_value(denv)
  5541. positional_args = self.positional_args.compile_time_value(denv)
  5542. keyword_args = self.keyword_args.compile_time_value(denv)
  5543. try:
  5544. return function(*positional_args, **keyword_args)
  5545. except Exception as e:
  5546. self.compile_time_value_error(e)
  5547. def explicit_args_kwds(self):
  5548. if (self.keyword_args and not self.keyword_args.is_dict_literal or
  5549. not self.positional_args.is_sequence_constructor):
  5550. raise CompileError(self.pos,
  5551. 'Compile-time keyword arguments must be explicit.')
  5552. return self.positional_args.args, self.keyword_args
  5553. def analyse_types(self, env):
  5554. if self.analyse_as_type_constructor(env):
  5555. return self
  5556. self.function = self.function.analyse_types(env)
  5557. if not self.function.type.is_pyobject:
  5558. if self.function.type.is_error:
  5559. self.type = error_type
  5560. return self
  5561. if hasattr(self.function, 'entry'):
  5562. node = self.map_to_simple_call_node()
  5563. if node is not None and node is not self:
  5564. return node.analyse_types(env)
  5565. elif self.function.entry.as_variable:
  5566. self.function = self.function.coerce_to_pyobject(env)
  5567. elif node is self:
  5568. error(self.pos,
  5569. "Non-trivial keyword arguments and starred "
  5570. "arguments not allowed in cdef functions.")
  5571. else:
  5572. # error was already reported
  5573. pass
  5574. else:
  5575. self.function = self.function.coerce_to_pyobject(env)
  5576. if self.keyword_args:
  5577. self.keyword_args = self.keyword_args.analyse_types(env)
  5578. self.positional_args = self.positional_args.analyse_types(env)
  5579. self.positional_args = \
  5580. self.positional_args.coerce_to_pyobject(env)
  5581. self.set_py_result_type(self.function)
  5582. self.is_temp = 1
  5583. return self
  5584. def map_to_simple_call_node(self):
  5585. """
  5586. Tries to map keyword arguments to declared positional arguments.
  5587. Returns self to try a Python call, None to report an error
  5588. or a SimpleCallNode if the mapping succeeds.
  5589. """
  5590. if not isinstance(self.positional_args, TupleNode):
  5591. # has starred argument
  5592. return self
  5593. if not self.keyword_args.is_dict_literal:
  5594. # keywords come from arbitrary expression => nothing to do here
  5595. return self
  5596. function = self.function
  5597. entry = getattr(function, 'entry', None)
  5598. if not entry:
  5599. return self
  5600. function_type = entry.type
  5601. if function_type.is_ptr:
  5602. function_type = function_type.base_type
  5603. if not function_type.is_cfunction:
  5604. return self
  5605. pos_args = self.positional_args.args
  5606. kwargs = self.keyword_args
  5607. declared_args = function_type.args
  5608. if entry.is_cmethod:
  5609. declared_args = declared_args[1:] # skip 'self'
  5610. if len(pos_args) > len(declared_args):
  5611. error(self.pos, "function call got too many positional arguments, "
  5612. "expected %d, got %s" % (len(declared_args),
  5613. len(pos_args)))
  5614. return None
  5615. matched_args = set([ arg.name for arg in declared_args[:len(pos_args)]
  5616. if arg.name ])
  5617. unmatched_args = declared_args[len(pos_args):]
  5618. matched_kwargs_count = 0
  5619. args = list(pos_args)
  5620. # check for duplicate keywords
  5621. seen = set(matched_args)
  5622. has_errors = False
  5623. for arg in kwargs.key_value_pairs:
  5624. name = arg.key.value
  5625. if name in seen:
  5626. error(arg.pos, "argument '%s' passed twice" % name)
  5627. has_errors = True
  5628. # continue to report more errors if there are any
  5629. seen.add(name)
  5630. # match keywords that are passed in order
  5631. for decl_arg, arg in zip(unmatched_args, kwargs.key_value_pairs):
  5632. name = arg.key.value
  5633. if decl_arg.name == name:
  5634. matched_args.add(name)
  5635. matched_kwargs_count += 1
  5636. args.append(arg.value)
  5637. else:
  5638. break
  5639. # match keyword arguments that are passed out-of-order, but keep
  5640. # the evaluation of non-simple arguments in order by moving them
  5641. # into temps
  5642. from .UtilNodes import EvalWithTempExprNode, LetRefNode
  5643. temps = []
  5644. if len(kwargs.key_value_pairs) > matched_kwargs_count:
  5645. unmatched_args = declared_args[len(args):]
  5646. keywords = dict([ (arg.key.value, (i+len(pos_args), arg))
  5647. for i, arg in enumerate(kwargs.key_value_pairs) ])
  5648. first_missing_keyword = None
  5649. for decl_arg in unmatched_args:
  5650. name = decl_arg.name
  5651. if name not in keywords:
  5652. # missing keyword argument => either done or error
  5653. if not first_missing_keyword:
  5654. first_missing_keyword = name
  5655. continue
  5656. elif first_missing_keyword:
  5657. if entry.as_variable:
  5658. # we might be able to convert the function to a Python
  5659. # object, which then allows full calling semantics
  5660. # with default values in gaps - currently, we only
  5661. # support optional arguments at the end
  5662. return self
  5663. # wasn't the last keyword => gaps are not supported
  5664. error(self.pos, "C function call is missing "
  5665. "argument '%s'" % first_missing_keyword)
  5666. return None
  5667. pos, arg = keywords[name]
  5668. matched_args.add(name)
  5669. matched_kwargs_count += 1
  5670. if arg.value.is_simple():
  5671. args.append(arg.value)
  5672. else:
  5673. temp = LetRefNode(arg.value)
  5674. assert temp.is_simple()
  5675. args.append(temp)
  5676. temps.append((pos, temp))
  5677. if temps:
  5678. # may have to move preceding non-simple args into temps
  5679. final_args = []
  5680. new_temps = []
  5681. first_temp_arg = temps[0][-1]
  5682. for arg_value in args:
  5683. if arg_value is first_temp_arg:
  5684. break # done
  5685. if arg_value.is_simple():
  5686. final_args.append(arg_value)
  5687. else:
  5688. temp = LetRefNode(arg_value)
  5689. new_temps.append(temp)
  5690. final_args.append(temp)
  5691. if new_temps:
  5692. args = final_args
  5693. temps = new_temps + [ arg for i,arg in sorted(temps) ]
  5694. # check for unexpected keywords
  5695. for arg in kwargs.key_value_pairs:
  5696. name = arg.key.value
  5697. if name not in matched_args:
  5698. has_errors = True
  5699. error(arg.pos,
  5700. "C function got unexpected keyword argument '%s'" %
  5701. name)
  5702. if has_errors:
  5703. # error was reported already
  5704. return None
  5705. # all keywords mapped to positional arguments
  5706. # if we are missing arguments, SimpleCallNode will figure it out
  5707. node = SimpleCallNode(self.pos, function=function, args=args)
  5708. for temp in temps[::-1]:
  5709. node = EvalWithTempExprNode(temp, node)
  5710. return node
  5711. def generate_result_code(self, code):
  5712. if self.type.is_error: return
  5713. if self.keyword_args:
  5714. kwargs = self.keyword_args.py_result()
  5715. else:
  5716. kwargs = 'NULL'
  5717. code.globalstate.use_utility_code(UtilityCode.load_cached(
  5718. "PyObjectCall", "ObjectHandling.c"))
  5719. code.putln(
  5720. "%s = __Pyx_PyObject_Call(%s, %s, %s); %s" % (
  5721. self.result(),
  5722. self.function.py_result(),
  5723. self.positional_args.py_result(),
  5724. kwargs,
  5725. code.error_goto_if_null(self.result(), self.pos)))
  5726. code.put_gotref(self.py_result())
  5727. class AsTupleNode(ExprNode):
  5728. # Convert argument to tuple. Used for normalising
  5729. # the * argument of a function call.
  5730. #
  5731. # arg ExprNode
  5732. subexprs = ['arg']
  5733. is_temp = 1
  5734. def calculate_constant_result(self):
  5735. self.constant_result = tuple(self.arg.constant_result)
  5736. def compile_time_value(self, denv):
  5737. arg = self.arg.compile_time_value(denv)
  5738. try:
  5739. return tuple(arg)
  5740. except Exception as e:
  5741. self.compile_time_value_error(e)
  5742. def analyse_types(self, env):
  5743. self.arg = self.arg.analyse_types(env).coerce_to_pyobject(env)
  5744. if self.arg.type is tuple_type:
  5745. return self.arg.as_none_safe_node("'NoneType' object is not iterable")
  5746. self.type = tuple_type
  5747. return self
  5748. def may_be_none(self):
  5749. return False
  5750. nogil_check = Node.gil_error
  5751. gil_message = "Constructing Python tuple"
  5752. def generate_result_code(self, code):
  5753. cfunc = "__Pyx_PySequence_Tuple" if self.arg.type in (py_object_type, tuple_type) else "PySequence_Tuple"
  5754. code.putln(
  5755. "%s = %s(%s); %s" % (
  5756. self.result(),
  5757. cfunc, self.arg.py_result(),
  5758. code.error_goto_if_null(self.result(), self.pos)))
  5759. code.put_gotref(self.py_result())
  5760. class MergedDictNode(ExprNode):
  5761. # Helper class for keyword arguments and other merged dicts.
  5762. #
  5763. # keyword_args [DictNode or other ExprNode]
  5764. subexprs = ['keyword_args']
  5765. is_temp = 1
  5766. type = dict_type
  5767. reject_duplicates = True
  5768. def calculate_constant_result(self):
  5769. result = {}
  5770. reject_duplicates = self.reject_duplicates
  5771. for item in self.keyword_args:
  5772. if item.is_dict_literal:
  5773. # process items in order
  5774. items = ((key.constant_result, value.constant_result)
  5775. for key, value in item.key_value_pairs)
  5776. else:
  5777. items = item.constant_result.iteritems()
  5778. for key, value in items:
  5779. if reject_duplicates and key in result:
  5780. raise ValueError("duplicate keyword argument found: %s" % key)
  5781. result[key] = value
  5782. self.constant_result = result
  5783. def compile_time_value(self, denv):
  5784. result = {}
  5785. reject_duplicates = self.reject_duplicates
  5786. for item in self.keyword_args:
  5787. if item.is_dict_literal:
  5788. # process items in order
  5789. items = [(key.compile_time_value(denv), value.compile_time_value(denv))
  5790. for key, value in item.key_value_pairs]
  5791. else:
  5792. items = item.compile_time_value(denv).iteritems()
  5793. try:
  5794. for key, value in items:
  5795. if reject_duplicates and key in result:
  5796. raise ValueError("duplicate keyword argument found: %s" % key)
  5797. result[key] = value
  5798. except Exception as e:
  5799. self.compile_time_value_error(e)
  5800. return result
  5801. def type_dependencies(self, env):
  5802. return ()
  5803. def infer_type(self, env):
  5804. return dict_type
  5805. def analyse_types(self, env):
  5806. self.keyword_args = [
  5807. arg.analyse_types(env).coerce_to_pyobject(env).as_none_safe_node(
  5808. # FIXME: CPython's error message starts with the runtime function name
  5809. 'argument after ** must be a mapping, not NoneType')
  5810. for arg in self.keyword_args
  5811. ]
  5812. return self
  5813. def may_be_none(self):
  5814. return False
  5815. gil_message = "Constructing Python dict"
  5816. def generate_evaluation_code(self, code):
  5817. code.mark_pos(self.pos)
  5818. self.allocate_temp_result(code)
  5819. args = iter(self.keyword_args)
  5820. item = next(args)
  5821. item.generate_evaluation_code(code)
  5822. if item.type is not dict_type:
  5823. # CPython supports calling functions with non-dicts, so do we
  5824. code.putln('if (likely(PyDict_CheckExact(%s))) {' %
  5825. item.py_result())
  5826. if item.is_dict_literal:
  5827. item.make_owned_reference(code)
  5828. code.putln("%s = %s;" % (self.result(), item.py_result()))
  5829. item.generate_post_assignment_code(code)
  5830. else:
  5831. code.putln("%s = PyDict_Copy(%s); %s" % (
  5832. self.result(),
  5833. item.py_result(),
  5834. code.error_goto_if_null(self.result(), item.pos)))
  5835. code.put_gotref(self.result())
  5836. item.generate_disposal_code(code)
  5837. if item.type is not dict_type:
  5838. code.putln('} else {')
  5839. code.putln("%s = PyObject_CallFunctionObjArgs((PyObject*)&PyDict_Type, %s, NULL); %s" % (
  5840. self.result(),
  5841. item.py_result(),
  5842. code.error_goto_if_null(self.result(), self.pos)))
  5843. code.put_gotref(self.py_result())
  5844. item.generate_disposal_code(code)
  5845. code.putln('}')
  5846. item.free_temps(code)
  5847. helpers = set()
  5848. for item in args:
  5849. if item.is_dict_literal:
  5850. # inline update instead of creating an intermediate dict
  5851. for arg in item.key_value_pairs:
  5852. arg.generate_evaluation_code(code)
  5853. if self.reject_duplicates:
  5854. code.putln("if (unlikely(PyDict_Contains(%s, %s))) {" % (
  5855. self.result(),
  5856. arg.key.py_result()))
  5857. helpers.add("RaiseDoubleKeywords")
  5858. # FIXME: find out function name at runtime!
  5859. code.putln('__Pyx_RaiseDoubleKeywordsError("function", %s); %s' % (
  5860. arg.key.py_result(),
  5861. code.error_goto(self.pos)))
  5862. code.putln("}")
  5863. code.put_error_if_neg(arg.key.pos, "PyDict_SetItem(%s, %s, %s)" % (
  5864. self.result(),
  5865. arg.key.py_result(),
  5866. arg.value.py_result()))
  5867. arg.generate_disposal_code(code)
  5868. arg.free_temps(code)
  5869. else:
  5870. item.generate_evaluation_code(code)
  5871. if self.reject_duplicates:
  5872. # merge mapping into kwdict one by one as we need to check for duplicates
  5873. helpers.add("MergeKeywords")
  5874. code.put_error_if_neg(item.pos, "__Pyx_MergeKeywords(%s, %s)" % (
  5875. self.result(), item.py_result()))
  5876. else:
  5877. # simple case, just add all entries
  5878. helpers.add("RaiseMappingExpected")
  5879. code.putln("if (unlikely(PyDict_Update(%s, %s) < 0)) {" % (
  5880. self.result(), item.py_result()))
  5881. code.putln("if (PyErr_ExceptionMatches(PyExc_AttributeError)) "
  5882. "__Pyx_RaiseMappingExpectedError(%s);" % item.py_result())
  5883. code.putln(code.error_goto(item.pos))
  5884. code.putln("}")
  5885. item.generate_disposal_code(code)
  5886. item.free_temps(code)
  5887. for helper in sorted(helpers):
  5888. code.globalstate.use_utility_code(UtilityCode.load_cached(helper, "FunctionArguments.c"))
  5889. def annotate(self, code):
  5890. for item in self.keyword_args:
  5891. item.annotate(code)
  5892. class AttributeNode(ExprNode):
  5893. # obj.attribute
  5894. #
  5895. # obj ExprNode
  5896. # attribute string
  5897. # needs_none_check boolean Used if obj is an extension type.
  5898. # If set to True, it is known that the type is not None.
  5899. #
  5900. # Used internally:
  5901. #
  5902. # is_py_attr boolean Is a Python getattr operation
  5903. # member string C name of struct member
  5904. # is_called boolean Function call is being done on result
  5905. # entry Entry Symbol table entry of attribute
  5906. is_attribute = 1
  5907. subexprs = ['obj']
  5908. type = PyrexTypes.error_type
  5909. entry = None
  5910. is_called = 0
  5911. needs_none_check = True
  5912. is_memslice_transpose = False
  5913. is_special_lookup = False
  5914. is_py_attr = 0
  5915. def as_cython_attribute(self):
  5916. if (isinstance(self.obj, NameNode) and
  5917. self.obj.is_cython_module and not
  5918. self.attribute == u"parallel"):
  5919. return self.attribute
  5920. cy = self.obj.as_cython_attribute()
  5921. if cy:
  5922. return "%s.%s" % (cy, self.attribute)
  5923. return None
  5924. def coerce_to(self, dst_type, env):
  5925. # If coercing to a generic pyobject and this is a cpdef function
  5926. # we can create the corresponding attribute
  5927. if dst_type is py_object_type:
  5928. entry = self.entry
  5929. if entry and entry.is_cfunction and entry.as_variable:
  5930. # must be a cpdef function
  5931. self.is_temp = 1
  5932. self.entry = entry.as_variable
  5933. self.analyse_as_python_attribute(env)
  5934. return self
  5935. return ExprNode.coerce_to(self, dst_type, env)
  5936. def calculate_constant_result(self):
  5937. attr = self.attribute
  5938. if attr.startswith("__") and attr.endswith("__"):
  5939. return
  5940. self.constant_result = getattr(self.obj.constant_result, attr)
  5941. def compile_time_value(self, denv):
  5942. attr = self.attribute
  5943. if attr.startswith("__") and attr.endswith("__"):
  5944. error(self.pos,
  5945. "Invalid attribute name '%s' in compile-time expression" % attr)
  5946. return None
  5947. obj = self.obj.compile_time_value(denv)
  5948. try:
  5949. return getattr(obj, attr)
  5950. except Exception as e:
  5951. self.compile_time_value_error(e)
  5952. def type_dependencies(self, env):
  5953. return self.obj.type_dependencies(env)
  5954. def infer_type(self, env):
  5955. # FIXME: this is way too redundant with analyse_types()
  5956. node = self.analyse_as_cimported_attribute_node(env, target=False)
  5957. if node is not None:
  5958. if node.entry.type and node.entry.type.is_cfunction:
  5959. # special-case - function converted to pointer
  5960. return PyrexTypes.CPtrType(node.entry.type)
  5961. else:
  5962. return node.entry.type
  5963. node = self.analyse_as_type_attribute(env)
  5964. if node is not None:
  5965. return node.entry.type
  5966. obj_type = self.obj.infer_type(env)
  5967. self.analyse_attribute(env, obj_type=obj_type)
  5968. if obj_type.is_builtin_type and self.type.is_cfunction:
  5969. # special case: C-API replacements for C methods of
  5970. # builtin types cannot be inferred as C functions as
  5971. # that would prevent their use as bound methods
  5972. return py_object_type
  5973. elif self.entry and self.entry.is_cmethod:
  5974. # special case: bound methods should not be inferred
  5975. # as their unbound method types
  5976. return py_object_type
  5977. return self.type
  5978. def analyse_target_declaration(self, env):
  5979. pass
  5980. def analyse_target_types(self, env):
  5981. node = self.analyse_types(env, target = 1)
  5982. if node.type.is_const:
  5983. error(self.pos, "Assignment to const attribute '%s'" % self.attribute)
  5984. if not node.is_lvalue():
  5985. error(self.pos, "Assignment to non-lvalue of type '%s'" % self.type)
  5986. return node
  5987. def analyse_types(self, env, target = 0):
  5988. self.initialized_check = env.directives['initializedcheck']
  5989. node = self.analyse_as_cimported_attribute_node(env, target)
  5990. if node is None and not target:
  5991. node = self.analyse_as_type_attribute(env)
  5992. if node is None:
  5993. node = self.analyse_as_ordinary_attribute_node(env, target)
  5994. assert node is not None
  5995. if node.entry:
  5996. node.entry.used = True
  5997. if node.is_attribute:
  5998. node.wrap_obj_in_nonecheck(env)
  5999. return node
  6000. def analyse_as_cimported_attribute_node(self, env, target):
  6001. # Try to interpret this as a reference to an imported
  6002. # C const, type, var or function. If successful, mutates
  6003. # this node into a NameNode and returns 1, otherwise
  6004. # returns 0.
  6005. module_scope = self.obj.analyse_as_module(env)
  6006. if module_scope:
  6007. entry = module_scope.lookup_here(self.attribute)
  6008. if entry and (
  6009. entry.is_cglobal or entry.is_cfunction
  6010. or entry.is_type or entry.is_const):
  6011. return self.as_name_node(env, entry, target)
  6012. if self.is_cimported_module_without_shadow(env):
  6013. error(self.pos, "cimported module has no attribute '%s'" % self.attribute)
  6014. return self
  6015. return None
  6016. def analyse_as_type_attribute(self, env):
  6017. # Try to interpret this as a reference to an unbound
  6018. # C method of an extension type or builtin type. If successful,
  6019. # creates a corresponding NameNode and returns it, otherwise
  6020. # returns None.
  6021. if self.obj.is_string_literal:
  6022. return
  6023. type = self.obj.analyse_as_type(env)
  6024. if type:
  6025. if type.is_extension_type or type.is_builtin_type or type.is_cpp_class:
  6026. entry = type.scope.lookup_here(self.attribute)
  6027. if entry and (entry.is_cmethod or type.is_cpp_class and entry.type.is_cfunction):
  6028. if type.is_builtin_type:
  6029. if not self.is_called:
  6030. # must handle this as Python object
  6031. return None
  6032. ubcm_entry = entry
  6033. else:
  6034. # Create a temporary entry describing the C method
  6035. # as an ordinary function.
  6036. if entry.func_cname and not hasattr(entry.type, 'op_arg_struct'):
  6037. cname = entry.func_cname
  6038. if entry.type.is_static_method or (
  6039. env.parent_scope and env.parent_scope.is_cpp_class_scope):
  6040. ctype = entry.type
  6041. elif type.is_cpp_class:
  6042. error(self.pos, "%s not a static member of %s" % (entry.name, type))
  6043. ctype = PyrexTypes.error_type
  6044. else:
  6045. # Fix self type.
  6046. ctype = copy.copy(entry.type)
  6047. ctype.args = ctype.args[:]
  6048. ctype.args[0] = PyrexTypes.CFuncTypeArg('self', type, 'self', None)
  6049. else:
  6050. cname = "%s->%s" % (type.vtabptr_cname, entry.cname)
  6051. ctype = entry.type
  6052. ubcm_entry = Symtab.Entry(entry.name, cname, ctype)
  6053. ubcm_entry.is_cfunction = 1
  6054. ubcm_entry.func_cname = entry.func_cname
  6055. ubcm_entry.is_unbound_cmethod = 1
  6056. ubcm_entry.scope = entry.scope
  6057. return self.as_name_node(env, ubcm_entry, target=False)
  6058. elif type.is_enum:
  6059. if self.attribute in type.values:
  6060. for entry in type.entry.enum_values:
  6061. if entry.name == self.attribute:
  6062. return self.as_name_node(env, entry, target=False)
  6063. else:
  6064. error(self.pos, "%s not a known value of %s" % (self.attribute, type))
  6065. else:
  6066. error(self.pos, "%s not a known value of %s" % (self.attribute, type))
  6067. return None
  6068. def analyse_as_type(self, env):
  6069. module_scope = self.obj.analyse_as_module(env)
  6070. if module_scope:
  6071. return module_scope.lookup_type(self.attribute)
  6072. if not self.obj.is_string_literal:
  6073. base_type = self.obj.analyse_as_type(env)
  6074. if base_type and hasattr(base_type, 'scope') and base_type.scope is not None:
  6075. return base_type.scope.lookup_type(self.attribute)
  6076. return None
  6077. def analyse_as_extension_type(self, env):
  6078. # Try to interpret this as a reference to an extension type
  6079. # in a cimported module. Returns the extension type, or None.
  6080. module_scope = self.obj.analyse_as_module(env)
  6081. if module_scope:
  6082. entry = module_scope.lookup_here(self.attribute)
  6083. if entry and entry.is_type:
  6084. if entry.type.is_extension_type or entry.type.is_builtin_type:
  6085. return entry.type
  6086. return None
  6087. def analyse_as_module(self, env):
  6088. # Try to interpret this as a reference to a cimported module
  6089. # in another cimported module. Returns the module scope, or None.
  6090. module_scope = self.obj.analyse_as_module(env)
  6091. if module_scope:
  6092. entry = module_scope.lookup_here(self.attribute)
  6093. if entry and entry.as_module:
  6094. return entry.as_module
  6095. return None
  6096. def as_name_node(self, env, entry, target):
  6097. # Create a corresponding NameNode from this node and complete the
  6098. # analyse_types phase.
  6099. node = NameNode.from_node(self, name=self.attribute, entry=entry)
  6100. if target:
  6101. node = node.analyse_target_types(env)
  6102. else:
  6103. node = node.analyse_rvalue_entry(env)
  6104. node.entry.used = 1
  6105. return node
  6106. def analyse_as_ordinary_attribute_node(self, env, target):
  6107. self.obj = self.obj.analyse_types(env)
  6108. self.analyse_attribute(env)
  6109. if self.entry and self.entry.is_cmethod and not self.is_called:
  6110. # error(self.pos, "C method can only be called")
  6111. pass
  6112. ## Reference to C array turns into pointer to first element.
  6113. #while self.type.is_array:
  6114. # self.type = self.type.element_ptr_type()
  6115. if self.is_py_attr:
  6116. if not target:
  6117. self.is_temp = 1
  6118. self.result_ctype = py_object_type
  6119. elif target and self.obj.type.is_builtin_type:
  6120. error(self.pos, "Assignment to an immutable object field")
  6121. #elif self.type.is_memoryviewslice and not target:
  6122. # self.is_temp = True
  6123. return self
  6124. def analyse_attribute(self, env, obj_type = None):
  6125. # Look up attribute and set self.type and self.member.
  6126. immutable_obj = obj_type is not None # used during type inference
  6127. self.is_py_attr = 0
  6128. self.member = self.attribute
  6129. if obj_type is None:
  6130. if self.obj.type.is_string or self.obj.type.is_pyunicode_ptr:
  6131. self.obj = self.obj.coerce_to_pyobject(env)
  6132. obj_type = self.obj.type
  6133. else:
  6134. if obj_type.is_string or obj_type.is_pyunicode_ptr:
  6135. obj_type = py_object_type
  6136. if obj_type.is_ptr or obj_type.is_array:
  6137. obj_type = obj_type.base_type
  6138. self.op = "->"
  6139. elif obj_type.is_extension_type or obj_type.is_builtin_type:
  6140. self.op = "->"
  6141. elif obj_type.is_reference and obj_type.is_fake_reference:
  6142. self.op = "->"
  6143. else:
  6144. self.op = "."
  6145. if obj_type.has_attributes:
  6146. if obj_type.attributes_known():
  6147. entry = obj_type.scope.lookup_here(self.attribute)
  6148. if obj_type.is_memoryviewslice and not entry:
  6149. if self.attribute == 'T':
  6150. self.is_memslice_transpose = True
  6151. self.is_temp = True
  6152. self.use_managed_ref = True
  6153. self.type = self.obj.type.transpose(self.pos)
  6154. return
  6155. else:
  6156. obj_type.declare_attribute(self.attribute, env, self.pos)
  6157. entry = obj_type.scope.lookup_here(self.attribute)
  6158. if entry and entry.is_member:
  6159. entry = None
  6160. else:
  6161. error(self.pos,
  6162. "Cannot select attribute of incomplete type '%s'"
  6163. % obj_type)
  6164. self.type = PyrexTypes.error_type
  6165. return
  6166. self.entry = entry
  6167. if entry:
  6168. if obj_type.is_extension_type and entry.name == "__weakref__":
  6169. error(self.pos, "Illegal use of special attribute __weakref__")
  6170. # def methods need the normal attribute lookup
  6171. # because they do not have struct entries
  6172. # fused function go through assignment synthesis
  6173. # (foo = pycfunction(foo_func_obj)) and need to go through
  6174. # regular Python lookup as well
  6175. if (entry.is_variable and not entry.fused_cfunction) or entry.is_cmethod:
  6176. self.type = entry.type
  6177. self.member = entry.cname
  6178. return
  6179. else:
  6180. # If it's not a variable or C method, it must be a Python
  6181. # method of an extension type, so we treat it like a Python
  6182. # attribute.
  6183. pass
  6184. # If we get here, the base object is not a struct/union/extension
  6185. # type, or it is an extension type and the attribute is either not
  6186. # declared or is declared as a Python method. Treat it as a Python
  6187. # attribute reference.
  6188. self.analyse_as_python_attribute(env, obj_type, immutable_obj)
  6189. def analyse_as_python_attribute(self, env, obj_type=None, immutable_obj=False):
  6190. if obj_type is None:
  6191. obj_type = self.obj.type
  6192. # mangle private '__*' Python attributes used inside of a class
  6193. self.attribute = env.mangle_class_private_name(self.attribute)
  6194. self.member = self.attribute
  6195. self.type = py_object_type
  6196. self.is_py_attr = 1
  6197. if not obj_type.is_pyobject and not obj_type.is_error:
  6198. # Expose python methods for immutable objects.
  6199. if (obj_type.is_string or obj_type.is_cpp_string
  6200. or obj_type.is_buffer or obj_type.is_memoryviewslice
  6201. or obj_type.is_numeric
  6202. or (obj_type.is_ctuple and obj_type.can_coerce_to_pyobject(env))
  6203. or (obj_type.is_struct and obj_type.can_coerce_to_pyobject(env))):
  6204. if not immutable_obj:
  6205. self.obj = self.obj.coerce_to_pyobject(env)
  6206. elif (obj_type.is_cfunction and (self.obj.is_name or self.obj.is_attribute)
  6207. and self.obj.entry.as_variable
  6208. and self.obj.entry.as_variable.type.is_pyobject):
  6209. # might be an optimised builtin function => unpack it
  6210. if not immutable_obj:
  6211. self.obj = self.obj.coerce_to_pyobject(env)
  6212. else:
  6213. error(self.pos,
  6214. "Object of type '%s' has no attribute '%s'" %
  6215. (obj_type, self.attribute))
  6216. def wrap_obj_in_nonecheck(self, env):
  6217. if not env.directives['nonecheck']:
  6218. return
  6219. msg = None
  6220. format_args = ()
  6221. if (self.obj.type.is_extension_type and self.needs_none_check and not
  6222. self.is_py_attr):
  6223. msg = "'NoneType' object has no attribute '%{0}s'".format('.30' if len(self.attribute) <= 30 else '')
  6224. format_args = (self.attribute,)
  6225. elif self.obj.type.is_memoryviewslice:
  6226. if self.is_memslice_transpose:
  6227. msg = "Cannot transpose None memoryview slice"
  6228. else:
  6229. entry = self.obj.type.scope.lookup_here(self.attribute)
  6230. if entry:
  6231. # copy/is_c_contig/shape/strides etc
  6232. msg = "Cannot access '%s' attribute of None memoryview slice"
  6233. format_args = (entry.name,)
  6234. if msg:
  6235. self.obj = self.obj.as_none_safe_node(msg, 'PyExc_AttributeError',
  6236. format_args=format_args)
  6237. def nogil_check(self, env):
  6238. if self.is_py_attr:
  6239. self.gil_error()
  6240. gil_message = "Accessing Python attribute"
  6241. def is_cimported_module_without_shadow(self, env):
  6242. return self.obj.is_cimported_module_without_shadow(env)
  6243. def is_simple(self):
  6244. if self.obj:
  6245. return self.result_in_temp() or self.obj.is_simple()
  6246. else:
  6247. return NameNode.is_simple(self)
  6248. def is_lvalue(self):
  6249. if self.obj:
  6250. return True
  6251. else:
  6252. return NameNode.is_lvalue(self)
  6253. def is_ephemeral(self):
  6254. if self.obj:
  6255. return self.obj.is_ephemeral()
  6256. else:
  6257. return NameNode.is_ephemeral(self)
  6258. def calculate_result_code(self):
  6259. #print "AttributeNode.calculate_result_code:", self.member ###
  6260. #print "...obj node =", self.obj, "code", self.obj.result() ###
  6261. #print "...obj type", self.obj.type, "ctype", self.obj.ctype() ###
  6262. obj = self.obj
  6263. obj_code = obj.result_as(obj.type)
  6264. #print "...obj_code =", obj_code ###
  6265. if self.entry and self.entry.is_cmethod:
  6266. if obj.type.is_extension_type and not self.entry.is_builtin_cmethod:
  6267. if self.entry.final_func_cname:
  6268. return self.entry.final_func_cname
  6269. if self.type.from_fused:
  6270. # If the attribute was specialized through indexing, make
  6271. # sure to get the right fused name, as our entry was
  6272. # replaced by our parent index node
  6273. # (AnalyseExpressionsTransform)
  6274. self.member = self.entry.cname
  6275. return "((struct %s *)%s%s%s)->%s" % (
  6276. obj.type.vtabstruct_cname, obj_code, self.op,
  6277. obj.type.vtabslot_cname, self.member)
  6278. elif self.result_is_used:
  6279. return self.member
  6280. # Generating no code at all for unused access to optimised builtin
  6281. # methods fixes the problem that some optimisations only exist as
  6282. # macros, i.e. there is no function pointer to them, so we would
  6283. # generate invalid C code here.
  6284. return
  6285. elif obj.type.is_complex:
  6286. return "__Pyx_C%s(%s)" % (self.member.upper(), obj_code)
  6287. else:
  6288. if obj.type.is_builtin_type and self.entry and self.entry.is_variable:
  6289. # accessing a field of a builtin type, need to cast better than result_as() does
  6290. obj_code = obj.type.cast_code(obj.result(), to_object_struct = True)
  6291. return "%s%s%s" % (obj_code, self.op, self.member)
  6292. def generate_result_code(self, code):
  6293. if self.is_py_attr:
  6294. if self.is_special_lookup:
  6295. code.globalstate.use_utility_code(
  6296. UtilityCode.load_cached("PyObjectLookupSpecial", "ObjectHandling.c"))
  6297. lookup_func_name = '__Pyx_PyObject_LookupSpecial'
  6298. else:
  6299. code.globalstate.use_utility_code(
  6300. UtilityCode.load_cached("PyObjectGetAttrStr", "ObjectHandling.c"))
  6301. lookup_func_name = '__Pyx_PyObject_GetAttrStr'
  6302. code.putln(
  6303. '%s = %s(%s, %s); %s' % (
  6304. self.result(),
  6305. lookup_func_name,
  6306. self.obj.py_result(),
  6307. code.intern_identifier(self.attribute),
  6308. code.error_goto_if_null(self.result(), self.pos)))
  6309. code.put_gotref(self.py_result())
  6310. elif self.type.is_memoryviewslice:
  6311. if self.is_memslice_transpose:
  6312. # transpose the slice
  6313. for access, packing in self.type.axes:
  6314. if access == 'ptr':
  6315. error(self.pos, "Transposing not supported for slices "
  6316. "with indirect dimensions")
  6317. return
  6318. code.putln("%s = %s;" % (self.result(), self.obj.result()))
  6319. code.put_incref_memoryviewslice(self.result(), have_gil=True)
  6320. T = "__pyx_memslice_transpose(&%s) == 0"
  6321. code.putln(code.error_goto_if(T % self.result(), self.pos))
  6322. elif self.initialized_check:
  6323. code.putln(
  6324. 'if (unlikely(!%s.memview)) {'
  6325. 'PyErr_SetString(PyExc_AttributeError,'
  6326. '"Memoryview is not initialized");'
  6327. '%s'
  6328. '}' % (self.result(), code.error_goto(self.pos)))
  6329. else:
  6330. # result_code contains what is needed, but we may need to insert
  6331. # a check and raise an exception
  6332. if self.obj.type and self.obj.type.is_extension_type:
  6333. pass
  6334. elif self.entry and self.entry.is_cmethod:
  6335. # C method implemented as function call with utility code
  6336. code.globalstate.use_entry_utility_code(self.entry)
  6337. def generate_disposal_code(self, code):
  6338. if self.is_temp and self.type.is_memoryviewslice and self.is_memslice_transpose:
  6339. # mirror condition for putting the memview incref here:
  6340. code.put_xdecref_memoryviewslice(
  6341. self.result(), have_gil=True)
  6342. code.putln("%s.memview = NULL;" % self.result())
  6343. code.putln("%s.data = NULL;" % self.result())
  6344. else:
  6345. ExprNode.generate_disposal_code(self, code)
  6346. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  6347. exception_check=None, exception_value=None):
  6348. self.obj.generate_evaluation_code(code)
  6349. if self.is_py_attr:
  6350. code.globalstate.use_utility_code(
  6351. UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
  6352. code.put_error_if_neg(self.pos,
  6353. '__Pyx_PyObject_SetAttrStr(%s, %s, %s)' % (
  6354. self.obj.py_result(),
  6355. code.intern_identifier(self.attribute),
  6356. rhs.py_result()))
  6357. rhs.generate_disposal_code(code)
  6358. rhs.free_temps(code)
  6359. elif self.obj.type.is_complex:
  6360. code.putln("__Pyx_SET_C%s(%s, %s);" % (
  6361. self.member.upper(),
  6362. self.obj.result_as(self.obj.type),
  6363. rhs.result_as(self.ctype())))
  6364. rhs.generate_disposal_code(code)
  6365. rhs.free_temps(code)
  6366. else:
  6367. select_code = self.result()
  6368. if self.type.is_pyobject and self.use_managed_ref:
  6369. rhs.make_owned_reference(code)
  6370. code.put_giveref(rhs.py_result())
  6371. code.put_gotref(select_code)
  6372. code.put_decref(select_code, self.ctype())
  6373. elif self.type.is_memoryviewslice:
  6374. from . import MemoryView
  6375. MemoryView.put_assign_to_memviewslice(
  6376. select_code, rhs, rhs.result(), self.type, code)
  6377. if not self.type.is_memoryviewslice:
  6378. code.putln(
  6379. "%s = %s;" % (
  6380. select_code,
  6381. rhs.result_as(self.ctype())))
  6382. #rhs.result()))
  6383. rhs.generate_post_assignment_code(code)
  6384. rhs.free_temps(code)
  6385. self.obj.generate_disposal_code(code)
  6386. self.obj.free_temps(code)
  6387. def generate_deletion_code(self, code, ignore_nonexisting=False):
  6388. self.obj.generate_evaluation_code(code)
  6389. if self.is_py_attr or (self.entry.scope.is_property_scope
  6390. and u'__del__' in self.entry.scope.entries):
  6391. code.globalstate.use_utility_code(
  6392. UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c"))
  6393. code.put_error_if_neg(self.pos,
  6394. '__Pyx_PyObject_DelAttrStr(%s, %s)' % (
  6395. self.obj.py_result(),
  6396. code.intern_identifier(self.attribute)))
  6397. else:
  6398. error(self.pos, "Cannot delete C attribute of extension type")
  6399. self.obj.generate_disposal_code(code)
  6400. self.obj.free_temps(code)
  6401. def annotate(self, code):
  6402. if self.is_py_attr:
  6403. style, text = 'py_attr', 'python attribute (%s)'
  6404. else:
  6405. style, text = 'c_attr', 'c attribute (%s)'
  6406. code.annotate(self.pos, AnnotationItem(style, text % self.type, size=len(self.attribute)))
  6407. #-------------------------------------------------------------------
  6408. #
  6409. # Constructor nodes
  6410. #
  6411. #-------------------------------------------------------------------
  6412. class StarredUnpackingNode(ExprNode):
  6413. # A starred expression like "*a"
  6414. #
  6415. # This is only allowed in sequence assignment or construction such as
  6416. #
  6417. # a, *b = (1,2,3,4) => a = 1 ; b = [2,3,4]
  6418. #
  6419. # and will be special cased during type analysis (or generate an error
  6420. # if it's found at unexpected places).
  6421. #
  6422. # target ExprNode
  6423. subexprs = ['target']
  6424. is_starred = 1
  6425. type = py_object_type
  6426. is_temp = 1
  6427. starred_expr_allowed_here = False
  6428. def __init__(self, pos, target):
  6429. ExprNode.__init__(self, pos, target=target)
  6430. def analyse_declarations(self, env):
  6431. if not self.starred_expr_allowed_here:
  6432. error(self.pos, "starred expression is not allowed here")
  6433. self.target.analyse_declarations(env)
  6434. def infer_type(self, env):
  6435. return self.target.infer_type(env)
  6436. def analyse_types(self, env):
  6437. if not self.starred_expr_allowed_here:
  6438. error(self.pos, "starred expression is not allowed here")
  6439. self.target = self.target.analyse_types(env)
  6440. self.type = self.target.type
  6441. return self
  6442. def analyse_target_declaration(self, env):
  6443. self.target.analyse_target_declaration(env)
  6444. def analyse_target_types(self, env):
  6445. self.target = self.target.analyse_target_types(env)
  6446. self.type = self.target.type
  6447. return self
  6448. def calculate_result_code(self):
  6449. return ""
  6450. def generate_result_code(self, code):
  6451. pass
  6452. class SequenceNode(ExprNode):
  6453. # Base class for list and tuple constructor nodes.
  6454. # Contains common code for performing sequence unpacking.
  6455. #
  6456. # args [ExprNode]
  6457. # unpacked_items [ExprNode] or None
  6458. # coerced_unpacked_items [ExprNode] or None
  6459. # mult_factor ExprNode the integer number of content repetitions ([1,2]*3)
  6460. subexprs = ['args', 'mult_factor']
  6461. is_sequence_constructor = 1
  6462. unpacked_items = None
  6463. mult_factor = None
  6464. slow = False # trade speed for code size (e.g. use PyTuple_Pack())
  6465. def compile_time_value_list(self, denv):
  6466. return [arg.compile_time_value(denv) for arg in self.args]
  6467. def replace_starred_target_node(self):
  6468. # replace a starred node in the targets by the contained expression
  6469. self.starred_assignment = False
  6470. args = []
  6471. for arg in self.args:
  6472. if arg.is_starred:
  6473. if self.starred_assignment:
  6474. error(arg.pos, "more than 1 starred expression in assignment")
  6475. self.starred_assignment = True
  6476. arg = arg.target
  6477. arg.is_starred = True
  6478. args.append(arg)
  6479. self.args = args
  6480. def analyse_target_declaration(self, env):
  6481. self.replace_starred_target_node()
  6482. for arg in self.args:
  6483. arg.analyse_target_declaration(env)
  6484. def analyse_types(self, env, skip_children=False):
  6485. for i, arg in enumerate(self.args):
  6486. if not skip_children:
  6487. arg = arg.analyse_types(env)
  6488. self.args[i] = arg.coerce_to_pyobject(env)
  6489. if self.mult_factor:
  6490. self.mult_factor = self.mult_factor.analyse_types(env)
  6491. if not self.mult_factor.type.is_int:
  6492. self.mult_factor = self.mult_factor.coerce_to_pyobject(env)
  6493. self.is_temp = 1
  6494. # not setting self.type here, subtypes do this
  6495. return self
  6496. def coerce_to_ctuple(self, dst_type, env):
  6497. if self.type == dst_type:
  6498. return self
  6499. assert not self.mult_factor
  6500. if len(self.args) != dst_type.size:
  6501. error(self.pos, "trying to coerce sequence to ctuple of wrong length, expected %d, got %d" % (
  6502. dst_type.size, len(self.args)))
  6503. coerced_args = [arg.coerce_to(type, env) for arg, type in zip(self.args, dst_type.components)]
  6504. return TupleNode(self.pos, args=coerced_args, type=dst_type, is_temp=True)
  6505. def _create_merge_node_if_necessary(self, env):
  6506. self._flatten_starred_args()
  6507. if not any(arg.is_starred for arg in self.args):
  6508. return self
  6509. # convert into MergedSequenceNode by building partial sequences
  6510. args = []
  6511. values = []
  6512. for arg in self.args:
  6513. if arg.is_starred:
  6514. if values:
  6515. args.append(TupleNode(values[0].pos, args=values).analyse_types(env, skip_children=True))
  6516. values = []
  6517. args.append(arg.target)
  6518. else:
  6519. values.append(arg)
  6520. if values:
  6521. args.append(TupleNode(values[0].pos, args=values).analyse_types(env, skip_children=True))
  6522. node = MergedSequenceNode(self.pos, args, self.type)
  6523. if self.mult_factor:
  6524. node = binop_node(
  6525. self.pos, '*', node, self.mult_factor.coerce_to_pyobject(env),
  6526. inplace=True, type=self.type, is_temp=True)
  6527. return node
  6528. def _flatten_starred_args(self):
  6529. args = []
  6530. for arg in self.args:
  6531. if arg.is_starred and arg.target.is_sequence_constructor and not arg.target.mult_factor:
  6532. args.extend(arg.target.args)
  6533. else:
  6534. args.append(arg)
  6535. self.args[:] = args
  6536. def may_be_none(self):
  6537. return False
  6538. def analyse_target_types(self, env):
  6539. if self.mult_factor:
  6540. error(self.pos, "can't assign to multiplied sequence")
  6541. self.unpacked_items = []
  6542. self.coerced_unpacked_items = []
  6543. self.any_coerced_items = False
  6544. for i, arg in enumerate(self.args):
  6545. arg = self.args[i] = arg.analyse_target_types(env)
  6546. if arg.is_starred:
  6547. if not arg.type.assignable_from(list_type):
  6548. error(arg.pos,
  6549. "starred target must have Python object (list) type")
  6550. if arg.type is py_object_type:
  6551. arg.type = list_type
  6552. unpacked_item = PyTempNode(self.pos, env)
  6553. coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
  6554. if unpacked_item is not coerced_unpacked_item:
  6555. self.any_coerced_items = True
  6556. self.unpacked_items.append(unpacked_item)
  6557. self.coerced_unpacked_items.append(coerced_unpacked_item)
  6558. self.type = py_object_type
  6559. return self
  6560. def generate_result_code(self, code):
  6561. self.generate_operation_code(code)
  6562. def generate_sequence_packing_code(self, code, target=None, plain=False):
  6563. if target is None:
  6564. target = self.result()
  6565. size_factor = c_mult = ''
  6566. mult_factor = None
  6567. if self.mult_factor and not plain:
  6568. mult_factor = self.mult_factor
  6569. if mult_factor.type.is_int:
  6570. c_mult = mult_factor.result()
  6571. if (isinstance(mult_factor.constant_result, _py_int_types) and
  6572. mult_factor.constant_result > 0):
  6573. size_factor = ' * %s' % mult_factor.constant_result
  6574. elif mult_factor.type.signed:
  6575. size_factor = ' * ((%s<0) ? 0:%s)' % (c_mult, c_mult)
  6576. else:
  6577. size_factor = ' * (%s)' % (c_mult,)
  6578. if self.type is tuple_type and (self.is_literal or self.slow) and not c_mult:
  6579. # use PyTuple_Pack() to avoid generating huge amounts of one-time code
  6580. code.putln('%s = PyTuple_Pack(%d, %s); %s' % (
  6581. target,
  6582. len(self.args),
  6583. ', '.join(arg.py_result() for arg in self.args),
  6584. code.error_goto_if_null(target, self.pos)))
  6585. code.put_gotref(target)
  6586. elif self.type.is_ctuple:
  6587. for i, arg in enumerate(self.args):
  6588. code.putln("%s.f%s = %s;" % (
  6589. target, i, arg.result()))
  6590. else:
  6591. # build the tuple/list step by step, potentially multiplying it as we go
  6592. if self.type is list_type:
  6593. create_func, set_item_func = 'PyList_New', 'PyList_SET_ITEM'
  6594. elif self.type is tuple_type:
  6595. create_func, set_item_func = 'PyTuple_New', 'PyTuple_SET_ITEM'
  6596. else:
  6597. raise InternalError("sequence packing for unexpected type %s" % self.type)
  6598. arg_count = len(self.args)
  6599. code.putln("%s = %s(%s%s); %s" % (
  6600. target, create_func, arg_count, size_factor,
  6601. code.error_goto_if_null(target, self.pos)))
  6602. code.put_gotref(target)
  6603. if c_mult:
  6604. # FIXME: can't use a temp variable here as the code may
  6605. # end up in the constant building function. Temps
  6606. # currently don't work there.
  6607. #counter = code.funcstate.allocate_temp(mult_factor.type, manage_ref=False)
  6608. counter = Naming.quick_temp_cname
  6609. code.putln('{ Py_ssize_t %s;' % counter)
  6610. if arg_count == 1:
  6611. offset = counter
  6612. else:
  6613. offset = '%s * %s' % (counter, arg_count)
  6614. code.putln('for (%s=0; %s < %s; %s++) {' % (
  6615. counter, counter, c_mult, counter
  6616. ))
  6617. else:
  6618. offset = ''
  6619. for i in range(arg_count):
  6620. arg = self.args[i]
  6621. if c_mult or not arg.result_in_temp():
  6622. code.put_incref(arg.result(), arg.ctype())
  6623. code.put_giveref(arg.py_result())
  6624. code.putln("%s(%s, %s, %s);" % (
  6625. set_item_func,
  6626. target,
  6627. (offset and i) and ('%s + %s' % (offset, i)) or (offset or i),
  6628. arg.py_result()))
  6629. if c_mult:
  6630. code.putln('}')
  6631. #code.funcstate.release_temp(counter)
  6632. code.putln('}')
  6633. if mult_factor is not None and mult_factor.type.is_pyobject:
  6634. code.putln('{ PyObject* %s = PyNumber_InPlaceMultiply(%s, %s); %s' % (
  6635. Naming.quick_temp_cname, target, mult_factor.py_result(),
  6636. code.error_goto_if_null(Naming.quick_temp_cname, self.pos)
  6637. ))
  6638. code.put_gotref(Naming.quick_temp_cname)
  6639. code.put_decref(target, py_object_type)
  6640. code.putln('%s = %s;' % (target, Naming.quick_temp_cname))
  6641. code.putln('}')
  6642. def generate_subexpr_disposal_code(self, code):
  6643. if self.mult_factor and self.mult_factor.type.is_int:
  6644. super(SequenceNode, self).generate_subexpr_disposal_code(code)
  6645. elif self.type is tuple_type and (self.is_literal or self.slow):
  6646. super(SequenceNode, self).generate_subexpr_disposal_code(code)
  6647. else:
  6648. # We call generate_post_assignment_code here instead
  6649. # of generate_disposal_code, because values were stored
  6650. # in the tuple using a reference-stealing operation.
  6651. for arg in self.args:
  6652. arg.generate_post_assignment_code(code)
  6653. # Should NOT call free_temps -- this is invoked by the default
  6654. # generate_evaluation_code which will do that.
  6655. if self.mult_factor:
  6656. self.mult_factor.generate_disposal_code(code)
  6657. def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
  6658. exception_check=None, exception_value=None):
  6659. if self.starred_assignment:
  6660. self.generate_starred_assignment_code(rhs, code)
  6661. else:
  6662. self.generate_parallel_assignment_code(rhs, code)
  6663. for item in self.unpacked_items:
  6664. item.release(code)
  6665. rhs.free_temps(code)
  6666. _func_iternext_type = PyrexTypes.CPtrType(PyrexTypes.CFuncType(
  6667. PyrexTypes.py_object_type, [
  6668. PyrexTypes.CFuncTypeArg("it", PyrexTypes.py_object_type, None),
  6669. ]))
  6670. def generate_parallel_assignment_code(self, rhs, code):
  6671. # Need to work around the fact that generate_evaluation_code
  6672. # allocates the temps in a rather hacky way -- the assignment
  6673. # is evaluated twice, within each if-block.
  6674. for item in self.unpacked_items:
  6675. item.allocate(code)
  6676. special_unpack = (rhs.type is py_object_type
  6677. or rhs.type in (tuple_type, list_type)
  6678. or not rhs.type.is_builtin_type)
  6679. long_enough_for_a_loop = len(self.unpacked_items) > 3
  6680. if special_unpack:
  6681. self.generate_special_parallel_unpacking_code(
  6682. code, rhs, use_loop=long_enough_for_a_loop)
  6683. else:
  6684. code.putln("{")
  6685. self.generate_generic_parallel_unpacking_code(
  6686. code, rhs, self.unpacked_items, use_loop=long_enough_for_a_loop)
  6687. code.putln("}")
  6688. for value_node in self.coerced_unpacked_items:
  6689. value_node.generate_evaluation_code(code)
  6690. for i in range(len(self.args)):
  6691. self.args[i].generate_assignment_code(
  6692. self.coerced_unpacked_items[i], code)
  6693. def generate_special_parallel_unpacking_code(self, code, rhs, use_loop):
  6694. sequence_type_test = '1'
  6695. none_check = "likely(%s != Py_None)" % rhs.py_result()
  6696. if rhs.type is list_type:
  6697. sequence_types = ['List']
  6698. if rhs.may_be_none():
  6699. sequence_type_test = none_check
  6700. elif rhs.type is tuple_type:
  6701. sequence_types = ['Tuple']
  6702. if rhs.may_be_none():
  6703. sequence_type_test = none_check
  6704. else:
  6705. sequence_types = ['Tuple', 'List']
  6706. tuple_check = 'likely(PyTuple_CheckExact(%s))' % rhs.py_result()
  6707. list_check = 'PyList_CheckExact(%s)' % rhs.py_result()
  6708. sequence_type_test = "(%s) || (%s)" % (tuple_check, list_check)
  6709. code.putln("if (%s) {" % sequence_type_test)
  6710. code.putln("PyObject* sequence = %s;" % rhs.py_result())
  6711. # list/tuple => check size
  6712. code.putln("Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);")
  6713. code.putln("if (unlikely(size != %d)) {" % len(self.args))
  6714. code.globalstate.use_utility_code(raise_too_many_values_to_unpack)
  6715. code.putln("if (size > %d) __Pyx_RaiseTooManyValuesError(%d);" % (
  6716. len(self.args), len(self.args)))
  6717. code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
  6718. code.putln("else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);")
  6719. # < 0 => exception
  6720. code.putln(code.error_goto(self.pos))
  6721. code.putln("}")
  6722. code.putln("#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS")
  6723. # unpack items from list/tuple in unrolled loop (can't fail)
  6724. if len(sequence_types) == 2:
  6725. code.putln("if (likely(Py%s_CheckExact(sequence))) {" % sequence_types[0])
  6726. for i, item in enumerate(self.unpacked_items):
  6727. code.putln("%s = Py%s_GET_ITEM(sequence, %d); " % (
  6728. item.result(), sequence_types[0], i))
  6729. if len(sequence_types) == 2:
  6730. code.putln("} else {")
  6731. for i, item in enumerate(self.unpacked_items):
  6732. code.putln("%s = Py%s_GET_ITEM(sequence, %d); " % (
  6733. item.result(), sequence_types[1], i))
  6734. code.putln("}")
  6735. for item in self.unpacked_items:
  6736. code.put_incref(item.result(), item.ctype())
  6737. code.putln("#else")
  6738. # in non-CPython, use the PySequence protocol (which can fail)
  6739. if not use_loop:
  6740. for i, item in enumerate(self.unpacked_items):
  6741. code.putln("%s = PySequence_ITEM(sequence, %d); %s" % (
  6742. item.result(), i,
  6743. code.error_goto_if_null(item.result(), self.pos)))
  6744. code.put_gotref(item.result())
  6745. else:
  6746. code.putln("{")
  6747. code.putln("Py_ssize_t i;")
  6748. code.putln("PyObject** temps[%s] = {%s};" % (
  6749. len(self.unpacked_items),
  6750. ','.join(['&%s' % item.result() for item in self.unpacked_items])))
  6751. code.putln("for (i=0; i < %s; i++) {" % len(self.unpacked_items))
  6752. code.putln("PyObject* item = PySequence_ITEM(sequence, i); %s" % (
  6753. code.error_goto_if_null('item', self.pos)))
  6754. code.put_gotref('item')
  6755. code.putln("*(temps[i]) = item;")
  6756. code.putln("}")
  6757. code.putln("}")
  6758. code.putln("#endif")
  6759. rhs.generate_disposal_code(code)
  6760. if sequence_type_test == '1':
  6761. code.putln("}") # all done
  6762. elif sequence_type_test == none_check:
  6763. # either tuple/list or None => save some code by generating the error directly
  6764. code.putln("} else {")
  6765. code.globalstate.use_utility_code(
  6766. UtilityCode.load_cached("RaiseNoneIterError", "ObjectHandling.c"))
  6767. code.putln("__Pyx_RaiseNoneNotIterableError(); %s" % code.error_goto(self.pos))
  6768. code.putln("}") # all done
  6769. else:
  6770. code.putln("} else {") # needs iteration fallback code
  6771. self.generate_generic_parallel_unpacking_code(
  6772. code, rhs, self.unpacked_items, use_loop=use_loop)
  6773. code.putln("}")
  6774. def generate_generic_parallel_unpacking_code(self, code, rhs, unpacked_items, use_loop, terminate=True):
  6775. code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
  6776. code.globalstate.use_utility_code(UtilityCode.load_cached("IterFinish", "ObjectHandling.c"))
  6777. code.putln("Py_ssize_t index = -1;") # must be at the start of a C block!
  6778. if use_loop:
  6779. code.putln("PyObject** temps[%s] = {%s};" % (
  6780. len(self.unpacked_items),
  6781. ','.join(['&%s' % item.result() for item in unpacked_items])))
  6782. iterator_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  6783. code.putln(
  6784. "%s = PyObject_GetIter(%s); %s" % (
  6785. iterator_temp,
  6786. rhs.py_result(),
  6787. code.error_goto_if_null(iterator_temp, self.pos)))
  6788. code.put_gotref(iterator_temp)
  6789. rhs.generate_disposal_code(code)
  6790. iternext_func = code.funcstate.allocate_temp(self._func_iternext_type, manage_ref=False)
  6791. code.putln("%s = Py_TYPE(%s)->tp_iternext;" % (
  6792. iternext_func, iterator_temp))
  6793. unpacking_error_label = code.new_label('unpacking_failed')
  6794. unpack_code = "%s(%s)" % (iternext_func, iterator_temp)
  6795. if use_loop:
  6796. code.putln("for (index=0; index < %s; index++) {" % len(unpacked_items))
  6797. code.put("PyObject* item = %s; if (unlikely(!item)) " % unpack_code)
  6798. code.put_goto(unpacking_error_label)
  6799. code.put_gotref("item")
  6800. code.putln("*(temps[index]) = item;")
  6801. code.putln("}")
  6802. else:
  6803. for i, item in enumerate(unpacked_items):
  6804. code.put(
  6805. "index = %d; %s = %s; if (unlikely(!%s)) " % (
  6806. i,
  6807. item.result(),
  6808. unpack_code,
  6809. item.result()))
  6810. code.put_goto(unpacking_error_label)
  6811. code.put_gotref(item.py_result())
  6812. if terminate:
  6813. code.globalstate.use_utility_code(
  6814. UtilityCode.load_cached("UnpackItemEndCheck", "ObjectHandling.c"))
  6815. code.put_error_if_neg(self.pos, "__Pyx_IternextUnpackEndCheck(%s, %d)" % (
  6816. unpack_code,
  6817. len(unpacked_items)))
  6818. code.putln("%s = NULL;" % iternext_func)
  6819. code.put_decref_clear(iterator_temp, py_object_type)
  6820. unpacking_done_label = code.new_label('unpacking_done')
  6821. code.put_goto(unpacking_done_label)
  6822. code.put_label(unpacking_error_label)
  6823. code.put_decref_clear(iterator_temp, py_object_type)
  6824. code.putln("%s = NULL;" % iternext_func)
  6825. code.putln("if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);")
  6826. code.putln(code.error_goto(self.pos))
  6827. code.put_label(unpacking_done_label)
  6828. code.funcstate.release_temp(iternext_func)
  6829. if terminate:
  6830. code.funcstate.release_temp(iterator_temp)
  6831. iterator_temp = None
  6832. return iterator_temp
  6833. def generate_starred_assignment_code(self, rhs, code):
  6834. for i, arg in enumerate(self.args):
  6835. if arg.is_starred:
  6836. starred_target = self.unpacked_items[i]
  6837. unpacked_fixed_items_left = self.unpacked_items[:i]
  6838. unpacked_fixed_items_right = self.unpacked_items[i+1:]
  6839. break
  6840. else:
  6841. assert False
  6842. iterator_temp = None
  6843. if unpacked_fixed_items_left:
  6844. for item in unpacked_fixed_items_left:
  6845. item.allocate(code)
  6846. code.putln('{')
  6847. iterator_temp = self.generate_generic_parallel_unpacking_code(
  6848. code, rhs, unpacked_fixed_items_left,
  6849. use_loop=True, terminate=False)
  6850. for i, item in enumerate(unpacked_fixed_items_left):
  6851. value_node = self.coerced_unpacked_items[i]
  6852. value_node.generate_evaluation_code(code)
  6853. code.putln('}')
  6854. starred_target.allocate(code)
  6855. target_list = starred_target.result()
  6856. code.putln("%s = PySequence_List(%s); %s" % (
  6857. target_list,
  6858. iterator_temp or rhs.py_result(),
  6859. code.error_goto_if_null(target_list, self.pos)))
  6860. code.put_gotref(target_list)
  6861. if iterator_temp:
  6862. code.put_decref_clear(iterator_temp, py_object_type)
  6863. code.funcstate.release_temp(iterator_temp)
  6864. else:
  6865. rhs.generate_disposal_code(code)
  6866. if unpacked_fixed_items_right:
  6867. code.globalstate.use_utility_code(raise_need_more_values_to_unpack)
  6868. length_temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
  6869. code.putln('%s = PyList_GET_SIZE(%s);' % (length_temp, target_list))
  6870. code.putln("if (unlikely(%s < %d)) {" % (length_temp, len(unpacked_fixed_items_right)))
  6871. code.putln("__Pyx_RaiseNeedMoreValuesError(%d+%s); %s" % (
  6872. len(unpacked_fixed_items_left), length_temp,
  6873. code.error_goto(self.pos)))
  6874. code.putln('}')
  6875. for item in unpacked_fixed_items_right[::-1]:
  6876. item.allocate(code)
  6877. for i, (item, coerced_arg) in enumerate(zip(unpacked_fixed_items_right[::-1],
  6878. self.coerced_unpacked_items[::-1])):
  6879. code.putln('#if CYTHON_COMPILING_IN_CPYTHON')
  6880. code.putln("%s = PyList_GET_ITEM(%s, %s-%d); " % (
  6881. item.py_result(), target_list, length_temp, i+1))
  6882. # resize the list the hard way
  6883. code.putln("((PyVarObject*)%s)->ob_size--;" % target_list)
  6884. code.putln('#else')
  6885. code.putln("%s = PySequence_ITEM(%s, %s-%d); " % (
  6886. item.py_result(), target_list, length_temp, i+1))
  6887. code.putln('#endif')
  6888. code.put_gotref(item.py_result())
  6889. coerced_arg.generate_evaluation_code(code)
  6890. code.putln('#if !CYTHON_COMPILING_IN_CPYTHON')
  6891. sublist_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
  6892. code.putln('%s = PySequence_GetSlice(%s, 0, %s-%d); %s' % (
  6893. sublist_temp, target_list, length_temp, len(unpacked_fixed_items_right),
  6894. code.error_goto_if_null(sublist_temp, self.pos)))
  6895. code.put_gotref(sublist_temp)
  6896. code.funcstate.release_temp(length_temp)
  6897. code.put_decref(target_list, py_object_type)
  6898. code.putln('%s = %s; %s = NULL;' % (target_list, sublist_temp, sublist_temp))
  6899. code.putln('#else')
  6900. code.putln('(void)%s;' % sublist_temp) # avoid warning about unused variable
  6901. code.funcstate.release_temp(sublist_temp)
  6902. code.putln('#endif')
  6903. for i, arg in enumerate(self.args):
  6904. arg.generate_assignment_code(self.coerced_unpacked_items[i], code)
  6905. def annotate(self, code):
  6906. for arg in self.args:
  6907. arg.annotate(code)
  6908. if self.unpacked_items:
  6909. for arg in self.unpacked_items:
  6910. arg.annotate(code)
  6911. for arg in self.coerced_unpacked_items:
  6912. arg.annotate(code)
  6913. class TupleNode(SequenceNode):
  6914. # Tuple constructor.
  6915. type = tuple_type
  6916. is_partly_literal = False
  6917. gil_message = "Constructing Python tuple"
  6918. def infer_type(self, env):
  6919. if self.mult_factor or not self.args:
  6920. return tuple_type
  6921. arg_types = [arg.infer_type(env) for arg in self.args]
  6922. if any(type.is_pyobject or type.is_memoryviewslice or type.is_unspecified or type.is_fused
  6923. for type in arg_types):
  6924. return tuple_type
  6925. return env.declare_tuple_type(self.pos, arg_types).type
  6926. def analyse_types(self, env, skip_children=False):
  6927. if len(self.args) == 0:
  6928. self.is_temp = False
  6929. self.is_literal = True
  6930. return self
  6931. if not skip_children:
  6932. for i, arg in enumerate(self.args):
  6933. if arg.is_starred:
  6934. arg.starred_expr_allowed_here = True
  6935. self.args[i] = arg.analyse_types(env)
  6936. if (not self.mult_factor and
  6937. not any((arg.is_starred or arg.type.is_pyobject or arg.type.is_memoryviewslice or arg.type.is_fused)
  6938. for arg in self.args)):
  6939. self.type = env.declare_tuple_type(self.pos, (arg.type for arg in self.args)).type
  6940. self.is_temp = 1
  6941. return self
  6942. node = SequenceNode.analyse_types(self, env, skip_children=True)
  6943. node = node._create_merge_node_if_necessary(env)
  6944. if not node.is_sequence_constructor:
  6945. return node
  6946. if not all(child.is_literal for child in node.args):
  6947. return node
  6948. if not node.mult_factor or (
  6949. node.mult_factor.is_literal and
  6950. isinstance(node.mult_factor.constant_result, _py_int_types)):
  6951. node.is_temp = False
  6952. node.is_literal = True
  6953. else:
  6954. if not node.mult_factor.type.is_pyobject:
  6955. node.mult_factor = node.mult_factor.coerce_to_pyobject(env)
  6956. node.is_temp = True
  6957. node.is_partly_literal = True
  6958. return node
  6959. def analyse_as_type(self, env):
  6960. # ctuple type
  6961. if not self.args:
  6962. return None
  6963. item_types = [arg.analyse_as_type(env) for arg in self.args]
  6964. if any(t is None for t in item_types):
  6965. return None
  6966. entry = env.declare_tuple_type(self.pos, item_types)
  6967. return entry.type
  6968. def coerce_to(self, dst_type, env):
  6969. if self.type.is_ctuple:
  6970. if dst_type.is_ctuple and self.type.size == dst_type.size:
  6971. return self.coerce_to_ctuple(dst_type, env)
  6972. elif dst_type is tuple_type or dst_type is py_object_type:
  6973. coerced_args = [arg.coerce_to_pyobject(env) for arg in self.args]
  6974. return TupleNode(self.pos, args=coerced_args, type=tuple_type, is_temp=1).analyse_types(env, skip_children=True)
  6975. else:
  6976. return self.coerce_to_pyobject(env).coerce_to(dst_type, env)
  6977. elif dst_type.is_ctuple and not self.mult_factor:
  6978. return self.coerce_to_ctuple(dst_type, env)
  6979. else:
  6980. return SequenceNode.coerce_to(self, dst_type, env)
  6981. def as_list(self):
  6982. t = ListNode(self.pos, args=self.args, mult_factor=self.mult_factor)
  6983. if isinstance(self.constant_result, tuple):
  6984. t.constant_result = list(self.constant_result)
  6985. return t
  6986. def is_simple(self):
  6987. # either temp or constant => always simple
  6988. return True
  6989. def nonlocally_immutable(self):
  6990. # either temp or constant => always safe
  6991. return True
  6992. def calculate_result_code(self):
  6993. if len(self.args) > 0:
  6994. return self.result_code
  6995. else:
  6996. return Naming.empty_tuple
  6997. def calculate_constant_result(self):
  6998. self.constant_result = tuple([
  6999. arg.constant_result for arg in self.args])
  7000. def compile_time_value(self, denv):
  7001. values = self.compile_time_value_list(denv)
  7002. try:
  7003. return tuple(values)
  7004. except Exception as e:
  7005. self.compile_time_value_error(e)
  7006. def generate_operation_code(self, code):
  7007. if len(self.args) == 0:
  7008. # result_code is Naming.empty_tuple
  7009. return
  7010. if self.is_literal or self.is_partly_literal:
  7011. # The "mult_factor" is part of the deduplication if it is also constant, i.e. when
  7012. # we deduplicate the multiplied result. Otherwise, only deduplicate the constant part.
  7013. dedup_key = make_dedup_key(self.type, [self.mult_factor if self.is_literal else None] + self.args)
  7014. tuple_target = code.get_py_const(py_object_type, 'tuple', cleanup_level=2, dedup_key=dedup_key)
  7015. const_code = code.get_cached_constants_writer(tuple_target)
  7016. if const_code is not None:
  7017. # constant is not yet initialised
  7018. const_code.mark_pos(self.pos)
  7019. self.generate_sequence_packing_code(const_code, tuple_target, plain=not self.is_literal)
  7020. const_code.put_giveref(tuple_target)
  7021. if self.is_literal:
  7022. self.result_code = tuple_target
  7023. else:
  7024. code.putln('%s = PyNumber_Multiply(%s, %s); %s' % (
  7025. self.result(), tuple_target, self.mult_factor.py_result(),
  7026. code.error_goto_if_null(self.result(), self.pos)
  7027. ))
  7028. code.put_gotref(self.py_result())
  7029. else:
  7030. self.type.entry.used = True
  7031. self.generate_sequence_packing_code(code)
  7032. class ListNode(SequenceNode):
  7033. # List constructor.
  7034. # obj_conversion_errors [PyrexError] used internally
  7035. # orignial_args [ExprNode] used internally
  7036. obj_conversion_errors = []
  7037. type = list_type
  7038. in_module_scope = False
  7039. gil_message = "Constructing Python list"
  7040. def type_dependencies(self, env):
  7041. return ()
  7042. def infer_type(self, env):
  7043. # TODO: Infer non-object list arrays.
  7044. return list_type
  7045. def analyse_expressions(self, env):
  7046. for arg in self.args:
  7047. if arg.is_starred:
  7048. arg.starred_expr_allowed_here = True
  7049. node = SequenceNode.analyse_expressions(self, env)
  7050. return node.coerce_to_pyobject(env)
  7051. def analyse_types(self, env):
  7052. with local_errors(ignore=True) as errors:
  7053. self.original_args = list(self.args)
  7054. node = SequenceNode.analyse_types(self, env)
  7055. node.obj_conversion_errors = errors
  7056. if env.is_module_scope:
  7057. self.in_module_scope = True
  7058. node = node._create_merge_node_if_necessary(env)
  7059. return node
  7060. def coerce_to(self, dst_type, env):
  7061. if dst_type.is_pyobject:
  7062. for err in self.obj_conversion_errors:
  7063. report_error(err)
  7064. self.obj_conversion_errors = []
  7065. if not self.type.subtype_of(dst_type):
  7066. error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
  7067. elif (dst_type.is_array or dst_type.is_ptr) and dst_type.base_type is not PyrexTypes.c_void_type:
  7068. array_length = len(self.args)
  7069. if self.mult_factor:
  7070. if isinstance(self.mult_factor.constant_result, _py_int_types):
  7071. if self.mult_factor.constant_result <= 0:
  7072. error(self.pos, "Cannot coerce non-positively multiplied list to '%s'" % dst_type)
  7073. else:
  7074. array_length *= self.mult_factor.constant_result
  7075. else:
  7076. error(self.pos, "Cannot coerce dynamically multiplied list to '%s'" % dst_type)
  7077. base_type = dst_type.base_type
  7078. self.type = PyrexTypes.CArrayType(base_type, array_length)
  7079. for i in range(len(self.original_args)):
  7080. arg = self.args[i]
  7081. if isinstance(arg, CoerceToPyTypeNode):
  7082. arg = arg.arg
  7083. self.args[i] = arg.coerce_to(base_type, env)
  7084. elif dst_type.is_cpp_class:
  7085. # TODO(robertwb): Avoid object conversion for vector/list/set.
  7086. return TypecastNode(self.pos, operand=self, type=PyrexTypes.py_object_type).coerce_to(dst_type, env)
  7087. elif self.mult_factor:
  7088. error(self.pos, "Cannot coerce multiplied list to '%s'" % dst_type)
  7089. elif dst_type.is_struct:
  7090. if len(self.args) > len(dst_type.scope.var_entries):
  7091. error(self.pos, "Too many members for '%s'" % dst_type)
  7092. else:
  7093. if len(self.args) < len(dst_type.scope.var_entries):
  7094. warning(self.pos, "Too few members for '%s'" % dst_type, 1)
  7095. for i, (arg, member) in enumerate(zip(self.original_args, dst_type.scope.var_entries)):
  7096. if isinstance(arg, CoerceToPyTypeNode):
  7097. arg = arg.arg
  7098. self.args[i] = arg.coerce_to(member.type, env)
  7099. self.type = dst_type
  7100. elif dst_type.is_ctuple:
  7101. return self.coerce_to_ctuple(dst_type, env)
  7102. else:
  7103. self.type = error_type
  7104. error(self.pos, "Cannot coerce list to type '%s'" % dst_type)
  7105. return self
  7106. def as_list(self): # dummy for compatibility with TupleNode
  7107. return self
  7108. def as_tuple(self):
  7109. t = TupleNode(self.pos, args=self.args, mult_factor=self.mult_factor)
  7110. if isinstance(self.constant_result, list):
  7111. t.constant_result = tuple(self.constant_result)
  7112. return t
  7113. def allocate_temp_result(self, code):
  7114. if self.type.is_array:
  7115. if self.in_module_scope:
  7116. self.temp_code = code.funcstate.allocate_temp(
  7117. self.type, manage_ref=False, static=True, reusable=False)
  7118. else:
  7119. # To be valid C++, we must allocate the memory on the stack
  7120. # manually and be sure not to reuse it for something else.
  7121. # Yes, this means that we leak a temp array variable.
  7122. self.temp_code = code.funcstate.allocate_temp(
  7123. self.type, manage_ref=False, reusable=False)
  7124. else:
  7125. SequenceNode.allocate_temp_result(self, code)
  7126. def calculate_constant_result(self):
  7127. if self.mult_factor:
  7128. raise ValueError() # may exceed the compile time memory
  7129. self.constant_result = [
  7130. arg.constant_result for arg in self.args]
  7131. def compile_time_value(self, denv):
  7132. l = self.compile_time_value_list(denv)
  7133. if self.mult_factor:
  7134. l *= self.mult_factor.compile_time_value(denv)
  7135. return l
  7136. def generate_operation_code(self, code):
  7137. if self.type.is_pyobject:
  7138. for err in self.obj_conversion_errors:
  7139. report_error(err)
  7140. self.generate_sequence_packing_code(code)
  7141. elif self.type.is_array:
  7142. if self.mult_factor:
  7143. code.putln("{")
  7144. code.putln("Py_ssize_t %s;" % Naming.quick_temp_cname)
  7145. code.putln("for ({i} = 0; {i} < {count}; {i}++) {{".format(
  7146. i=Naming.quick_temp_cname, count=self.mult_factor.result()))
  7147. offset = '+ (%d * %s)' % (len(self.args), Naming.quick_temp_cname)
  7148. else:
  7149. offset = ''
  7150. for i, arg in enumerate(self.args):
  7151. if arg.type.is_array:
  7152. code.globalstate.use_utility_code(UtilityCode.load_cached("IncludeStringH", "StringTools.c"))
  7153. code.putln("memcpy(&(%s[%s%s]), %s, sizeof(%s[0]));" % (
  7154. self.result(), i, offset,
  7155. arg.result(), self.result()
  7156. ))
  7157. else:
  7158. code.putln("%s[%s%s] = %s;" % (
  7159. self.result(),
  7160. i,
  7161. offset,
  7162. arg.result()))
  7163. if self.mult_factor:
  7164. code.putln("}")
  7165. code.putln("}")
  7166. elif self.type.is_struct:
  7167. for arg, member in zip(self.args, self.type.scope.var_entries):
  7168. code.putln("%s.%s = %s;" % (
  7169. self.result(),
  7170. member.cname,
  7171. arg.result()))
  7172. else:
  7173. raise InternalError("List type never specified")
  7174. class ScopedExprNode(ExprNode):
  7175. # Abstract base class for ExprNodes that have their own local
  7176. # scope, such as generator expressions.
  7177. #
  7178. # expr_scope Scope the inner scope of the expression
  7179. subexprs = []
  7180. expr_scope = None
  7181. # does this node really have a local scope, e.g. does it leak loop
  7182. # variables or not? non-leaking Py3 behaviour is default, except
  7183. # for list comprehensions where the behaviour differs in Py2 and
  7184. # Py3 (set in Parsing.py based on parser context)
  7185. has_local_scope = True
  7186. def init_scope(self, outer_scope, expr_scope=None):
  7187. if expr_scope is not None:
  7188. self.expr_scope = expr_scope
  7189. elif self.has_local_scope:
  7190. self.expr_scope = Symtab.GeneratorExpressionScope(outer_scope)
  7191. else:
  7192. self.expr_scope = None
  7193. def analyse_declarations(self, env):
  7194. self.init_scope(env)
  7195. def analyse_scoped_declarations(self, env):
  7196. # this is called with the expr_scope as env
  7197. pass
  7198. def analyse_types(self, env):
  7199. # no recursion here, the children will be analysed separately below
  7200. return self
  7201. def analyse_scoped_expressions(self, env):
  7202. # this is called with the expr_scope as env
  7203. return self
  7204. def generate_evaluation_code(self, code):
  7205. # set up local variables and free their references on exit
  7206. generate_inner_evaluation_code = super(ScopedExprNode, self).generate_evaluation_code
  7207. if not self.has_local_scope or not self.expr_scope.var_entries:
  7208. # no local variables => delegate, done
  7209. generate_inner_evaluation_code(code)
  7210. return
  7211. code.putln('{ /* enter inner scope */')
  7212. py_entries = []
  7213. for _, entry in sorted(item for item in self.expr_scope.entries.items() if item[0]):
  7214. if not entry.in_closure:
  7215. if entry.type.is_pyobject and entry.used:
  7216. py_entries.append(entry)
  7217. if not py_entries:
  7218. # no local Python references => no cleanup required
  7219. generate_inner_evaluation_code(code)
  7220. code.putln('} /* exit inner scope */')
  7221. return
  7222. # must free all local Python references at each exit point
  7223. old_loop_labels = code.new_loop_labels()
  7224. old_error_label = code.new_error_label()
  7225. generate_inner_evaluation_code(code)
  7226. # normal (non-error) exit
  7227. self._generate_vars_cleanup(code, py_entries)
  7228. # error/loop body exit points
  7229. exit_scope = code.new_label('exit_scope')
  7230. code.put_goto(exit_scope)
  7231. for label, old_label in ([(code.error_label, old_error_label)] +
  7232. list(zip(code.get_loop_labels(), old_loop_labels))):
  7233. if code.label_used(label):
  7234. code.put_label(label)
  7235. self._generate_vars_cleanup(code, py_entries)
  7236. code.put_goto(old_label)
  7237. code.put_label(exit_scope)
  7238. code.putln('} /* exit inner scope */')
  7239. code.set_loop_labels(old_loop_labels)
  7240. code.error_label = old_error_label
  7241. def _generate_vars_cleanup(self, code, py_entries):
  7242. for entry in py_entries:
  7243. if entry.is_cglobal:
  7244. code.put_var_gotref(entry)
  7245. code.put_decref_set(entry.cname, "Py_None")
  7246. else:
  7247. code.put_var_xdecref_clear(entry)
  7248. class ComprehensionNode(ScopedExprNode):
  7249. # A list/set/dict comprehension
  7250. child_attrs = ["loop"]
  7251. is_temp = True
  7252. constant_result = not_a_constant
  7253. def infer_type(self, env):
  7254. return self.type
  7255. def analyse_declarations(self, env):
  7256. self.append.target = self # this is used in the PyList_Append of the inner loop
  7257. self.init_scope(env)
  7258. def analyse_scoped_declarations(self, env):
  7259. self.loop.analyse_declarations(env)
  7260. def analyse_types(self, env):
  7261. if not self.has_local_scope:
  7262. self.loop = self.loop.analyse_expressions(env)
  7263. return self
  7264. def analyse_scoped_expressions(self, env):
  7265. if self.has_local_scope:
  7266. self.loop = self.loop.analyse_expressions(env)
  7267. return self
  7268. def may_be_none(self):
  7269. return False
  7270. def generate_result_code(self, code):
  7271. self.generate_operation_code(code)
  7272. def generate_operation_code(self, code):
  7273. if self.type is Builtin.list_type:
  7274. create_code = 'PyList_New(0)'
  7275. elif self.type is Builtin.set_type:
  7276. create_code = 'PySet_New(NULL)'
  7277. elif self.type is Builtin.dict_type:
  7278. create_code = 'PyDict_New()'
  7279. else:
  7280. raise InternalError("illegal type for comprehension: %s" % self.type)
  7281. code.putln('%s = %s; %s' % (
  7282. self.result(), create_code,
  7283. code.error_goto_if_null(self.result(), self.pos)))
  7284. code.put_gotref(self.result())
  7285. self.loop.generate_execution_code(code)
  7286. def annotate(self, code):
  7287. self.loop.annotate(code)
  7288. class ComprehensionAppendNode(Node):
  7289. # Need to be careful to avoid infinite recursion:
  7290. # target must not be in child_attrs/subexprs
  7291. child_attrs = ['expr']
  7292. target = None
  7293. type = PyrexTypes.c_int_type
  7294. def analyse_expressions(self, env):
  7295. self.expr = self.expr.analyse_expressions(env)
  7296. if not self.expr.type.is_pyobject:
  7297. self.expr = self.expr.coerce_to_pyobject(env)
  7298. return self
  7299. def generate_execution_code(self, code):
  7300. if self.target.type is list_type:
  7301. code.globalstate.use_utility_code(
  7302. UtilityCode.load_cached("ListCompAppend", "Optimize.c"))
  7303. function = "__Pyx_ListComp_Append"
  7304. elif self.target.type is set_type:
  7305. function = "PySet_Add"
  7306. else:
  7307. raise InternalError(
  7308. "Invalid type for comprehension node: %s" % self.target.type)
  7309. self.expr.generate_evaluation_code(code)
  7310. code.putln(code.error_goto_if("%s(%s, (PyObject*)%s)" % (
  7311. function,
  7312. self.target.result(),
  7313. self.expr.result()
  7314. ), self.pos))
  7315. self.expr.generate_disposal_code(code)
  7316. self.expr.free_temps(code)
  7317. def generate_function_definitions(self, env, code):
  7318. self.expr.generate_function_definitions(env, code)
  7319. def annotate(self, code):
  7320. self.expr.annotate(code)
  7321. class DictComprehensionAppendNode(ComprehensionAppendNode):
  7322. child_attrs = ['key_expr', 'value_expr']
  7323. def analyse_expressions(self, env):
  7324. self.key_expr = self.key_expr.analyse_expressions(env)
  7325. if not self.key_expr.type.is_pyobject:
  7326. self.key_expr = self.key_expr.coerce_to_pyobject(env)
  7327. self.value_expr = self.value_expr.analyse_expressions(env)
  7328. if not self.value_expr.type.is_pyobject:
  7329. self.value_expr = self.value_expr.coerce_to_pyobject(env)
  7330. return self
  7331. def generate_execution_code(self, code):
  7332. self.key_expr.generate_evaluation_code(code)
  7333. self.value_expr.generate_evaluation_code(code)
  7334. code.putln(code.error_goto_if("PyDict_SetItem(%s, (PyObject*)%s, (PyObject*)%s)" % (
  7335. self.target.result(),
  7336. self.key_expr.result(),
  7337. self.value_expr.result()
  7338. ), self.pos))
  7339. self.key_expr.generate_disposal_code(code)
  7340. self.key_expr.free_temps(code)
  7341. self.value_expr.generate_disposal_code(code)
  7342. self.value_expr.free_temps(code)
  7343. def generate_function_definitions(self, env, code):
  7344. self.key_expr.generate_function_definitions(env, code)
  7345. self.value_expr.generate_function_definitions(env, code)
  7346. def annotate(self, code):
  7347. self.key_expr.annotate(code)
  7348. self.value_expr.annotate(code)
  7349. class InlinedGeneratorExpressionNode(ExprNode):
  7350. # An inlined generator expression for which the result is calculated
  7351. # inside of the loop and returned as a single, first and only Generator
  7352. # return value.
  7353. # This will only be created by transforms when replacing safe builtin
  7354. # calls on generator expressions.
  7355. #
  7356. # gen GeneratorExpressionNode the generator, not containing any YieldExprNodes
  7357. # orig_func String the name of the builtin function this node replaces
  7358. # target ExprNode or None a 'target' for a ComprehensionAppend node
  7359. subexprs = ["gen"]
  7360. orig_func = None
  7361. target = None
  7362. is_temp = True
  7363. type = py_object_type
  7364. def __init__(self, pos, gen, comprehension_type=None, **kwargs):
  7365. gbody = gen.def_node.gbody
  7366. gbody.is_inlined = True
  7367. if comprehension_type is not None:
  7368. assert comprehension_type in (list_type, set_type, dict_type), comprehension_type
  7369. gbody.inlined_comprehension_type = comprehension_type
  7370. kwargs.update(
  7371. target=RawCNameExprNode(pos, comprehension_type, Naming.retval_cname),
  7372. type=comprehension_type,
  7373. )
  7374. super(InlinedGeneratorExpressionNode, self).__init__(pos, gen=gen, **kwargs)
  7375. def may_be_none(self):
  7376. return self.orig_func not in ('any', 'all', 'sorted')
  7377. def infer_type(self, env):
  7378. return self.type
  7379. def analyse_types(self, env):
  7380. self.gen = self.gen.analyse_expressions(env)
  7381. return self
  7382. def generate_result_code(self, code):
  7383. code.putln("%s = __Pyx_Generator_Next(%s); %s" % (
  7384. self.result(), self.gen.result(),
  7385. code.error_goto_if_null(self.result(), self.pos)))
  7386. code.put_gotref(self.result())
  7387. class MergedSequenceNode(ExprNode):
  7388. """
  7389. Merge a sequence of iterables into a set/list/tuple.
  7390. The target collection is determined by self.type, which must be set externally.
  7391. args [ExprNode]
  7392. """
  7393. subexprs = ['args']
  7394. is_temp = True
  7395. gil_message = "Constructing Python collection"
  7396. def __init__(self, pos, args, type):
  7397. if type in (list_type, tuple_type) and args and args[0].is_sequence_constructor:
  7398. # construct a list directly from the first argument that we can then extend
  7399. if args[0].type is not list_type:
  7400. args[0] = ListNode(args[0].pos, args=args[0].args, is_temp=True)
  7401. ExprNode.__init__(self, pos, args=args, type=type)
  7402. def calculate_constant_result(self):
  7403. result = []
  7404. for item in self.args:
  7405. if item.is_sequence_constructor and item.mult_factor:
  7406. if item.mult_factor.constant_result <= 0:
  7407. continue
  7408. # otherwise, adding each item once should be enough
  7409. if item.is_set_literal or item.is_sequence_constructor:
  7410. # process items in order
  7411. items = (arg.constant_result for arg in item.args)
  7412. else:
  7413. items = item.constant_result
  7414. result.extend(items)
  7415. if self.type is set_type:
  7416. result = set(result)
  7417. elif self.type is tuple_type:
  7418. result = tuple(result)
  7419. else:
  7420. assert self.type is list_type
  7421. self.constant_result = result
  7422. def compile_time_value(self, denv):
  7423. result = []
  7424. for item in self.args:
  7425. if item.is_sequence_constructor and item.mult_factor:
  7426. if item.mult_factor.compile_time_value(denv) <= 0:
  7427. continue
  7428. if item.is_set_literal or item.is_sequence_constructor:
  7429. # process items in order
  7430. items = (arg.compile_time_value(denv) for arg in item.args)
  7431. else:
  7432. items = item.compile_time_value(denv)
  7433. result.extend(items)
  7434. if self.type is set_type:
  7435. try:
  7436. result = set(result)
  7437. except Exception as e:
  7438. self.compile_time_value_error(e)
  7439. elif self.type is tuple_type:
  7440. result = tuple(result)
  7441. else:
  7442. assert self.type is list_type
  7443. return result
  7444. def type_dependencies(self, env):
  7445. return ()
  7446. def infer_type(self, env):
  7447. return self.type
  7448. def analyse_types(self, env):
  7449. args = [
  7450. arg.analyse_types(env).coerce_to_pyobject(env).as_none_safe_node(
  7451. # FIXME: CPython's error message starts with the runtime function name
  7452. 'argument after * must be an iterable, not NoneType')
  7453. for arg in self.args
  7454. ]
  7455. if len(args) == 1 and args[0].type is self.type:
  7456. # strip this intermediate node and use the bare collection
  7457. return args[0]
  7458. assert self.type in (set_type, list_type, tuple_type)
  7459. self.args = args
  7460. return self
  7461. def may_be_none(self):
  7462. return False
  7463. def generate_evaluation_code(self, code):
  7464. code.mark_pos(self.pos)
  7465. self.allocate_temp_result(code)
  7466. is_set = self.type is set_type
  7467. args = iter(self.args)
  7468. item = next(args)
  7469. item.generate_evaluation_code(code)
  7470. if (is_set and item.is_set_literal or
  7471. not is_set and item.is_sequence_constructor and item.type is list_type):
  7472. code.putln("%s = %s;" % (self.result(), item.py_result()))
  7473. item.generate_post_assignment_code(code)
  7474. else:
  7475. code.putln("%s = %s(%s); %s" % (
  7476. self.result(),
  7477. 'PySet_New' if is_set else 'PySequence_List',
  7478. item.py_result(),
  7479. code.error_goto_if_null(self.result(), self.pos)))
  7480. code.put_gotref(self.py_result())
  7481. item.generate_disposal_code(code)
  7482. item.free_temps(code)
  7483. helpers = set()
  7484. if is_set:
  7485. add_func = "PySet_Add"
  7486. extend_func = "__Pyx_PySet_Update"
  7487. else:
  7488. add_func = "__Pyx_ListComp_Append"
  7489. extend_func = "__Pyx_PyList_Extend"
  7490. for item in args:
  7491. if (is_set and (item.is_set_literal or item.is_sequence_constructor) or
  7492. (item.is_sequence_constructor and not item.mult_factor)):
  7493. if not is_set and item.args:
  7494. helpers.add(("ListCompAppend", "Optimize.c"))
  7495. for arg in item.args:
  7496. arg.generate_evaluation_code(code)
  7497. code.put_error_if_neg(arg.pos, "%s(%s, %s)" % (
  7498. add_func,
  7499. self.result(),
  7500. arg.py_result()))
  7501. arg.generate_disposal_code(code)
  7502. arg.free_temps(code)
  7503. continue
  7504. if is_set:
  7505. helpers.add(("PySet_Update", "Builtins.c"))
  7506. else:
  7507. helpers.add(("ListExtend", "Optimize.c"))
  7508. item.generate_evaluation_code(code)
  7509. code.put_error_if_neg(item.pos, "%s(%s, %s)" % (
  7510. extend_func,
  7511. self.result(),
  7512. item.py_result()))
  7513. item.generate_disposal_code(code)
  7514. item.free_temps(code)
  7515. if self.type is tuple_type:
  7516. code.putln("{")
  7517. code.putln("PyObject *%s = PyList_AsTuple(%s);" % (
  7518. Naming.quick_temp_cname,
  7519. self.result()))
  7520. code.put_decref(self.result(), py_object_type)
  7521. code.putln("%s = %s; %s" % (
  7522. self.result(),
  7523. Naming.quick_temp_cname,
  7524. code.error_goto_if_null(self.result(), self.pos)))
  7525. code.put_gotref(self.result())
  7526. code.putln("}")
  7527. for helper in sorted(helpers):
  7528. code.globalstate.use_utility_code(UtilityCode.load_cached(*helper))
  7529. def annotate(self, code):
  7530. for item in self.args:
  7531. item.annotate(code)
  7532. class SetNode(ExprNode):
  7533. """
  7534. Set constructor.
  7535. """
  7536. subexprs = ['args']
  7537. type = set_type
  7538. is_set_literal = True
  7539. gil_message = "Constructing Python set"
  7540. def analyse_types(self, env):
  7541. for i in range(len(self.args)):
  7542. arg = self.args[i]
  7543. arg = arg.analyse_types(env)
  7544. self.args[i] = arg.coerce_to_pyobject(env)
  7545. self.type = set_type
  7546. self.is_temp = 1
  7547. return self
  7548. def may_be_none(self):
  7549. return False
  7550. def calculate_constant_result(self):
  7551. self.constant_result = set([arg.constant_result for arg in self.args])
  7552. def compile_time_value(self, denv):
  7553. values = [arg.compile_time_value(denv) for arg in self.args]
  7554. try:
  7555. return set(values)
  7556. except Exception as e:
  7557. self.compile_time_value_error(e)
  7558. def generate_evaluation_code(self, code):
  7559. for arg in self.args:
  7560. arg.generate_evaluation_code(code)
  7561. self.allocate_temp_result(code)
  7562. code.putln(
  7563. "%s = PySet_New(0); %s" % (
  7564. self.result(),
  7565. code.error_goto_if_null(self.result(), self.pos)))
  7566. code.put_gotref(self.py_result())
  7567. for arg in self.args:
  7568. code.put_error_if_neg(
  7569. self.pos,
  7570. "PySet_Add(%s, %s)" % (self.result(), arg.py_result()))
  7571. arg.generate_disposal_code(code)
  7572. arg.free_temps(code)
  7573. class DictNode(ExprNode):
  7574. # Dictionary constructor.
  7575. #
  7576. # key_value_pairs [DictItemNode]
  7577. # exclude_null_values [boolean] Do not add NULL values to dict
  7578. #
  7579. # obj_conversion_errors [PyrexError] used internally
  7580. subexprs = ['key_value_pairs']
  7581. is_temp = 1
  7582. exclude_null_values = False
  7583. type = dict_type
  7584. is_dict_literal = True
  7585. reject_duplicates = False
  7586. obj_conversion_errors = []
  7587. @classmethod
  7588. def from_pairs(cls, pos, pairs):
  7589. return cls(pos, key_value_pairs=[
  7590. DictItemNode(pos, key=k, value=v) for k, v in pairs])
  7591. def calculate_constant_result(self):
  7592. self.constant_result = dict([
  7593. item.constant_result for item in self.key_value_pairs])
  7594. def compile_time_value(self, denv):
  7595. pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
  7596. for item in self.key_value_pairs]
  7597. try:
  7598. return dict(pairs)
  7599. except Exception as e:
  7600. self.compile_time_value_error(e)
  7601. def type_dependencies(self, env):
  7602. return ()
  7603. def infer_type(self, env):
  7604. # TODO: Infer struct constructors.
  7605. return dict_type
  7606. def analyse_types(self, env):
  7607. with local_errors(ignore=True) as errors:
  7608. self.key_value_pairs = [
  7609. item.analyse_types(env)
  7610. for item in self.key_value_pairs
  7611. ]
  7612. self.obj_conversion_errors = errors
  7613. return self
  7614. def may_be_none(self):
  7615. return False
  7616. def coerce_to(self, dst_type, env):
  7617. if dst_type.is_pyobject:
  7618. self.release_errors()
  7619. if self.type.is_struct_or_union:
  7620. if not dict_type.subtype_of(dst_type):
  7621. error(self.pos, "Cannot interpret struct as non-dict type '%s'" % dst_type)
  7622. return DictNode(self.pos, key_value_pairs=[
  7623. DictItemNode(item.pos, key=item.key.coerce_to_pyobject(env),
  7624. value=item.value.coerce_to_pyobject(env))
  7625. for item in self.key_value_pairs])
  7626. if not self.type.subtype_of(dst_type):
  7627. error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
  7628. elif dst_type.is_struct_or_union:
  7629. self.type = dst_type
  7630. if not dst_type.is_struct and len(self.key_value_pairs) != 1:
  7631. error(self.pos, "Exactly one field must be specified to convert to union '%s'" % dst_type)
  7632. elif dst_type.is_struct and len(self.key_value_pairs) < len(dst_type.scope.var_entries):
  7633. warning(self.pos, "Not all members given for struct '%s'" % dst_type, 1)
  7634. for item in self.key_value_pairs:
  7635. if isinstance(item.key, CoerceToPyTypeNode):
  7636. item.key = item.key.arg
  7637. if not item.key.is_string_literal:
  7638. error(item.key.pos, "Invalid struct field identifier")
  7639. item.key = StringNode(item.key.pos, value="<error>")
  7640. else:
  7641. key = str(item.key.value) # converts string literals to unicode in Py3
  7642. member = dst_type.scope.lookup_here(key)
  7643. if not member:
  7644. error(item.key.pos, "struct '%s' has no field '%s'" % (dst_type, key))
  7645. else:
  7646. value = item.value
  7647. if isinstance(value, CoerceToPyTypeNode):
  7648. value = value.arg
  7649. item.value = value.coerce_to(member.type, env)
  7650. else:
  7651. self.type = error_type
  7652. error(self.pos, "Cannot interpret dict as type '%s'" % dst_type)
  7653. return self
  7654. def release_errors(self):
  7655. for err in self.obj_conversion_errors:
  7656. report_error(err)
  7657. self.obj_conversion_errors = []
  7658. gil_message = "Constructing Python dict"
  7659. def generate_evaluation_code(self, code):
  7660. # Custom method used here because key-value
  7661. # pairs are evaluated and used one at a time.
  7662. code.mark_pos(self.pos)
  7663. self.allocate_temp_result(code)
  7664. is_dict = self.type.is_pyobject
  7665. if is_dict:
  7666. self.release_errors()
  7667. code.putln(
  7668. "%s = __Pyx_PyDict_NewPresized(%d); %s" % (
  7669. self.result(),
  7670. len(self.key_value_pairs),
  7671. code.error_goto_if_null(self.result(), self.pos)))
  7672. code.put_gotref(self.py_result())
  7673. keys_seen = set()
  7674. key_type = None
  7675. needs_error_helper = False
  7676. for item in self.key_value_pairs:
  7677. item.generate_evaluation_code(code)
  7678. if is_dict:
  7679. if self.exclude_null_values:
  7680. code.putln('if (%s) {' % item.value.py_result())
  7681. key = item.key
  7682. if self.reject_duplicates:
  7683. if keys_seen is not None:
  7684. # avoid runtime 'in' checks for literals that we can do at compile time
  7685. if not key.is_string_literal:
  7686. keys_seen = None
  7687. elif key.value in keys_seen:
  7688. # FIXME: this could be a compile time error, at least in Cython code
  7689. keys_seen = None
  7690. elif key_type is not type(key.value):
  7691. if key_type is None:
  7692. key_type = type(key.value)
  7693. keys_seen.add(key.value)
  7694. else:
  7695. # different types => may not be able to compare at compile time
  7696. keys_seen = None
  7697. else:
  7698. keys_seen.add(key.value)
  7699. if keys_seen is None:
  7700. code.putln('if (unlikely(PyDict_Contains(%s, %s))) {' % (
  7701. self.result(), key.py_result()))
  7702. # currently only used in function calls
  7703. needs_error_helper = True
  7704. code.putln('__Pyx_RaiseDoubleKeywordsError("function", %s); %s' % (
  7705. key.py_result(),
  7706. code.error_goto(item.pos)))
  7707. code.putln("} else {")
  7708. code.put_error_if_neg(self.pos, "PyDict_SetItem(%s, %s, %s)" % (
  7709. self.result(),
  7710. item.key.py_result(),
  7711. item.value.py_result()))
  7712. if self.reject_duplicates and keys_seen is None:
  7713. code.putln('}')
  7714. if self.exclude_null_values:
  7715. code.putln('}')
  7716. else:
  7717. code.putln("%s.%s = %s;" % (
  7718. self.result(),
  7719. item.key.value,
  7720. item.value.result()))
  7721. item.generate_disposal_code(code)
  7722. item.free_temps(code)
  7723. if needs_error_helper:
  7724. code.globalstate.use_utility_code(
  7725. UtilityCode.load_cached("RaiseDoubleKeywords", "FunctionArguments.c"))
  7726. def annotate(self, code):
  7727. for item in self.key_value_pairs:
  7728. item.annotate(code)
  7729. class DictItemNode(ExprNode):
  7730. # Represents a single item in a DictNode
  7731. #
  7732. # key ExprNode
  7733. # value ExprNode
  7734. subexprs = ['key', 'value']
  7735. nogil_check = None # Parent DictNode takes care of it
  7736. def calculate_constant_result(self):
  7737. self.constant_result = (
  7738. self.key.constant_result, self.value.constant_result)
  7739. def analyse_types(self, env):
  7740. self.key = self.key.analyse_types(env)
  7741. self.value = self.value.analyse_types(env)
  7742. self.key = self.key.coerce_to_pyobject(env)
  7743. self.value = self.value.coerce_to_pyobject(env)
  7744. return self
  7745. def generate_evaluation_code(self, code):
  7746. self.key.generate_evaluation_code(code)
  7747. self.value.generate_evaluation_code(code)
  7748. def generate_disposal_code(self, code):
  7749. self.key.generate_disposal_code(code)
  7750. self.value.generate_disposal_code(code)
  7751. def free_temps(self, code):
  7752. self.key.free_temps(code)
  7753. self.value.free_temps(code)
  7754. def __iter__(self):
  7755. return iter([self.key, self.value])
  7756. class SortedDictKeysNode(ExprNode):
  7757. # build sorted list of dict keys, e.g. for dir()
  7758. subexprs = ['arg']
  7759. is_temp = True
  7760. def __init__(self, arg):
  7761. ExprNode.__init__(self, arg.pos, arg=arg)
  7762. self.type = Builtin.list_type
  7763. def analyse_types(self, env):
  7764. arg = self.arg.analyse_types(env)
  7765. if arg.type is Builtin.dict_type:
  7766. arg = arg.as_none_safe_node(
  7767. "'NoneType' object is not iterable")
  7768. self.arg = arg
  7769. return self
  7770. def may_be_none(self):
  7771. return False
  7772. def generate_result_code(self, code):
  7773. dict_result = self.arg.py_result()
  7774. if self.arg.type is Builtin.dict_type:
  7775. code.putln('%s = PyDict_Keys(%s); %s' % (
  7776. self.result(), dict_result,
  7777. code.error_goto_if_null(self.result(), self.pos)))
  7778. code.put_gotref(self.py_result())
  7779. else:
  7780. # originally used PyMapping_Keys() here, but that may return a tuple
  7781. code.globalstate.use_utility_code(UtilityCode.load_cached(
  7782. 'PyObjectCallMethod0', 'ObjectHandling.c'))
  7783. keys_cname = code.intern_identifier(StringEncoding.EncodedString("keys"))
  7784. code.putln('%s = __Pyx_PyObject_CallMethod0(%s, %s); %s' % (
  7785. self.result(), dict_result, keys_cname,
  7786. code.error_goto_if_null(self.result(), self.pos)))
  7787. code.put_gotref(self.py_result())
  7788. code.putln("if (unlikely(!PyList_Check(%s))) {" % self.result())
  7789. code.put_decref_set(self.result(), "PySequence_List(%s)" % self.result())
  7790. code.putln(code.error_goto_if_null(self.result(), self.pos))
  7791. code.put_gotref(self.py_result())
  7792. code.putln("}")
  7793. code.put_error_if_neg(
  7794. self.pos, 'PyList_Sort(%s)' % self.py_result())
  7795. class ModuleNameMixin(object):
  7796. def get_py_mod_name(self, code):
  7797. return code.get_py_string_const(
  7798. self.module_name, identifier=True)
  7799. def get_py_qualified_name(self, code):
  7800. return code.get_py_string_const(
  7801. self.qualname, identifier=True)
  7802. class ClassNode(ExprNode, ModuleNameMixin):
  7803. # Helper class used in the implementation of Python
  7804. # class definitions. Constructs a class object given
  7805. # a name, tuple of bases and class dictionary.
  7806. #
  7807. # name EncodedString Name of the class
  7808. # class_def_node PyClassDefNode PyClassDefNode defining this class
  7809. # doc ExprNode or None Doc string
  7810. # module_name EncodedString Name of defining module
  7811. subexprs = ['doc']
  7812. type = py_object_type
  7813. is_temp = True
  7814. def infer_type(self, env):
  7815. # TODO: could return 'type' in some cases
  7816. return py_object_type
  7817. def analyse_types(self, env):
  7818. if self.doc:
  7819. self.doc = self.doc.analyse_types(env)
  7820. self.doc = self.doc.coerce_to_pyobject(env)
  7821. env.use_utility_code(UtilityCode.load_cached("CreateClass", "ObjectHandling.c"))
  7822. return self
  7823. def may_be_none(self):
  7824. return True
  7825. gil_message = "Constructing Python class"
  7826. def generate_result_code(self, code):
  7827. class_def_node = self.class_def_node
  7828. cname = code.intern_identifier(self.name)
  7829. if self.doc:
  7830. code.put_error_if_neg(self.pos,
  7831. 'PyDict_SetItem(%s, %s, %s)' % (
  7832. class_def_node.dict.py_result(),
  7833. code.intern_identifier(
  7834. StringEncoding.EncodedString("__doc__")),
  7835. self.doc.py_result()))
  7836. py_mod_name = self.get_py_mod_name(code)
  7837. qualname = self.get_py_qualified_name(code)
  7838. code.putln(
  7839. '%s = __Pyx_CreateClass(%s, %s, %s, %s, %s); %s' % (
  7840. self.result(),
  7841. class_def_node.bases.py_result(),
  7842. class_def_node.dict.py_result(),
  7843. cname,
  7844. qualname,
  7845. py_mod_name,
  7846. code.error_goto_if_null(self.result(), self.pos)))
  7847. code.put_gotref(self.py_result())
  7848. class Py3ClassNode(ExprNode):
  7849. # Helper class used in the implementation of Python3+
  7850. # class definitions. Constructs a class object given
  7851. # a name, tuple of bases and class dictionary.
  7852. #
  7853. # name EncodedString Name of the class
  7854. # module_name EncodedString Name of defining module
  7855. # class_def_node PyClassDefNode PyClassDefNode defining this class
  7856. # calculate_metaclass bool should call CalculateMetaclass()
  7857. # allow_py2_metaclass bool should look for Py2 metaclass
  7858. subexprs = []
  7859. type = py_object_type
  7860. is_temp = True
  7861. def infer_type(self, env):
  7862. # TODO: could return 'type' in some cases
  7863. return py_object_type
  7864. def analyse_types(self, env):
  7865. return self
  7866. def may_be_none(self):
  7867. return True
  7868. gil_message = "Constructing Python class"
  7869. def generate_result_code(self, code):
  7870. code.globalstate.use_utility_code(UtilityCode.load_cached("Py3ClassCreate", "ObjectHandling.c"))
  7871. cname = code.intern_identifier(self.name)
  7872. class_def_node = self.class_def_node
  7873. mkw = class_def_node.mkw.py_result() if class_def_node.mkw else 'NULL'
  7874. if class_def_node.metaclass:
  7875. metaclass = class_def_node.metaclass.py_result()
  7876. else:
  7877. metaclass = "((PyObject*)&__Pyx_DefaultClassType)"
  7878. code.putln(
  7879. '%s = __Pyx_Py3ClassCreate(%s, %s, %s, %s, %s, %d, %d); %s' % (
  7880. self.result(),
  7881. metaclass,
  7882. cname,
  7883. class_def_node.bases.py_result(),
  7884. class_def_node.dict.py_result(),
  7885. mkw,
  7886. self.calculate_metaclass,
  7887. self.allow_py2_metaclass,
  7888. code.error_goto_if_null(self.result(), self.pos)))
  7889. code.put_gotref(self.py_result())
  7890. class PyClassMetaclassNode(ExprNode):
  7891. # Helper class holds Python3 metaclass object
  7892. #
  7893. # class_def_node PyClassDefNode PyClassDefNode defining this class
  7894. subexprs = []
  7895. def analyse_types(self, env):
  7896. self.type = py_object_type
  7897. self.is_temp = True
  7898. return self
  7899. def may_be_none(self):
  7900. return True
  7901. def generate_result_code(self, code):
  7902. bases = self.class_def_node.bases
  7903. mkw = self.class_def_node.mkw
  7904. if mkw:
  7905. code.globalstate.use_utility_code(
  7906. UtilityCode.load_cached("Py3MetaclassGet", "ObjectHandling.c"))
  7907. call = "__Pyx_Py3MetaclassGet(%s, %s)" % (
  7908. bases.result(),
  7909. mkw.result())
  7910. else:
  7911. code.globalstate.use_utility_code(
  7912. UtilityCode.load_cached("CalculateMetaclass", "ObjectHandling.c"))
  7913. call = "__Pyx_CalculateMetaclass(NULL, %s)" % (
  7914. bases.result())
  7915. code.putln(
  7916. "%s = %s; %s" % (
  7917. self.result(), call,
  7918. code.error_goto_if_null(self.result(), self.pos)))
  7919. code.put_gotref(self.py_result())
  7920. class PyClassNamespaceNode(ExprNode, ModuleNameMixin):
  7921. # Helper class holds Python3 namespace object
  7922. #
  7923. # All this are not owned by this node
  7924. # class_def_node PyClassDefNode PyClassDefNode defining this class
  7925. # doc ExprNode or None Doc string (owned)
  7926. subexprs = ['doc']
  7927. def analyse_types(self, env):
  7928. if self.doc:
  7929. self.doc = self.doc.analyse_types(env).coerce_to_pyobject(env)
  7930. self.type = py_object_type
  7931. self.is_temp = 1
  7932. return self
  7933. def may_be_none(self):
  7934. return True
  7935. def generate_result_code(self, code):
  7936. cname = code.intern_identifier(self.name)
  7937. py_mod_name = self.get_py_mod_name(code)
  7938. qualname = self.get_py_qualified_name(code)
  7939. class_def_node = self.class_def_node
  7940. null = "(PyObject *) NULL"
  7941. doc_code = self.doc.result() if self.doc else null
  7942. mkw = class_def_node.mkw.py_result() if class_def_node.mkw else null
  7943. metaclass = class_def_node.metaclass.py_result() if class_def_node.metaclass else null
  7944. code.putln(
  7945. "%s = __Pyx_Py3MetaclassPrepare(%s, %s, %s, %s, %s, %s, %s); %s" % (
  7946. self.result(),
  7947. metaclass,
  7948. class_def_node.bases.result(),
  7949. cname,
  7950. qualname,
  7951. mkw,
  7952. py_mod_name,
  7953. doc_code,
  7954. code.error_goto_if_null(self.result(), self.pos)))
  7955. code.put_gotref(self.py_result())
  7956. class ClassCellInjectorNode(ExprNode):
  7957. # Initialize CyFunction.func_classobj
  7958. is_temp = True
  7959. type = py_object_type
  7960. subexprs = []
  7961. is_active = False
  7962. def analyse_expressions(self, env):
  7963. return self
  7964. def generate_result_code(self, code):
  7965. assert self.is_active
  7966. code.putln(
  7967. '%s = PyList_New(0); %s' % (
  7968. self.result(),
  7969. code.error_goto_if_null(self.result(), self.pos)))
  7970. code.put_gotref(self.result())
  7971. def generate_injection_code(self, code, classobj_cname):
  7972. assert self.is_active
  7973. code.globalstate.use_utility_code(
  7974. UtilityCode.load_cached("CyFunctionClassCell", "CythonFunction.c"))
  7975. code.put_error_if_neg(self.pos, '__Pyx_CyFunction_InitClassCell(%s, %s)' % (
  7976. self.result(), classobj_cname))
  7977. class ClassCellNode(ExprNode):
  7978. # Class Cell for noargs super()
  7979. subexprs = []
  7980. is_temp = True
  7981. is_generator = False
  7982. type = py_object_type
  7983. def analyse_types(self, env):
  7984. return self
  7985. def generate_result_code(self, code):
  7986. if not self.is_generator:
  7987. code.putln('%s = __Pyx_CyFunction_GetClassObj(%s);' % (
  7988. self.result(),
  7989. Naming.self_cname))
  7990. else:
  7991. code.putln('%s = %s->classobj;' % (
  7992. self.result(), Naming.generator_cname))
  7993. code.putln(
  7994. 'if (!%s) { PyErr_SetString(PyExc_SystemError, '
  7995. '"super(): empty __class__ cell"); %s }' % (
  7996. self.result(),
  7997. code.error_goto(self.pos)))
  7998. code.put_incref(self.result(), py_object_type)
  7999. class PyCFunctionNode(ExprNode, ModuleNameMixin):
  8000. # Helper class used in the implementation of Python
  8001. # functions. Constructs a PyCFunction object
  8002. # from a PyMethodDef struct.
  8003. #
  8004. # pymethdef_cname string PyMethodDef structure
  8005. # self_object ExprNode or None
  8006. # binding bool
  8007. # def_node DefNode the Python function node
  8008. # module_name EncodedString Name of defining module
  8009. # code_object CodeObjectNode the PyCodeObject creator node
  8010. subexprs = ['code_object', 'defaults_tuple', 'defaults_kwdict',
  8011. 'annotations_dict']
  8012. self_object = None
  8013. code_object = None
  8014. binding = False
  8015. def_node = None
  8016. defaults = None
  8017. defaults_struct = None
  8018. defaults_pyobjects = 0
  8019. defaults_tuple = None
  8020. defaults_kwdict = None
  8021. annotations_dict = None
  8022. type = py_object_type
  8023. is_temp = 1
  8024. specialized_cpdefs = None
  8025. is_specialization = False
  8026. @classmethod
  8027. def from_defnode(cls, node, binding):
  8028. return cls(node.pos,
  8029. def_node=node,
  8030. pymethdef_cname=node.entry.pymethdef_cname,
  8031. binding=binding or node.specialized_cpdefs,
  8032. specialized_cpdefs=node.specialized_cpdefs,
  8033. code_object=CodeObjectNode(node))
  8034. def analyse_types(self, env):
  8035. if self.binding:
  8036. self.analyse_default_args(env)
  8037. return self
  8038. def analyse_default_args(self, env):
  8039. """
  8040. Handle non-literal function's default arguments.
  8041. """
  8042. nonliteral_objects = []
  8043. nonliteral_other = []
  8044. default_args = []
  8045. default_kwargs = []
  8046. annotations = []
  8047. # For global cpdef functions and def/cpdef methods in cdef classes, we must use global constants
  8048. # for default arguments to avoid the dependency on the CyFunction object as 'self' argument
  8049. # in the underlying C function. Basically, cpdef functions/methods are static C functions,
  8050. # so their optional arguments must be static, too.
  8051. # TODO: change CyFunction implementation to pass both function object and owning object for method calls
  8052. must_use_constants = env.is_c_class_scope or (self.def_node.is_wrapper and env.is_module_scope)
  8053. for arg in self.def_node.args:
  8054. if arg.default and not must_use_constants:
  8055. if not arg.default.is_literal:
  8056. arg.is_dynamic = True
  8057. if arg.type.is_pyobject:
  8058. nonliteral_objects.append(arg)
  8059. else:
  8060. nonliteral_other.append(arg)
  8061. else:
  8062. arg.default = DefaultLiteralArgNode(arg.pos, arg.default)
  8063. if arg.kw_only:
  8064. default_kwargs.append(arg)
  8065. else:
  8066. default_args.append(arg)
  8067. if arg.annotation:
  8068. arg.annotation = self.analyse_annotation(env, arg.annotation)
  8069. annotations.append((arg.pos, arg.name, arg.annotation))
  8070. for arg in (self.def_node.star_arg, self.def_node.starstar_arg):
  8071. if arg and arg.annotation:
  8072. arg.annotation = self.analyse_annotation(env, arg.annotation)
  8073. annotations.append((arg.pos, arg.name, arg.annotation))
  8074. annotation = self.def_node.return_type_annotation
  8075. if annotation:
  8076. annotation = self.analyse_annotation(env, annotation)
  8077. self.def_node.return_type_annotation = annotation
  8078. annotations.append((annotation.pos, StringEncoding.EncodedString("return"), annotation))
  8079. if nonliteral_objects or nonliteral_other:
  8080. module_scope = env.global_scope()
  8081. cname = module_scope.next_id(Naming.defaults_struct_prefix)
  8082. scope = Symtab.StructOrUnionScope(cname)
  8083. self.defaults = []
  8084. for arg in nonliteral_objects:
  8085. entry = scope.declare_var(arg.name, arg.type, None,
  8086. Naming.arg_prefix + arg.name,
  8087. allow_pyobject=True)
  8088. self.defaults.append((arg, entry))
  8089. for arg in nonliteral_other:
  8090. entry = scope.declare_var(arg.name, arg.type, None,
  8091. Naming.arg_prefix + arg.name,
  8092. allow_pyobject=False, allow_memoryview=True)
  8093. self.defaults.append((arg, entry))
  8094. entry = module_scope.declare_struct_or_union(
  8095. None, 'struct', scope, 1, None, cname=cname)
  8096. self.defaults_struct = scope
  8097. self.defaults_pyobjects = len(nonliteral_objects)
  8098. for arg, entry in self.defaults:
  8099. arg.default_value = '%s->%s' % (
  8100. Naming.dynamic_args_cname, entry.cname)
  8101. self.def_node.defaults_struct = self.defaults_struct.name
  8102. if default_args or default_kwargs:
  8103. if self.defaults_struct is None:
  8104. if default_args:
  8105. defaults_tuple = TupleNode(self.pos, args=[
  8106. arg.default for arg in default_args])
  8107. self.defaults_tuple = defaults_tuple.analyse_types(env).coerce_to_pyobject(env)
  8108. if default_kwargs:
  8109. defaults_kwdict = DictNode(self.pos, key_value_pairs=[
  8110. DictItemNode(
  8111. arg.pos,
  8112. key=IdentifierStringNode(arg.pos, value=arg.name),
  8113. value=arg.default)
  8114. for arg in default_kwargs])
  8115. self.defaults_kwdict = defaults_kwdict.analyse_types(env)
  8116. else:
  8117. if default_args:
  8118. defaults_tuple = DefaultsTupleNode(
  8119. self.pos, default_args, self.defaults_struct)
  8120. else:
  8121. defaults_tuple = NoneNode(self.pos)
  8122. if default_kwargs:
  8123. defaults_kwdict = DefaultsKwDictNode(
  8124. self.pos, default_kwargs, self.defaults_struct)
  8125. else:
  8126. defaults_kwdict = NoneNode(self.pos)
  8127. defaults_getter = Nodes.DefNode(
  8128. self.pos, args=[], star_arg=None, starstar_arg=None,
  8129. body=Nodes.ReturnStatNode(
  8130. self.pos, return_type=py_object_type,
  8131. value=TupleNode(
  8132. self.pos, args=[defaults_tuple, defaults_kwdict])),
  8133. decorators=None,
  8134. name=StringEncoding.EncodedString("__defaults__"))
  8135. # defaults getter must never live in class scopes, it's always a module function
  8136. module_scope = env.global_scope()
  8137. defaults_getter.analyse_declarations(module_scope)
  8138. defaults_getter = defaults_getter.analyse_expressions(module_scope)
  8139. defaults_getter.body = defaults_getter.body.analyse_expressions(
  8140. defaults_getter.local_scope)
  8141. defaults_getter.py_wrapper_required = False
  8142. defaults_getter.pymethdef_required = False
  8143. self.def_node.defaults_getter = defaults_getter
  8144. if annotations:
  8145. annotations_dict = DictNode(self.pos, key_value_pairs=[
  8146. DictItemNode(
  8147. pos, key=IdentifierStringNode(pos, value=name),
  8148. value=value)
  8149. for pos, name, value in annotations])
  8150. self.annotations_dict = annotations_dict.analyse_types(env)
  8151. def analyse_annotation(self, env, annotation):
  8152. if annotation is None:
  8153. return None
  8154. atype = annotation.analyse_as_type(env)
  8155. if atype is not None:
  8156. # Keep parsed types as strings as they might not be Python representable.
  8157. annotation = UnicodeNode(
  8158. annotation.pos,
  8159. value=StringEncoding.EncodedString(atype.declaration_code('', for_display=True)))
  8160. annotation = annotation.analyse_types(env)
  8161. if not annotation.type.is_pyobject:
  8162. annotation = annotation.coerce_to_pyobject(env)
  8163. return annotation
  8164. def may_be_none(self):
  8165. return False
  8166. gil_message = "Constructing Python function"
  8167. def self_result_code(self):
  8168. if self.self_object is None:
  8169. self_result = "NULL"
  8170. else:
  8171. self_result = self.self_object.py_result()
  8172. return self_result
  8173. def generate_result_code(self, code):
  8174. if self.binding:
  8175. self.generate_cyfunction_code(code)
  8176. else:
  8177. self.generate_pycfunction_code(code)
  8178. def generate_pycfunction_code(self, code):
  8179. py_mod_name = self.get_py_mod_name(code)
  8180. code.putln(
  8181. '%s = PyCFunction_NewEx(&%s, %s, %s); %s' % (
  8182. self.result(),
  8183. self.pymethdef_cname,
  8184. self.self_result_code(),
  8185. py_mod_name,
  8186. code.error_goto_if_null(self.result(), self.pos)))
  8187. code.put_gotref(self.py_result())
  8188. def generate_cyfunction_code(self, code):
  8189. if self.specialized_cpdefs:
  8190. def_node = self.specialized_cpdefs[0]
  8191. else:
  8192. def_node = self.def_node
  8193. if self.specialized_cpdefs or self.is_specialization:
  8194. code.globalstate.use_utility_code(
  8195. UtilityCode.load_cached("FusedFunction", "CythonFunction.c"))
  8196. constructor = "__pyx_FusedFunction_New"
  8197. else:
  8198. code.globalstate.use_utility_code(
  8199. UtilityCode.load_cached("CythonFunction", "CythonFunction.c"))
  8200. constructor = "__Pyx_CyFunction_New"
  8201. if self.code_object:
  8202. code_object_result = self.code_object.py_result()
  8203. else:
  8204. code_object_result = 'NULL'
  8205. flags = []
  8206. if def_node.is_staticmethod:
  8207. flags.append('__Pyx_CYFUNCTION_STATICMETHOD')
  8208. elif def_node.is_classmethod:
  8209. flags.append('__Pyx_CYFUNCTION_CLASSMETHOD')
  8210. if def_node.local_scope.parent_scope.is_c_class_scope and not def_node.entry.is_anonymous:
  8211. flags.append('__Pyx_CYFUNCTION_CCLASS')
  8212. if flags:
  8213. flags = ' | '.join(flags)
  8214. else:
  8215. flags = '0'
  8216. code.putln(
  8217. '%s = %s(&%s, %s, %s, %s, %s, %s, %s); %s' % (
  8218. self.result(),
  8219. constructor,
  8220. self.pymethdef_cname,
  8221. flags,
  8222. self.get_py_qualified_name(code),
  8223. self.self_result_code(),
  8224. self.get_py_mod_name(code),
  8225. Naming.moddict_cname,
  8226. code_object_result,
  8227. code.error_goto_if_null(self.result(), self.pos)))
  8228. code.put_gotref(self.py_result())
  8229. if def_node.requires_classobj:
  8230. assert code.pyclass_stack, "pyclass_stack is empty"
  8231. class_node = code.pyclass_stack[-1]
  8232. code.put_incref(self.py_result(), py_object_type)
  8233. code.putln(
  8234. 'PyList_Append(%s, %s);' % (
  8235. class_node.class_cell.result(),
  8236. self.result()))
  8237. code.put_giveref(self.py_result())
  8238. if self.defaults:
  8239. code.putln(
  8240. 'if (!__Pyx_CyFunction_InitDefaults(%s, sizeof(%s), %d)) %s' % (
  8241. self.result(), self.defaults_struct.name,
  8242. self.defaults_pyobjects, code.error_goto(self.pos)))
  8243. defaults = '__Pyx_CyFunction_Defaults(%s, %s)' % (
  8244. self.defaults_struct.name, self.result())
  8245. for arg, entry in self.defaults:
  8246. arg.generate_assignment_code(code, target='%s->%s' % (
  8247. defaults, entry.cname))
  8248. if self.defaults_tuple:
  8249. code.putln('__Pyx_CyFunction_SetDefaultsTuple(%s, %s);' % (
  8250. self.result(), self.defaults_tuple.py_result()))
  8251. if self.defaults_kwdict:
  8252. code.putln('__Pyx_CyFunction_SetDefaultsKwDict(%s, %s);' % (
  8253. self.result(), self.defaults_kwdict.py_result()))
  8254. if def_node.defaults_getter and not self.specialized_cpdefs:
  8255. # Fused functions do not support dynamic defaults, only their specialisations can have them for now.
  8256. code.putln('__Pyx_CyFunction_SetDefaultsGetter(%s, %s);' % (
  8257. self.result(), def_node.defaults_getter.entry.pyfunc_cname))
  8258. if self.annotations_dict:
  8259. code.putln('__Pyx_CyFunction_SetAnnotationsDict(%s, %s);' % (
  8260. self.result(), self.annotations_dict.py_result()))
  8261. class InnerFunctionNode(PyCFunctionNode):
  8262. # Special PyCFunctionNode that depends on a closure class
  8263. #
  8264. binding = True
  8265. needs_self_code = True
  8266. def self_result_code(self):
  8267. if self.needs_self_code:
  8268. return "((PyObject*)%s)" % Naming.cur_scope_cname
  8269. return "NULL"
  8270. class CodeObjectNode(ExprNode):
  8271. # Create a PyCodeObject for a CyFunction instance.
  8272. #
  8273. # def_node DefNode the Python function node
  8274. # varnames TupleNode a tuple with all local variable names
  8275. subexprs = ['varnames']
  8276. is_temp = False
  8277. result_code = None
  8278. def __init__(self, def_node):
  8279. ExprNode.__init__(self, def_node.pos, def_node=def_node)
  8280. args = list(def_node.args)
  8281. # if we have args/kwargs, then the first two in var_entries are those
  8282. local_vars = [arg for arg in def_node.local_scope.var_entries if arg.name]
  8283. self.varnames = TupleNode(
  8284. def_node.pos,
  8285. args=[IdentifierStringNode(arg.pos, value=arg.name)
  8286. for arg in args + local_vars],
  8287. is_temp=0,
  8288. is_literal=1)
  8289. def may_be_none(self):
  8290. return False
  8291. def calculate_result_code(self, code=None):
  8292. if self.result_code is None:
  8293. self.result_code = code.get_py_const(py_object_type, 'codeobj', cleanup_level=2)
  8294. return self.result_code
  8295. def generate_result_code(self, code):
  8296. if self.result_code is None:
  8297. self.result_code = code.get_py_const(py_object_type, 'codeobj', cleanup_level=2)
  8298. code = code.get_cached_constants_writer(self.result_code)
  8299. if code is None:
  8300. return # already initialised
  8301. code.mark_pos(self.pos)
  8302. func = self.def_node
  8303. func_name = code.get_py_string_const(
  8304. func.name, identifier=True, is_str=False, unicode_value=func.name)
  8305. # FIXME: better way to get the module file path at module init time? Encoding to use?
  8306. file_path = StringEncoding.bytes_literal(func.pos[0].get_filenametable_entry().encode('utf8'), 'utf8')
  8307. # XXX Use get_description() to set arcadia root relative filename
  8308. file_path = StringEncoding.bytes_literal(func.pos[0].get_description().encode('utf8'), 'utf8')
  8309. file_path_const = code.get_py_string_const(file_path, identifier=False, is_str=True)
  8310. # This combination makes CPython create a new dict for "frame.f_locals" (see GH #1836).
  8311. flags = ['CO_OPTIMIZED', 'CO_NEWLOCALS']
  8312. if self.def_node.star_arg:
  8313. flags.append('CO_VARARGS')
  8314. if self.def_node.starstar_arg:
  8315. flags.append('CO_VARKEYWORDS')
  8316. code.putln("%s = (PyObject*)__Pyx_PyCode_New(%d, %d, %d, 0, %s, %s, %s, %s, %s, %s, %s, %s, %s, %d, %s); %s" % (
  8317. self.result_code,
  8318. len(func.args) - func.num_kwonly_args, # argcount
  8319. func.num_kwonly_args, # kwonlyargcount (Py3 only)
  8320. len(self.varnames.args), # nlocals
  8321. '|'.join(flags) or '0', # flags
  8322. Naming.empty_bytes, # code
  8323. Naming.empty_tuple, # consts
  8324. Naming.empty_tuple, # names (FIXME)
  8325. self.varnames.result(), # varnames
  8326. Naming.empty_tuple, # freevars (FIXME)
  8327. Naming.empty_tuple, # cellvars (FIXME)
  8328. file_path_const, # filename
  8329. func_name, # name
  8330. self.pos[1], # firstlineno
  8331. Naming.empty_bytes, # lnotab
  8332. code.error_goto_if_null(self.result_code, self.pos),
  8333. ))
  8334. class DefaultLiteralArgNode(ExprNode):
  8335. # CyFunction's literal argument default value
  8336. #
  8337. # Evaluate literal only once.
  8338. subexprs = []
  8339. is_literal = True
  8340. is_temp = False
  8341. def __init__(self, pos, arg):
  8342. super(DefaultLiteralArgNode, self).__init__(pos)
  8343. self.arg = arg
  8344. self.type = self.arg.type
  8345. self.evaluated = False
  8346. def analyse_types(self, env):
  8347. return self
  8348. def generate_result_code(self, code):
  8349. pass
  8350. def generate_evaluation_code(self, code):
  8351. if not self.evaluated:
  8352. self.arg.generate_evaluation_code(code)
  8353. self.evaluated = True
  8354. def result(self):
  8355. return self.type.cast_code(self.arg.result())
  8356. class DefaultNonLiteralArgNode(ExprNode):
  8357. # CyFunction's non-literal argument default value
  8358. subexprs = []
  8359. def __init__(self, pos, arg, defaults_struct):
  8360. super(DefaultNonLiteralArgNode, self).__init__(pos)
  8361. self.arg = arg
  8362. self.defaults_struct = defaults_struct
  8363. def analyse_types(self, env):
  8364. self.type = self.arg.type
  8365. self.is_temp = False
  8366. return self
  8367. def generate_result_code(self, code):
  8368. pass
  8369. def result(self):
  8370. return '__Pyx_CyFunction_Defaults(%s, %s)->%s' % (
  8371. self.defaults_struct.name, Naming.self_cname,
  8372. self.defaults_struct.lookup(self.arg.name).cname)
  8373. class DefaultsTupleNode(TupleNode):
  8374. # CyFunction's __defaults__ tuple
  8375. def __init__(self, pos, defaults, defaults_struct):
  8376. args = []
  8377. for arg in defaults:
  8378. if not arg.default.is_literal:
  8379. arg = DefaultNonLiteralArgNode(pos, arg, defaults_struct)
  8380. else:
  8381. arg = arg.default
  8382. args.append(arg)
  8383. super(DefaultsTupleNode, self).__init__(pos, args=args)
  8384. def analyse_types(self, env, skip_children=False):
  8385. return super(DefaultsTupleNode, self).analyse_types(env, skip_children).coerce_to_pyobject(env)
  8386. class DefaultsKwDictNode(DictNode):
  8387. # CyFunction's __kwdefaults__ dict
  8388. def __init__(self, pos, defaults, defaults_struct):
  8389. items = []
  8390. for arg in defaults:
  8391. name = IdentifierStringNode(arg.pos, value=arg.name)
  8392. if not arg.default.is_literal:
  8393. arg = DefaultNonLiteralArgNode(pos, arg, defaults_struct)
  8394. else:
  8395. arg = arg.default
  8396. items.append(DictItemNode(arg.pos, key=name, value=arg))
  8397. super(DefaultsKwDictNode, self).__init__(pos, key_value_pairs=items)
  8398. class LambdaNode(InnerFunctionNode):
  8399. # Lambda expression node (only used as a function reference)
  8400. #
  8401. # args [CArgDeclNode] formal arguments
  8402. # star_arg PyArgDeclNode or None * argument
  8403. # starstar_arg PyArgDeclNode or None ** argument
  8404. # lambda_name string a module-globally unique lambda name
  8405. # result_expr ExprNode
  8406. # def_node DefNode the underlying function 'def' node
  8407. child_attrs = ['def_node']
  8408. name = StringEncoding.EncodedString('<lambda>')
  8409. def analyse_declarations(self, env):
  8410. self.lambda_name = self.def_node.lambda_name = env.next_id('lambda')
  8411. self.def_node.no_assignment_synthesis = True
  8412. self.def_node.pymethdef_required = True
  8413. self.def_node.analyse_declarations(env)
  8414. self.def_node.is_cyfunction = True
  8415. self.pymethdef_cname = self.def_node.entry.pymethdef_cname
  8416. env.add_lambda_def(self.def_node)
  8417. def analyse_types(self, env):
  8418. self.def_node = self.def_node.analyse_expressions(env)
  8419. return super(LambdaNode, self).analyse_types(env)
  8420. def generate_result_code(self, code):
  8421. self.def_node.generate_execution_code(code)
  8422. super(LambdaNode, self).generate_result_code(code)
  8423. class GeneratorExpressionNode(LambdaNode):
  8424. # A generator expression, e.g. (i for i in range(10))
  8425. #
  8426. # Result is a generator.
  8427. #
  8428. # loop ForStatNode the for-loop, containing a YieldExprNode
  8429. # def_node DefNode the underlying generator 'def' node
  8430. name = StringEncoding.EncodedString('genexpr')
  8431. binding = False
  8432. def analyse_declarations(self, env):
  8433. self.genexpr_name = env.next_id('genexpr')
  8434. super(GeneratorExpressionNode, self).analyse_declarations(env)
  8435. # No pymethdef required
  8436. self.def_node.pymethdef_required = False
  8437. self.def_node.py_wrapper_required = False
  8438. self.def_node.is_cyfunction = False
  8439. # Force genexpr signature
  8440. self.def_node.entry.signature = TypeSlots.pyfunction_noargs
  8441. def generate_result_code(self, code):
  8442. code.putln(
  8443. '%s = %s(%s); %s' % (
  8444. self.result(),
  8445. self.def_node.entry.pyfunc_cname,
  8446. self.self_result_code(),
  8447. code.error_goto_if_null(self.result(), self.pos)))
  8448. code.put_gotref(self.py_result())
  8449. class YieldExprNode(ExprNode):
  8450. # Yield expression node
  8451. #
  8452. # arg ExprNode the value to return from the generator
  8453. # label_num integer yield label number
  8454. # is_yield_from boolean is a YieldFromExprNode to delegate to another generator
  8455. subexprs = ['arg']
  8456. type = py_object_type
  8457. label_num = 0
  8458. is_yield_from = False
  8459. is_await = False
  8460. in_async_gen = False
  8461. expr_keyword = 'yield'
  8462. def analyse_types(self, env):
  8463. if not self.label_num or (self.is_yield_from and self.in_async_gen):
  8464. error(self.pos, "'%s' not supported here" % self.expr_keyword)
  8465. self.is_temp = 1
  8466. if self.arg is not None:
  8467. self.arg = self.arg.analyse_types(env)
  8468. if not self.arg.type.is_pyobject:
  8469. self.coerce_yield_argument(env)
  8470. return self
  8471. def coerce_yield_argument(self, env):
  8472. self.arg = self.arg.coerce_to_pyobject(env)
  8473. def generate_evaluation_code(self, code):
  8474. if self.arg:
  8475. self.arg.generate_evaluation_code(code)
  8476. self.arg.make_owned_reference(code)
  8477. code.putln(
  8478. "%s = %s;" % (
  8479. Naming.retval_cname,
  8480. self.arg.result_as(py_object_type)))
  8481. self.arg.generate_post_assignment_code(code)
  8482. self.arg.free_temps(code)
  8483. else:
  8484. code.put_init_to_py_none(Naming.retval_cname, py_object_type)
  8485. self.generate_yield_code(code)
  8486. def generate_yield_code(self, code):
  8487. """
  8488. Generate the code to return the argument in 'Naming.retval_cname'
  8489. and to continue at the yield label.
  8490. """
  8491. label_num, label_name = code.new_yield_label(
  8492. self.expr_keyword.replace(' ', '_'))
  8493. code.use_label(label_name)
  8494. saved = []
  8495. code.funcstate.closure_temps.reset()
  8496. for cname, type, manage_ref in code.funcstate.temps_in_use():
  8497. save_cname = code.funcstate.closure_temps.allocate_temp(type)
  8498. saved.append((cname, save_cname, type))
  8499. if type.is_pyobject:
  8500. code.put_xgiveref(cname)
  8501. code.putln('%s->%s = %s;' % (Naming.cur_scope_cname, save_cname, cname))
  8502. code.put_xgiveref(Naming.retval_cname)
  8503. profile = code.globalstate.directives['profile']
  8504. linetrace = code.globalstate.directives['linetrace']
  8505. if profile or linetrace:
  8506. code.put_trace_return(Naming.retval_cname,
  8507. nogil=not code.funcstate.gil_owned)
  8508. code.put_finish_refcount_context()
  8509. if code.funcstate.current_except is not None:
  8510. # inside of an except block => save away currently handled exception
  8511. code.putln("__Pyx_Coroutine_SwapException(%s);" % Naming.generator_cname)
  8512. else:
  8513. # no exceptions being handled => restore exception state of caller
  8514. code.putln("__Pyx_Coroutine_ResetAndClearException(%s);" % Naming.generator_cname)
  8515. code.putln("/* return from %sgenerator, %sing value */" % (
  8516. 'async ' if self.in_async_gen else '',
  8517. 'await' if self.is_await else 'yield'))
  8518. code.putln("%s->resume_label = %d;" % (
  8519. Naming.generator_cname, label_num))
  8520. if self.in_async_gen and not self.is_await:
  8521. # __Pyx__PyAsyncGenValueWrapperNew() steals a reference to the return value
  8522. code.putln("return __Pyx__PyAsyncGenValueWrapperNew(%s);" % Naming.retval_cname)
  8523. else:
  8524. code.putln("return %s;" % Naming.retval_cname)
  8525. code.put_label(label_name)
  8526. for cname, save_cname, type in saved:
  8527. code.putln('%s = %s->%s;' % (cname, Naming.cur_scope_cname, save_cname))
  8528. if type.is_pyobject:
  8529. code.putln('%s->%s = 0;' % (Naming.cur_scope_cname, save_cname))
  8530. code.put_xgotref(cname)
  8531. self.generate_sent_value_handling_code(code, Naming.sent_value_cname)
  8532. if self.result_is_used:
  8533. self.allocate_temp_result(code)
  8534. code.put('%s = %s; ' % (self.result(), Naming.sent_value_cname))
  8535. code.put_incref(self.result(), py_object_type)
  8536. def generate_sent_value_handling_code(self, code, value_cname):
  8537. code.putln(code.error_goto_if_null(value_cname, self.pos))
  8538. class _YieldDelegationExprNode(YieldExprNode):
  8539. def yield_from_func(self, code):
  8540. raise NotImplementedError()
  8541. def generate_evaluation_code(self, code, source_cname=None, decref_source=False):
  8542. if source_cname is None:
  8543. self.arg.generate_evaluation_code(code)
  8544. code.putln("%s = %s(%s, %s);" % (
  8545. Naming.retval_cname,
  8546. self.yield_from_func(code),
  8547. Naming.generator_cname,
  8548. self.arg.py_result() if source_cname is None else source_cname))
  8549. if source_cname is None:
  8550. self.arg.generate_disposal_code(code)
  8551. self.arg.free_temps(code)
  8552. elif decref_source:
  8553. code.put_decref_clear(source_cname, py_object_type)
  8554. code.put_xgotref(Naming.retval_cname)
  8555. code.putln("if (likely(%s)) {" % Naming.retval_cname)
  8556. self.generate_yield_code(code)
  8557. code.putln("} else {")
  8558. # either error or sub-generator has normally terminated: return value => node result
  8559. if self.result_is_used:
  8560. self.fetch_iteration_result(code)
  8561. else:
  8562. self.handle_iteration_exception(code)
  8563. code.putln("}")
  8564. def fetch_iteration_result(self, code):
  8565. # YieldExprNode has allocated the result temp for us
  8566. code.putln("%s = NULL;" % self.result())
  8567. code.put_error_if_neg(self.pos, "__Pyx_PyGen_FetchStopIterationValue(&%s)" % self.result())
  8568. code.put_gotref(self.result())
  8569. def handle_iteration_exception(self, code):
  8570. code.putln("PyObject* exc_type = __Pyx_PyErr_Occurred();")
  8571. code.putln("if (exc_type) {")
  8572. code.putln("if (likely(exc_type == PyExc_StopIteration || (exc_type != PyExc_GeneratorExit &&"
  8573. " __Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration)))) PyErr_Clear();")
  8574. code.putln("else %s" % code.error_goto(self.pos))
  8575. code.putln("}")
  8576. class YieldFromExprNode(_YieldDelegationExprNode):
  8577. # "yield from GEN" expression
  8578. is_yield_from = True
  8579. expr_keyword = 'yield from'
  8580. def coerce_yield_argument(self, env):
  8581. if not self.arg.type.is_string:
  8582. # FIXME: support C arrays and C++ iterators?
  8583. error(self.pos, "yielding from non-Python object not supported")
  8584. self.arg = self.arg.coerce_to_pyobject(env)
  8585. def yield_from_func(self, code):
  8586. code.globalstate.use_utility_code(UtilityCode.load_cached("GeneratorYieldFrom", "Coroutine.c"))
  8587. return "__Pyx_Generator_Yield_From"
  8588. class AwaitExprNode(_YieldDelegationExprNode):
  8589. # 'await' expression node
  8590. #
  8591. # arg ExprNode the Awaitable value to await
  8592. # label_num integer yield label number
  8593. is_await = True
  8594. expr_keyword = 'await'
  8595. def coerce_yield_argument(self, env):
  8596. if self.arg is not None:
  8597. # FIXME: use same check as in YieldFromExprNode.coerce_yield_argument() ?
  8598. self.arg = self.arg.coerce_to_pyobject(env)
  8599. def yield_from_func(self, code):
  8600. code.globalstate.use_utility_code(UtilityCode.load_cached("CoroutineYieldFrom", "Coroutine.c"))
  8601. return "__Pyx_Coroutine_Yield_From"
  8602. class AwaitIterNextExprNode(AwaitExprNode):
  8603. # 'await' expression node as part of 'async for' iteration
  8604. #
  8605. # Breaks out of loop on StopAsyncIteration exception.
  8606. def _generate_break(self, code):
  8607. code.globalstate.use_utility_code(UtilityCode.load_cached("StopAsyncIteration", "Coroutine.c"))
  8608. code.putln("PyObject* exc_type = __Pyx_PyErr_Occurred();")
  8609. code.putln("if (unlikely(exc_type && (exc_type == __Pyx_PyExc_StopAsyncIteration || ("
  8610. " exc_type != PyExc_StopIteration && exc_type != PyExc_GeneratorExit &&"
  8611. " __Pyx_PyErr_GivenExceptionMatches(exc_type, __Pyx_PyExc_StopAsyncIteration))))) {")
  8612. code.putln("PyErr_Clear();")
  8613. code.putln("break;")
  8614. code.putln("}")
  8615. def fetch_iteration_result(self, code):
  8616. assert code.break_label, "AwaitIterNextExprNode outside of 'async for' loop"
  8617. self._generate_break(code)
  8618. super(AwaitIterNextExprNode, self).fetch_iteration_result(code)
  8619. def generate_sent_value_handling_code(self, code, value_cname):
  8620. assert code.break_label, "AwaitIterNextExprNode outside of 'async for' loop"
  8621. code.putln("if (unlikely(!%s)) {" % value_cname)
  8622. self._generate_break(code)
  8623. # all non-break exceptions are errors, as in parent class
  8624. code.putln(code.error_goto(self.pos))
  8625. code.putln("}")
  8626. class GlobalsExprNode(AtomicExprNode):
  8627. type = dict_type
  8628. is_temp = 1
  8629. def analyse_types(self, env):
  8630. env.use_utility_code(Builtin.globals_utility_code)
  8631. return self
  8632. gil_message = "Constructing globals dict"
  8633. def may_be_none(self):
  8634. return False
  8635. def generate_result_code(self, code):
  8636. code.putln('%s = __Pyx_Globals(); %s' % (
  8637. self.result(),
  8638. code.error_goto_if_null(self.result(), self.pos)))
  8639. code.put_gotref(self.result())
  8640. class LocalsDictItemNode(DictItemNode):
  8641. def analyse_types(self, env):
  8642. self.key = self.key.analyse_types(env)
  8643. self.value = self.value.analyse_types(env)
  8644. self.key = self.key.coerce_to_pyobject(env)
  8645. if self.value.type.can_coerce_to_pyobject(env):
  8646. self.value = self.value.coerce_to_pyobject(env)
  8647. else:
  8648. self.value = None
  8649. return self
  8650. class FuncLocalsExprNode(DictNode):
  8651. def __init__(self, pos, env):
  8652. local_vars = sorted([
  8653. entry.name for entry in env.entries.values() if entry.name])
  8654. items = [LocalsDictItemNode(
  8655. pos, key=IdentifierStringNode(pos, value=var),
  8656. value=NameNode(pos, name=var, allow_null=True))
  8657. for var in local_vars]
  8658. DictNode.__init__(self, pos, key_value_pairs=items,
  8659. exclude_null_values=True)
  8660. def analyse_types(self, env):
  8661. node = super(FuncLocalsExprNode, self).analyse_types(env)
  8662. node.key_value_pairs = [ i for i in node.key_value_pairs
  8663. if i.value is not None ]
  8664. return node
  8665. class PyClassLocalsExprNode(AtomicExprNode):
  8666. def __init__(self, pos, pyclass_dict):
  8667. AtomicExprNode.__init__(self, pos)
  8668. self.pyclass_dict = pyclass_dict
  8669. def analyse_types(self, env):
  8670. self.type = self.pyclass_dict.type
  8671. self.is_temp = False
  8672. return self
  8673. def may_be_none(self):
  8674. return False
  8675. def result(self):
  8676. return self.pyclass_dict.result()
  8677. def generate_result_code(self, code):
  8678. pass
  8679. def LocalsExprNode(pos, scope_node, env):
  8680. if env.is_module_scope:
  8681. return GlobalsExprNode(pos)
  8682. if env.is_py_class_scope:
  8683. return PyClassLocalsExprNode(pos, scope_node.dict)
  8684. return FuncLocalsExprNode(pos, env)
  8685. #-------------------------------------------------------------------
  8686. #
  8687. # Unary operator nodes
  8688. #
  8689. #-------------------------------------------------------------------
  8690. compile_time_unary_operators = {
  8691. 'not': operator.not_,
  8692. '~': operator.inv,
  8693. '-': operator.neg,
  8694. '+': operator.pos,
  8695. }
  8696. class UnopNode(ExprNode):
  8697. # operator string
  8698. # operand ExprNode
  8699. #
  8700. # Processing during analyse_expressions phase:
  8701. #
  8702. # analyse_c_operation
  8703. # Called when the operand is not a pyobject.
  8704. # - Check operand type and coerce if needed.
  8705. # - Determine result type and result code fragment.
  8706. # - Allocate temporary for result if needed.
  8707. subexprs = ['operand']
  8708. infix = True
  8709. def calculate_constant_result(self):
  8710. func = compile_time_unary_operators[self.operator]
  8711. self.constant_result = func(self.operand.constant_result)
  8712. def compile_time_value(self, denv):
  8713. func = compile_time_unary_operators.get(self.operator)
  8714. if not func:
  8715. error(self.pos,
  8716. "Unary '%s' not supported in compile-time expression"
  8717. % self.operator)
  8718. operand = self.operand.compile_time_value(denv)
  8719. try:
  8720. return func(operand)
  8721. except Exception as e:
  8722. self.compile_time_value_error(e)
  8723. def infer_type(self, env):
  8724. operand_type = self.operand.infer_type(env)
  8725. if operand_type.is_cpp_class or operand_type.is_ptr:
  8726. cpp_type = operand_type.find_cpp_operation_type(self.operator)
  8727. if cpp_type is not None:
  8728. return cpp_type
  8729. return self.infer_unop_type(env, operand_type)
  8730. def infer_unop_type(self, env, operand_type):
  8731. if operand_type.is_pyobject:
  8732. return py_object_type
  8733. else:
  8734. return operand_type
  8735. def may_be_none(self):
  8736. if self.operand.type and self.operand.type.is_builtin_type:
  8737. if self.operand.type is not type_type:
  8738. return False
  8739. return ExprNode.may_be_none(self)
  8740. def analyse_types(self, env):
  8741. self.operand = self.operand.analyse_types(env)
  8742. if self.is_pythran_operation(env):
  8743. self.type = PythranExpr(pythran_unaryop_type(self.operator, self.operand.type))
  8744. self.is_temp = 1
  8745. elif self.is_py_operation():
  8746. self.coerce_operand_to_pyobject(env)
  8747. self.type = py_object_type
  8748. self.is_temp = 1
  8749. elif self.is_cpp_operation():
  8750. self.analyse_cpp_operation(env)
  8751. else:
  8752. self.analyse_c_operation(env)
  8753. return self
  8754. def check_const(self):
  8755. return self.operand.check_const()
  8756. def is_py_operation(self):
  8757. return self.operand.type.is_pyobject or self.operand.type.is_ctuple
  8758. def is_pythran_operation(self, env):
  8759. np_pythran = has_np_pythran(env)
  8760. op_type = self.operand.type
  8761. return np_pythran and (op_type.is_buffer or op_type.is_pythran_expr)
  8762. def nogil_check(self, env):
  8763. if self.is_py_operation():
  8764. self.gil_error()
  8765. def is_cpp_operation(self):
  8766. type = self.operand.type
  8767. return type.is_cpp_class
  8768. def coerce_operand_to_pyobject(self, env):
  8769. self.operand = self.operand.coerce_to_pyobject(env)
  8770. def generate_result_code(self, code):
  8771. if self.type.is_pythran_expr:
  8772. code.putln("// Pythran unaryop")
  8773. code.putln("__Pyx_call_destructor(%s);" % self.result())
  8774. code.putln("new (&%s) decltype(%s){%s%s};" % (
  8775. self.result(),
  8776. self.result(),
  8777. self.operator,
  8778. self.operand.pythran_result()))
  8779. elif self.operand.type.is_pyobject:
  8780. self.generate_py_operation_code(code)
  8781. elif self.is_temp:
  8782. if self.is_cpp_operation() and self.exception_check == '+':
  8783. translate_cpp_exception(code, self.pos,
  8784. "%s = %s %s;" % (self.result(), self.operator, self.operand.result()),
  8785. self.result() if self.type.is_pyobject else None,
  8786. self.exception_value, self.in_nogil_context)
  8787. else:
  8788. code.putln("%s = %s %s;" % (self.result(), self.operator, self.operand.result()))
  8789. def generate_py_operation_code(self, code):
  8790. function = self.py_operation_function(code)
  8791. code.putln(
  8792. "%s = %s(%s); %s" % (
  8793. self.result(),
  8794. function,
  8795. self.operand.py_result(),
  8796. code.error_goto_if_null(self.result(), self.pos)))
  8797. code.put_gotref(self.py_result())
  8798. def type_error(self):
  8799. if not self.operand.type.is_error:
  8800. error(self.pos, "Invalid operand type for '%s' (%s)" %
  8801. (self.operator, self.operand.type))
  8802. self.type = PyrexTypes.error_type
  8803. def analyse_cpp_operation(self, env, overload_check=True):
  8804. entry = env.lookup_operator(self.operator, [self.operand])
  8805. if overload_check and not entry:
  8806. self.type_error()
  8807. return
  8808. if entry:
  8809. self.exception_check = entry.type.exception_check
  8810. self.exception_value = entry.type.exception_value
  8811. if self.exception_check == '+':
  8812. self.is_temp = True
  8813. if self.exception_value is None:
  8814. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  8815. else:
  8816. self.exception_check = ''
  8817. self.exception_value = ''
  8818. cpp_type = self.operand.type.find_cpp_operation_type(self.operator)
  8819. if overload_check and cpp_type is None:
  8820. error(self.pos, "'%s' operator not defined for %s" % (
  8821. self.operator, type))
  8822. self.type_error()
  8823. return
  8824. self.type = cpp_type
  8825. class NotNode(UnopNode):
  8826. # 'not' operator
  8827. #
  8828. # operand ExprNode
  8829. operator = '!'
  8830. type = PyrexTypes.c_bint_type
  8831. def calculate_constant_result(self):
  8832. self.constant_result = not self.operand.constant_result
  8833. def compile_time_value(self, denv):
  8834. operand = self.operand.compile_time_value(denv)
  8835. try:
  8836. return not operand
  8837. except Exception as e:
  8838. self.compile_time_value_error(e)
  8839. def infer_unop_type(self, env, operand_type):
  8840. return PyrexTypes.c_bint_type
  8841. def analyse_types(self, env):
  8842. self.operand = self.operand.analyse_types(env)
  8843. operand_type = self.operand.type
  8844. if operand_type.is_cpp_class:
  8845. self.analyse_cpp_operation(env)
  8846. else:
  8847. self.operand = self.operand.coerce_to_boolean(env)
  8848. return self
  8849. def calculate_result_code(self):
  8850. return "(!%s)" % self.operand.result()
  8851. class UnaryPlusNode(UnopNode):
  8852. # unary '+' operator
  8853. operator = '+'
  8854. def analyse_c_operation(self, env):
  8855. self.type = PyrexTypes.widest_numeric_type(
  8856. self.operand.type, PyrexTypes.c_int_type)
  8857. def py_operation_function(self, code):
  8858. return "PyNumber_Positive"
  8859. def calculate_result_code(self):
  8860. if self.is_cpp_operation():
  8861. return "(+%s)" % self.operand.result()
  8862. else:
  8863. return self.operand.result()
  8864. class UnaryMinusNode(UnopNode):
  8865. # unary '-' operator
  8866. operator = '-'
  8867. def analyse_c_operation(self, env):
  8868. if self.operand.type.is_numeric:
  8869. self.type = PyrexTypes.widest_numeric_type(
  8870. self.operand.type, PyrexTypes.c_int_type)
  8871. elif self.operand.type.is_enum:
  8872. self.type = PyrexTypes.c_int_type
  8873. else:
  8874. self.type_error()
  8875. if self.type.is_complex:
  8876. self.infix = False
  8877. def py_operation_function(self, code):
  8878. return "PyNumber_Negative"
  8879. def calculate_result_code(self):
  8880. if self.infix:
  8881. return "(-%s)" % self.operand.result()
  8882. else:
  8883. return "%s(%s)" % (self.operand.type.unary_op('-'), self.operand.result())
  8884. def get_constant_c_result_code(self):
  8885. value = self.operand.get_constant_c_result_code()
  8886. if value:
  8887. return "(-%s)" % value
  8888. class TildeNode(UnopNode):
  8889. # unary '~' operator
  8890. def analyse_c_operation(self, env):
  8891. if self.operand.type.is_int:
  8892. self.type = PyrexTypes.widest_numeric_type(
  8893. self.operand.type, PyrexTypes.c_int_type)
  8894. elif self.operand.type.is_enum:
  8895. self.type = PyrexTypes.c_int_type
  8896. else:
  8897. self.type_error()
  8898. def py_operation_function(self, code):
  8899. return "PyNumber_Invert"
  8900. def calculate_result_code(self):
  8901. return "(~%s)" % self.operand.result()
  8902. class CUnopNode(UnopNode):
  8903. def is_py_operation(self):
  8904. return False
  8905. class DereferenceNode(CUnopNode):
  8906. # unary * operator
  8907. operator = '*'
  8908. def infer_unop_type(self, env, operand_type):
  8909. if operand_type.is_ptr:
  8910. return operand_type.base_type
  8911. else:
  8912. return PyrexTypes.error_type
  8913. def analyse_c_operation(self, env):
  8914. if self.operand.type.is_ptr:
  8915. self.type = self.operand.type.base_type
  8916. else:
  8917. self.type_error()
  8918. def calculate_result_code(self):
  8919. return "(*%s)" % self.operand.result()
  8920. class DecrementIncrementNode(CUnopNode):
  8921. # unary ++/-- operator
  8922. def analyse_c_operation(self, env):
  8923. if self.operand.type.is_numeric:
  8924. self.type = PyrexTypes.widest_numeric_type(
  8925. self.operand.type, PyrexTypes.c_int_type)
  8926. elif self.operand.type.is_ptr:
  8927. self.type = self.operand.type
  8928. else:
  8929. self.type_error()
  8930. def calculate_result_code(self):
  8931. if self.is_prefix:
  8932. return "(%s%s)" % (self.operator, self.operand.result())
  8933. else:
  8934. return "(%s%s)" % (self.operand.result(), self.operator)
  8935. def inc_dec_constructor(is_prefix, operator):
  8936. return lambda pos, **kwds: DecrementIncrementNode(pos, is_prefix=is_prefix, operator=operator, **kwds)
  8937. class AmpersandNode(CUnopNode):
  8938. # The C address-of operator.
  8939. #
  8940. # operand ExprNode
  8941. operator = '&'
  8942. def infer_unop_type(self, env, operand_type):
  8943. return PyrexTypes.c_ptr_type(operand_type)
  8944. def analyse_types(self, env):
  8945. self.operand = self.operand.analyse_types(env)
  8946. argtype = self.operand.type
  8947. if argtype.is_cpp_class:
  8948. self.analyse_cpp_operation(env, overload_check=False)
  8949. if not (argtype.is_cfunction or argtype.is_reference or self.operand.is_addressable()):
  8950. if argtype.is_memoryviewslice:
  8951. self.error("Cannot take address of memoryview slice")
  8952. else:
  8953. self.error("Taking address of non-lvalue (type %s)" % argtype)
  8954. return self
  8955. if argtype.is_pyobject:
  8956. self.error("Cannot take address of Python %s" % (
  8957. "variable '%s'" % self.operand.name if self.operand.is_name else
  8958. "object attribute '%s'" % self.operand.attribute if self.operand.is_attribute else
  8959. "object"))
  8960. return self
  8961. if not argtype.is_cpp_class or not self.type:
  8962. self.type = PyrexTypes.c_ptr_type(argtype)
  8963. return self
  8964. def check_const(self):
  8965. return self.operand.check_const_addr()
  8966. def error(self, mess):
  8967. error(self.pos, mess)
  8968. self.type = PyrexTypes.error_type
  8969. self.result_code = "<error>"
  8970. def calculate_result_code(self):
  8971. return "(&%s)" % self.operand.result()
  8972. def generate_result_code(self, code):
  8973. if (self.operand.type.is_cpp_class and self.exception_check == '+'):
  8974. translate_cpp_exception(code, self.pos,
  8975. "%s = %s %s;" % (self.result(), self.operator, self.operand.result()),
  8976. self.result() if self.type.is_pyobject else None,
  8977. self.exception_value, self.in_nogil_context)
  8978. unop_node_classes = {
  8979. "+": UnaryPlusNode,
  8980. "-": UnaryMinusNode,
  8981. "~": TildeNode,
  8982. }
  8983. def unop_node(pos, operator, operand):
  8984. # Construct unnop node of appropriate class for
  8985. # given operator.
  8986. if isinstance(operand, IntNode) and operator == '-':
  8987. return IntNode(pos = operand.pos, value = str(-Utils.str_to_number(operand.value)),
  8988. longness=operand.longness, unsigned=operand.unsigned)
  8989. elif isinstance(operand, UnopNode) and operand.operator == operator in '+-':
  8990. warning(pos, "Python has no increment/decrement operator: %s%sx == %s(%sx) == x" % ((operator,)*4), 5)
  8991. return unop_node_classes[operator](pos,
  8992. operator = operator,
  8993. operand = operand)
  8994. class TypecastNode(ExprNode):
  8995. # C type cast
  8996. #
  8997. # operand ExprNode
  8998. # base_type CBaseTypeNode
  8999. # declarator CDeclaratorNode
  9000. # typecheck boolean
  9001. #
  9002. # If used from a transform, one can if wanted specify the attribute
  9003. # "type" directly and leave base_type and declarator to None
  9004. subexprs = ['operand']
  9005. base_type = declarator = type = None
  9006. def type_dependencies(self, env):
  9007. return ()
  9008. def infer_type(self, env):
  9009. if self.type is None:
  9010. base_type = self.base_type.analyse(env)
  9011. _, self.type = self.declarator.analyse(base_type, env)
  9012. return self.type
  9013. def analyse_types(self, env):
  9014. if self.type is None:
  9015. base_type = self.base_type.analyse(env)
  9016. _, self.type = self.declarator.analyse(base_type, env)
  9017. if self.operand.has_constant_result():
  9018. # Must be done after self.type is resolved.
  9019. self.calculate_constant_result()
  9020. if self.type.is_cfunction:
  9021. error(self.pos,
  9022. "Cannot cast to a function type")
  9023. self.type = PyrexTypes.error_type
  9024. self.operand = self.operand.analyse_types(env)
  9025. if self.type is PyrexTypes.c_bint_type:
  9026. # short circuit this to a coercion
  9027. return self.operand.coerce_to_boolean(env)
  9028. to_py = self.type.is_pyobject
  9029. from_py = self.operand.type.is_pyobject
  9030. if from_py and not to_py and self.operand.is_ephemeral():
  9031. if not self.type.is_numeric and not self.type.is_cpp_class:
  9032. error(self.pos, "Casting temporary Python object to non-numeric non-Python type")
  9033. if to_py and not from_py:
  9034. if self.type is bytes_type and self.operand.type.is_int:
  9035. return CoerceIntToBytesNode(self.operand, env)
  9036. elif self.operand.type.can_coerce_to_pyobject(env):
  9037. self.result_ctype = py_object_type
  9038. self.operand = self.operand.coerce_to(self.type, env)
  9039. else:
  9040. if self.operand.type.is_ptr:
  9041. if not (self.operand.type.base_type.is_void or self.operand.type.base_type.is_struct):
  9042. error(self.pos, "Python objects cannot be cast from pointers of primitive types")
  9043. else:
  9044. # Should this be an error?
  9045. warning(self.pos, "No conversion from %s to %s, python object pointer used." % (
  9046. self.operand.type, self.type))
  9047. self.operand = self.operand.coerce_to_simple(env)
  9048. elif from_py and not to_py:
  9049. if self.type.create_from_py_utility_code(env):
  9050. self.operand = self.operand.coerce_to(self.type, env)
  9051. elif self.type.is_ptr:
  9052. if not (self.type.base_type.is_void or self.type.base_type.is_struct):
  9053. error(self.pos, "Python objects cannot be cast to pointers of primitive types")
  9054. else:
  9055. warning(self.pos, "No conversion from %s to %s, python object pointer used." % (
  9056. self.type, self.operand.type))
  9057. elif from_py and to_py:
  9058. if self.typecheck:
  9059. self.operand = PyTypeTestNode(self.operand, self.type, env, notnone=True)
  9060. elif isinstance(self.operand, SliceIndexNode):
  9061. # This cast can influence the created type of string slices.
  9062. self.operand = self.operand.coerce_to(self.type, env)
  9063. elif self.type.is_complex and self.operand.type.is_complex:
  9064. self.operand = self.operand.coerce_to_simple(env)
  9065. elif self.operand.type.is_fused:
  9066. self.operand = self.operand.coerce_to(self.type, env)
  9067. #self.type = self.operand.type
  9068. if self.type.is_ptr and self.type.base_type.is_cfunction and self.type.base_type.nogil:
  9069. op_type = self.operand.type
  9070. if op_type.is_ptr:
  9071. op_type = op_type.base_type
  9072. if op_type.is_cfunction and not op_type.nogil:
  9073. warning(self.pos,
  9074. "Casting a GIL-requiring function into a nogil function circumvents GIL validation", 1)
  9075. return self
  9076. def is_simple(self):
  9077. # either temp or a C cast => no side effects other than the operand's
  9078. return self.operand.is_simple()
  9079. def is_ephemeral(self):
  9080. # either temp or a C cast => no side effects other than the operand's
  9081. return self.operand.is_ephemeral()
  9082. def nonlocally_immutable(self):
  9083. return self.is_temp or self.operand.nonlocally_immutable()
  9084. def nogil_check(self, env):
  9085. if self.type and self.type.is_pyobject and self.is_temp:
  9086. self.gil_error()
  9087. def check_const(self):
  9088. return self.operand.check_const()
  9089. def calculate_constant_result(self):
  9090. self.constant_result = self.calculate_result_code(self.operand.constant_result)
  9091. def calculate_result_code(self, operand_result = None):
  9092. if operand_result is None:
  9093. operand_result = self.operand.result()
  9094. if self.type.is_complex:
  9095. operand_result = self.operand.result()
  9096. if self.operand.type.is_complex:
  9097. real_part = self.type.real_type.cast_code("__Pyx_CREAL(%s)" % operand_result)
  9098. imag_part = self.type.real_type.cast_code("__Pyx_CIMAG(%s)" % operand_result)
  9099. else:
  9100. real_part = self.type.real_type.cast_code(operand_result)
  9101. imag_part = "0"
  9102. return "%s(%s, %s)" % (
  9103. self.type.from_parts,
  9104. real_part,
  9105. imag_part)
  9106. else:
  9107. return self.type.cast_code(operand_result)
  9108. def get_constant_c_result_code(self):
  9109. operand_result = self.operand.get_constant_c_result_code()
  9110. if operand_result:
  9111. return self.type.cast_code(operand_result)
  9112. def result_as(self, type):
  9113. if self.type.is_pyobject and not self.is_temp:
  9114. # Optimise away some unnecessary casting
  9115. return self.operand.result_as(type)
  9116. else:
  9117. return ExprNode.result_as(self, type)
  9118. def generate_result_code(self, code):
  9119. if self.is_temp:
  9120. code.putln(
  9121. "%s = (PyObject *)%s;" % (
  9122. self.result(),
  9123. self.operand.result()))
  9124. code.put_incref(self.result(), self.ctype())
  9125. ERR_START = "Start may not be given"
  9126. ERR_NOT_STOP = "Stop must be provided to indicate shape"
  9127. ERR_STEPS = ("Strides may only be given to indicate contiguity. "
  9128. "Consider slicing it after conversion")
  9129. ERR_NOT_POINTER = "Can only create cython.array from pointer or array"
  9130. ERR_BASE_TYPE = "Pointer base type does not match cython.array base type"
  9131. class CythonArrayNode(ExprNode):
  9132. """
  9133. Used when a pointer of base_type is cast to a memoryviewslice with that
  9134. base type. i.e.
  9135. <int[:M:1, :N]> p
  9136. creates a fortran-contiguous cython.array.
  9137. We leave the type set to object so coercions to object are more efficient
  9138. and less work. Acquiring a memoryviewslice from this will be just as
  9139. efficient. ExprNode.coerce_to() will do the additional typecheck on
  9140. self.compile_time_type
  9141. This also handles <int[:, :]> my_c_array
  9142. operand ExprNode the thing we're casting
  9143. base_type_node MemoryViewSliceTypeNode the cast expression node
  9144. """
  9145. subexprs = ['operand', 'shapes']
  9146. shapes = None
  9147. is_temp = True
  9148. mode = "c"
  9149. array_dtype = None
  9150. shape_type = PyrexTypes.c_py_ssize_t_type
  9151. def analyse_types(self, env):
  9152. from . import MemoryView
  9153. self.operand = self.operand.analyse_types(env)
  9154. if self.array_dtype:
  9155. array_dtype = self.array_dtype
  9156. else:
  9157. array_dtype = self.base_type_node.base_type_node.analyse(env)
  9158. axes = self.base_type_node.axes
  9159. self.type = error_type
  9160. self.shapes = []
  9161. ndim = len(axes)
  9162. # Base type of the pointer or C array we are converting
  9163. base_type = self.operand.type
  9164. if not self.operand.type.is_ptr and not self.operand.type.is_array:
  9165. error(self.operand.pos, ERR_NOT_POINTER)
  9166. return self
  9167. # Dimension sizes of C array
  9168. array_dimension_sizes = []
  9169. if base_type.is_array:
  9170. while base_type.is_array:
  9171. array_dimension_sizes.append(base_type.size)
  9172. base_type = base_type.base_type
  9173. elif base_type.is_ptr:
  9174. base_type = base_type.base_type
  9175. else:
  9176. error(self.pos, "unexpected base type %s found" % base_type)
  9177. return self
  9178. if not (base_type.same_as(array_dtype) or base_type.is_void):
  9179. error(self.operand.pos, ERR_BASE_TYPE)
  9180. return self
  9181. elif self.operand.type.is_array and len(array_dimension_sizes) != ndim:
  9182. error(self.operand.pos,
  9183. "Expected %d dimensions, array has %d dimensions" %
  9184. (ndim, len(array_dimension_sizes)))
  9185. return self
  9186. # Verify the start, stop and step values
  9187. # In case of a C array, use the size of C array in each dimension to
  9188. # get an automatic cast
  9189. for axis_no, axis in enumerate(axes):
  9190. if not axis.start.is_none:
  9191. error(axis.start.pos, ERR_START)
  9192. return self
  9193. if axis.stop.is_none:
  9194. if array_dimension_sizes:
  9195. dimsize = array_dimension_sizes[axis_no]
  9196. axis.stop = IntNode(self.pos, value=str(dimsize),
  9197. constant_result=dimsize,
  9198. type=PyrexTypes.c_int_type)
  9199. else:
  9200. error(axis.pos, ERR_NOT_STOP)
  9201. return self
  9202. axis.stop = axis.stop.analyse_types(env)
  9203. shape = axis.stop.coerce_to(self.shape_type, env)
  9204. if not shape.is_literal:
  9205. shape.coerce_to_temp(env)
  9206. self.shapes.append(shape)
  9207. first_or_last = axis_no in (0, ndim - 1)
  9208. if not axis.step.is_none and first_or_last:
  9209. # '1' in the first or last dimension denotes F or C contiguity
  9210. axis.step = axis.step.analyse_types(env)
  9211. if (not axis.step.type.is_int and axis.step.is_literal and not
  9212. axis.step.type.is_error):
  9213. error(axis.step.pos, "Expected an integer literal")
  9214. return self
  9215. if axis.step.compile_time_value(env) != 1:
  9216. error(axis.step.pos, ERR_STEPS)
  9217. return self
  9218. if axis_no == 0:
  9219. self.mode = "fortran"
  9220. elif not axis.step.is_none and not first_or_last:
  9221. # step provided in some other dimension
  9222. error(axis.step.pos, ERR_STEPS)
  9223. return self
  9224. if not self.operand.is_name:
  9225. self.operand = self.operand.coerce_to_temp(env)
  9226. axes = [('direct', 'follow')] * len(axes)
  9227. if self.mode == "fortran":
  9228. axes[0] = ('direct', 'contig')
  9229. else:
  9230. axes[-1] = ('direct', 'contig')
  9231. self.coercion_type = PyrexTypes.MemoryViewSliceType(array_dtype, axes)
  9232. self.coercion_type.validate_memslice_dtype(self.pos)
  9233. self.type = self.get_cython_array_type(env)
  9234. MemoryView.use_cython_array_utility_code(env)
  9235. env.use_utility_code(MemoryView.typeinfo_to_format_code)
  9236. return self
  9237. def allocate_temp_result(self, code):
  9238. if self.temp_code:
  9239. raise RuntimeError("temp allocated multiple times")
  9240. self.temp_code = code.funcstate.allocate_temp(self.type, True)
  9241. def infer_type(self, env):
  9242. return self.get_cython_array_type(env)
  9243. def get_cython_array_type(self, env):
  9244. cython_scope = env.global_scope().context.cython_scope
  9245. cython_scope.load_cythonscope()
  9246. return cython_scope.viewscope.lookup("array").type
  9247. def generate_result_code(self, code):
  9248. from . import Buffer
  9249. shapes = [self.shape_type.cast_code(shape.result())
  9250. for shape in self.shapes]
  9251. dtype = self.coercion_type.dtype
  9252. shapes_temp = code.funcstate.allocate_temp(py_object_type, True)
  9253. format_temp = code.funcstate.allocate_temp(py_object_type, True)
  9254. itemsize = "sizeof(%s)" % dtype.empty_declaration_code()
  9255. type_info = Buffer.get_type_information_cname(code, dtype)
  9256. if self.operand.type.is_ptr:
  9257. code.putln("if (!%s) {" % self.operand.result())
  9258. code.putln( 'PyErr_SetString(PyExc_ValueError,'
  9259. '"Cannot create cython.array from NULL pointer");')
  9260. code.putln(code.error_goto(self.operand.pos))
  9261. code.putln("}")
  9262. code.putln("%s = __pyx_format_from_typeinfo(&%s); %s" % (
  9263. format_temp,
  9264. type_info,
  9265. code.error_goto_if_null(format_temp, self.pos),
  9266. ))
  9267. code.put_gotref(format_temp)
  9268. buildvalue_fmt = " __PYX_BUILD_PY_SSIZE_T " * len(shapes)
  9269. code.putln('%s = Py_BuildValue((char*) "(" %s ")", %s); %s' % (
  9270. shapes_temp,
  9271. buildvalue_fmt,
  9272. ", ".join(shapes),
  9273. code.error_goto_if_null(shapes_temp, self.pos),
  9274. ))
  9275. code.put_gotref(shapes_temp)
  9276. tup = (self.result(), shapes_temp, itemsize, format_temp,
  9277. self.mode, self.operand.result())
  9278. code.putln('%s = __pyx_array_new('
  9279. '%s, %s, PyBytes_AS_STRING(%s), '
  9280. '(char *) "%s", (char *) %s);' % tup)
  9281. code.putln(code.error_goto_if_null(self.result(), self.pos))
  9282. code.put_gotref(self.result())
  9283. def dispose(temp):
  9284. code.put_decref_clear(temp, py_object_type)
  9285. code.funcstate.release_temp(temp)
  9286. dispose(shapes_temp)
  9287. dispose(format_temp)
  9288. @classmethod
  9289. def from_carray(cls, src_node, env):
  9290. """
  9291. Given a C array type, return a CythonArrayNode
  9292. """
  9293. pos = src_node.pos
  9294. base_type = src_node.type
  9295. none_node = NoneNode(pos)
  9296. axes = []
  9297. while base_type.is_array:
  9298. axes.append(SliceNode(pos, start=none_node, stop=none_node,
  9299. step=none_node))
  9300. base_type = base_type.base_type
  9301. axes[-1].step = IntNode(pos, value="1", is_c_literal=True)
  9302. memslicenode = Nodes.MemoryViewSliceTypeNode(pos, axes=axes,
  9303. base_type_node=base_type)
  9304. result = CythonArrayNode(pos, base_type_node=memslicenode,
  9305. operand=src_node, array_dtype=base_type)
  9306. result = result.analyse_types(env)
  9307. return result
  9308. class SizeofNode(ExprNode):
  9309. # Abstract base class for sizeof(x) expression nodes.
  9310. type = PyrexTypes.c_size_t_type
  9311. def check_const(self):
  9312. return True
  9313. def generate_result_code(self, code):
  9314. pass
  9315. class SizeofTypeNode(SizeofNode):
  9316. # C sizeof function applied to a type
  9317. #
  9318. # base_type CBaseTypeNode
  9319. # declarator CDeclaratorNode
  9320. subexprs = []
  9321. arg_type = None
  9322. def analyse_types(self, env):
  9323. # we may have incorrectly interpreted a dotted name as a type rather than an attribute
  9324. # this could be better handled by more uniformly treating types as runtime-available objects
  9325. if 0 and self.base_type.module_path:
  9326. path = self.base_type.module_path
  9327. obj = env.lookup(path[0])
  9328. if obj.as_module is None:
  9329. operand = NameNode(pos=self.pos, name=path[0])
  9330. for attr in path[1:]:
  9331. operand = AttributeNode(pos=self.pos, obj=operand, attribute=attr)
  9332. operand = AttributeNode(pos=self.pos, obj=operand, attribute=self.base_type.name)
  9333. node = SizeofVarNode(self.pos, operand=operand).analyse_types(env)
  9334. return node
  9335. if self.arg_type is None:
  9336. base_type = self.base_type.analyse(env)
  9337. _, arg_type = self.declarator.analyse(base_type, env)
  9338. self.arg_type = arg_type
  9339. self.check_type()
  9340. return self
  9341. def check_type(self):
  9342. arg_type = self.arg_type
  9343. if not arg_type:
  9344. return
  9345. if arg_type.is_pyobject and not arg_type.is_extension_type:
  9346. error(self.pos, "Cannot take sizeof Python object")
  9347. elif arg_type.is_void:
  9348. error(self.pos, "Cannot take sizeof void")
  9349. elif not arg_type.is_complete():
  9350. error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
  9351. def calculate_result_code(self):
  9352. if self.arg_type.is_extension_type:
  9353. # the size of the pointer is boring
  9354. # we want the size of the actual struct
  9355. arg_code = self.arg_type.declaration_code("", deref=1)
  9356. else:
  9357. arg_code = self.arg_type.empty_declaration_code()
  9358. return "(sizeof(%s))" % arg_code
  9359. class SizeofVarNode(SizeofNode):
  9360. # C sizeof function applied to a variable
  9361. #
  9362. # operand ExprNode
  9363. subexprs = ['operand']
  9364. def analyse_types(self, env):
  9365. # We may actually be looking at a type rather than a variable...
  9366. # If we are, traditional analysis would fail...
  9367. operand_as_type = self.operand.analyse_as_type(env)
  9368. if operand_as_type:
  9369. self.arg_type = operand_as_type
  9370. if self.arg_type.is_fused:
  9371. self.arg_type = self.arg_type.specialize(env.fused_to_specific)
  9372. self.__class__ = SizeofTypeNode
  9373. self.check_type()
  9374. else:
  9375. self.operand = self.operand.analyse_types(env)
  9376. return self
  9377. def calculate_result_code(self):
  9378. return "(sizeof(%s))" % self.operand.result()
  9379. def generate_result_code(self, code):
  9380. pass
  9381. class TypeidNode(ExprNode):
  9382. # C++ typeid operator applied to a type or variable
  9383. #
  9384. # operand ExprNode
  9385. # arg_type ExprNode
  9386. # is_variable boolean
  9387. type = PyrexTypes.error_type
  9388. subexprs = ['operand']
  9389. arg_type = None
  9390. is_variable = None
  9391. is_temp = 1
  9392. def get_type_info_type(self, env):
  9393. env_module = env
  9394. while not env_module.is_module_scope:
  9395. env_module = env_module.outer_scope
  9396. typeinfo_module = env_module.find_module('libcpp.typeinfo', self.pos)
  9397. typeinfo_entry = typeinfo_module.lookup('type_info')
  9398. return PyrexTypes.CFakeReferenceType(PyrexTypes.c_const_type(typeinfo_entry.type))
  9399. cpp_message = 'typeid operator'
  9400. def analyse_types(self, env):
  9401. self.cpp_check(env)
  9402. type_info = self.get_type_info_type(env)
  9403. if not type_info:
  9404. self.error("The 'libcpp.typeinfo' module must be cimported to use the typeid() operator")
  9405. return self
  9406. self.type = type_info
  9407. as_type = self.operand.analyse_as_type(env)
  9408. if as_type:
  9409. self.arg_type = as_type
  9410. self.is_type = True
  9411. else:
  9412. self.arg_type = self.operand.analyse_types(env)
  9413. self.is_type = False
  9414. if self.arg_type.type.is_pyobject:
  9415. self.error("Cannot use typeid on a Python object")
  9416. return self
  9417. elif self.arg_type.type.is_void:
  9418. self.error("Cannot use typeid on void")
  9419. return self
  9420. elif not self.arg_type.type.is_complete():
  9421. self.error("Cannot use typeid on incomplete type '%s'" % self.arg_type.type)
  9422. return self
  9423. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  9424. return self
  9425. def error(self, mess):
  9426. error(self.pos, mess)
  9427. self.type = PyrexTypes.error_type
  9428. self.result_code = "<error>"
  9429. def check_const(self):
  9430. return True
  9431. def calculate_result_code(self):
  9432. return self.temp_code
  9433. def generate_result_code(self, code):
  9434. if self.is_type:
  9435. arg_code = self.arg_type.empty_declaration_code()
  9436. else:
  9437. arg_code = self.arg_type.result()
  9438. translate_cpp_exception(code, self.pos,
  9439. "%s = typeid(%s);" % (self.temp_code, arg_code),
  9440. None, None, self.in_nogil_context)
  9441. class TypeofNode(ExprNode):
  9442. # Compile-time type of an expression, as a string.
  9443. #
  9444. # operand ExprNode
  9445. # literal StringNode # internal
  9446. literal = None
  9447. type = py_object_type
  9448. subexprs = ['literal'] # 'operand' will be ignored after type analysis!
  9449. def analyse_types(self, env):
  9450. self.operand = self.operand.analyse_types(env)
  9451. value = StringEncoding.EncodedString(str(self.operand.type)) #self.operand.type.typeof_name())
  9452. literal = StringNode(self.pos, value=value)
  9453. literal = literal.analyse_types(env)
  9454. self.literal = literal.coerce_to_pyobject(env)
  9455. return self
  9456. def analyse_as_type(self, env):
  9457. self.operand = self.operand.analyse_types(env)
  9458. return self.operand.type
  9459. def may_be_none(self):
  9460. return False
  9461. def generate_evaluation_code(self, code):
  9462. self.literal.generate_evaluation_code(code)
  9463. def calculate_result_code(self):
  9464. return self.literal.calculate_result_code()
  9465. #-------------------------------------------------------------------
  9466. #
  9467. # Binary operator nodes
  9468. #
  9469. #-------------------------------------------------------------------
  9470. try:
  9471. matmul_operator = operator.matmul
  9472. except AttributeError:
  9473. def matmul_operator(a, b):
  9474. try:
  9475. func = a.__matmul__
  9476. except AttributeError:
  9477. func = b.__rmatmul__
  9478. return func(a, b)
  9479. compile_time_binary_operators = {
  9480. '<': operator.lt,
  9481. '<=': operator.le,
  9482. '==': operator.eq,
  9483. '!=': operator.ne,
  9484. '>=': operator.ge,
  9485. '>': operator.gt,
  9486. 'is': operator.is_,
  9487. 'is_not': operator.is_not,
  9488. '+': operator.add,
  9489. '&': operator.and_,
  9490. '/': operator.truediv,
  9491. '//': operator.floordiv,
  9492. '<<': operator.lshift,
  9493. '%': operator.mod,
  9494. '*': operator.mul,
  9495. '|': operator.or_,
  9496. '**': operator.pow,
  9497. '>>': operator.rshift,
  9498. '-': operator.sub,
  9499. '^': operator.xor,
  9500. '@': matmul_operator,
  9501. 'in': lambda x, seq: x in seq,
  9502. 'not_in': lambda x, seq: x not in seq,
  9503. }
  9504. def get_compile_time_binop(node):
  9505. func = compile_time_binary_operators.get(node.operator)
  9506. if not func:
  9507. error(node.pos,
  9508. "Binary '%s' not supported in compile-time expression"
  9509. % node.operator)
  9510. return func
  9511. class BinopNode(ExprNode):
  9512. # operator string
  9513. # operand1 ExprNode
  9514. # operand2 ExprNode
  9515. #
  9516. # Processing during analyse_expressions phase:
  9517. #
  9518. # analyse_c_operation
  9519. # Called when neither operand is a pyobject.
  9520. # - Check operand types and coerce if needed.
  9521. # - Determine result type and result code fragment.
  9522. # - Allocate temporary for result if needed.
  9523. subexprs = ['operand1', 'operand2']
  9524. inplace = False
  9525. def calculate_constant_result(self):
  9526. func = compile_time_binary_operators[self.operator]
  9527. self.constant_result = func(
  9528. self.operand1.constant_result,
  9529. self.operand2.constant_result)
  9530. def compile_time_value(self, denv):
  9531. func = get_compile_time_binop(self)
  9532. operand1 = self.operand1.compile_time_value(denv)
  9533. operand2 = self.operand2.compile_time_value(denv)
  9534. try:
  9535. return func(operand1, operand2)
  9536. except Exception as e:
  9537. self.compile_time_value_error(e)
  9538. def infer_type(self, env):
  9539. return self.result_type(self.operand1.infer_type(env),
  9540. self.operand2.infer_type(env), env)
  9541. def analyse_types(self, env):
  9542. self.operand1 = self.operand1.analyse_types(env)
  9543. self.operand2 = self.operand2.analyse_types(env)
  9544. self.analyse_operation(env)
  9545. return self
  9546. def analyse_operation(self, env):
  9547. if self.is_pythran_operation(env):
  9548. self.type = self.result_type(self.operand1.type,
  9549. self.operand2.type, env)
  9550. assert self.type.is_pythran_expr
  9551. self.is_temp = 1
  9552. elif self.is_py_operation():
  9553. self.coerce_operands_to_pyobjects(env)
  9554. self.type = self.result_type(self.operand1.type,
  9555. self.operand2.type, env)
  9556. assert self.type.is_pyobject
  9557. self.is_temp = 1
  9558. elif self.is_cpp_operation():
  9559. self.analyse_cpp_operation(env)
  9560. else:
  9561. self.analyse_c_operation(env)
  9562. def is_py_operation(self):
  9563. return self.is_py_operation_types(self.operand1.type, self.operand2.type)
  9564. def is_py_operation_types(self, type1, type2):
  9565. return type1.is_pyobject or type2.is_pyobject or type1.is_ctuple or type2.is_ctuple
  9566. def is_pythran_operation(self, env):
  9567. return self.is_pythran_operation_types(self.operand1.type, self.operand2.type, env)
  9568. def is_pythran_operation_types(self, type1, type2, env):
  9569. # Support only expr op supported_type, or supported_type op expr
  9570. return has_np_pythran(env) and \
  9571. (is_pythran_supported_operation_type(type1) and is_pythran_supported_operation_type(type2)) and \
  9572. (is_pythran_expr(type1) or is_pythran_expr(type2))
  9573. def is_cpp_operation(self):
  9574. return (self.operand1.type.is_cpp_class
  9575. or self.operand2.type.is_cpp_class)
  9576. def analyse_cpp_operation(self, env):
  9577. entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
  9578. if not entry:
  9579. self.type_error()
  9580. return
  9581. func_type = entry.type
  9582. self.exception_check = func_type.exception_check
  9583. self.exception_value = func_type.exception_value
  9584. if self.exception_check == '+':
  9585. # Used by NumBinopNodes to break up expressions involving multiple
  9586. # operators so that exceptions can be handled properly.
  9587. self.is_temp = 1
  9588. if self.exception_value is None:
  9589. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  9590. if func_type.is_ptr:
  9591. func_type = func_type.base_type
  9592. if len(func_type.args) == 1:
  9593. self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
  9594. else:
  9595. self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
  9596. self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
  9597. self.type = func_type.return_type
  9598. def result_type(self, type1, type2, env):
  9599. if self.is_pythran_operation_types(type1, type2, env):
  9600. return PythranExpr(pythran_binop_type(self.operator, type1, type2))
  9601. if self.is_py_operation_types(type1, type2):
  9602. if type2.is_string:
  9603. type2 = Builtin.bytes_type
  9604. elif type2.is_pyunicode_ptr:
  9605. type2 = Builtin.unicode_type
  9606. if type1.is_string:
  9607. type1 = Builtin.bytes_type
  9608. elif type1.is_pyunicode_ptr:
  9609. type1 = Builtin.unicode_type
  9610. if type1.is_builtin_type or type2.is_builtin_type:
  9611. if type1 is type2 and self.operator in '**%+|&^':
  9612. # FIXME: at least these operators should be safe - others?
  9613. return type1
  9614. result_type = self.infer_builtin_types_operation(type1, type2)
  9615. if result_type is not None:
  9616. return result_type
  9617. return py_object_type
  9618. elif type1.is_error or type2.is_error:
  9619. return PyrexTypes.error_type
  9620. else:
  9621. return self.compute_c_result_type(type1, type2)
  9622. def infer_builtin_types_operation(self, type1, type2):
  9623. return None
  9624. def nogil_check(self, env):
  9625. if self.is_py_operation():
  9626. self.gil_error()
  9627. def coerce_operands_to_pyobjects(self, env):
  9628. self.operand1 = self.operand1.coerce_to_pyobject(env)
  9629. self.operand2 = self.operand2.coerce_to_pyobject(env)
  9630. def check_const(self):
  9631. return self.operand1.check_const() and self.operand2.check_const()
  9632. def is_ephemeral(self):
  9633. return (super(BinopNode, self).is_ephemeral() or
  9634. self.operand1.is_ephemeral() or self.operand2.is_ephemeral())
  9635. def generate_result_code(self, code):
  9636. if self.type.is_pythran_expr:
  9637. code.putln("// Pythran binop")
  9638. code.putln("__Pyx_call_destructor(%s);" % self.result())
  9639. if self.operator == '**':
  9640. code.putln("new (&%s) decltype(%s){pythonic::numpy::functor::power{}(%s, %s)};" % (
  9641. self.result(),
  9642. self.result(),
  9643. self.operand1.pythran_result(),
  9644. self.operand2.pythran_result()))
  9645. else:
  9646. code.putln("new (&%s) decltype(%s){%s %s %s};" % (
  9647. self.result(),
  9648. self.result(),
  9649. self.operand1.pythran_result(),
  9650. self.operator,
  9651. self.operand2.pythran_result()))
  9652. elif self.operand1.type.is_pyobject:
  9653. function = self.py_operation_function(code)
  9654. if self.operator == '**':
  9655. extra_args = ", Py_None"
  9656. else:
  9657. extra_args = ""
  9658. code.putln(
  9659. "%s = %s(%s, %s%s); %s" % (
  9660. self.result(),
  9661. function,
  9662. self.operand1.py_result(),
  9663. self.operand2.py_result(),
  9664. extra_args,
  9665. code.error_goto_if_null(self.result(), self.pos)))
  9666. code.put_gotref(self.py_result())
  9667. elif self.is_temp:
  9668. # C++ overloaded operators with exception values are currently all
  9669. # handled through temporaries.
  9670. if self.is_cpp_operation() and self.exception_check == '+':
  9671. translate_cpp_exception(code, self.pos,
  9672. "%s = %s;" % (self.result(), self.calculate_result_code()),
  9673. self.result() if self.type.is_pyobject else None,
  9674. self.exception_value, self.in_nogil_context)
  9675. else:
  9676. code.putln("%s = %s;" % (self.result(), self.calculate_result_code()))
  9677. def type_error(self):
  9678. if not (self.operand1.type.is_error
  9679. or self.operand2.type.is_error):
  9680. error(self.pos, "Invalid operand types for '%s' (%s; %s)" %
  9681. (self.operator, self.operand1.type,
  9682. self.operand2.type))
  9683. self.type = PyrexTypes.error_type
  9684. class CBinopNode(BinopNode):
  9685. def analyse_types(self, env):
  9686. node = BinopNode.analyse_types(self, env)
  9687. if node.is_py_operation():
  9688. node.type = PyrexTypes.error_type
  9689. return node
  9690. def py_operation_function(self, code):
  9691. return ""
  9692. def calculate_result_code(self):
  9693. return "(%s %s %s)" % (
  9694. self.operand1.result(),
  9695. self.operator,
  9696. self.operand2.result())
  9697. def compute_c_result_type(self, type1, type2):
  9698. cpp_type = None
  9699. if type1.is_cpp_class or type1.is_ptr:
  9700. cpp_type = type1.find_cpp_operation_type(self.operator, type2)
  9701. if cpp_type is None and (type2.is_cpp_class or type2.is_ptr):
  9702. cpp_type = type2.find_cpp_operation_type(self.operator, type1)
  9703. # FIXME: do we need to handle other cases here?
  9704. return cpp_type
  9705. def c_binop_constructor(operator):
  9706. def make_binop_node(pos, **operands):
  9707. return CBinopNode(pos, operator=operator, **operands)
  9708. return make_binop_node
  9709. class NumBinopNode(BinopNode):
  9710. # Binary operation taking numeric arguments.
  9711. infix = True
  9712. overflow_check = False
  9713. overflow_bit_node = None
  9714. def analyse_c_operation(self, env):
  9715. type1 = self.operand1.type
  9716. type2 = self.operand2.type
  9717. self.type = self.compute_c_result_type(type1, type2)
  9718. if not self.type:
  9719. self.type_error()
  9720. return
  9721. if self.type.is_complex:
  9722. self.infix = False
  9723. if (self.type.is_int
  9724. and env.directives['overflowcheck']
  9725. and self.operator in self.overflow_op_names):
  9726. if (self.operator in ('+', '*')
  9727. and self.operand1.has_constant_result()
  9728. and not self.operand2.has_constant_result()):
  9729. self.operand1, self.operand2 = self.operand2, self.operand1
  9730. self.overflow_check = True
  9731. self.overflow_fold = env.directives['overflowcheck.fold']
  9732. self.func = self.type.overflow_check_binop(
  9733. self.overflow_op_names[self.operator],
  9734. env,
  9735. const_rhs = self.operand2.has_constant_result())
  9736. self.is_temp = True
  9737. if not self.infix or (type1.is_numeric and type2.is_numeric):
  9738. self.operand1 = self.operand1.coerce_to(self.type, env)
  9739. self.operand2 = self.operand2.coerce_to(self.type, env)
  9740. def compute_c_result_type(self, type1, type2):
  9741. if self.c_types_okay(type1, type2):
  9742. widest_type = PyrexTypes.widest_numeric_type(type1, type2)
  9743. if widest_type is PyrexTypes.c_bint_type:
  9744. if self.operator not in '|^&':
  9745. # False + False == 0 # not False!
  9746. widest_type = PyrexTypes.c_int_type
  9747. else:
  9748. widest_type = PyrexTypes.widest_numeric_type(
  9749. widest_type, PyrexTypes.c_int_type)
  9750. return widest_type
  9751. else:
  9752. return None
  9753. def may_be_none(self):
  9754. if self.type and self.type.is_builtin_type:
  9755. # if we know the result type, we know the operation, so it can't be None
  9756. return False
  9757. type1 = self.operand1.type
  9758. type2 = self.operand2.type
  9759. if type1 and type1.is_builtin_type and type2 and type2.is_builtin_type:
  9760. # XXX: I can't think of any case where a binary operation
  9761. # on builtin types evaluates to None - add a special case
  9762. # here if there is one.
  9763. return False
  9764. return super(NumBinopNode, self).may_be_none()
  9765. def get_constant_c_result_code(self):
  9766. value1 = self.operand1.get_constant_c_result_code()
  9767. value2 = self.operand2.get_constant_c_result_code()
  9768. if value1 and value2:
  9769. return "(%s %s %s)" % (value1, self.operator, value2)
  9770. else:
  9771. return None
  9772. def c_types_okay(self, type1, type2):
  9773. #print "NumBinopNode.c_types_okay:", type1, type2 ###
  9774. return (type1.is_numeric or type1.is_enum) \
  9775. and (type2.is_numeric or type2.is_enum)
  9776. def generate_evaluation_code(self, code):
  9777. if self.overflow_check:
  9778. self.overflow_bit_node = self
  9779. self.overflow_bit = code.funcstate.allocate_temp(PyrexTypes.c_int_type, manage_ref=False)
  9780. code.putln("%s = 0;" % self.overflow_bit)
  9781. super(NumBinopNode, self).generate_evaluation_code(code)
  9782. if self.overflow_check:
  9783. code.putln("if (unlikely(%s)) {" % self.overflow_bit)
  9784. code.putln('PyErr_SetString(PyExc_OverflowError, "value too large");')
  9785. code.putln(code.error_goto(self.pos))
  9786. code.putln("}")
  9787. code.funcstate.release_temp(self.overflow_bit)
  9788. def calculate_result_code(self):
  9789. if self.overflow_bit_node is not None:
  9790. return "%s(%s, %s, &%s)" % (
  9791. self.func,
  9792. self.operand1.result(),
  9793. self.operand2.result(),
  9794. self.overflow_bit_node.overflow_bit)
  9795. elif self.type.is_cpp_class or self.infix:
  9796. if is_pythran_expr(self.type):
  9797. result1, result2 = self.operand1.pythran_result(), self.operand2.pythran_result()
  9798. else:
  9799. result1, result2 = self.operand1.result(), self.operand2.result()
  9800. return "(%s %s %s)" % (result1, self.operator, result2)
  9801. else:
  9802. func = self.type.binary_op(self.operator)
  9803. if func is None:
  9804. error(self.pos, "binary operator %s not supported for %s" % (self.operator, self.type))
  9805. return "%s(%s, %s)" % (
  9806. func,
  9807. self.operand1.result(),
  9808. self.operand2.result())
  9809. def is_py_operation_types(self, type1, type2):
  9810. return (type1.is_unicode_char or
  9811. type2.is_unicode_char or
  9812. BinopNode.is_py_operation_types(self, type1, type2))
  9813. def py_operation_function(self, code):
  9814. function_name = self.py_functions[self.operator]
  9815. if self.inplace:
  9816. function_name = function_name.replace('PyNumber_', 'PyNumber_InPlace')
  9817. return function_name
  9818. py_functions = {
  9819. "|": "PyNumber_Or",
  9820. "^": "PyNumber_Xor",
  9821. "&": "PyNumber_And",
  9822. "<<": "PyNumber_Lshift",
  9823. ">>": "PyNumber_Rshift",
  9824. "+": "PyNumber_Add",
  9825. "-": "PyNumber_Subtract",
  9826. "*": "PyNumber_Multiply",
  9827. "@": "__Pyx_PyNumber_MatrixMultiply",
  9828. "/": "__Pyx_PyNumber_Divide",
  9829. "//": "PyNumber_FloorDivide",
  9830. "%": "PyNumber_Remainder",
  9831. "**": "PyNumber_Power",
  9832. }
  9833. overflow_op_names = {
  9834. "+": "add",
  9835. "-": "sub",
  9836. "*": "mul",
  9837. "<<": "lshift",
  9838. }
  9839. class IntBinopNode(NumBinopNode):
  9840. # Binary operation taking integer arguments.
  9841. def c_types_okay(self, type1, type2):
  9842. #print "IntBinopNode.c_types_okay:", type1, type2 ###
  9843. return (type1.is_int or type1.is_enum) \
  9844. and (type2.is_int or type2.is_enum)
  9845. class AddNode(NumBinopNode):
  9846. # '+' operator.
  9847. def is_py_operation_types(self, type1, type2):
  9848. if type1.is_string and type2.is_string or type1.is_pyunicode_ptr and type2.is_pyunicode_ptr:
  9849. return 1
  9850. else:
  9851. return NumBinopNode.is_py_operation_types(self, type1, type2)
  9852. def infer_builtin_types_operation(self, type1, type2):
  9853. # b'abc' + 'abc' raises an exception in Py3,
  9854. # so we can safely infer the Py2 type for bytes here
  9855. string_types = (bytes_type, bytearray_type, str_type, basestring_type, unicode_type)
  9856. if type1 in string_types and type2 in string_types:
  9857. return string_types[max(string_types.index(type1),
  9858. string_types.index(type2))]
  9859. return None
  9860. def compute_c_result_type(self, type1, type2):
  9861. #print "AddNode.compute_c_result_type:", type1, self.operator, type2 ###
  9862. if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
  9863. return type1
  9864. elif (type2.is_ptr or type2.is_array) and (type1.is_int or type1.is_enum):
  9865. return type2
  9866. else:
  9867. return NumBinopNode.compute_c_result_type(
  9868. self, type1, type2)
  9869. def py_operation_function(self, code):
  9870. type1, type2 = self.operand1.type, self.operand2.type
  9871. if type1 is unicode_type or type2 is unicode_type:
  9872. if type1 in (unicode_type, str_type) and type2 in (unicode_type, str_type):
  9873. is_unicode_concat = True
  9874. elif isinstance(self.operand1, FormattedValueNode) or isinstance(self.operand2, FormattedValueNode):
  9875. # Assume that even if we don't know the second type, it's going to be a string.
  9876. is_unicode_concat = True
  9877. else:
  9878. # Operation depends on the second type.
  9879. is_unicode_concat = False
  9880. if is_unicode_concat:
  9881. if self.operand1.may_be_none() or self.operand2.may_be_none():
  9882. return '__Pyx_PyUnicode_ConcatSafe'
  9883. else:
  9884. return '__Pyx_PyUnicode_Concat'
  9885. return super(AddNode, self).py_operation_function(code)
  9886. class SubNode(NumBinopNode):
  9887. # '-' operator.
  9888. def compute_c_result_type(self, type1, type2):
  9889. if (type1.is_ptr or type1.is_array) and (type2.is_int or type2.is_enum):
  9890. return type1
  9891. elif (type1.is_ptr or type1.is_array) and (type2.is_ptr or type2.is_array):
  9892. return PyrexTypes.c_ptrdiff_t_type
  9893. else:
  9894. return NumBinopNode.compute_c_result_type(
  9895. self, type1, type2)
  9896. class MulNode(NumBinopNode):
  9897. # '*' operator.
  9898. def is_py_operation_types(self, type1, type2):
  9899. if ((type1.is_string and type2.is_int) or
  9900. (type2.is_string and type1.is_int)):
  9901. return 1
  9902. else:
  9903. return NumBinopNode.is_py_operation_types(self, type1, type2)
  9904. def infer_builtin_types_operation(self, type1, type2):
  9905. # let's assume that whatever builtin type you multiply a string with
  9906. # will either return a string of the same type or fail with an exception
  9907. string_types = (bytes_type, bytearray_type, str_type, basestring_type, unicode_type)
  9908. if type1 in string_types and type2.is_builtin_type:
  9909. return type1
  9910. if type2 in string_types and type1.is_builtin_type:
  9911. return type2
  9912. # multiplication of containers/numbers with an integer value
  9913. # always (?) returns the same type
  9914. if type1.is_int:
  9915. return type2
  9916. if type2.is_int:
  9917. return type1
  9918. return None
  9919. class MatMultNode(NumBinopNode):
  9920. # '@' operator.
  9921. def is_py_operation_types(self, type1, type2):
  9922. return True
  9923. def generate_evaluation_code(self, code):
  9924. code.globalstate.use_utility_code(UtilityCode.load_cached("MatrixMultiply", "ObjectHandling.c"))
  9925. super(MatMultNode, self).generate_evaluation_code(code)
  9926. class DivNode(NumBinopNode):
  9927. # '/' or '//' operator.
  9928. cdivision = None
  9929. truedivision = None # == "unknown" if operator == '/'
  9930. ctruedivision = False
  9931. cdivision_warnings = False
  9932. zerodivision_check = None
  9933. def find_compile_time_binary_operator(self, op1, op2):
  9934. func = compile_time_binary_operators[self.operator]
  9935. if self.operator == '/' and self.truedivision is None:
  9936. # => true div for floats, floor div for integers
  9937. if isinstance(op1, _py_int_types) and isinstance(op2, _py_int_types):
  9938. func = compile_time_binary_operators['//']
  9939. return func
  9940. def calculate_constant_result(self):
  9941. op1 = self.operand1.constant_result
  9942. op2 = self.operand2.constant_result
  9943. func = self.find_compile_time_binary_operator(op1, op2)
  9944. self.constant_result = func(
  9945. self.operand1.constant_result,
  9946. self.operand2.constant_result)
  9947. def compile_time_value(self, denv):
  9948. operand1 = self.operand1.compile_time_value(denv)
  9949. operand2 = self.operand2.compile_time_value(denv)
  9950. try:
  9951. func = self.find_compile_time_binary_operator(
  9952. operand1, operand2)
  9953. return func(operand1, operand2)
  9954. except Exception as e:
  9955. self.compile_time_value_error(e)
  9956. def _check_truedivision(self, env):
  9957. if self.cdivision or env.directives['cdivision']:
  9958. self.ctruedivision = False
  9959. else:
  9960. self.ctruedivision = self.truedivision
  9961. def infer_type(self, env):
  9962. self._check_truedivision(env)
  9963. return self.result_type(
  9964. self.operand1.infer_type(env),
  9965. self.operand2.infer_type(env), env)
  9966. def analyse_operation(self, env):
  9967. self._check_truedivision(env)
  9968. NumBinopNode.analyse_operation(self, env)
  9969. if self.is_cpp_operation():
  9970. self.cdivision = True
  9971. if not self.type.is_pyobject:
  9972. self.zerodivision_check = (
  9973. self.cdivision is None and not env.directives['cdivision']
  9974. and (not self.operand2.has_constant_result() or
  9975. self.operand2.constant_result == 0))
  9976. if self.zerodivision_check or env.directives['cdivision_warnings']:
  9977. # Need to check ahead of time to warn or raise zero division error
  9978. self.operand1 = self.operand1.coerce_to_simple(env)
  9979. self.operand2 = self.operand2.coerce_to_simple(env)
  9980. def compute_c_result_type(self, type1, type2):
  9981. if self.operator == '/' and self.ctruedivision and not type1.is_cpp_class and not type2.is_cpp_class:
  9982. if not type1.is_float and not type2.is_float:
  9983. widest_type = PyrexTypes.widest_numeric_type(type1, PyrexTypes.c_double_type)
  9984. widest_type = PyrexTypes.widest_numeric_type(type2, widest_type)
  9985. return widest_type
  9986. return NumBinopNode.compute_c_result_type(self, type1, type2)
  9987. def zero_division_message(self):
  9988. if self.type.is_int:
  9989. return "integer division or modulo by zero"
  9990. else:
  9991. return "float division"
  9992. def generate_evaluation_code(self, code):
  9993. if not self.type.is_pyobject and not self.type.is_complex:
  9994. if self.cdivision is None:
  9995. self.cdivision = (
  9996. code.globalstate.directives['cdivision']
  9997. or self.type.is_float
  9998. or ((self.type.is_numeric or self.type.is_enum) and not self.type.signed)
  9999. )
  10000. if not self.cdivision:
  10001. code.globalstate.use_utility_code(
  10002. UtilityCode.load_cached("DivInt", "CMath.c").specialize(self.type))
  10003. NumBinopNode.generate_evaluation_code(self, code)
  10004. self.generate_div_warning_code(code)
  10005. def generate_div_warning_code(self, code):
  10006. in_nogil = self.in_nogil_context
  10007. if not self.type.is_pyobject:
  10008. if self.zerodivision_check:
  10009. if not self.infix:
  10010. zero_test = "%s(%s)" % (self.type.unary_op('zero'), self.operand2.result())
  10011. else:
  10012. zero_test = "%s == 0" % self.operand2.result()
  10013. code.putln("if (unlikely(%s)) {" % zero_test)
  10014. if in_nogil:
  10015. code.put_ensure_gil()
  10016. code.putln('PyErr_SetString(PyExc_ZeroDivisionError, "%s");' % self.zero_division_message())
  10017. if in_nogil:
  10018. code.put_release_ensured_gil()
  10019. code.putln(code.error_goto(self.pos))
  10020. code.putln("}")
  10021. if self.type.is_int and self.type.signed and self.operator != '%':
  10022. code.globalstate.use_utility_code(UtilityCode.load_cached("UnaryNegOverflows", "Overflow.c"))
  10023. if self.operand2.type.signed == 2:
  10024. # explicitly signed, no runtime check needed
  10025. minus1_check = 'unlikely(%s == -1)' % self.operand2.result()
  10026. else:
  10027. type_of_op2 = self.operand2.type.empty_declaration_code()
  10028. minus1_check = '(!(((%s)-1) > 0)) && unlikely(%s == (%s)-1)' % (
  10029. type_of_op2, self.operand2.result(), type_of_op2)
  10030. code.putln("else if (sizeof(%s) == sizeof(long) && %s "
  10031. " && unlikely(UNARY_NEG_WOULD_OVERFLOW(%s))) {" % (
  10032. self.type.empty_declaration_code(),
  10033. minus1_check,
  10034. self.operand1.result()))
  10035. if in_nogil:
  10036. code.put_ensure_gil()
  10037. code.putln('PyErr_SetString(PyExc_OverflowError, "value too large to perform division");')
  10038. if in_nogil:
  10039. code.put_release_ensured_gil()
  10040. code.putln(code.error_goto(self.pos))
  10041. code.putln("}")
  10042. if code.globalstate.directives['cdivision_warnings'] and self.operator != '/':
  10043. code.globalstate.use_utility_code(
  10044. UtilityCode.load_cached("CDivisionWarning", "CMath.c"))
  10045. code.putln("if (unlikely((%s < 0) ^ (%s < 0))) {" % (
  10046. self.operand1.result(),
  10047. self.operand2.result()))
  10048. warning_code = "__Pyx_cdivision_warning(%(FILENAME)s, %(LINENO)s)" % {
  10049. 'FILENAME': Naming.filename_cname,
  10050. 'LINENO': Naming.lineno_cname,
  10051. }
  10052. if in_nogil:
  10053. result_code = 'result'
  10054. code.putln("int %s;" % result_code)
  10055. code.put_ensure_gil()
  10056. code.putln(code.set_error_info(self.pos, used=True))
  10057. code.putln("%s = %s;" % (result_code, warning_code))
  10058. code.put_release_ensured_gil()
  10059. else:
  10060. result_code = warning_code
  10061. code.putln(code.set_error_info(self.pos, used=True))
  10062. code.put("if (unlikely(%s)) " % result_code)
  10063. code.put_goto(code.error_label)
  10064. code.putln("}")
  10065. def calculate_result_code(self):
  10066. if self.type.is_complex or self.is_cpp_operation():
  10067. return NumBinopNode.calculate_result_code(self)
  10068. elif self.type.is_float and self.operator == '//':
  10069. return "floor(%s / %s)" % (
  10070. self.operand1.result(),
  10071. self.operand2.result())
  10072. elif self.truedivision or self.cdivision:
  10073. op1 = self.operand1.result()
  10074. op2 = self.operand2.result()
  10075. if self.truedivision:
  10076. if self.type != self.operand1.type:
  10077. op1 = self.type.cast_code(op1)
  10078. if self.type != self.operand2.type:
  10079. op2 = self.type.cast_code(op2)
  10080. return "(%s / %s)" % (op1, op2)
  10081. else:
  10082. return "__Pyx_div_%s(%s, %s)" % (
  10083. self.type.specialization_name(),
  10084. self.operand1.result(),
  10085. self.operand2.result())
  10086. _find_formatting_types = re.compile(
  10087. br"%"
  10088. br"(?:%|" # %%
  10089. br"(?:\([^)]+\))?" # %(name)
  10090. br"[-+#,0-9 ]*([a-z])" # %.2f etc.
  10091. br")").findall
  10092. # These format conversion types can never trigger a Unicode string conversion in Py2.
  10093. _safe_bytes_formats = set([
  10094. # Excludes 's' and 'r', which can generate non-bytes strings.
  10095. 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',
  10096. ])
  10097. class ModNode(DivNode):
  10098. # '%' operator.
  10099. def is_py_operation_types(self, type1, type2):
  10100. return (type1.is_string
  10101. or type2.is_string
  10102. or NumBinopNode.is_py_operation_types(self, type1, type2))
  10103. def infer_builtin_types_operation(self, type1, type2):
  10104. # b'%s' % xyz raises an exception in Py3<3.5, so it's safe to infer the type for Py2 and later Py3's.
  10105. if type1 is unicode_type:
  10106. # None + xyz may be implemented by RHS
  10107. if type2.is_builtin_type or not self.operand1.may_be_none():
  10108. return type1
  10109. elif type1 in (bytes_type, str_type, basestring_type):
  10110. if type2 is unicode_type:
  10111. return type2
  10112. elif type2.is_numeric:
  10113. return type1
  10114. elif self.operand1.is_string_literal:
  10115. if type1 is str_type or type1 is bytes_type:
  10116. if set(_find_formatting_types(self.operand1.value)) <= _safe_bytes_formats:
  10117. return type1
  10118. return basestring_type
  10119. elif type1 is bytes_type and not type2.is_builtin_type:
  10120. return None # RHS might implement '% operator differently in Py3
  10121. else:
  10122. return basestring_type # either str or unicode, can't tell
  10123. return None
  10124. def zero_division_message(self):
  10125. if self.type.is_int:
  10126. return "integer division or modulo by zero"
  10127. else:
  10128. return "float divmod()"
  10129. def analyse_operation(self, env):
  10130. DivNode.analyse_operation(self, env)
  10131. if not self.type.is_pyobject:
  10132. if self.cdivision is None:
  10133. self.cdivision = env.directives['cdivision'] or not self.type.signed
  10134. if not self.cdivision and not self.type.is_int and not self.type.is_float:
  10135. error(self.pos, "mod operator not supported for type '%s'" % self.type)
  10136. def generate_evaluation_code(self, code):
  10137. if not self.type.is_pyobject and not self.cdivision:
  10138. if self.type.is_int:
  10139. code.globalstate.use_utility_code(
  10140. UtilityCode.load_cached("ModInt", "CMath.c").specialize(self.type))
  10141. else: # float
  10142. code.globalstate.use_utility_code(
  10143. UtilityCode.load_cached("ModFloat", "CMath.c").specialize(
  10144. self.type, math_h_modifier=self.type.math_h_modifier))
  10145. # NOTE: skipping over DivNode here
  10146. NumBinopNode.generate_evaluation_code(self, code)
  10147. self.generate_div_warning_code(code)
  10148. def calculate_result_code(self):
  10149. if self.cdivision:
  10150. if self.type.is_float:
  10151. return "fmod%s(%s, %s)" % (
  10152. self.type.math_h_modifier,
  10153. self.operand1.result(),
  10154. self.operand2.result())
  10155. else:
  10156. return "(%s %% %s)" % (
  10157. self.operand1.result(),
  10158. self.operand2.result())
  10159. else:
  10160. return "__Pyx_mod_%s(%s, %s)" % (
  10161. self.type.specialization_name(),
  10162. self.operand1.result(),
  10163. self.operand2.result())
  10164. def py_operation_function(self, code):
  10165. type1, type2 = self.operand1.type, self.operand2.type
  10166. # ("..." % x) must call "x.__rmod__()" for string subtypes.
  10167. if type1 is unicode_type:
  10168. if self.operand1.may_be_none() or (
  10169. type2.is_extension_type and type2.subtype_of(type1) or
  10170. type2 is py_object_type and not isinstance(self.operand2, CoerceToPyTypeNode)):
  10171. return '__Pyx_PyUnicode_FormatSafe'
  10172. else:
  10173. return 'PyUnicode_Format'
  10174. elif type1 is str_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_PyString_FormatSafe'
  10179. else:
  10180. return '__Pyx_PyString_Format'
  10181. return super(ModNode, self).py_operation_function(code)
  10182. class PowNode(NumBinopNode):
  10183. # '**' operator.
  10184. def analyse_c_operation(self, env):
  10185. NumBinopNode.analyse_c_operation(self, env)
  10186. if self.type.is_complex:
  10187. if self.type.real_type.is_float:
  10188. self.operand1 = self.operand1.coerce_to(self.type, env)
  10189. self.operand2 = self.operand2.coerce_to(self.type, env)
  10190. self.pow_func = self.type.binary_op('**')
  10191. else:
  10192. error(self.pos, "complex int powers not supported")
  10193. self.pow_func = "<error>"
  10194. elif self.type.is_float:
  10195. self.pow_func = "pow" + self.type.math_h_modifier
  10196. elif self.type.is_int:
  10197. self.pow_func = "__Pyx_pow_%s" % self.type.empty_declaration_code().replace(' ', '_')
  10198. env.use_utility_code(
  10199. UtilityCode.load_cached("IntPow", "CMath.c").specialize(
  10200. func_name=self.pow_func,
  10201. type=self.type.empty_declaration_code(),
  10202. signed=self.type.signed and 1 or 0))
  10203. elif not self.type.is_error:
  10204. error(self.pos, "got unexpected types for C power operator: %s, %s" %
  10205. (self.operand1.type, self.operand2.type))
  10206. def calculate_result_code(self):
  10207. # Work around MSVC overloading ambiguity.
  10208. def typecast(operand):
  10209. if self.type == operand.type:
  10210. return operand.result()
  10211. else:
  10212. return self.type.cast_code(operand.result())
  10213. return "%s(%s, %s)" % (
  10214. self.pow_func,
  10215. typecast(self.operand1),
  10216. typecast(self.operand2))
  10217. def py_operation_function(self, code):
  10218. if (self.type.is_pyobject and
  10219. self.operand1.constant_result == 2 and
  10220. isinstance(self.operand1.constant_result, _py_int_types) and
  10221. self.operand2.type is py_object_type):
  10222. code.globalstate.use_utility_code(UtilityCode.load_cached('PyNumberPow2', 'Optimize.c'))
  10223. if self.inplace:
  10224. return '__Pyx_PyNumber_InPlacePowerOf2'
  10225. else:
  10226. return '__Pyx_PyNumber_PowerOf2'
  10227. return super(PowNode, self).py_operation_function(code)
  10228. class BoolBinopNode(ExprNode):
  10229. """
  10230. Short-circuiting boolean operation.
  10231. Note that this node provides the same code generation method as
  10232. BoolBinopResultNode to simplify expression nesting.
  10233. operator string "and"/"or"
  10234. operand1 BoolBinopNode/BoolBinopResultNode left operand
  10235. operand2 BoolBinopNode/BoolBinopResultNode right operand
  10236. """
  10237. subexprs = ['operand1', 'operand2']
  10238. is_temp = True
  10239. operator = None
  10240. operand1 = None
  10241. operand2 = None
  10242. def infer_type(self, env):
  10243. type1 = self.operand1.infer_type(env)
  10244. type2 = self.operand2.infer_type(env)
  10245. return PyrexTypes.independent_spanning_type(type1, type2)
  10246. def may_be_none(self):
  10247. if self.operator == 'or':
  10248. return self.operand2.may_be_none()
  10249. else:
  10250. return self.operand1.may_be_none() or self.operand2.may_be_none()
  10251. def calculate_constant_result(self):
  10252. operand1 = self.operand1.constant_result
  10253. operand2 = self.operand2.constant_result
  10254. if self.operator == 'and':
  10255. self.constant_result = operand1 and operand2
  10256. else:
  10257. self.constant_result = operand1 or operand2
  10258. def compile_time_value(self, denv):
  10259. operand1 = self.operand1.compile_time_value(denv)
  10260. operand2 = self.operand2.compile_time_value(denv)
  10261. if self.operator == 'and':
  10262. return operand1 and operand2
  10263. else:
  10264. return operand1 or operand2
  10265. def is_ephemeral(self):
  10266. return self.operand1.is_ephemeral() or self.operand2.is_ephemeral()
  10267. def analyse_types(self, env):
  10268. # Note: we do not do any coercion here as we most likely do not know the final type anyway.
  10269. # We even accept to set self.type to ErrorType if both operands do not have a spanning type.
  10270. # The coercion to the final type and to a "simple" value is left to coerce_to().
  10271. operand1 = self.operand1.analyse_types(env)
  10272. operand2 = self.operand2.analyse_types(env)
  10273. self.type = PyrexTypes.independent_spanning_type(
  10274. operand1.type, operand2.type)
  10275. self.operand1 = self._wrap_operand(operand1, env)
  10276. self.operand2 = self._wrap_operand(operand2, env)
  10277. return self
  10278. def _wrap_operand(self, operand, env):
  10279. if not isinstance(operand, (BoolBinopNode, BoolBinopResultNode)):
  10280. operand = BoolBinopResultNode(operand, self.type, env)
  10281. return operand
  10282. def wrap_operands(self, env):
  10283. """
  10284. Must get called by transforms that want to create a correct BoolBinopNode
  10285. after the type analysis phase.
  10286. """
  10287. self.operand1 = self._wrap_operand(self.operand1, env)
  10288. self.operand2 = self._wrap_operand(self.operand2, env)
  10289. def coerce_to_boolean(self, env):
  10290. return self.coerce_to(PyrexTypes.c_bint_type, env)
  10291. def coerce_to(self, dst_type, env):
  10292. operand1 = self.operand1.coerce_to(dst_type, env)
  10293. operand2 = self.operand2.coerce_to(dst_type, env)
  10294. return BoolBinopNode.from_node(
  10295. self, type=dst_type,
  10296. operator=self.operator,
  10297. operand1=operand1, operand2=operand2)
  10298. def generate_bool_evaluation_code(self, code, final_result_temp, final_result_type, and_label, or_label, end_label, fall_through):
  10299. code.mark_pos(self.pos)
  10300. outer_labels = (and_label, or_label)
  10301. if self.operator == 'and':
  10302. my_label = and_label = code.new_label('next_and')
  10303. else:
  10304. my_label = or_label = code.new_label('next_or')
  10305. self.operand1.generate_bool_evaluation_code(
  10306. code, final_result_temp, final_result_type, and_label, or_label, end_label, my_label)
  10307. and_label, or_label = outer_labels
  10308. code.put_label(my_label)
  10309. self.operand2.generate_bool_evaluation_code(
  10310. code, final_result_temp, final_result_type, and_label, or_label, end_label, fall_through)
  10311. def generate_evaluation_code(self, code):
  10312. self.allocate_temp_result(code)
  10313. result_type = PyrexTypes.py_object_type if self.type.is_pyobject else self.type
  10314. or_label = and_label = None
  10315. end_label = code.new_label('bool_binop_done')
  10316. self.generate_bool_evaluation_code(code, self.result(), result_type, and_label, or_label, end_label, end_label)
  10317. code.put_label(end_label)
  10318. gil_message = "Truth-testing Python object"
  10319. def check_const(self):
  10320. return self.operand1.check_const() and self.operand2.check_const()
  10321. def generate_subexpr_disposal_code(self, code):
  10322. pass # nothing to do here, all done in generate_evaluation_code()
  10323. def free_subexpr_temps(self, code):
  10324. pass # nothing to do here, all done in generate_evaluation_code()
  10325. def generate_operand1_test(self, code):
  10326. # Generate code to test the truth of the first operand.
  10327. if self.type.is_pyobject:
  10328. test_result = code.funcstate.allocate_temp(
  10329. PyrexTypes.c_bint_type, manage_ref=False)
  10330. code.putln(
  10331. "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
  10332. test_result,
  10333. self.operand1.py_result(),
  10334. code.error_goto_if_neg(test_result, self.pos)))
  10335. else:
  10336. test_result = self.operand1.result()
  10337. return (test_result, self.type.is_pyobject)
  10338. class BoolBinopResultNode(ExprNode):
  10339. """
  10340. Intermediate result of a short-circuiting and/or expression.
  10341. Tests the result for 'truthiness' and takes care of coercing the final result
  10342. of the overall expression to the target type.
  10343. Note that this node provides the same code generation method as
  10344. BoolBinopNode to simplify expression nesting.
  10345. arg ExprNode the argument to test
  10346. value ExprNode the coerced result value node
  10347. """
  10348. subexprs = ['arg', 'value']
  10349. is_temp = True
  10350. arg = None
  10351. value = None
  10352. def __init__(self, arg, result_type, env):
  10353. # using 'arg' multiple times, so it must be a simple/temp value
  10354. arg = arg.coerce_to_simple(env)
  10355. # wrap in ProxyNode, in case a transform wants to replace self.arg later
  10356. arg = ProxyNode(arg)
  10357. super(BoolBinopResultNode, self).__init__(
  10358. arg.pos, arg=arg, type=result_type,
  10359. value=CloneNode(arg).coerce_to(result_type, env))
  10360. def coerce_to_boolean(self, env):
  10361. return self.coerce_to(PyrexTypes.c_bint_type, env)
  10362. def coerce_to(self, dst_type, env):
  10363. # unwrap, coerce, rewrap
  10364. arg = self.arg.arg
  10365. if dst_type is PyrexTypes.c_bint_type:
  10366. arg = arg.coerce_to_boolean(env)
  10367. # TODO: unwrap more coercion nodes?
  10368. return BoolBinopResultNode(arg, dst_type, env)
  10369. def nogil_check(self, env):
  10370. # let's leave all errors to BoolBinopNode
  10371. pass
  10372. def generate_operand_test(self, code):
  10373. # Generate code to test the truth of the first operand.
  10374. if self.arg.type.is_pyobject:
  10375. test_result = code.funcstate.allocate_temp(
  10376. PyrexTypes.c_bint_type, manage_ref=False)
  10377. code.putln(
  10378. "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
  10379. test_result,
  10380. self.arg.py_result(),
  10381. code.error_goto_if_neg(test_result, self.pos)))
  10382. else:
  10383. test_result = self.arg.result()
  10384. return (test_result, self.arg.type.is_pyobject)
  10385. def generate_bool_evaluation_code(self, code, final_result_temp, final_result_type, and_label, or_label, end_label, fall_through):
  10386. code.mark_pos(self.pos)
  10387. # x => x
  10388. # x and ... or ... => next 'and' / 'or'
  10389. # False ... or x => next 'or'
  10390. # True and x => next 'and'
  10391. # True or x => True (operand)
  10392. self.arg.generate_evaluation_code(code)
  10393. if and_label or or_label:
  10394. test_result, uses_temp = self.generate_operand_test(code)
  10395. if uses_temp and (and_label and or_label):
  10396. # cannot become final result => free early
  10397. # disposal: uses_temp and (and_label and or_label)
  10398. self.arg.generate_disposal_code(code)
  10399. sense = '!' if or_label else ''
  10400. code.putln("if (%s%s) {" % (sense, test_result))
  10401. if uses_temp:
  10402. code.funcstate.release_temp(test_result)
  10403. if not uses_temp or not (and_label and or_label):
  10404. # disposal: (not uses_temp) or {not (and_label and or_label) [if]}
  10405. self.arg.generate_disposal_code(code)
  10406. if or_label and or_label != fall_through:
  10407. # value is false => short-circuit to next 'or'
  10408. code.put_goto(or_label)
  10409. if and_label:
  10410. # value is true => go to next 'and'
  10411. if or_label:
  10412. code.putln("} else {")
  10413. if not uses_temp:
  10414. # disposal: (not uses_temp) and {(and_label and or_label) [else]}
  10415. self.arg.generate_disposal_code(code)
  10416. if and_label != fall_through:
  10417. code.put_goto(and_label)
  10418. if not and_label or not or_label:
  10419. # if no next 'and' or 'or', we provide the result
  10420. if and_label or or_label:
  10421. code.putln("} else {")
  10422. self.value.generate_evaluation_code(code)
  10423. self.value.make_owned_reference(code)
  10424. code.putln("%s = %s;" % (final_result_temp, self.value.result_as(final_result_type)))
  10425. self.value.generate_post_assignment_code(code)
  10426. # disposal: {not (and_label and or_label) [else]}
  10427. self.arg.generate_disposal_code(code)
  10428. self.value.free_temps(code)
  10429. if end_label != fall_through:
  10430. code.put_goto(end_label)
  10431. if and_label or or_label:
  10432. code.putln("}")
  10433. self.arg.free_temps(code)
  10434. class CondExprNode(ExprNode):
  10435. # Short-circuiting conditional expression.
  10436. #
  10437. # test ExprNode
  10438. # true_val ExprNode
  10439. # false_val ExprNode
  10440. true_val = None
  10441. false_val = None
  10442. is_temp = True
  10443. subexprs = ['test', 'true_val', 'false_val']
  10444. def type_dependencies(self, env):
  10445. return self.true_val.type_dependencies(env) + self.false_val.type_dependencies(env)
  10446. def infer_type(self, env):
  10447. return PyrexTypes.independent_spanning_type(
  10448. self.true_val.infer_type(env),
  10449. self.false_val.infer_type(env))
  10450. def calculate_constant_result(self):
  10451. if self.test.constant_result:
  10452. self.constant_result = self.true_val.constant_result
  10453. else:
  10454. self.constant_result = self.false_val.constant_result
  10455. def is_ephemeral(self):
  10456. return self.true_val.is_ephemeral() or self.false_val.is_ephemeral()
  10457. def analyse_types(self, env):
  10458. self.test = self.test.analyse_types(env).coerce_to_boolean(env)
  10459. self.true_val = self.true_val.analyse_types(env)
  10460. self.false_val = self.false_val.analyse_types(env)
  10461. return self.analyse_result_type(env)
  10462. def analyse_result_type(self, env):
  10463. self.type = PyrexTypes.independent_spanning_type(
  10464. self.true_val.type, self.false_val.type)
  10465. if self.type.is_reference:
  10466. self.type = PyrexTypes.CFakeReferenceType(self.type.ref_base_type)
  10467. if self.type.is_pyobject:
  10468. self.result_ctype = py_object_type
  10469. elif self.true_val.is_ephemeral() or self.false_val.is_ephemeral():
  10470. error(self.pos, "Unsafe C derivative of temporary Python reference used in conditional expression")
  10471. if self.true_val.type.is_pyobject or self.false_val.type.is_pyobject:
  10472. self.true_val = self.true_val.coerce_to(self.type, env)
  10473. self.false_val = self.false_val.coerce_to(self.type, env)
  10474. if self.type.is_error:
  10475. self.type_error()
  10476. return self
  10477. def coerce_to_integer(self, env):
  10478. self.true_val = self.true_val.coerce_to_integer(env)
  10479. self.false_val = self.false_val.coerce_to_integer(env)
  10480. self.result_ctype = None
  10481. return self.analyse_result_type(env)
  10482. def coerce_to(self, dst_type, env):
  10483. self.true_val = self.true_val.coerce_to(dst_type, env)
  10484. self.false_val = self.false_val.coerce_to(dst_type, env)
  10485. self.result_ctype = None
  10486. return self.analyse_result_type(env)
  10487. def type_error(self):
  10488. if not (self.true_val.type.is_error or self.false_val.type.is_error):
  10489. error(self.pos, "Incompatible types in conditional expression (%s; %s)" %
  10490. (self.true_val.type, self.false_val.type))
  10491. self.type = PyrexTypes.error_type
  10492. def check_const(self):
  10493. return (self.test.check_const()
  10494. and self.true_val.check_const()
  10495. and self.false_val.check_const())
  10496. def generate_evaluation_code(self, code):
  10497. # Because subexprs may not be evaluated we can use a more optimal
  10498. # subexpr allocation strategy than the default, so override evaluation_code.
  10499. code.mark_pos(self.pos)
  10500. self.allocate_temp_result(code)
  10501. self.test.generate_evaluation_code(code)
  10502. code.putln("if (%s) {" % self.test.result())
  10503. self.eval_and_get(code, self.true_val)
  10504. code.putln("} else {")
  10505. self.eval_and_get(code, self.false_val)
  10506. code.putln("}")
  10507. self.test.generate_disposal_code(code)
  10508. self.test.free_temps(code)
  10509. def eval_and_get(self, code, expr):
  10510. expr.generate_evaluation_code(code)
  10511. if self.type.is_memoryviewslice:
  10512. expr.make_owned_memoryviewslice(code)
  10513. else:
  10514. expr.make_owned_reference(code)
  10515. code.putln('%s = %s;' % (self.result(), expr.result_as(self.ctype())))
  10516. expr.generate_post_assignment_code(code)
  10517. expr.free_temps(code)
  10518. def generate_subexpr_disposal_code(self, code):
  10519. pass # done explicitly above (cleanup must separately happen within the if/else blocks)
  10520. def free_subexpr_temps(self, code):
  10521. pass # done explicitly above (cleanup must separately happen within the if/else blocks)
  10522. richcmp_constants = {
  10523. "<" : "Py_LT",
  10524. "<=": "Py_LE",
  10525. "==": "Py_EQ",
  10526. "!=": "Py_NE",
  10527. "<>": "Py_NE",
  10528. ">" : "Py_GT",
  10529. ">=": "Py_GE",
  10530. # the following are faked by special compare functions
  10531. "in" : "Py_EQ",
  10532. "not_in": "Py_NE",
  10533. }
  10534. class CmpNode(object):
  10535. # Mixin class containing code common to PrimaryCmpNodes
  10536. # and CascadedCmpNodes.
  10537. special_bool_cmp_function = None
  10538. special_bool_cmp_utility_code = None
  10539. def infer_type(self, env):
  10540. # TODO: Actually implement this (after merging with -unstable).
  10541. return py_object_type
  10542. def calculate_cascaded_constant_result(self, operand1_result):
  10543. func = compile_time_binary_operators[self.operator]
  10544. operand2_result = self.operand2.constant_result
  10545. if (isinstance(operand1_result, any_string_type) and
  10546. isinstance(operand2_result, any_string_type) and
  10547. type(operand1_result) != type(operand2_result)):
  10548. # string comparison of different types isn't portable
  10549. return
  10550. if self.operator in ('in', 'not_in'):
  10551. if isinstance(self.operand2, (ListNode, TupleNode, SetNode)):
  10552. if not self.operand2.args:
  10553. self.constant_result = self.operator == 'not_in'
  10554. return
  10555. elif isinstance(self.operand2, ListNode) and not self.cascade:
  10556. # tuples are more efficient to store than lists
  10557. self.operand2 = self.operand2.as_tuple()
  10558. elif isinstance(self.operand2, DictNode):
  10559. if not self.operand2.key_value_pairs:
  10560. self.constant_result = self.operator == 'not_in'
  10561. return
  10562. self.constant_result = func(operand1_result, operand2_result)
  10563. def cascaded_compile_time_value(self, operand1, denv):
  10564. func = get_compile_time_binop(self)
  10565. operand2 = self.operand2.compile_time_value(denv)
  10566. try:
  10567. result = func(operand1, operand2)
  10568. except Exception as e:
  10569. self.compile_time_value_error(e)
  10570. result = None
  10571. if result:
  10572. cascade = self.cascade
  10573. if cascade:
  10574. result = result and cascade.cascaded_compile_time_value(operand2, denv)
  10575. return result
  10576. def is_cpp_comparison(self):
  10577. return self.operand1.type.is_cpp_class or self.operand2.type.is_cpp_class
  10578. def find_common_int_type(self, env, op, operand1, operand2):
  10579. # type1 != type2 and at least one of the types is not a C int
  10580. type1 = operand1.type
  10581. type2 = operand2.type
  10582. type1_can_be_int = False
  10583. type2_can_be_int = False
  10584. if operand1.is_string_literal and operand1.can_coerce_to_char_literal():
  10585. type1_can_be_int = True
  10586. if operand2.is_string_literal and operand2.can_coerce_to_char_literal():
  10587. type2_can_be_int = True
  10588. if type1.is_int:
  10589. if type2_can_be_int:
  10590. return type1
  10591. elif type2.is_int:
  10592. if type1_can_be_int:
  10593. return type2
  10594. elif type1_can_be_int:
  10595. if type2_can_be_int:
  10596. if Builtin.unicode_type in (type1, type2):
  10597. return PyrexTypes.c_py_ucs4_type
  10598. else:
  10599. return PyrexTypes.c_uchar_type
  10600. return None
  10601. def find_common_type(self, env, op, operand1, common_type=None):
  10602. operand2 = self.operand2
  10603. type1 = operand1.type
  10604. type2 = operand2.type
  10605. new_common_type = None
  10606. # catch general errors
  10607. if (type1 == str_type and (type2.is_string or type2 in (bytes_type, unicode_type)) or
  10608. type2 == str_type and (type1.is_string or type1 in (bytes_type, unicode_type))):
  10609. error(self.pos, "Comparisons between bytes/unicode and str are not portable to Python 3")
  10610. new_common_type = error_type
  10611. # try to use numeric comparisons where possible
  10612. elif type1.is_complex or type2.is_complex:
  10613. if (op not in ('==', '!=')
  10614. and (type1.is_complex or type1.is_numeric)
  10615. and (type2.is_complex or type2.is_numeric)):
  10616. error(self.pos, "complex types are unordered")
  10617. new_common_type = error_type
  10618. elif type1.is_pyobject:
  10619. new_common_type = Builtin.complex_type if type1.subtype_of(Builtin.complex_type) else py_object_type
  10620. elif type2.is_pyobject:
  10621. new_common_type = Builtin.complex_type if type2.subtype_of(Builtin.complex_type) else py_object_type
  10622. else:
  10623. new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
  10624. elif type1.is_numeric and type2.is_numeric:
  10625. new_common_type = PyrexTypes.widest_numeric_type(type1, type2)
  10626. elif common_type is None or not common_type.is_pyobject:
  10627. new_common_type = self.find_common_int_type(env, op, operand1, operand2)
  10628. if new_common_type is None:
  10629. # fall back to generic type compatibility tests
  10630. if type1.is_ctuple or type2.is_ctuple:
  10631. new_common_type = py_object_type
  10632. elif type1 == type2:
  10633. new_common_type = type1
  10634. elif type1.is_pyobject or type2.is_pyobject:
  10635. if type2.is_numeric or type2.is_string:
  10636. if operand2.check_for_coercion_error(type1, env):
  10637. new_common_type = error_type
  10638. else:
  10639. new_common_type = py_object_type
  10640. elif type1.is_numeric or type1.is_string:
  10641. if operand1.check_for_coercion_error(type2, env):
  10642. new_common_type = error_type
  10643. else:
  10644. new_common_type = py_object_type
  10645. elif py_object_type.assignable_from(type1) and py_object_type.assignable_from(type2):
  10646. new_common_type = py_object_type
  10647. else:
  10648. # one Python type and one non-Python type, not assignable
  10649. self.invalid_types_error(operand1, op, operand2)
  10650. new_common_type = error_type
  10651. elif type1.assignable_from(type2):
  10652. new_common_type = type1
  10653. elif type2.assignable_from(type1):
  10654. new_common_type = type2
  10655. else:
  10656. # C types that we couldn't handle up to here are an error
  10657. self.invalid_types_error(operand1, op, operand2)
  10658. new_common_type = error_type
  10659. if new_common_type.is_string and (isinstance(operand1, BytesNode) or
  10660. isinstance(operand2, BytesNode)):
  10661. # special case when comparing char* to bytes literal: must
  10662. # compare string values!
  10663. new_common_type = bytes_type
  10664. # recursively merge types
  10665. if common_type is None or new_common_type.is_error:
  10666. common_type = new_common_type
  10667. else:
  10668. # we could do a lot better by splitting the comparison
  10669. # into a non-Python part and a Python part, but this is
  10670. # safer for now
  10671. common_type = PyrexTypes.spanning_type(common_type, new_common_type)
  10672. if self.cascade:
  10673. common_type = self.cascade.find_common_type(env, self.operator, operand2, common_type)
  10674. return common_type
  10675. def invalid_types_error(self, operand1, op, operand2):
  10676. error(self.pos, "Invalid types for '%s' (%s, %s)" %
  10677. (op, operand1.type, operand2.type))
  10678. def is_python_comparison(self):
  10679. return (not self.is_ptr_contains()
  10680. and not self.is_c_string_contains()
  10681. and (self.has_python_operands()
  10682. or (self.cascade and self.cascade.is_python_comparison())
  10683. or self.operator in ('in', 'not_in')))
  10684. def coerce_operands_to(self, dst_type, env):
  10685. operand2 = self.operand2
  10686. if operand2.type != dst_type:
  10687. self.operand2 = operand2.coerce_to(dst_type, env)
  10688. if self.cascade:
  10689. self.cascade.coerce_operands_to(dst_type, env)
  10690. def is_python_result(self):
  10691. return ((self.has_python_operands() and
  10692. self.special_bool_cmp_function is None and
  10693. self.operator not in ('is', 'is_not', 'in', 'not_in') and
  10694. not self.is_c_string_contains() and
  10695. not self.is_ptr_contains())
  10696. or (self.cascade and self.cascade.is_python_result()))
  10697. def is_c_string_contains(self):
  10698. return self.operator in ('in', 'not_in') and \
  10699. ((self.operand1.type.is_int
  10700. and (self.operand2.type.is_string or self.operand2.type is bytes_type)) or
  10701. (self.operand1.type.is_unicode_char
  10702. and self.operand2.type is unicode_type))
  10703. def is_ptr_contains(self):
  10704. if self.operator in ('in', 'not_in'):
  10705. container_type = self.operand2.type
  10706. return (container_type.is_ptr or container_type.is_array) \
  10707. and not container_type.is_string
  10708. def find_special_bool_compare_function(self, env, operand1, result_is_bool=False):
  10709. # note: currently operand1 must get coerced to a Python object if we succeed here!
  10710. if self.operator in ('==', '!='):
  10711. type1, type2 = operand1.type, self.operand2.type
  10712. if result_is_bool or (type1.is_builtin_type and type2.is_builtin_type):
  10713. if type1 is Builtin.unicode_type or type2 is Builtin.unicode_type:
  10714. self.special_bool_cmp_utility_code = UtilityCode.load_cached("UnicodeEquals", "StringTools.c")
  10715. self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
  10716. return True
  10717. elif type1 is Builtin.bytes_type or type2 is Builtin.bytes_type:
  10718. self.special_bool_cmp_utility_code = UtilityCode.load_cached("BytesEquals", "StringTools.c")
  10719. self.special_bool_cmp_function = "__Pyx_PyBytes_Equals"
  10720. return True
  10721. elif type1 is Builtin.basestring_type or type2 is Builtin.basestring_type:
  10722. self.special_bool_cmp_utility_code = UtilityCode.load_cached("UnicodeEquals", "StringTools.c")
  10723. self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
  10724. return True
  10725. elif type1 is Builtin.str_type or type2 is Builtin.str_type:
  10726. self.special_bool_cmp_utility_code = UtilityCode.load_cached("StrEquals", "StringTools.c")
  10727. self.special_bool_cmp_function = "__Pyx_PyString_Equals"
  10728. return True
  10729. elif self.operator in ('in', 'not_in'):
  10730. if self.operand2.type is Builtin.dict_type:
  10731. self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
  10732. self.special_bool_cmp_utility_code = UtilityCode.load_cached("PyDictContains", "ObjectHandling.c")
  10733. self.special_bool_cmp_function = "__Pyx_PyDict_ContainsTF"
  10734. return True
  10735. elif self.operand2.type is Builtin.set_type:
  10736. self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
  10737. self.special_bool_cmp_utility_code = UtilityCode.load_cached("PySetContains", "ObjectHandling.c")
  10738. self.special_bool_cmp_function = "__Pyx_PySet_ContainsTF"
  10739. return True
  10740. elif self.operand2.type is Builtin.unicode_type:
  10741. self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
  10742. self.special_bool_cmp_utility_code = UtilityCode.load_cached("PyUnicodeContains", "StringTools.c")
  10743. self.special_bool_cmp_function = "__Pyx_PyUnicode_ContainsTF"
  10744. return True
  10745. else:
  10746. if not self.operand2.type.is_pyobject:
  10747. self.operand2 = self.operand2.coerce_to_pyobject(env)
  10748. self.special_bool_cmp_utility_code = UtilityCode.load_cached("PySequenceContains", "ObjectHandling.c")
  10749. self.special_bool_cmp_function = "__Pyx_PySequence_ContainsTF"
  10750. return True
  10751. return False
  10752. def generate_operation_code(self, code, result_code,
  10753. operand1, op , operand2):
  10754. if self.type.is_pyobject:
  10755. error_clause = code.error_goto_if_null
  10756. got_ref = "__Pyx_XGOTREF(%s); " % result_code
  10757. if self.special_bool_cmp_function:
  10758. code.globalstate.use_utility_code(
  10759. UtilityCode.load_cached("PyBoolOrNullFromLong", "ObjectHandling.c"))
  10760. coerce_result = "__Pyx_PyBoolOrNull_FromLong"
  10761. else:
  10762. coerce_result = "__Pyx_PyBool_FromLong"
  10763. else:
  10764. error_clause = code.error_goto_if_neg
  10765. got_ref = ""
  10766. coerce_result = ""
  10767. if self.special_bool_cmp_function:
  10768. if operand1.type.is_pyobject:
  10769. result1 = operand1.py_result()
  10770. else:
  10771. result1 = operand1.result()
  10772. if operand2.type.is_pyobject:
  10773. result2 = operand2.py_result()
  10774. else:
  10775. result2 = operand2.result()
  10776. if self.special_bool_cmp_utility_code:
  10777. code.globalstate.use_utility_code(self.special_bool_cmp_utility_code)
  10778. code.putln(
  10779. "%s = %s(%s(%s, %s, %s)); %s%s" % (
  10780. result_code,
  10781. coerce_result,
  10782. self.special_bool_cmp_function,
  10783. result1, result2, richcmp_constants[op],
  10784. got_ref,
  10785. error_clause(result_code, self.pos)))
  10786. elif operand1.type.is_pyobject and op not in ('is', 'is_not'):
  10787. assert op not in ('in', 'not_in'), op
  10788. code.putln("%s = PyObject_RichCompare(%s, %s, %s); %s%s" % (
  10789. result_code,
  10790. operand1.py_result(),
  10791. operand2.py_result(),
  10792. richcmp_constants[op],
  10793. got_ref,
  10794. error_clause(result_code, self.pos)))
  10795. elif operand1.type.is_complex:
  10796. code.putln("%s = %s(%s%s(%s, %s));" % (
  10797. result_code,
  10798. coerce_result,
  10799. op == "!=" and "!" or "",
  10800. operand1.type.unary_op('eq'),
  10801. operand1.result(),
  10802. operand2.result()))
  10803. else:
  10804. type1 = operand1.type
  10805. type2 = operand2.type
  10806. if (type1.is_extension_type or type2.is_extension_type) \
  10807. and not type1.same_as(type2):
  10808. common_type = py_object_type
  10809. elif type1.is_numeric:
  10810. common_type = PyrexTypes.widest_numeric_type(type1, type2)
  10811. else:
  10812. common_type = type1
  10813. code1 = operand1.result_as(common_type)
  10814. code2 = operand2.result_as(common_type)
  10815. statement = "%s = %s(%s %s %s);" % (
  10816. result_code,
  10817. coerce_result,
  10818. code1,
  10819. self.c_operator(op),
  10820. code2)
  10821. if self.is_cpp_comparison() and self.exception_check == '+':
  10822. translate_cpp_exception(
  10823. code,
  10824. self.pos,
  10825. statement,
  10826. result_code if self.type.is_pyobject else None,
  10827. self.exception_value,
  10828. self.in_nogil_context)
  10829. else:
  10830. code.putln(statement)
  10831. def c_operator(self, op):
  10832. if op == 'is':
  10833. return "=="
  10834. elif op == 'is_not':
  10835. return "!="
  10836. else:
  10837. return op
  10838. class PrimaryCmpNode(ExprNode, CmpNode):
  10839. # Non-cascaded comparison or first comparison of
  10840. # a cascaded sequence.
  10841. #
  10842. # operator string
  10843. # operand1 ExprNode
  10844. # operand2 ExprNode
  10845. # cascade CascadedCmpNode
  10846. # We don't use the subexprs mechanism, because
  10847. # things here are too complicated for it to handle.
  10848. # Instead, we override all the framework methods
  10849. # which use it.
  10850. child_attrs = ['operand1', 'operand2', 'coerced_operand2', 'cascade']
  10851. cascade = None
  10852. coerced_operand2 = None
  10853. is_memslice_nonecheck = False
  10854. def infer_type(self, env):
  10855. type1 = self.operand1.infer_type(env)
  10856. type2 = self.operand2.infer_type(env)
  10857. if is_pythran_expr(type1) or is_pythran_expr(type2):
  10858. if is_pythran_supported_type(type1) and is_pythran_supported_type(type2):
  10859. return PythranExpr(pythran_binop_type(self.operator, type1, type2))
  10860. # TODO: implement this for other types.
  10861. return py_object_type
  10862. def type_dependencies(self, env):
  10863. return ()
  10864. def calculate_constant_result(self):
  10865. assert not self.cascade
  10866. self.calculate_cascaded_constant_result(self.operand1.constant_result)
  10867. def compile_time_value(self, denv):
  10868. operand1 = self.operand1.compile_time_value(denv)
  10869. return self.cascaded_compile_time_value(operand1, denv)
  10870. def analyse_types(self, env):
  10871. self.operand1 = self.operand1.analyse_types(env)
  10872. self.operand2 = self.operand2.analyse_types(env)
  10873. if self.is_cpp_comparison():
  10874. self.analyse_cpp_comparison(env)
  10875. if self.cascade:
  10876. error(self.pos, "Cascading comparison not yet supported for cpp types.")
  10877. return self
  10878. type1 = self.operand1.type
  10879. type2 = self.operand2.type
  10880. if is_pythran_expr(type1) or is_pythran_expr(type2):
  10881. if is_pythran_supported_type(type1) and is_pythran_supported_type(type2):
  10882. self.type = PythranExpr(pythran_binop_type(self.operator, type1, type2))
  10883. self.is_pycmp = False
  10884. return self
  10885. if self.analyse_memoryviewslice_comparison(env):
  10886. return self
  10887. if self.cascade:
  10888. self.cascade = self.cascade.analyse_types(env)
  10889. if self.operator in ('in', 'not_in'):
  10890. if self.is_c_string_contains():
  10891. self.is_pycmp = False
  10892. common_type = None
  10893. if self.cascade:
  10894. error(self.pos, "Cascading comparison not yet supported for 'int_val in string'.")
  10895. return self
  10896. if self.operand2.type is unicode_type:
  10897. env.use_utility_code(UtilityCode.load_cached("PyUCS4InUnicode", "StringTools.c"))
  10898. else:
  10899. if self.operand1.type is PyrexTypes.c_uchar_type:
  10900. self.operand1 = self.operand1.coerce_to(PyrexTypes.c_char_type, env)
  10901. if self.operand2.type is not bytes_type:
  10902. self.operand2 = self.operand2.coerce_to(bytes_type, env)
  10903. env.use_utility_code(UtilityCode.load_cached("BytesContains", "StringTools.c"))
  10904. self.operand2 = self.operand2.as_none_safe_node(
  10905. "argument of type 'NoneType' is not iterable")
  10906. elif self.is_ptr_contains():
  10907. if self.cascade:
  10908. error(self.pos, "Cascading comparison not supported for 'val in sliced pointer'.")
  10909. self.type = PyrexTypes.c_bint_type
  10910. # Will be transformed by IterationTransform
  10911. return self
  10912. elif self.find_special_bool_compare_function(env, self.operand1):
  10913. if not self.operand1.type.is_pyobject:
  10914. self.operand1 = self.operand1.coerce_to_pyobject(env)
  10915. common_type = None # if coercion needed, the method call above has already done it
  10916. self.is_pycmp = False # result is bint
  10917. else:
  10918. common_type = py_object_type
  10919. self.is_pycmp = True
  10920. elif self.find_special_bool_compare_function(env, self.operand1):
  10921. if not self.operand1.type.is_pyobject:
  10922. self.operand1 = self.operand1.coerce_to_pyobject(env)
  10923. common_type = None # if coercion needed, the method call above has already done it
  10924. self.is_pycmp = False # result is bint
  10925. else:
  10926. common_type = self.find_common_type(env, self.operator, self.operand1)
  10927. self.is_pycmp = common_type.is_pyobject
  10928. if common_type is not None and not common_type.is_error:
  10929. if self.operand1.type != common_type:
  10930. self.operand1 = self.operand1.coerce_to(common_type, env)
  10931. self.coerce_operands_to(common_type, env)
  10932. if self.cascade:
  10933. self.operand2 = self.operand2.coerce_to_simple(env)
  10934. self.cascade.coerce_cascaded_operands_to_temp(env)
  10935. operand2 = self.cascade.optimise_comparison(self.operand2, env)
  10936. if operand2 is not self.operand2:
  10937. self.coerced_operand2 = operand2
  10938. if self.is_python_result():
  10939. self.type = PyrexTypes.py_object_type
  10940. else:
  10941. self.type = PyrexTypes.c_bint_type
  10942. cdr = self.cascade
  10943. while cdr:
  10944. cdr.type = self.type
  10945. cdr = cdr.cascade
  10946. if self.is_pycmp or self.cascade or self.special_bool_cmp_function:
  10947. # 1) owned reference, 2) reused value, 3) potential function error return value
  10948. self.is_temp = 1
  10949. return self
  10950. def analyse_cpp_comparison(self, env):
  10951. type1 = self.operand1.type
  10952. type2 = self.operand2.type
  10953. self.is_pycmp = False
  10954. entry = env.lookup_operator(self.operator, [self.operand1, self.operand2])
  10955. if entry is None:
  10956. error(self.pos, "Invalid types for '%s' (%s, %s)" %
  10957. (self.operator, type1, type2))
  10958. self.type = PyrexTypes.error_type
  10959. self.result_code = "<error>"
  10960. return
  10961. func_type = entry.type
  10962. if func_type.is_ptr:
  10963. func_type = func_type.base_type
  10964. self.exception_check = func_type.exception_check
  10965. self.exception_value = func_type.exception_value
  10966. if self.exception_check == '+':
  10967. self.is_temp = True
  10968. if self.exception_value is None:
  10969. env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
  10970. if len(func_type.args) == 1:
  10971. self.operand2 = self.operand2.coerce_to(func_type.args[0].type, env)
  10972. else:
  10973. self.operand1 = self.operand1.coerce_to(func_type.args[0].type, env)
  10974. self.operand2 = self.operand2.coerce_to(func_type.args[1].type, env)
  10975. self.type = func_type.return_type
  10976. def analyse_memoryviewslice_comparison(self, env):
  10977. have_none = self.operand1.is_none or self.operand2.is_none
  10978. have_slice = (self.operand1.type.is_memoryviewslice or
  10979. self.operand2.type.is_memoryviewslice)
  10980. ops = ('==', '!=', 'is', 'is_not')
  10981. if have_slice and have_none and self.operator in ops:
  10982. self.is_pycmp = False
  10983. self.type = PyrexTypes.c_bint_type
  10984. self.is_memslice_nonecheck = True
  10985. return True
  10986. return False
  10987. def coerce_to_boolean(self, env):
  10988. if self.is_pycmp:
  10989. # coercing to bool => may allow for more efficient comparison code
  10990. if self.find_special_bool_compare_function(
  10991. env, self.operand1, result_is_bool=True):
  10992. self.is_pycmp = False
  10993. self.type = PyrexTypes.c_bint_type
  10994. self.is_temp = 1
  10995. if self.cascade:
  10996. operand2 = self.cascade.optimise_comparison(
  10997. self.operand2, env, result_is_bool=True)
  10998. if operand2 is not self.operand2:
  10999. self.coerced_operand2 = operand2
  11000. return self
  11001. # TODO: check if we can optimise parts of the cascade here
  11002. return ExprNode.coerce_to_boolean(self, env)
  11003. def has_python_operands(self):
  11004. return (self.operand1.type.is_pyobject
  11005. or self.operand2.type.is_pyobject)
  11006. def check_const(self):
  11007. if self.cascade:
  11008. self.not_const()
  11009. return False
  11010. else:
  11011. return self.operand1.check_const() and self.operand2.check_const()
  11012. def calculate_result_code(self):
  11013. operand1, operand2 = self.operand1, self.operand2
  11014. if operand1.type.is_complex:
  11015. if self.operator == "!=":
  11016. negation = "!"
  11017. else:
  11018. negation = ""
  11019. return "(%s%s(%s, %s))" % (
  11020. negation,
  11021. operand1.type.binary_op('=='),
  11022. operand1.result(),
  11023. operand2.result())
  11024. elif self.is_c_string_contains():
  11025. if operand2.type is unicode_type:
  11026. method = "__Pyx_UnicodeContainsUCS4"
  11027. else:
  11028. method = "__Pyx_BytesContains"
  11029. if self.operator == "not_in":
  11030. negation = "!"
  11031. else:
  11032. negation = ""
  11033. return "(%s%s(%s, %s))" % (
  11034. negation,
  11035. method,
  11036. operand2.result(),
  11037. operand1.result())
  11038. else:
  11039. if is_pythran_expr(self.type):
  11040. result1, result2 = operand1.pythran_result(), operand2.pythran_result()
  11041. else:
  11042. result1, result2 = operand1.result(), operand2.result()
  11043. if self.is_memslice_nonecheck:
  11044. if operand1.type.is_memoryviewslice:
  11045. result1 = "((PyObject *) %s.memview)" % result1
  11046. else:
  11047. result2 = "((PyObject *) %s.memview)" % result2
  11048. return "(%s %s %s)" % (
  11049. result1,
  11050. self.c_operator(self.operator),
  11051. result2)
  11052. def generate_evaluation_code(self, code):
  11053. self.operand1.generate_evaluation_code(code)
  11054. self.operand2.generate_evaluation_code(code)
  11055. if self.is_temp:
  11056. self.allocate_temp_result(code)
  11057. self.generate_operation_code(code, self.result(),
  11058. self.operand1, self.operator, self.operand2)
  11059. if self.cascade:
  11060. self.cascade.generate_evaluation_code(
  11061. code, self.result(), self.coerced_operand2 or self.operand2,
  11062. needs_evaluation=self.coerced_operand2 is not None)
  11063. self.operand1.generate_disposal_code(code)
  11064. self.operand1.free_temps(code)
  11065. self.operand2.generate_disposal_code(code)
  11066. self.operand2.free_temps(code)
  11067. def generate_subexpr_disposal_code(self, code):
  11068. # If this is called, it is a non-cascaded cmp,
  11069. # so only need to dispose of the two main operands.
  11070. self.operand1.generate_disposal_code(code)
  11071. self.operand2.generate_disposal_code(code)
  11072. def free_subexpr_temps(self, code):
  11073. # If this is called, it is a non-cascaded cmp,
  11074. # so only need to dispose of the two main operands.
  11075. self.operand1.free_temps(code)
  11076. self.operand2.free_temps(code)
  11077. def annotate(self, code):
  11078. self.operand1.annotate(code)
  11079. self.operand2.annotate(code)
  11080. if self.cascade:
  11081. self.cascade.annotate(code)
  11082. class CascadedCmpNode(Node, CmpNode):
  11083. # A CascadedCmpNode is not a complete expression node. It
  11084. # hangs off the side of another comparison node, shares
  11085. # its left operand with that node, and shares its result
  11086. # with the PrimaryCmpNode at the head of the chain.
  11087. #
  11088. # operator string
  11089. # operand2 ExprNode
  11090. # cascade CascadedCmpNode
  11091. child_attrs = ['operand2', 'coerced_operand2', 'cascade']
  11092. cascade = None
  11093. coerced_operand2 = None
  11094. constant_result = constant_value_not_set # FIXME: where to calculate this?
  11095. def infer_type(self, env):
  11096. # TODO: Actually implement this (after merging with -unstable).
  11097. return py_object_type
  11098. def type_dependencies(self, env):
  11099. return ()
  11100. def has_constant_result(self):
  11101. return self.constant_result is not constant_value_not_set and \
  11102. self.constant_result is not not_a_constant
  11103. def analyse_types(self, env):
  11104. self.operand2 = self.operand2.analyse_types(env)
  11105. if self.cascade:
  11106. self.cascade = self.cascade.analyse_types(env)
  11107. return self
  11108. def has_python_operands(self):
  11109. return self.operand2.type.is_pyobject
  11110. def is_cpp_comparison(self):
  11111. # cascaded comparisons aren't currently implemented for c++ classes.
  11112. return False
  11113. def optimise_comparison(self, operand1, env, result_is_bool=False):
  11114. if self.find_special_bool_compare_function(env, operand1, result_is_bool):
  11115. self.is_pycmp = False
  11116. self.type = PyrexTypes.c_bint_type
  11117. if not operand1.type.is_pyobject:
  11118. operand1 = operand1.coerce_to_pyobject(env)
  11119. if self.cascade:
  11120. operand2 = self.cascade.optimise_comparison(self.operand2, env, result_is_bool)
  11121. if operand2 is not self.operand2:
  11122. self.coerced_operand2 = operand2
  11123. return operand1
  11124. def coerce_operands_to_pyobjects(self, env):
  11125. self.operand2 = self.operand2.coerce_to_pyobject(env)
  11126. if self.operand2.type is dict_type and self.operator in ('in', 'not_in'):
  11127. self.operand2 = self.operand2.as_none_safe_node("'NoneType' object is not iterable")
  11128. if self.cascade:
  11129. self.cascade.coerce_operands_to_pyobjects(env)
  11130. def coerce_cascaded_operands_to_temp(self, env):
  11131. if self.cascade:
  11132. #self.operand2 = self.operand2.coerce_to_temp(env) #CTT
  11133. self.operand2 = self.operand2.coerce_to_simple(env)
  11134. self.cascade.coerce_cascaded_operands_to_temp(env)
  11135. def generate_evaluation_code(self, code, result, operand1, needs_evaluation=False):
  11136. if self.type.is_pyobject:
  11137. code.putln("if (__Pyx_PyObject_IsTrue(%s)) {" % result)
  11138. code.put_decref(result, self.type)
  11139. else:
  11140. code.putln("if (%s) {" % result)
  11141. if needs_evaluation:
  11142. operand1.generate_evaluation_code(code)
  11143. self.operand2.generate_evaluation_code(code)
  11144. self.generate_operation_code(code, result,
  11145. operand1, self.operator, self.operand2)
  11146. if self.cascade:
  11147. self.cascade.generate_evaluation_code(
  11148. code, result, self.coerced_operand2 or self.operand2,
  11149. needs_evaluation=self.coerced_operand2 is not None)
  11150. if needs_evaluation:
  11151. operand1.generate_disposal_code(code)
  11152. operand1.free_temps(code)
  11153. # Cascaded cmp result is always temp
  11154. self.operand2.generate_disposal_code(code)
  11155. self.operand2.free_temps(code)
  11156. code.putln("}")
  11157. def annotate(self, code):
  11158. self.operand2.annotate(code)
  11159. if self.cascade:
  11160. self.cascade.annotate(code)
  11161. binop_node_classes = {
  11162. "or": BoolBinopNode,
  11163. "and": BoolBinopNode,
  11164. "|": IntBinopNode,
  11165. "^": IntBinopNode,
  11166. "&": IntBinopNode,
  11167. "<<": IntBinopNode,
  11168. ">>": IntBinopNode,
  11169. "+": AddNode,
  11170. "-": SubNode,
  11171. "*": MulNode,
  11172. "@": MatMultNode,
  11173. "/": DivNode,
  11174. "//": DivNode,
  11175. "%": ModNode,
  11176. "**": PowNode,
  11177. }
  11178. def binop_node(pos, operator, operand1, operand2, inplace=False, **kwargs):
  11179. # Construct binop node of appropriate class for
  11180. # given operator.
  11181. return binop_node_classes[operator](
  11182. pos,
  11183. operator=operator,
  11184. operand1=operand1,
  11185. operand2=operand2,
  11186. inplace=inplace,
  11187. **kwargs)
  11188. #-------------------------------------------------------------------
  11189. #
  11190. # Coercion nodes
  11191. #
  11192. # Coercion nodes are special in that they are created during
  11193. # the analyse_types phase of parse tree processing.
  11194. # Their __init__ methods consequently incorporate some aspects
  11195. # of that phase.
  11196. #
  11197. #-------------------------------------------------------------------
  11198. class CoercionNode(ExprNode):
  11199. # Abstract base class for coercion nodes.
  11200. #
  11201. # arg ExprNode node being coerced
  11202. subexprs = ['arg']
  11203. constant_result = not_a_constant
  11204. def __init__(self, arg):
  11205. super(CoercionNode, self).__init__(arg.pos)
  11206. self.arg = arg
  11207. if debug_coercion:
  11208. print("%s Coercing %s" % (self, self.arg))
  11209. def calculate_constant_result(self):
  11210. # constant folding can break type coercion, so this is disabled
  11211. pass
  11212. def annotate(self, code):
  11213. self.arg.annotate(code)
  11214. if self.arg.type != self.type:
  11215. file, line, col = self.pos
  11216. code.annotate((file, line, col-1), AnnotationItem(
  11217. style='coerce', tag='coerce', text='[%s] to [%s]' % (self.arg.type, self.type)))
  11218. class CoerceToMemViewSliceNode(CoercionNode):
  11219. """
  11220. Coerce an object to a memoryview slice. This holds a new reference in
  11221. a managed temp.
  11222. """
  11223. def __init__(self, arg, dst_type, env):
  11224. assert dst_type.is_memoryviewslice
  11225. assert not arg.type.is_memoryviewslice
  11226. CoercionNode.__init__(self, arg)
  11227. self.type = dst_type
  11228. self.is_temp = 1
  11229. self.use_managed_ref = True
  11230. self.arg = arg
  11231. self.type.create_from_py_utility_code(env)
  11232. def generate_result_code(self, code):
  11233. code.putln(self.type.from_py_call_code(
  11234. self.arg.py_result(),
  11235. self.result(),
  11236. self.pos,
  11237. code
  11238. ))
  11239. class CastNode(CoercionNode):
  11240. # Wrap a node in a C type cast.
  11241. def __init__(self, arg, new_type):
  11242. CoercionNode.__init__(self, arg)
  11243. self.type = new_type
  11244. def may_be_none(self):
  11245. return self.arg.may_be_none()
  11246. def calculate_result_code(self):
  11247. return self.arg.result_as(self.type)
  11248. def generate_result_code(self, code):
  11249. self.arg.generate_result_code(code)
  11250. class PyTypeTestNode(CoercionNode):
  11251. # This node is used to check that a generic Python
  11252. # object is an instance of a particular extension type.
  11253. # This node borrows the result of its argument node.
  11254. exact_builtin_type = True
  11255. def __init__(self, arg, dst_type, env, notnone=False):
  11256. # The arg is know to be a Python object, and
  11257. # the dst_type is known to be an extension type.
  11258. assert dst_type.is_extension_type or dst_type.is_builtin_type, "PyTypeTest on non extension type"
  11259. CoercionNode.__init__(self, arg)
  11260. self.type = dst_type
  11261. self.result_ctype = arg.ctype()
  11262. self.notnone = notnone
  11263. nogil_check = Node.gil_error
  11264. gil_message = "Python type test"
  11265. def analyse_types(self, env):
  11266. return self
  11267. def may_be_none(self):
  11268. if self.notnone:
  11269. return False
  11270. return self.arg.may_be_none()
  11271. def is_simple(self):
  11272. return self.arg.is_simple()
  11273. def result_in_temp(self):
  11274. return self.arg.result_in_temp()
  11275. def is_ephemeral(self):
  11276. return self.arg.is_ephemeral()
  11277. def nonlocally_immutable(self):
  11278. return self.arg.nonlocally_immutable()
  11279. def reanalyse(self):
  11280. if self.type != self.arg.type or not self.arg.is_temp:
  11281. return self
  11282. if not self.type.typeobj_is_available():
  11283. return self
  11284. if self.arg.may_be_none() and self.notnone:
  11285. return self.arg.as_none_safe_node("Cannot convert NoneType to %.200s" % self.type.name)
  11286. return self.arg
  11287. def calculate_constant_result(self):
  11288. # FIXME
  11289. pass
  11290. def calculate_result_code(self):
  11291. return self.arg.result()
  11292. def generate_result_code(self, code):
  11293. if self.type.typeobj_is_available():
  11294. if self.type.is_builtin_type:
  11295. type_test = self.type.type_test_code(
  11296. self.arg.py_result(),
  11297. self.notnone, exact=self.exact_builtin_type)
  11298. else:
  11299. type_test = self.type.type_test_code(
  11300. self.arg.py_result(), self.notnone)
  11301. code.globalstate.use_utility_code(
  11302. UtilityCode.load_cached("ExtTypeTest", "ObjectHandling.c"))
  11303. code.putln("if (!(%s)) %s" % (
  11304. type_test, code.error_goto(self.pos)))
  11305. else:
  11306. error(self.pos, "Cannot test type of extern C class "
  11307. "without type object name specification")
  11308. def generate_post_assignment_code(self, code):
  11309. self.arg.generate_post_assignment_code(code)
  11310. def allocate_temp_result(self, code):
  11311. pass
  11312. def release_temp_result(self, code):
  11313. pass
  11314. def free_temps(self, code):
  11315. self.arg.free_temps(code)
  11316. def free_subexpr_temps(self, code):
  11317. self.arg.free_subexpr_temps(code)
  11318. class NoneCheckNode(CoercionNode):
  11319. # This node is used to check that a Python object is not None and
  11320. # raises an appropriate exception (as specified by the creating
  11321. # transform).
  11322. is_nonecheck = True
  11323. def __init__(self, arg, exception_type_cname, exception_message,
  11324. exception_format_args=()):
  11325. CoercionNode.__init__(self, arg)
  11326. self.type = arg.type
  11327. self.result_ctype = arg.ctype()
  11328. self.exception_type_cname = exception_type_cname
  11329. self.exception_message = exception_message
  11330. self.exception_format_args = tuple(exception_format_args or ())
  11331. nogil_check = None # this node only guards an operation that would fail already
  11332. def analyse_types(self, env):
  11333. return self
  11334. def may_be_none(self):
  11335. return False
  11336. def is_simple(self):
  11337. return self.arg.is_simple()
  11338. def result_in_temp(self):
  11339. return self.arg.result_in_temp()
  11340. def nonlocally_immutable(self):
  11341. return self.arg.nonlocally_immutable()
  11342. def calculate_result_code(self):
  11343. return self.arg.result()
  11344. def condition(self):
  11345. if self.type.is_pyobject:
  11346. return self.arg.py_result()
  11347. elif self.type.is_memoryviewslice:
  11348. return "((PyObject *) %s.memview)" % self.arg.result()
  11349. else:
  11350. raise Exception("unsupported type")
  11351. @classmethod
  11352. def generate(cls, arg, code, exception_message,
  11353. exception_type_cname="PyExc_TypeError", exception_format_args=(), in_nogil_context=False):
  11354. node = cls(arg, exception_type_cname, exception_message, exception_format_args)
  11355. node.in_nogil_context = in_nogil_context
  11356. node.put_nonecheck(code)
  11357. @classmethod
  11358. def generate_if_needed(cls, arg, code, exception_message,
  11359. exception_type_cname="PyExc_TypeError", exception_format_args=(), in_nogil_context=False):
  11360. if arg.may_be_none():
  11361. cls.generate(arg, code, exception_message, exception_type_cname, exception_format_args, in_nogil_context)
  11362. def put_nonecheck(self, code):
  11363. code.putln(
  11364. "if (unlikely(%s == Py_None)) {" % self.condition())
  11365. if self.in_nogil_context:
  11366. code.put_ensure_gil()
  11367. escape = StringEncoding.escape_byte_string
  11368. if self.exception_format_args:
  11369. code.putln('PyErr_Format(%s, "%s", %s);' % (
  11370. self.exception_type_cname,
  11371. StringEncoding.escape_byte_string(
  11372. self.exception_message.encode('UTF-8')),
  11373. ', '.join([ '"%s"' % escape(str(arg).encode('UTF-8'))
  11374. for arg in self.exception_format_args ])))
  11375. else:
  11376. code.putln('PyErr_SetString(%s, "%s");' % (
  11377. self.exception_type_cname,
  11378. escape(self.exception_message.encode('UTF-8'))))
  11379. if self.in_nogil_context:
  11380. code.put_release_ensured_gil()
  11381. code.putln(code.error_goto(self.pos))
  11382. code.putln("}")
  11383. def generate_result_code(self, code):
  11384. self.put_nonecheck(code)
  11385. def generate_post_assignment_code(self, code):
  11386. self.arg.generate_post_assignment_code(code)
  11387. def free_temps(self, code):
  11388. self.arg.free_temps(code)
  11389. class CoerceToPyTypeNode(CoercionNode):
  11390. # This node is used to convert a C data type
  11391. # to a Python object.
  11392. type = py_object_type
  11393. target_type = py_object_type
  11394. is_temp = 1
  11395. def __init__(self, arg, env, type=py_object_type):
  11396. if not arg.type.create_to_py_utility_code(env):
  11397. error(arg.pos, "Cannot convert '%s' to Python object" % arg.type)
  11398. elif arg.type.is_complex:
  11399. # special case: complex coercion is so complex that it
  11400. # uses a macro ("__pyx_PyComplex_FromComplex()"), for
  11401. # which the argument must be simple
  11402. arg = arg.coerce_to_simple(env)
  11403. CoercionNode.__init__(self, arg)
  11404. if type is py_object_type:
  11405. # be specific about some known types
  11406. if arg.type.is_string or arg.type.is_cpp_string:
  11407. self.type = default_str_type(env)
  11408. elif arg.type.is_pyunicode_ptr or arg.type.is_unicode_char:
  11409. self.type = unicode_type
  11410. elif arg.type.is_complex:
  11411. self.type = Builtin.complex_type
  11412. self.target_type = self.type
  11413. elif arg.type.is_string or arg.type.is_cpp_string:
  11414. if (type not in (bytes_type, bytearray_type)
  11415. and not env.directives['c_string_encoding']):
  11416. error(arg.pos,
  11417. "default encoding required for conversion from '%s' to '%s'" %
  11418. (arg.type, type))
  11419. self.type = self.target_type = type
  11420. else:
  11421. # FIXME: check that the target type and the resulting type are compatible
  11422. self.target_type = type
  11423. gil_message = "Converting to Python object"
  11424. def may_be_none(self):
  11425. # FIXME: is this always safe?
  11426. return False
  11427. def coerce_to_boolean(self, env):
  11428. arg_type = self.arg.type
  11429. if (arg_type == PyrexTypes.c_bint_type or
  11430. (arg_type.is_pyobject and arg_type.name == 'bool')):
  11431. return self.arg.coerce_to_temp(env)
  11432. else:
  11433. return CoerceToBooleanNode(self, env)
  11434. def coerce_to_integer(self, env):
  11435. # If not already some C integer type, coerce to longint.
  11436. if self.arg.type.is_int:
  11437. return self.arg
  11438. else:
  11439. return self.arg.coerce_to(PyrexTypes.c_long_type, env)
  11440. def analyse_types(self, env):
  11441. # The arg is always already analysed
  11442. return self
  11443. def generate_result_code(self, code):
  11444. code.putln('%s; %s' % (
  11445. self.arg.type.to_py_call_code(
  11446. self.arg.result(),
  11447. self.result(),
  11448. self.target_type),
  11449. code.error_goto_if_null(self.result(), self.pos)))
  11450. code.put_gotref(self.py_result())
  11451. class CoerceIntToBytesNode(CoerceToPyTypeNode):
  11452. # This node is used to convert a C int type to a Python bytes
  11453. # object.
  11454. is_temp = 1
  11455. def __init__(self, arg, env):
  11456. arg = arg.coerce_to_simple(env)
  11457. CoercionNode.__init__(self, arg)
  11458. self.type = Builtin.bytes_type
  11459. def generate_result_code(self, code):
  11460. arg = self.arg
  11461. arg_result = arg.result()
  11462. if arg.type not in (PyrexTypes.c_char_type,
  11463. PyrexTypes.c_uchar_type,
  11464. PyrexTypes.c_schar_type):
  11465. if arg.type.signed:
  11466. code.putln("if ((%s < 0) || (%s > 255)) {" % (
  11467. arg_result, arg_result))
  11468. else:
  11469. code.putln("if (%s > 255) {" % arg_result)
  11470. code.putln('PyErr_SetString(PyExc_OverflowError, '
  11471. '"value too large to pack into a byte"); %s' % (
  11472. code.error_goto(self.pos)))
  11473. code.putln('}')
  11474. temp = None
  11475. if arg.type is not PyrexTypes.c_char_type:
  11476. temp = code.funcstate.allocate_temp(PyrexTypes.c_char_type, manage_ref=False)
  11477. code.putln("%s = (char)%s;" % (temp, arg_result))
  11478. arg_result = temp
  11479. code.putln('%s = PyBytes_FromStringAndSize(&%s, 1); %s' % (
  11480. self.result(),
  11481. arg_result,
  11482. code.error_goto_if_null(self.result(), self.pos)))
  11483. if temp is not None:
  11484. code.funcstate.release_temp(temp)
  11485. code.put_gotref(self.py_result())
  11486. class CoerceFromPyTypeNode(CoercionNode):
  11487. # This node is used to convert a Python object
  11488. # to a C data type.
  11489. def __init__(self, result_type, arg, env):
  11490. CoercionNode.__init__(self, arg)
  11491. self.type = result_type
  11492. self.is_temp = 1
  11493. if not result_type.create_from_py_utility_code(env):
  11494. error(arg.pos,
  11495. "Cannot convert Python object to '%s'" % result_type)
  11496. if self.type.is_string or self.type.is_pyunicode_ptr:
  11497. if self.arg.is_name and self.arg.entry and self.arg.entry.is_pyglobal:
  11498. warning(arg.pos,
  11499. "Obtaining '%s' from externally modifiable global Python value" % result_type,
  11500. level=1)
  11501. def analyse_types(self, env):
  11502. # The arg is always already analysed
  11503. return self
  11504. def is_ephemeral(self):
  11505. return (self.type.is_ptr and not self.type.is_array) and self.arg.is_ephemeral()
  11506. def generate_result_code(self, code):
  11507. from_py_function = None
  11508. # for certain source types, we can do better than the generic coercion
  11509. if self.type.is_string and self.arg.type is bytes_type:
  11510. if self.type.from_py_function.startswith('__Pyx_PyObject_As'):
  11511. from_py_function = '__Pyx_PyBytes' + self.type.from_py_function[len('__Pyx_PyObject'):]
  11512. NoneCheckNode.generate_if_needed(self.arg, code, "expected bytes, NoneType found")
  11513. code.putln(self.type.from_py_call_code(
  11514. self.arg.py_result(), self.result(), self.pos, code, from_py_function=from_py_function))
  11515. if self.type.is_pyobject:
  11516. code.put_gotref(self.py_result())
  11517. def nogil_check(self, env):
  11518. error(self.pos, "Coercion from Python not allowed without the GIL")
  11519. class CoerceToBooleanNode(CoercionNode):
  11520. # This node is used when a result needs to be used
  11521. # in a boolean context.
  11522. type = PyrexTypes.c_bint_type
  11523. _special_builtins = {
  11524. Builtin.list_type: 'PyList_GET_SIZE',
  11525. Builtin.tuple_type: 'PyTuple_GET_SIZE',
  11526. Builtin.set_type: 'PySet_GET_SIZE',
  11527. Builtin.frozenset_type: 'PySet_GET_SIZE',
  11528. Builtin.bytes_type: 'PyBytes_GET_SIZE',
  11529. Builtin.bytearray_type: 'PyByteArray_GET_SIZE',
  11530. Builtin.unicode_type: '__Pyx_PyUnicode_IS_TRUE',
  11531. }
  11532. def __init__(self, arg, env):
  11533. CoercionNode.__init__(self, arg)
  11534. if arg.type.is_pyobject:
  11535. self.is_temp = 1
  11536. def nogil_check(self, env):
  11537. if self.arg.type.is_pyobject and self._special_builtins.get(self.arg.type) is None:
  11538. self.gil_error()
  11539. gil_message = "Truth-testing Python object"
  11540. def check_const(self):
  11541. if self.is_temp:
  11542. self.not_const()
  11543. return False
  11544. return self.arg.check_const()
  11545. def calculate_result_code(self):
  11546. return "(%s != 0)" % self.arg.result()
  11547. def generate_result_code(self, code):
  11548. if not self.is_temp:
  11549. return
  11550. test_func = self._special_builtins.get(self.arg.type)
  11551. if test_func is not None:
  11552. checks = ["(%s != Py_None)" % self.arg.py_result()] if self.arg.may_be_none() else []
  11553. checks.append("(%s(%s) != 0)" % (test_func, self.arg.py_result()))
  11554. code.putln("%s = %s;" % (self.result(), '&&'.join(checks)))
  11555. else:
  11556. code.putln(
  11557. "%s = __Pyx_PyObject_IsTrue(%s); %s" % (
  11558. self.result(),
  11559. self.arg.py_result(),
  11560. code.error_goto_if_neg(self.result(), self.pos)))
  11561. class CoerceToComplexNode(CoercionNode):
  11562. def __init__(self, arg, dst_type, env):
  11563. if arg.type.is_complex:
  11564. arg = arg.coerce_to_simple(env)
  11565. self.type = dst_type
  11566. CoercionNode.__init__(self, arg)
  11567. dst_type.create_declaration_utility_code(env)
  11568. def calculate_result_code(self):
  11569. if self.arg.type.is_complex:
  11570. real_part = "__Pyx_CREAL(%s)" % self.arg.result()
  11571. imag_part = "__Pyx_CIMAG(%s)" % self.arg.result()
  11572. else:
  11573. real_part = self.arg.result()
  11574. imag_part = "0"
  11575. return "%s(%s, %s)" % (
  11576. self.type.from_parts,
  11577. real_part,
  11578. imag_part)
  11579. def generate_result_code(self, code):
  11580. pass
  11581. class CoerceToTempNode(CoercionNode):
  11582. # This node is used to force the result of another node
  11583. # to be stored in a temporary. It is only used if the
  11584. # argument node's result is not already in a temporary.
  11585. def __init__(self, arg, env):
  11586. CoercionNode.__init__(self, arg)
  11587. self.type = self.arg.type.as_argument_type()
  11588. self.constant_result = self.arg.constant_result
  11589. self.is_temp = 1
  11590. if self.type.is_pyobject:
  11591. self.result_ctype = py_object_type
  11592. gil_message = "Creating temporary Python reference"
  11593. def analyse_types(self, env):
  11594. # The arg is always already analysed
  11595. return self
  11596. def coerce_to_boolean(self, env):
  11597. self.arg = self.arg.coerce_to_boolean(env)
  11598. if self.arg.is_simple():
  11599. return self.arg
  11600. self.type = self.arg.type
  11601. self.result_ctype = self.type
  11602. return self
  11603. def generate_result_code(self, code):
  11604. #self.arg.generate_evaluation_code(code) # Already done
  11605. # by generic generate_subexpr_evaluation_code!
  11606. code.putln("%s = %s;" % (
  11607. self.result(), self.arg.result_as(self.ctype())))
  11608. if self.use_managed_ref:
  11609. if self.type.is_pyobject:
  11610. code.put_incref(self.result(), self.ctype())
  11611. elif self.type.is_memoryviewslice:
  11612. code.put_incref_memoryviewslice(self.result(),
  11613. not self.in_nogil_context)
  11614. class ProxyNode(CoercionNode):
  11615. """
  11616. A node that should not be replaced by transforms or other means,
  11617. and hence can be useful to wrap the argument to a clone node
  11618. MyNode -> ProxyNode -> ArgNode
  11619. CloneNode -^
  11620. """
  11621. nogil_check = None
  11622. def __init__(self, arg):
  11623. super(ProxyNode, self).__init__(arg)
  11624. self.constant_result = arg.constant_result
  11625. self._proxy_type()
  11626. def analyse_types(self, env):
  11627. self.arg = self.arg.analyse_expressions(env)
  11628. self._proxy_type()
  11629. return self
  11630. def infer_type(self, env):
  11631. return self.arg.infer_type(env)
  11632. def _proxy_type(self):
  11633. if hasattr(self.arg, 'type'):
  11634. self.type = self.arg.type
  11635. self.result_ctype = self.arg.result_ctype
  11636. if hasattr(self.arg, 'entry'):
  11637. self.entry = self.arg.entry
  11638. def generate_result_code(self, code):
  11639. self.arg.generate_result_code(code)
  11640. def result(self):
  11641. return self.arg.result()
  11642. def is_simple(self):
  11643. return self.arg.is_simple()
  11644. def may_be_none(self):
  11645. return self.arg.may_be_none()
  11646. def generate_evaluation_code(self, code):
  11647. self.arg.generate_evaluation_code(code)
  11648. def generate_disposal_code(self, code):
  11649. self.arg.generate_disposal_code(code)
  11650. def free_temps(self, code):
  11651. self.arg.free_temps(code)
  11652. class CloneNode(CoercionNode):
  11653. # This node is employed when the result of another node needs
  11654. # to be used multiple times. The argument node's result must
  11655. # be in a temporary. This node "borrows" the result from the
  11656. # argument node, and does not generate any evaluation or
  11657. # disposal code for it. The original owner of the argument
  11658. # node is responsible for doing those things.
  11659. subexprs = [] # Arg is not considered a subexpr
  11660. nogil_check = None
  11661. def __init__(self, arg):
  11662. CoercionNode.__init__(self, arg)
  11663. self.constant_result = arg.constant_result
  11664. if hasattr(arg, 'type'):
  11665. self.type = arg.type
  11666. self.result_ctype = arg.result_ctype
  11667. if hasattr(arg, 'entry'):
  11668. self.entry = arg.entry
  11669. def result(self):
  11670. return self.arg.result()
  11671. def may_be_none(self):
  11672. return self.arg.may_be_none()
  11673. def type_dependencies(self, env):
  11674. return self.arg.type_dependencies(env)
  11675. def infer_type(self, env):
  11676. return self.arg.infer_type(env)
  11677. def analyse_types(self, env):
  11678. self.type = self.arg.type
  11679. self.result_ctype = self.arg.result_ctype
  11680. self.is_temp = 1
  11681. if hasattr(self.arg, 'entry'):
  11682. self.entry = self.arg.entry
  11683. return self
  11684. def coerce_to(self, dest_type, env):
  11685. if self.arg.is_literal:
  11686. return self.arg.coerce_to(dest_type, env)
  11687. return super(CloneNode, self).coerce_to(dest_type, env)
  11688. def is_simple(self):
  11689. return True # result is always in a temp (or a name)
  11690. def generate_evaluation_code(self, code):
  11691. pass
  11692. def generate_result_code(self, code):
  11693. pass
  11694. def generate_disposal_code(self, code):
  11695. pass
  11696. def free_temps(self, code):
  11697. pass
  11698. class CMethodSelfCloneNode(CloneNode):
  11699. # Special CloneNode for the self argument of builtin C methods
  11700. # that accepts subtypes of the builtin type. This is safe only
  11701. # for 'final' subtypes, as subtypes of the declared type may
  11702. # override the C method.
  11703. def coerce_to(self, dst_type, env):
  11704. if dst_type.is_builtin_type and self.type.subtype_of(dst_type):
  11705. return self
  11706. return CloneNode.coerce_to(self, dst_type, env)
  11707. class ModuleRefNode(ExprNode):
  11708. # Simple returns the module object
  11709. type = py_object_type
  11710. is_temp = False
  11711. subexprs = []
  11712. def analyse_types(self, env):
  11713. return self
  11714. def may_be_none(self):
  11715. return False
  11716. def calculate_result_code(self):
  11717. return Naming.module_cname
  11718. def generate_result_code(self, code):
  11719. pass
  11720. class DocstringRefNode(ExprNode):
  11721. # Extracts the docstring of the body element
  11722. subexprs = ['body']
  11723. type = py_object_type
  11724. is_temp = True
  11725. def __init__(self, pos, body):
  11726. ExprNode.__init__(self, pos)
  11727. assert body.type.is_pyobject
  11728. self.body = body
  11729. def analyse_types(self, env):
  11730. return self
  11731. def generate_result_code(self, code):
  11732. code.putln('%s = __Pyx_GetAttr(%s, %s); %s' % (
  11733. self.result(), self.body.result(),
  11734. code.intern_identifier(StringEncoding.EncodedString("__doc__")),
  11735. code.error_goto_if_null(self.result(), self.pos)))
  11736. code.put_gotref(self.result())
  11737. #------------------------------------------------------------------------------------
  11738. #
  11739. # Runtime support code
  11740. #
  11741. #------------------------------------------------------------------------------------
  11742. pyerr_occurred_withgil_utility_code= UtilityCode(
  11743. proto = """
  11744. static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void); /* proto */
  11745. """,
  11746. impl = """
  11747. static CYTHON_INLINE int __Pyx_ErrOccurredWithGIL(void) {
  11748. int err;
  11749. #ifdef WITH_THREAD
  11750. PyGILState_STATE _save = PyGILState_Ensure();
  11751. #endif
  11752. err = !!PyErr_Occurred();
  11753. #ifdef WITH_THREAD
  11754. PyGILState_Release(_save);
  11755. #endif
  11756. return err;
  11757. }
  11758. """
  11759. )
  11760. #------------------------------------------------------------------------------------
  11761. raise_unbound_local_error_utility_code = UtilityCode(
  11762. proto = """
  11763. static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname);
  11764. """,
  11765. impl = """
  11766. static CYTHON_INLINE void __Pyx_RaiseUnboundLocalError(const char *varname) {
  11767. PyErr_Format(PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", varname);
  11768. }
  11769. """)
  11770. raise_closure_name_error_utility_code = UtilityCode(
  11771. proto = """
  11772. static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname);
  11773. """,
  11774. impl = """
  11775. static CYTHON_INLINE void __Pyx_RaiseClosureNameError(const char *varname) {
  11776. PyErr_Format(PyExc_NameError, "free variable '%s' referenced before assignment in enclosing scope", varname);
  11777. }
  11778. """)
  11779. # Don't inline the function, it should really never be called in production
  11780. raise_unbound_memoryview_utility_code_nogil = UtilityCode(
  11781. proto = """
  11782. static void __Pyx_RaiseUnboundMemoryviewSliceNogil(const char *varname);
  11783. """,
  11784. impl = """
  11785. static void __Pyx_RaiseUnboundMemoryviewSliceNogil(const char *varname) {
  11786. #ifdef WITH_THREAD
  11787. PyGILState_STATE gilstate = PyGILState_Ensure();
  11788. #endif
  11789. __Pyx_RaiseUnboundLocalError(varname);
  11790. #ifdef WITH_THREAD
  11791. PyGILState_Release(gilstate);
  11792. #endif
  11793. }
  11794. """,
  11795. requires = [raise_unbound_local_error_utility_code])
  11796. #------------------------------------------------------------------------------------
  11797. raise_too_many_values_to_unpack = UtilityCode.load_cached("RaiseTooManyValuesToUnpack", "ObjectHandling.c")
  11798. raise_need_more_values_to_unpack = UtilityCode.load_cached("RaiseNeedMoreValuesToUnpack", "ObjectHandling.c")
  11799. tuple_unpacking_error_code = UtilityCode.load_cached("UnpackTupleError", "ObjectHandling.c")