test_buffer.py 160 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434
  1. #
  2. # The ndarray object from _testbuffer.c is a complete implementation of
  3. # a PEP-3118 buffer provider. It is independent from NumPy's ndarray
  4. # and the tests don't require NumPy.
  5. #
  6. # If NumPy is present, some tests check both ndarray implementations
  7. # against each other.
  8. #
  9. # Most ndarray tests also check that memoryview(ndarray) behaves in
  10. # the same way as the original. Thus, a substantial part of the
  11. # memoryview tests is now in this module.
  12. #
  13. # Written and designed by Stefan Krah for Python 3.3.
  14. #
  15. import contextlib
  16. import unittest
  17. from test import support
  18. from test.support import os_helper
  19. from itertools import permutations, product
  20. from random import randrange, sample, choice
  21. import warnings
  22. import sys, array, io, os
  23. from decimal import Decimal
  24. from fractions import Fraction
  25. try:
  26. from _testbuffer import *
  27. except ImportError:
  28. ndarray = None
  29. try:
  30. import struct
  31. except ImportError:
  32. struct = None
  33. try:
  34. import ctypes
  35. except ImportError:
  36. ctypes = None
  37. try:
  38. with os_helper.EnvironmentVarGuard() as os.environ, \
  39. warnings.catch_warnings():
  40. from numpy import ndarray as numpy_array
  41. except ImportError:
  42. numpy_array = None
  43. try:
  44. import _testcapi
  45. except ImportError:
  46. _testcapi = None
  47. SHORT_TEST = True
  48. # ======================================================================
  49. # Random lists by format specifier
  50. # ======================================================================
  51. # Native format chars and their ranges.
  52. NATIVE = {
  53. '?':0, 'c':0, 'b':0, 'B':0,
  54. 'h':0, 'H':0, 'i':0, 'I':0,
  55. 'l':0, 'L':0, 'n':0, 'N':0,
  56. 'f':0, 'd':0, 'P':0
  57. }
  58. # NumPy does not have 'n' or 'N':
  59. if numpy_array:
  60. del NATIVE['n']
  61. del NATIVE['N']
  62. if struct:
  63. try:
  64. # Add "qQ" if present in native mode.
  65. struct.pack('Q', 2**64-1)
  66. NATIVE['q'] = 0
  67. NATIVE['Q'] = 0
  68. except struct.error:
  69. pass
  70. # Standard format chars and their ranges.
  71. STANDARD = {
  72. '?':(0, 2), 'c':(0, 1<<8),
  73. 'b':(-(1<<7), 1<<7), 'B':(0, 1<<8),
  74. 'h':(-(1<<15), 1<<15), 'H':(0, 1<<16),
  75. 'i':(-(1<<31), 1<<31), 'I':(0, 1<<32),
  76. 'l':(-(1<<31), 1<<31), 'L':(0, 1<<32),
  77. 'q':(-(1<<63), 1<<63), 'Q':(0, 1<<64),
  78. 'f':(-(1<<63), 1<<63), 'd':(-(1<<1023), 1<<1023)
  79. }
  80. def native_type_range(fmt):
  81. """Return range of a native type."""
  82. if fmt == 'c':
  83. lh = (0, 256)
  84. elif fmt == '?':
  85. lh = (0, 2)
  86. elif fmt == 'f':
  87. lh = (-(1<<63), 1<<63)
  88. elif fmt == 'd':
  89. lh = (-(1<<1023), 1<<1023)
  90. else:
  91. for exp in (128, 127, 64, 63, 32, 31, 16, 15, 8, 7):
  92. try:
  93. struct.pack(fmt, (1<<exp)-1)
  94. break
  95. except struct.error:
  96. pass
  97. lh = (-(1<<exp), 1<<exp) if exp & 1 else (0, 1<<exp)
  98. return lh
  99. fmtdict = {
  100. '':NATIVE,
  101. '@':NATIVE,
  102. '<':STANDARD,
  103. '>':STANDARD,
  104. '=':STANDARD,
  105. '!':STANDARD
  106. }
  107. if struct:
  108. for fmt in fmtdict['@']:
  109. fmtdict['@'][fmt] = native_type_range(fmt)
  110. MEMORYVIEW = NATIVE.copy()
  111. ARRAY = NATIVE.copy()
  112. for k in NATIVE:
  113. if not k in "bBhHiIlLfd":
  114. del ARRAY[k]
  115. BYTEFMT = NATIVE.copy()
  116. for k in NATIVE:
  117. if not k in "Bbc":
  118. del BYTEFMT[k]
  119. fmtdict['m'] = MEMORYVIEW
  120. fmtdict['@m'] = MEMORYVIEW
  121. fmtdict['a'] = ARRAY
  122. fmtdict['b'] = BYTEFMT
  123. fmtdict['@b'] = BYTEFMT
  124. # Capabilities of the test objects:
  125. MODE = 0
  126. MULT = 1
  127. cap = { # format chars # multiplier
  128. 'ndarray': (['', '@', '<', '>', '=', '!'], ['', '1', '2', '3']),
  129. 'array': (['a'], ['']),
  130. 'numpy': ([''], ['']),
  131. 'memoryview': (['@m', 'm'], ['']),
  132. 'bytefmt': (['@b', 'b'], ['']),
  133. }
  134. def randrange_fmt(mode, char, obj):
  135. """Return random item for a type specified by a mode and a single
  136. format character."""
  137. x = randrange(*fmtdict[mode][char])
  138. if char == 'c':
  139. x = bytes([x])
  140. if obj == 'numpy' and x == b'\x00':
  141. # http://projects.scipy.org/numpy/ticket/1925
  142. x = b'\x01'
  143. if char == '?':
  144. x = bool(x)
  145. if char == 'f' or char == 'd':
  146. x = struct.pack(char, x)
  147. x = struct.unpack(char, x)[0]
  148. return x
  149. def gen_item(fmt, obj):
  150. """Return single random item."""
  151. mode, chars = fmt.split('#')
  152. x = []
  153. for c in chars:
  154. x.append(randrange_fmt(mode, c, obj))
  155. return x[0] if len(x) == 1 else tuple(x)
  156. def gen_items(n, fmt, obj):
  157. """Return a list of random items (or a scalar)."""
  158. if n == 0:
  159. return gen_item(fmt, obj)
  160. lst = [0] * n
  161. for i in range(n):
  162. lst[i] = gen_item(fmt, obj)
  163. return lst
  164. def struct_items(n, obj):
  165. mode = choice(cap[obj][MODE])
  166. xfmt = mode + '#'
  167. fmt = mode.strip('amb')
  168. nmemb = randrange(2, 10) # number of struct members
  169. for _ in range(nmemb):
  170. char = choice(tuple(fmtdict[mode]))
  171. multiplier = choice(cap[obj][MULT])
  172. xfmt += (char * int(multiplier if multiplier else 1))
  173. fmt += (multiplier + char)
  174. items = gen_items(n, xfmt, obj)
  175. item = gen_item(xfmt, obj)
  176. return fmt, items, item
  177. def randitems(n, obj='ndarray', mode=None, char=None):
  178. """Return random format, items, item."""
  179. if mode is None:
  180. mode = choice(cap[obj][MODE])
  181. if char is None:
  182. char = choice(tuple(fmtdict[mode]))
  183. multiplier = choice(cap[obj][MULT])
  184. fmt = mode + '#' + char * int(multiplier if multiplier else 1)
  185. items = gen_items(n, fmt, obj)
  186. item = gen_item(fmt, obj)
  187. fmt = mode.strip('amb') + multiplier + char
  188. return fmt, items, item
  189. def iter_mode(n, obj='ndarray'):
  190. """Iterate through supported mode/char combinations."""
  191. for mode in cap[obj][MODE]:
  192. for char in fmtdict[mode]:
  193. yield randitems(n, obj, mode, char)
  194. def iter_format(nitems, testobj='ndarray'):
  195. """Yield (format, items, item) for all possible modes and format
  196. characters plus one random compound format string."""
  197. for t in iter_mode(nitems, testobj):
  198. yield t
  199. if testobj != 'ndarray':
  200. return
  201. yield struct_items(nitems, testobj)
  202. def is_byte_format(fmt):
  203. return 'c' in fmt or 'b' in fmt or 'B' in fmt
  204. def is_memoryview_format(fmt):
  205. """format suitable for memoryview"""
  206. x = len(fmt)
  207. return ((x == 1 or (x == 2 and fmt[0] == '@')) and
  208. fmt[x-1] in MEMORYVIEW)
  209. NON_BYTE_FORMAT = [c for c in fmtdict['@'] if not is_byte_format(c)]
  210. # ======================================================================
  211. # Multi-dimensional tolist(), slicing and slice assignments
  212. # ======================================================================
  213. def atomp(lst):
  214. """Tuple items (representing structs) are regarded as atoms."""
  215. return not isinstance(lst, list)
  216. def listp(lst):
  217. return isinstance(lst, list)
  218. def prod(lst):
  219. """Product of list elements."""
  220. if len(lst) == 0:
  221. return 0
  222. x = lst[0]
  223. for v in lst[1:]:
  224. x *= v
  225. return x
  226. def strides_from_shape(ndim, shape, itemsize, layout):
  227. """Calculate strides of a contiguous array. Layout is 'C' or
  228. 'F' (Fortran)."""
  229. if ndim == 0:
  230. return ()
  231. if layout == 'C':
  232. strides = list(shape[1:]) + [itemsize]
  233. for i in range(ndim-2, -1, -1):
  234. strides[i] *= strides[i+1]
  235. else:
  236. strides = [itemsize] + list(shape[:-1])
  237. for i in range(1, ndim):
  238. strides[i] *= strides[i-1]
  239. return strides
  240. def _ca(items, s):
  241. """Convert flat item list to the nested list representation of a
  242. multidimensional C array with shape 's'."""
  243. if atomp(items):
  244. return items
  245. if len(s) == 0:
  246. return items[0]
  247. lst = [0] * s[0]
  248. stride = len(items) // s[0] if s[0] else 0
  249. for i in range(s[0]):
  250. start = i*stride
  251. lst[i] = _ca(items[start:start+stride], s[1:])
  252. return lst
  253. def _fa(items, s):
  254. """Convert flat item list to the nested list representation of a
  255. multidimensional Fortran array with shape 's'."""
  256. if atomp(items):
  257. return items
  258. if len(s) == 0:
  259. return items[0]
  260. lst = [0] * s[0]
  261. stride = s[0]
  262. for i in range(s[0]):
  263. lst[i] = _fa(items[i::stride], s[1:])
  264. return lst
  265. def carray(items, shape):
  266. if listp(items) and not 0 in shape and prod(shape) != len(items):
  267. raise ValueError("prod(shape) != len(items)")
  268. return _ca(items, shape)
  269. def farray(items, shape):
  270. if listp(items) and not 0 in shape and prod(shape) != len(items):
  271. raise ValueError("prod(shape) != len(items)")
  272. return _fa(items, shape)
  273. def indices(shape):
  274. """Generate all possible tuples of indices."""
  275. iterables = [range(v) for v in shape]
  276. return product(*iterables)
  277. def getindex(ndim, ind, strides):
  278. """Convert multi-dimensional index to the position in the flat list."""
  279. ret = 0
  280. for i in range(ndim):
  281. ret += strides[i] * ind[i]
  282. return ret
  283. def transpose(src, shape):
  284. """Transpose flat item list that is regarded as a multi-dimensional
  285. matrix defined by shape: dest...[k][j][i] = src[i][j][k]... """
  286. if not shape:
  287. return src
  288. ndim = len(shape)
  289. sstrides = strides_from_shape(ndim, shape, 1, 'C')
  290. dstrides = strides_from_shape(ndim, shape[::-1], 1, 'C')
  291. dest = [0] * len(src)
  292. for ind in indices(shape):
  293. fr = getindex(ndim, ind, sstrides)
  294. to = getindex(ndim, ind[::-1], dstrides)
  295. dest[to] = src[fr]
  296. return dest
  297. def _flatten(lst):
  298. """flatten list"""
  299. if lst == []:
  300. return lst
  301. if atomp(lst):
  302. return [lst]
  303. return _flatten(lst[0]) + _flatten(lst[1:])
  304. def flatten(lst):
  305. """flatten list or return scalar"""
  306. if atomp(lst): # scalar
  307. return lst
  308. return _flatten(lst)
  309. def slice_shape(lst, slices):
  310. """Get the shape of lst after slicing: slices is a list of slice
  311. objects."""
  312. if atomp(lst):
  313. return []
  314. return [len(lst[slices[0]])] + slice_shape(lst[0], slices[1:])
  315. def multislice(lst, slices):
  316. """Multi-dimensional slicing: slices is a list of slice objects."""
  317. if atomp(lst):
  318. return lst
  319. return [multislice(sublst, slices[1:]) for sublst in lst[slices[0]]]
  320. def m_assign(llst, rlst, lslices, rslices):
  321. """Multi-dimensional slice assignment: llst and rlst are the operands,
  322. lslices and rslices are lists of slice objects. llst and rlst must
  323. have the same structure.
  324. For a two-dimensional example, this is not implemented in Python:
  325. llst[0:3:2, 0:3:2] = rlst[1:3:1, 1:3:1]
  326. Instead we write:
  327. lslices = [slice(0,3,2), slice(0,3,2)]
  328. rslices = [slice(1,3,1), slice(1,3,1)]
  329. multislice_assign(llst, rlst, lslices, rslices)
  330. """
  331. if atomp(rlst):
  332. return rlst
  333. rlst = [m_assign(l, r, lslices[1:], rslices[1:])
  334. for l, r in zip(llst[lslices[0]], rlst[rslices[0]])]
  335. llst[lslices[0]] = rlst
  336. return llst
  337. def cmp_structure(llst, rlst, lslices, rslices):
  338. """Compare the structure of llst[lslices] and rlst[rslices]."""
  339. lshape = slice_shape(llst, lslices)
  340. rshape = slice_shape(rlst, rslices)
  341. if (len(lshape) != len(rshape)):
  342. return -1
  343. for i in range(len(lshape)):
  344. if lshape[i] != rshape[i]:
  345. return -1
  346. if lshape[i] == 0:
  347. return 0
  348. return 0
  349. def multislice_assign(llst, rlst, lslices, rslices):
  350. """Return llst after assigning: llst[lslices] = rlst[rslices]"""
  351. if cmp_structure(llst, rlst, lslices, rslices) < 0:
  352. raise ValueError("lvalue and rvalue have different structures")
  353. return m_assign(llst, rlst, lslices, rslices)
  354. # ======================================================================
  355. # Random structures
  356. # ======================================================================
  357. #
  358. # PEP-3118 is very permissive with respect to the contents of a
  359. # Py_buffer. In particular:
  360. #
  361. # - shape can be zero
  362. # - strides can be any integer, including zero
  363. # - offset can point to any location in the underlying
  364. # memory block, provided that it is a multiple of
  365. # itemsize.
  366. #
  367. # The functions in this section test and verify random structures
  368. # in full generality. A structure is valid iff it fits in the
  369. # underlying memory block.
  370. #
  371. # The structure 't' (short for 'tuple') is fully defined by:
  372. #
  373. # t = (memlen, itemsize, ndim, shape, strides, offset)
  374. #
  375. def verify_structure(memlen, itemsize, ndim, shape, strides, offset):
  376. """Verify that the parameters represent a valid array within
  377. the bounds of the allocated memory:
  378. char *mem: start of the physical memory block
  379. memlen: length of the physical memory block
  380. offset: (char *)buf - mem
  381. """
  382. if offset % itemsize:
  383. return False
  384. if offset < 0 or offset+itemsize > memlen:
  385. return False
  386. if any(v % itemsize for v in strides):
  387. return False
  388. if ndim <= 0:
  389. return ndim == 0 and not shape and not strides
  390. if 0 in shape:
  391. return True
  392. imin = sum(strides[j]*(shape[j]-1) for j in range(ndim)
  393. if strides[j] <= 0)
  394. imax = sum(strides[j]*(shape[j]-1) for j in range(ndim)
  395. if strides[j] > 0)
  396. return 0 <= offset+imin and offset+imax+itemsize <= memlen
  397. def get_item(lst, indices):
  398. for i in indices:
  399. lst = lst[i]
  400. return lst
  401. def memory_index(indices, t):
  402. """Location of an item in the underlying memory."""
  403. memlen, itemsize, ndim, shape, strides, offset = t
  404. p = offset
  405. for i in range(ndim):
  406. p += strides[i]*indices[i]
  407. return p
  408. def is_overlapping(t):
  409. """The structure 't' is overlapping if at least one memory location
  410. is visited twice while iterating through all possible tuples of
  411. indices."""
  412. memlen, itemsize, ndim, shape, strides, offset = t
  413. visited = 1<<memlen
  414. for ind in indices(shape):
  415. i = memory_index(ind, t)
  416. bit = 1<<i
  417. if visited & bit:
  418. return True
  419. visited |= bit
  420. return False
  421. def rand_structure(itemsize, valid, maxdim=5, maxshape=16, shape=()):
  422. """Return random structure:
  423. (memlen, itemsize, ndim, shape, strides, offset)
  424. If 'valid' is true, the returned structure is valid, otherwise invalid.
  425. If 'shape' is given, use that instead of creating a random shape.
  426. """
  427. if not shape:
  428. ndim = randrange(maxdim+1)
  429. if (ndim == 0):
  430. if valid:
  431. return itemsize, itemsize, ndim, (), (), 0
  432. else:
  433. nitems = randrange(1, 16+1)
  434. memlen = nitems * itemsize
  435. offset = -itemsize if randrange(2) == 0 else memlen
  436. return memlen, itemsize, ndim, (), (), offset
  437. minshape = 2
  438. n = randrange(100)
  439. if n >= 95 and valid:
  440. minshape = 0
  441. elif n >= 90:
  442. minshape = 1
  443. shape = [0] * ndim
  444. for i in range(ndim):
  445. shape[i] = randrange(minshape, maxshape+1)
  446. else:
  447. ndim = len(shape)
  448. maxstride = 5
  449. n = randrange(100)
  450. zero_stride = True if n >= 95 and n & 1 else False
  451. strides = [0] * ndim
  452. strides[ndim-1] = itemsize * randrange(-maxstride, maxstride+1)
  453. if not zero_stride and strides[ndim-1] == 0:
  454. strides[ndim-1] = itemsize
  455. for i in range(ndim-2, -1, -1):
  456. maxstride *= shape[i+1] if shape[i+1] else 1
  457. if zero_stride:
  458. strides[i] = itemsize * randrange(-maxstride, maxstride+1)
  459. else:
  460. strides[i] = ((1,-1)[randrange(2)] *
  461. itemsize * randrange(1, maxstride+1))
  462. imin = imax = 0
  463. if not 0 in shape:
  464. imin = sum(strides[j]*(shape[j]-1) for j in range(ndim)
  465. if strides[j] <= 0)
  466. imax = sum(strides[j]*(shape[j]-1) for j in range(ndim)
  467. if strides[j] > 0)
  468. nitems = imax - imin
  469. if valid:
  470. offset = -imin * itemsize
  471. memlen = offset + (imax+1) * itemsize
  472. else:
  473. memlen = (-imin + imax) * itemsize
  474. offset = -imin-itemsize if randrange(2) == 0 else memlen
  475. return memlen, itemsize, ndim, shape, strides, offset
  476. def randslice_from_slicelen(slicelen, listlen):
  477. """Create a random slice of len slicelen that fits into listlen."""
  478. maxstart = listlen - slicelen
  479. start = randrange(maxstart+1)
  480. maxstep = (listlen - start) // slicelen if slicelen else 1
  481. step = randrange(1, maxstep+1)
  482. stop = start + slicelen * step
  483. s = slice(start, stop, step)
  484. _, _, _, control = slice_indices(s, listlen)
  485. if control != slicelen:
  486. raise RuntimeError
  487. return s
  488. def randslice_from_shape(ndim, shape):
  489. """Create two sets of slices for an array x with shape 'shape'
  490. such that shapeof(x[lslices]) == shapeof(x[rslices])."""
  491. lslices = [0] * ndim
  492. rslices = [0] * ndim
  493. for n in range(ndim):
  494. l = shape[n]
  495. slicelen = randrange(1, l+1) if l > 0 else 0
  496. lslices[n] = randslice_from_slicelen(slicelen, l)
  497. rslices[n] = randslice_from_slicelen(slicelen, l)
  498. return tuple(lslices), tuple(rslices)
  499. def rand_aligned_slices(maxdim=5, maxshape=16):
  500. """Create (lshape, rshape, tuple(lslices), tuple(rslices)) such that
  501. shapeof(x[lslices]) == shapeof(y[rslices]), where x is an array
  502. with shape 'lshape' and y is an array with shape 'rshape'."""
  503. ndim = randrange(1, maxdim+1)
  504. minshape = 2
  505. n = randrange(100)
  506. if n >= 95:
  507. minshape = 0
  508. elif n >= 90:
  509. minshape = 1
  510. all_random = True if randrange(100) >= 80 else False
  511. lshape = [0]*ndim; rshape = [0]*ndim
  512. lslices = [0]*ndim; rslices = [0]*ndim
  513. for n in range(ndim):
  514. small = randrange(minshape, maxshape+1)
  515. big = randrange(minshape, maxshape+1)
  516. if big < small:
  517. big, small = small, big
  518. # Create a slice that fits the smaller value.
  519. if all_random:
  520. start = randrange(-small, small+1)
  521. stop = randrange(-small, small+1)
  522. step = (1,-1)[randrange(2)] * randrange(1, small+2)
  523. s_small = slice(start, stop, step)
  524. _, _, _, slicelen = slice_indices(s_small, small)
  525. else:
  526. slicelen = randrange(1, small+1) if small > 0 else 0
  527. s_small = randslice_from_slicelen(slicelen, small)
  528. # Create a slice of the same length for the bigger value.
  529. s_big = randslice_from_slicelen(slicelen, big)
  530. if randrange(2) == 0:
  531. rshape[n], lshape[n] = big, small
  532. rslices[n], lslices[n] = s_big, s_small
  533. else:
  534. rshape[n], lshape[n] = small, big
  535. rslices[n], lslices[n] = s_small, s_big
  536. return lshape, rshape, tuple(lslices), tuple(rslices)
  537. def randitems_from_structure(fmt, t):
  538. """Return a list of random items for structure 't' with format
  539. 'fmtchar'."""
  540. memlen, itemsize, _, _, _, _ = t
  541. return gen_items(memlen//itemsize, '#'+fmt, 'numpy')
  542. def ndarray_from_structure(items, fmt, t, flags=0):
  543. """Return ndarray from the tuple returned by rand_structure()"""
  544. memlen, itemsize, ndim, shape, strides, offset = t
  545. return ndarray(items, shape=shape, strides=strides, format=fmt,
  546. offset=offset, flags=ND_WRITABLE|flags)
  547. def numpy_array_from_structure(items, fmt, t):
  548. """Return numpy_array from the tuple returned by rand_structure()"""
  549. memlen, itemsize, ndim, shape, strides, offset = t
  550. buf = bytearray(memlen)
  551. for j, v in enumerate(items):
  552. struct.pack_into(fmt, buf, j*itemsize, v)
  553. return numpy_array(buffer=buf, shape=shape, strides=strides,
  554. dtype=fmt, offset=offset)
  555. # ======================================================================
  556. # memoryview casts
  557. # ======================================================================
  558. def cast_items(exporter, fmt, itemsize, shape=None):
  559. """Interpret the raw memory of 'exporter' as a list of items with
  560. size 'itemsize'. If shape=None, the new structure is assumed to
  561. be 1-D with n * itemsize = bytelen. If shape is given, the usual
  562. constraint for contiguous arrays prod(shape) * itemsize = bytelen
  563. applies. On success, return (items, shape). If the constraints
  564. cannot be met, return (None, None). If a chunk of bytes is interpreted
  565. as NaN as a result of float conversion, return ('nan', None)."""
  566. bytelen = exporter.nbytes
  567. if shape:
  568. if prod(shape) * itemsize != bytelen:
  569. return None, shape
  570. elif shape == []:
  571. if exporter.ndim == 0 or itemsize != bytelen:
  572. return None, shape
  573. else:
  574. n, r = divmod(bytelen, itemsize)
  575. shape = [n]
  576. if r != 0:
  577. return None, shape
  578. mem = exporter.tobytes()
  579. byteitems = [mem[i:i+itemsize] for i in range(0, len(mem), itemsize)]
  580. items = []
  581. for v in byteitems:
  582. item = struct.unpack(fmt, v)[0]
  583. if item != item:
  584. return 'nan', shape
  585. items.append(item)
  586. return (items, shape) if shape != [] else (items[0], shape)
  587. def gencastshapes():
  588. """Generate shapes to test casting."""
  589. for n in range(32):
  590. yield [n]
  591. ndim = randrange(4, 6)
  592. minshape = 1 if randrange(100) > 80 else 2
  593. yield [randrange(minshape, 5) for _ in range(ndim)]
  594. ndim = randrange(2, 4)
  595. minshape = 1 if randrange(100) > 80 else 2
  596. yield [randrange(minshape, 5) for _ in range(ndim)]
  597. # ======================================================================
  598. # Actual tests
  599. # ======================================================================
  600. def genslices(n):
  601. """Generate all possible slices for a single dimension."""
  602. return product(range(-n, n+1), range(-n, n+1), range(-n, n+1))
  603. def genslices_ndim(ndim, shape):
  604. """Generate all possible slice tuples for 'shape'."""
  605. iterables = [genslices(shape[n]) for n in range(ndim)]
  606. return product(*iterables)
  607. def rslice(n, allow_empty=False):
  608. """Generate random slice for a single dimension of length n.
  609. If zero=True, the slices may be empty, otherwise they will
  610. be non-empty."""
  611. minlen = 0 if allow_empty or n == 0 else 1
  612. slicelen = randrange(minlen, n+1)
  613. return randslice_from_slicelen(slicelen, n)
  614. def rslices(n, allow_empty=False):
  615. """Generate random slices for a single dimension."""
  616. for _ in range(5):
  617. yield rslice(n, allow_empty)
  618. def rslices_ndim(ndim, shape, iterations=5):
  619. """Generate random slice tuples for 'shape'."""
  620. # non-empty slices
  621. for _ in range(iterations):
  622. yield tuple(rslice(shape[n]) for n in range(ndim))
  623. # possibly empty slices
  624. for _ in range(iterations):
  625. yield tuple(rslice(shape[n], allow_empty=True) for n in range(ndim))
  626. # invalid slices
  627. yield tuple(slice(0,1,0) for _ in range(ndim))
  628. def rpermutation(iterable, r=None):
  629. pool = tuple(iterable)
  630. r = len(pool) if r is None else r
  631. yield tuple(sample(pool, r))
  632. def ndarray_print(nd):
  633. """Print ndarray for debugging."""
  634. try:
  635. x = nd.tolist()
  636. except (TypeError, NotImplementedError):
  637. x = nd.tobytes()
  638. if isinstance(nd, ndarray):
  639. offset = nd.offset
  640. flags = nd.flags
  641. else:
  642. offset = 'unknown'
  643. flags = 'unknown'
  644. print("ndarray(%s, shape=%s, strides=%s, suboffsets=%s, offset=%s, "
  645. "format='%s', itemsize=%s, flags=%s)" %
  646. (x, nd.shape, nd.strides, nd.suboffsets, offset,
  647. nd.format, nd.itemsize, flags))
  648. sys.stdout.flush()
  649. ITERATIONS = 100
  650. MAXDIM = 5
  651. MAXSHAPE = 10
  652. if SHORT_TEST:
  653. ITERATIONS = 10
  654. MAXDIM = 3
  655. MAXSHAPE = 4
  656. genslices = rslices
  657. genslices_ndim = rslices_ndim
  658. permutations = rpermutation
  659. @unittest.skipUnless(struct, 'struct module required for this test.')
  660. @unittest.skipUnless(ndarray, 'ndarray object required for this test')
  661. class TestBufferProtocol(unittest.TestCase):
  662. def setUp(self):
  663. # The suboffsets tests need sizeof(void *).
  664. self.sizeof_void_p = get_sizeof_void_p()
  665. def verify(self, result, *, obj,
  666. itemsize, fmt, readonly,
  667. ndim, shape, strides,
  668. lst, sliced=False, cast=False):
  669. # Verify buffer contents against expected values.
  670. if shape:
  671. expected_len = prod(shape)*itemsize
  672. else:
  673. if not fmt: # array has been implicitly cast to unsigned bytes
  674. expected_len = len(lst)
  675. else: # ndim = 0
  676. expected_len = itemsize
  677. # Reconstruct suboffsets from strides. Support for slicing
  678. # could be added, but is currently only needed for test_getbuf().
  679. suboffsets = ()
  680. if result.suboffsets:
  681. self.assertGreater(ndim, 0)
  682. suboffset0 = 0
  683. for n in range(1, ndim):
  684. if shape[n] == 0:
  685. break
  686. if strides[n] <= 0:
  687. suboffset0 += -strides[n] * (shape[n]-1)
  688. suboffsets = [suboffset0] + [-1 for v in range(ndim-1)]
  689. # Not correct if slicing has occurred in the first dimension.
  690. stride0 = self.sizeof_void_p
  691. if strides[0] < 0:
  692. stride0 = -stride0
  693. strides = [stride0] + list(strides[1:])
  694. self.assertIs(result.obj, obj)
  695. self.assertEqual(result.nbytes, expected_len)
  696. self.assertEqual(result.itemsize, itemsize)
  697. self.assertEqual(result.format, fmt)
  698. self.assertIs(result.readonly, readonly)
  699. self.assertEqual(result.ndim, ndim)
  700. self.assertEqual(result.shape, tuple(shape))
  701. if not (sliced and suboffsets):
  702. self.assertEqual(result.strides, tuple(strides))
  703. self.assertEqual(result.suboffsets, tuple(suboffsets))
  704. if isinstance(result, ndarray) or is_memoryview_format(fmt):
  705. rep = result.tolist() if fmt else result.tobytes()
  706. self.assertEqual(rep, lst)
  707. if not fmt: # array has been cast to unsigned bytes,
  708. return # the remaining tests won't work.
  709. # PyBuffer_GetPointer() is the definition how to access an item.
  710. # If PyBuffer_GetPointer(indices) is correct for all possible
  711. # combinations of indices, the buffer is correct.
  712. #
  713. # Also test tobytes() against the flattened 'lst', with all items
  714. # packed to bytes.
  715. if not cast: # casts chop up 'lst' in different ways
  716. b = bytearray()
  717. buf_err = None
  718. for ind in indices(shape):
  719. try:
  720. item1 = get_pointer(result, ind)
  721. item2 = get_item(lst, ind)
  722. if isinstance(item2, tuple):
  723. x = struct.pack(fmt, *item2)
  724. else:
  725. x = struct.pack(fmt, item2)
  726. b.extend(x)
  727. except BufferError:
  728. buf_err = True # re-exporter does not provide full buffer
  729. break
  730. self.assertEqual(item1, item2)
  731. if not buf_err:
  732. # test tobytes()
  733. self.assertEqual(result.tobytes(), b)
  734. # test hex()
  735. m = memoryview(result)
  736. h = "".join("%02x" % c for c in b)
  737. self.assertEqual(m.hex(), h)
  738. # lst := expected multi-dimensional logical representation
  739. # flatten(lst) := elements in C-order
  740. ff = fmt if fmt else 'B'
  741. flattened = flatten(lst)
  742. # Rules for 'A': if the array is already contiguous, return
  743. # the array unaltered. Otherwise, return a contiguous 'C'
  744. # representation.
  745. for order in ['C', 'F', 'A']:
  746. expected = result
  747. if order == 'F':
  748. if not is_contiguous(result, 'A') or \
  749. is_contiguous(result, 'C'):
  750. # For constructing the ndarray, convert the
  751. # flattened logical representation to Fortran order.
  752. trans = transpose(flattened, shape)
  753. expected = ndarray(trans, shape=shape, format=ff,
  754. flags=ND_FORTRAN)
  755. else: # 'C', 'A'
  756. if not is_contiguous(result, 'A') or \
  757. is_contiguous(result, 'F') and order == 'C':
  758. # The flattened list is already in C-order.
  759. expected = ndarray(flattened, shape=shape, format=ff)
  760. contig = get_contiguous(result, PyBUF_READ, order)
  761. self.assertEqual(contig.tobytes(), b)
  762. self.assertTrue(cmp_contig(contig, expected))
  763. if ndim == 0:
  764. continue
  765. nmemb = len(flattened)
  766. ro = 0 if readonly else ND_WRITABLE
  767. ### See comment in test_py_buffer_to_contiguous for an
  768. ### explanation why these tests are valid.
  769. # To 'C'
  770. contig = py_buffer_to_contiguous(result, 'C', PyBUF_FULL_RO)
  771. self.assertEqual(len(contig), nmemb * itemsize)
  772. initlst = [struct.unpack_from(fmt, contig, n*itemsize)
  773. for n in range(nmemb)]
  774. if len(initlst[0]) == 1:
  775. initlst = [v[0] for v in initlst]
  776. y = ndarray(initlst, shape=shape, flags=ro, format=fmt)
  777. self.assertEqual(memoryview(y), memoryview(result))
  778. contig_bytes = memoryview(result).tobytes()
  779. self.assertEqual(contig_bytes, contig)
  780. contig_bytes = memoryview(result).tobytes(order=None)
  781. self.assertEqual(contig_bytes, contig)
  782. contig_bytes = memoryview(result).tobytes(order='C')
  783. self.assertEqual(contig_bytes, contig)
  784. # To 'F'
  785. contig = py_buffer_to_contiguous(result, 'F', PyBUF_FULL_RO)
  786. self.assertEqual(len(contig), nmemb * itemsize)
  787. initlst = [struct.unpack_from(fmt, contig, n*itemsize)
  788. for n in range(nmemb)]
  789. if len(initlst[0]) == 1:
  790. initlst = [v[0] for v in initlst]
  791. y = ndarray(initlst, shape=shape, flags=ro|ND_FORTRAN,
  792. format=fmt)
  793. self.assertEqual(memoryview(y), memoryview(result))
  794. contig_bytes = memoryview(result).tobytes(order='F')
  795. self.assertEqual(contig_bytes, contig)
  796. # To 'A'
  797. contig = py_buffer_to_contiguous(result, 'A', PyBUF_FULL_RO)
  798. self.assertEqual(len(contig), nmemb * itemsize)
  799. initlst = [struct.unpack_from(fmt, contig, n*itemsize)
  800. for n in range(nmemb)]
  801. if len(initlst[0]) == 1:
  802. initlst = [v[0] for v in initlst]
  803. f = ND_FORTRAN if is_contiguous(result, 'F') else 0
  804. y = ndarray(initlst, shape=shape, flags=f|ro, format=fmt)
  805. self.assertEqual(memoryview(y), memoryview(result))
  806. contig_bytes = memoryview(result).tobytes(order='A')
  807. self.assertEqual(contig_bytes, contig)
  808. if is_memoryview_format(fmt):
  809. try:
  810. m = memoryview(result)
  811. except BufferError: # re-exporter does not provide full information
  812. return
  813. ex = result.obj if isinstance(result, memoryview) else result
  814. def check_memoryview(m, expected_readonly=readonly):
  815. self.assertIs(m.obj, ex)
  816. self.assertEqual(m.nbytes, expected_len)
  817. self.assertEqual(m.itemsize, itemsize)
  818. self.assertEqual(m.format, fmt)
  819. self.assertEqual(m.readonly, expected_readonly)
  820. self.assertEqual(m.ndim, ndim)
  821. self.assertEqual(m.shape, tuple(shape))
  822. if not (sliced and suboffsets):
  823. self.assertEqual(m.strides, tuple(strides))
  824. self.assertEqual(m.suboffsets, tuple(suboffsets))
  825. n = 1 if ndim == 0 else len(lst)
  826. self.assertEqual(len(m), n)
  827. rep = result.tolist() if fmt else result.tobytes()
  828. self.assertEqual(rep, lst)
  829. self.assertEqual(m, result)
  830. check_memoryview(m)
  831. with m.toreadonly() as mm:
  832. check_memoryview(mm, expected_readonly=True)
  833. m.tobytes() # Releasing mm didn't release m
  834. def verify_getbuf(self, orig_ex, ex, req, sliced=False):
  835. def match(req, flag):
  836. return ((req&flag) == flag)
  837. if (# writable request to read-only exporter
  838. (ex.readonly and match(req, PyBUF_WRITABLE)) or
  839. # cannot match explicit contiguity request
  840. (match(req, PyBUF_C_CONTIGUOUS) and not ex.c_contiguous) or
  841. (match(req, PyBUF_F_CONTIGUOUS) and not ex.f_contiguous) or
  842. (match(req, PyBUF_ANY_CONTIGUOUS) and not ex.contiguous) or
  843. # buffer needs suboffsets
  844. (not match(req, PyBUF_INDIRECT) and ex.suboffsets) or
  845. # buffer without strides must be C-contiguous
  846. (not match(req, PyBUF_STRIDES) and not ex.c_contiguous) or
  847. # PyBUF_SIMPLE|PyBUF_FORMAT and PyBUF_WRITABLE|PyBUF_FORMAT
  848. (not match(req, PyBUF_ND) and match(req, PyBUF_FORMAT))):
  849. self.assertRaises(BufferError, ndarray, ex, getbuf=req)
  850. return
  851. if isinstance(ex, ndarray) or is_memoryview_format(ex.format):
  852. lst = ex.tolist()
  853. else:
  854. nd = ndarray(ex, getbuf=PyBUF_FULL_RO)
  855. lst = nd.tolist()
  856. # The consumer may have requested default values or a NULL format.
  857. ro = False if match(req, PyBUF_WRITABLE) else ex.readonly
  858. fmt = ex.format
  859. itemsize = ex.itemsize
  860. ndim = ex.ndim
  861. if not match(req, PyBUF_FORMAT):
  862. # itemsize refers to the original itemsize before the cast.
  863. # The equality product(shape) * itemsize = len still holds.
  864. # The equality calcsize(format) = itemsize does _not_ hold.
  865. fmt = ''
  866. lst = orig_ex.tobytes() # Issue 12834
  867. if not match(req, PyBUF_ND):
  868. ndim = 1
  869. shape = orig_ex.shape if match(req, PyBUF_ND) else ()
  870. strides = orig_ex.strides if match(req, PyBUF_STRIDES) else ()
  871. nd = ndarray(ex, getbuf=req)
  872. self.verify(nd, obj=ex,
  873. itemsize=itemsize, fmt=fmt, readonly=ro,
  874. ndim=ndim, shape=shape, strides=strides,
  875. lst=lst, sliced=sliced)
  876. def test_ndarray_getbuf(self):
  877. requests = (
  878. # distinct flags
  879. PyBUF_INDIRECT, PyBUF_STRIDES, PyBUF_ND, PyBUF_SIMPLE,
  880. PyBUF_C_CONTIGUOUS, PyBUF_F_CONTIGUOUS, PyBUF_ANY_CONTIGUOUS,
  881. # compound requests
  882. PyBUF_FULL, PyBUF_FULL_RO,
  883. PyBUF_RECORDS, PyBUF_RECORDS_RO,
  884. PyBUF_STRIDED, PyBUF_STRIDED_RO,
  885. PyBUF_CONTIG, PyBUF_CONTIG_RO,
  886. )
  887. # items and format
  888. items_fmt = (
  889. ([True if x % 2 else False for x in range(12)], '?'),
  890. ([1,2,3,4,5,6,7,8,9,10,11,12], 'b'),
  891. ([1,2,3,4,5,6,7,8,9,10,11,12], 'B'),
  892. ([(2**31-x) if x % 2 else (-2**31+x) for x in range(12)], 'l')
  893. )
  894. # shape, strides, offset
  895. structure = (
  896. ([], [], 0),
  897. ([1,3,1], [], 0),
  898. ([12], [], 0),
  899. ([12], [-1], 11),
  900. ([6], [2], 0),
  901. ([6], [-2], 11),
  902. ([3, 4], [], 0),
  903. ([3, 4], [-4, -1], 11),
  904. ([2, 2], [4, 1], 4),
  905. ([2, 2], [-4, -1], 8)
  906. )
  907. # ndarray creation flags
  908. ndflags = (
  909. 0, ND_WRITABLE, ND_FORTRAN, ND_FORTRAN|ND_WRITABLE,
  910. ND_PIL, ND_PIL|ND_WRITABLE
  911. )
  912. # flags that can actually be used as flags
  913. real_flags = (0, PyBUF_WRITABLE, PyBUF_FORMAT,
  914. PyBUF_WRITABLE|PyBUF_FORMAT)
  915. for items, fmt in items_fmt:
  916. itemsize = struct.calcsize(fmt)
  917. for shape, strides, offset in structure:
  918. strides = [v * itemsize for v in strides]
  919. offset *= itemsize
  920. for flags in ndflags:
  921. if strides and (flags&ND_FORTRAN):
  922. continue
  923. if not shape and (flags&ND_PIL):
  924. continue
  925. _items = items if shape else items[0]
  926. ex1 = ndarray(_items, format=fmt, flags=flags,
  927. shape=shape, strides=strides, offset=offset)
  928. ex2 = ex1[::-2] if shape else None
  929. m1 = memoryview(ex1)
  930. if ex2:
  931. m2 = memoryview(ex2)
  932. if ex1.ndim == 0 or (ex1.ndim == 1 and shape and strides):
  933. self.assertEqual(m1, ex1)
  934. if ex2 and ex2.ndim == 1 and shape and strides:
  935. self.assertEqual(m2, ex2)
  936. for req in requests:
  937. for bits in real_flags:
  938. self.verify_getbuf(ex1, ex1, req|bits)
  939. self.verify_getbuf(ex1, m1, req|bits)
  940. if ex2:
  941. self.verify_getbuf(ex2, ex2, req|bits,
  942. sliced=True)
  943. self.verify_getbuf(ex2, m2, req|bits,
  944. sliced=True)
  945. items = [1,2,3,4,5,6,7,8,9,10,11,12]
  946. # ND_GETBUF_FAIL
  947. ex = ndarray(items, shape=[12], flags=ND_GETBUF_FAIL)
  948. self.assertRaises(BufferError, ndarray, ex)
  949. # Request complex structure from a simple exporter. In this
  950. # particular case the test object is not PEP-3118 compliant.
  951. base = ndarray([9], [1])
  952. ex = ndarray(base, getbuf=PyBUF_SIMPLE)
  953. self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_WRITABLE)
  954. self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_ND)
  955. self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_STRIDES)
  956. self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_C_CONTIGUOUS)
  957. self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_F_CONTIGUOUS)
  958. self.assertRaises(BufferError, ndarray, ex, getbuf=PyBUF_ANY_CONTIGUOUS)
  959. nd = ndarray(ex, getbuf=PyBUF_SIMPLE)
  960. # Issue #22445: New precise contiguity definition.
  961. for shape in [1,12,1], [7,0,7]:
  962. for order in 0, ND_FORTRAN:
  963. ex = ndarray(items, shape=shape, flags=order|ND_WRITABLE)
  964. self.assertTrue(is_contiguous(ex, 'F'))
  965. self.assertTrue(is_contiguous(ex, 'C'))
  966. for flags in requests:
  967. nd = ndarray(ex, getbuf=flags)
  968. self.assertTrue(is_contiguous(nd, 'F'))
  969. self.assertTrue(is_contiguous(nd, 'C'))
  970. def test_ndarray_exceptions(self):
  971. nd = ndarray([9], [1])
  972. ndm = ndarray([9], [1], flags=ND_VAREXPORT)
  973. # Initialization of a new ndarray or mutation of an existing array.
  974. for c in (ndarray, nd.push, ndm.push):
  975. # Invalid types.
  976. self.assertRaises(TypeError, c, {1,2,3})
  977. self.assertRaises(TypeError, c, [1,2,'3'])
  978. self.assertRaises(TypeError, c, [1,2,(3,4)])
  979. self.assertRaises(TypeError, c, [1,2,3], shape={3})
  980. self.assertRaises(TypeError, c, [1,2,3], shape=[3], strides={1})
  981. self.assertRaises(TypeError, c, [1,2,3], shape=[3], offset=[])
  982. self.assertRaises(TypeError, c, [1], shape=[1], format={})
  983. self.assertRaises(TypeError, c, [1], shape=[1], flags={})
  984. self.assertRaises(TypeError, c, [1], shape=[1], getbuf={})
  985. # ND_FORTRAN flag is only valid without strides.
  986. self.assertRaises(TypeError, c, [1], shape=[1], strides=[1],
  987. flags=ND_FORTRAN)
  988. # ND_PIL flag is only valid with ndim > 0.
  989. self.assertRaises(TypeError, c, [1], shape=[], flags=ND_PIL)
  990. # Invalid items.
  991. self.assertRaises(ValueError, c, [], shape=[1])
  992. self.assertRaises(ValueError, c, ['XXX'], shape=[1], format="L")
  993. # Invalid combination of items and format.
  994. self.assertRaises(struct.error, c, [1000], shape=[1], format="B")
  995. self.assertRaises(ValueError, c, [1,(2,3)], shape=[2], format="B")
  996. self.assertRaises(ValueError, c, [1,2,3], shape=[3], format="QL")
  997. # Invalid ndim.
  998. n = ND_MAX_NDIM+1
  999. self.assertRaises(ValueError, c, [1]*n, shape=[1]*n)
  1000. # Invalid shape.
  1001. self.assertRaises(ValueError, c, [1], shape=[-1])
  1002. self.assertRaises(ValueError, c, [1,2,3], shape=['3'])
  1003. self.assertRaises(OverflowError, c, [1], shape=[2**128])
  1004. # prod(shape) * itemsize != len(items)
  1005. self.assertRaises(ValueError, c, [1,2,3,4,5], shape=[2,2], offset=3)
  1006. # Invalid strides.
  1007. self.assertRaises(ValueError, c, [1,2,3], shape=[3], strides=['1'])
  1008. self.assertRaises(OverflowError, c, [1], shape=[1],
  1009. strides=[2**128])
  1010. # Invalid combination of strides and shape.
  1011. self.assertRaises(ValueError, c, [1,2], shape=[2,1], strides=[1])
  1012. # Invalid combination of strides and format.
  1013. self.assertRaises(ValueError, c, [1,2,3,4], shape=[2], strides=[3],
  1014. format="L")
  1015. # Invalid offset.
  1016. self.assertRaises(ValueError, c, [1,2,3], shape=[3], offset=4)
  1017. self.assertRaises(ValueError, c, [1,2,3], shape=[1], offset=3,
  1018. format="L")
  1019. # Invalid format.
  1020. self.assertRaises(ValueError, c, [1,2,3], shape=[3], format="")
  1021. self.assertRaises(struct.error, c, [(1,2,3)], shape=[1],
  1022. format="@#$")
  1023. # Striding out of the memory bounds.
  1024. items = [1,2,3,4,5,6,7,8,9,10]
  1025. self.assertRaises(ValueError, c, items, shape=[2,3],
  1026. strides=[-3, -2], offset=5)
  1027. # Constructing consumer: format argument invalid.
  1028. self.assertRaises(TypeError, c, bytearray(), format="Q")
  1029. # Constructing original base object: getbuf argument invalid.
  1030. self.assertRaises(TypeError, c, [1], shape=[1], getbuf=PyBUF_FULL)
  1031. # Shape argument is mandatory for original base objects.
  1032. self.assertRaises(TypeError, c, [1])
  1033. # PyBUF_WRITABLE request to read-only provider.
  1034. self.assertRaises(BufferError, ndarray, b'123', getbuf=PyBUF_WRITABLE)
  1035. # ND_VAREXPORT can only be specified during construction.
  1036. nd = ndarray([9], [1], flags=ND_VAREXPORT)
  1037. self.assertRaises(ValueError, nd.push, [1], [1], flags=ND_VAREXPORT)
  1038. # Invalid operation for consumers: push/pop
  1039. nd = ndarray(b'123')
  1040. self.assertRaises(BufferError, nd.push, [1], [1])
  1041. self.assertRaises(BufferError, nd.pop)
  1042. # ND_VAREXPORT not set: push/pop fail with exported buffers
  1043. nd = ndarray([9], [1])
  1044. nd.push([1], [1])
  1045. m = memoryview(nd)
  1046. self.assertRaises(BufferError, nd.push, [1], [1])
  1047. self.assertRaises(BufferError, nd.pop)
  1048. m.release()
  1049. nd.pop()
  1050. # Single remaining buffer: pop fails
  1051. self.assertRaises(BufferError, nd.pop)
  1052. del nd
  1053. # get_pointer()
  1054. self.assertRaises(TypeError, get_pointer, {}, [1,2,3])
  1055. self.assertRaises(TypeError, get_pointer, b'123', {})
  1056. nd = ndarray(list(range(100)), shape=[1]*100)
  1057. self.assertRaises(ValueError, get_pointer, nd, [5])
  1058. nd = ndarray(list(range(12)), shape=[3,4])
  1059. self.assertRaises(ValueError, get_pointer, nd, [2,3,4])
  1060. self.assertRaises(ValueError, get_pointer, nd, [3,3])
  1061. self.assertRaises(ValueError, get_pointer, nd, [-3,3])
  1062. self.assertRaises(OverflowError, get_pointer, nd, [1<<64,3])
  1063. # tolist() needs format
  1064. ex = ndarray([1,2,3], shape=[3], format='L')
  1065. nd = ndarray(ex, getbuf=PyBUF_SIMPLE)
  1066. self.assertRaises(ValueError, nd.tolist)
  1067. # memoryview_from_buffer()
  1068. ex1 = ndarray([1,2,3], shape=[3], format='L')
  1069. ex2 = ndarray(ex1)
  1070. nd = ndarray(ex2)
  1071. self.assertRaises(TypeError, nd.memoryview_from_buffer)
  1072. nd = ndarray([(1,)*200], shape=[1], format='L'*200)
  1073. self.assertRaises(TypeError, nd.memoryview_from_buffer)
  1074. n = ND_MAX_NDIM
  1075. nd = ndarray(list(range(n)), shape=[1]*n)
  1076. self.assertRaises(ValueError, nd.memoryview_from_buffer)
  1077. # get_contiguous()
  1078. nd = ndarray([1], shape=[1])
  1079. self.assertRaises(TypeError, get_contiguous, 1, 2, 3, 4, 5)
  1080. self.assertRaises(TypeError, get_contiguous, nd, "xyz", 'C')
  1081. self.assertRaises(OverflowError, get_contiguous, nd, 2**64, 'C')
  1082. self.assertRaises(TypeError, get_contiguous, nd, PyBUF_READ, 961)
  1083. self.assertRaises(UnicodeEncodeError, get_contiguous, nd, PyBUF_READ,
  1084. '\u2007')
  1085. self.assertRaises(ValueError, get_contiguous, nd, PyBUF_READ, 'Z')
  1086. self.assertRaises(ValueError, get_contiguous, nd, 255, 'A')
  1087. # cmp_contig()
  1088. nd = ndarray([1], shape=[1])
  1089. self.assertRaises(TypeError, cmp_contig, 1, 2, 3, 4, 5)
  1090. self.assertRaises(TypeError, cmp_contig, {}, nd)
  1091. self.assertRaises(TypeError, cmp_contig, nd, {})
  1092. # is_contiguous()
  1093. nd = ndarray([1], shape=[1])
  1094. self.assertRaises(TypeError, is_contiguous, 1, 2, 3, 4, 5)
  1095. self.assertRaises(TypeError, is_contiguous, {}, 'A')
  1096. self.assertRaises(TypeError, is_contiguous, nd, 201)
  1097. def test_ndarray_linked_list(self):
  1098. for perm in permutations(range(5)):
  1099. m = [0]*5
  1100. nd = ndarray([1,2,3], shape=[3], flags=ND_VAREXPORT)
  1101. m[0] = memoryview(nd)
  1102. for i in range(1, 5):
  1103. nd.push([1,2,3], shape=[3])
  1104. m[i] = memoryview(nd)
  1105. for i in range(5):
  1106. m[perm[i]].release()
  1107. self.assertRaises(BufferError, nd.pop)
  1108. del nd
  1109. def test_ndarray_format_scalar(self):
  1110. # ndim = 0: scalar
  1111. for fmt, scalar, _ in iter_format(0):
  1112. itemsize = struct.calcsize(fmt)
  1113. nd = ndarray(scalar, shape=(), format=fmt)
  1114. self.verify(nd, obj=None,
  1115. itemsize=itemsize, fmt=fmt, readonly=True,
  1116. ndim=0, shape=(), strides=(),
  1117. lst=scalar)
  1118. def test_ndarray_format_shape(self):
  1119. # ndim = 1, shape = [n]
  1120. nitems = randrange(1, 10)
  1121. for fmt, items, _ in iter_format(nitems):
  1122. itemsize = struct.calcsize(fmt)
  1123. for flags in (0, ND_PIL):
  1124. nd = ndarray(items, shape=[nitems], format=fmt, flags=flags)
  1125. self.verify(nd, obj=None,
  1126. itemsize=itemsize, fmt=fmt, readonly=True,
  1127. ndim=1, shape=(nitems,), strides=(itemsize,),
  1128. lst=items)
  1129. def test_ndarray_format_strides(self):
  1130. # ndim = 1, strides
  1131. nitems = randrange(1, 30)
  1132. for fmt, items, _ in iter_format(nitems):
  1133. itemsize = struct.calcsize(fmt)
  1134. for step in range(-5, 5):
  1135. if step == 0:
  1136. continue
  1137. shape = [len(items[::step])]
  1138. strides = [step*itemsize]
  1139. offset = itemsize*(nitems-1) if step < 0 else 0
  1140. for flags in (0, ND_PIL):
  1141. nd = ndarray(items, shape=shape, strides=strides,
  1142. format=fmt, offset=offset, flags=flags)
  1143. self.verify(nd, obj=None,
  1144. itemsize=itemsize, fmt=fmt, readonly=True,
  1145. ndim=1, shape=shape, strides=strides,
  1146. lst=items[::step])
  1147. def test_ndarray_fortran(self):
  1148. items = [1,2,3,4,5,6,7,8,9,10,11,12]
  1149. ex = ndarray(items, shape=(3, 4), strides=(1, 3))
  1150. nd = ndarray(ex, getbuf=PyBUF_F_CONTIGUOUS|PyBUF_FORMAT)
  1151. self.assertEqual(nd.tolist(), farray(items, (3, 4)))
  1152. def test_ndarray_multidim(self):
  1153. for ndim in range(5):
  1154. shape_t = [randrange(2, 10) for _ in range(ndim)]
  1155. nitems = prod(shape_t)
  1156. for shape in permutations(shape_t):
  1157. fmt, items, _ = randitems(nitems)
  1158. itemsize = struct.calcsize(fmt)
  1159. for flags in (0, ND_PIL):
  1160. if ndim == 0 and flags == ND_PIL:
  1161. continue
  1162. # C array
  1163. nd = ndarray(items, shape=shape, format=fmt, flags=flags)
  1164. strides = strides_from_shape(ndim, shape, itemsize, 'C')
  1165. lst = carray(items, shape)
  1166. self.verify(nd, obj=None,
  1167. itemsize=itemsize, fmt=fmt, readonly=True,
  1168. ndim=ndim, shape=shape, strides=strides,
  1169. lst=lst)
  1170. if is_memoryview_format(fmt):
  1171. # memoryview: reconstruct strides
  1172. ex = ndarray(items, shape=shape, format=fmt)
  1173. nd = ndarray(ex, getbuf=PyBUF_CONTIG_RO|PyBUF_FORMAT)
  1174. self.assertTrue(nd.strides == ())
  1175. mv = nd.memoryview_from_buffer()
  1176. self.verify(mv, obj=None,
  1177. itemsize=itemsize, fmt=fmt, readonly=True,
  1178. ndim=ndim, shape=shape, strides=strides,
  1179. lst=lst)
  1180. # Fortran array
  1181. nd = ndarray(items, shape=shape, format=fmt,
  1182. flags=flags|ND_FORTRAN)
  1183. strides = strides_from_shape(ndim, shape, itemsize, 'F')
  1184. lst = farray(items, shape)
  1185. self.verify(nd, obj=None,
  1186. itemsize=itemsize, fmt=fmt, readonly=True,
  1187. ndim=ndim, shape=shape, strides=strides,
  1188. lst=lst)
  1189. def test_ndarray_index_invalid(self):
  1190. # not writable
  1191. nd = ndarray([1], shape=[1])
  1192. self.assertRaises(TypeError, nd.__setitem__, 1, 8)
  1193. mv = memoryview(nd)
  1194. self.assertEqual(mv, nd)
  1195. self.assertRaises(TypeError, mv.__setitem__, 1, 8)
  1196. # cannot be deleted
  1197. nd = ndarray([1], shape=[1], flags=ND_WRITABLE)
  1198. self.assertRaises(TypeError, nd.__delitem__, 1)
  1199. mv = memoryview(nd)
  1200. self.assertEqual(mv, nd)
  1201. self.assertRaises(TypeError, mv.__delitem__, 1)
  1202. # overflow
  1203. nd = ndarray([1], shape=[1], flags=ND_WRITABLE)
  1204. self.assertRaises(OverflowError, nd.__getitem__, 1<<64)
  1205. self.assertRaises(OverflowError, nd.__setitem__, 1<<64, 8)
  1206. mv = memoryview(nd)
  1207. self.assertEqual(mv, nd)
  1208. self.assertRaises(IndexError, mv.__getitem__, 1<<64)
  1209. self.assertRaises(IndexError, mv.__setitem__, 1<<64, 8)
  1210. # format
  1211. items = [1,2,3,4,5,6,7,8]
  1212. nd = ndarray(items, shape=[len(items)], format="B", flags=ND_WRITABLE)
  1213. self.assertRaises(struct.error, nd.__setitem__, 2, 300)
  1214. self.assertRaises(ValueError, nd.__setitem__, 1, (100, 200))
  1215. mv = memoryview(nd)
  1216. self.assertEqual(mv, nd)
  1217. self.assertRaises(ValueError, mv.__setitem__, 2, 300)
  1218. self.assertRaises(TypeError, mv.__setitem__, 1, (100, 200))
  1219. items = [(1,2), (3,4), (5,6)]
  1220. nd = ndarray(items, shape=[len(items)], format="LQ", flags=ND_WRITABLE)
  1221. self.assertRaises(ValueError, nd.__setitem__, 2, 300)
  1222. self.assertRaises(struct.error, nd.__setitem__, 1, (b'\x001', 200))
  1223. def test_ndarray_index_scalar(self):
  1224. # scalar
  1225. nd = ndarray(1, shape=(), flags=ND_WRITABLE)
  1226. mv = memoryview(nd)
  1227. self.assertEqual(mv, nd)
  1228. x = nd[()]; self.assertEqual(x, 1)
  1229. x = nd[...]; self.assertEqual(x.tolist(), nd.tolist())
  1230. x = mv[()]; self.assertEqual(x, 1)
  1231. x = mv[...]; self.assertEqual(x.tolist(), nd.tolist())
  1232. self.assertRaises(TypeError, nd.__getitem__, 0)
  1233. self.assertRaises(TypeError, mv.__getitem__, 0)
  1234. self.assertRaises(TypeError, nd.__setitem__, 0, 8)
  1235. self.assertRaises(TypeError, mv.__setitem__, 0, 8)
  1236. self.assertEqual(nd.tolist(), 1)
  1237. self.assertEqual(mv.tolist(), 1)
  1238. nd[()] = 9; self.assertEqual(nd.tolist(), 9)
  1239. mv[()] = 9; self.assertEqual(mv.tolist(), 9)
  1240. nd[...] = 5; self.assertEqual(nd.tolist(), 5)
  1241. mv[...] = 5; self.assertEqual(mv.tolist(), 5)
  1242. def test_ndarray_index_null_strides(self):
  1243. ex = ndarray(list(range(2*4)), shape=[2, 4], flags=ND_WRITABLE)
  1244. nd = ndarray(ex, getbuf=PyBUF_CONTIG)
  1245. # Sub-views are only possible for full exporters.
  1246. self.assertRaises(BufferError, nd.__getitem__, 1)
  1247. # Same for slices.
  1248. self.assertRaises(BufferError, nd.__getitem__, slice(3,5,1))
  1249. def test_ndarray_index_getitem_single(self):
  1250. # getitem
  1251. for fmt, items, _ in iter_format(5):
  1252. nd = ndarray(items, shape=[5], format=fmt)
  1253. for i in range(-5, 5):
  1254. self.assertEqual(nd[i], items[i])
  1255. self.assertRaises(IndexError, nd.__getitem__, -6)
  1256. self.assertRaises(IndexError, nd.__getitem__, 5)
  1257. if is_memoryview_format(fmt):
  1258. mv = memoryview(nd)
  1259. self.assertEqual(mv, nd)
  1260. for i in range(-5, 5):
  1261. self.assertEqual(mv[i], items[i])
  1262. self.assertRaises(IndexError, mv.__getitem__, -6)
  1263. self.assertRaises(IndexError, mv.__getitem__, 5)
  1264. # getitem with null strides
  1265. for fmt, items, _ in iter_format(5):
  1266. ex = ndarray(items, shape=[5], flags=ND_WRITABLE, format=fmt)
  1267. nd = ndarray(ex, getbuf=PyBUF_CONTIG|PyBUF_FORMAT)
  1268. for i in range(-5, 5):
  1269. self.assertEqual(nd[i], items[i])
  1270. if is_memoryview_format(fmt):
  1271. mv = nd.memoryview_from_buffer()
  1272. self.assertIs(mv.__eq__(nd), NotImplemented)
  1273. for i in range(-5, 5):
  1274. self.assertEqual(mv[i], items[i])
  1275. # getitem with null format
  1276. items = [1,2,3,4,5]
  1277. ex = ndarray(items, shape=[5])
  1278. nd = ndarray(ex, getbuf=PyBUF_CONTIG_RO)
  1279. for i in range(-5, 5):
  1280. self.assertEqual(nd[i], items[i])
  1281. # getitem with null shape/strides/format
  1282. items = [1,2,3,4,5]
  1283. ex = ndarray(items, shape=[5])
  1284. nd = ndarray(ex, getbuf=PyBUF_SIMPLE)
  1285. for i in range(-5, 5):
  1286. self.assertEqual(nd[i], items[i])
  1287. def test_ndarray_index_setitem_single(self):
  1288. # assign single value
  1289. for fmt, items, single_item in iter_format(5):
  1290. nd = ndarray(items, shape=[5], format=fmt, flags=ND_WRITABLE)
  1291. for i in range(5):
  1292. items[i] = single_item
  1293. nd[i] = single_item
  1294. self.assertEqual(nd.tolist(), items)
  1295. self.assertRaises(IndexError, nd.__setitem__, -6, single_item)
  1296. self.assertRaises(IndexError, nd.__setitem__, 5, single_item)
  1297. if not is_memoryview_format(fmt):
  1298. continue
  1299. nd = ndarray(items, shape=[5], format=fmt, flags=ND_WRITABLE)
  1300. mv = memoryview(nd)
  1301. self.assertEqual(mv, nd)
  1302. for i in range(5):
  1303. items[i] = single_item
  1304. mv[i] = single_item
  1305. self.assertEqual(mv.tolist(), items)
  1306. self.assertRaises(IndexError, mv.__setitem__, -6, single_item)
  1307. self.assertRaises(IndexError, mv.__setitem__, 5, single_item)
  1308. # assign single value: lobject = robject
  1309. for fmt, items, single_item in iter_format(5):
  1310. nd = ndarray(items, shape=[5], format=fmt, flags=ND_WRITABLE)
  1311. for i in range(-5, 4):
  1312. items[i] = items[i+1]
  1313. nd[i] = nd[i+1]
  1314. self.assertEqual(nd.tolist(), items)
  1315. if not is_memoryview_format(fmt):
  1316. continue
  1317. nd = ndarray(items, shape=[5], format=fmt, flags=ND_WRITABLE)
  1318. mv = memoryview(nd)
  1319. self.assertEqual(mv, nd)
  1320. for i in range(-5, 4):
  1321. items[i] = items[i+1]
  1322. mv[i] = mv[i+1]
  1323. self.assertEqual(mv.tolist(), items)
  1324. def test_ndarray_index_getitem_multidim(self):
  1325. shape_t = (2, 3, 5)
  1326. nitems = prod(shape_t)
  1327. for shape in permutations(shape_t):
  1328. fmt, items, _ = randitems(nitems)
  1329. for flags in (0, ND_PIL):
  1330. # C array
  1331. nd = ndarray(items, shape=shape, format=fmt, flags=flags)
  1332. lst = carray(items, shape)
  1333. for i in range(-shape[0], shape[0]):
  1334. self.assertEqual(lst[i], nd[i].tolist())
  1335. for j in range(-shape[1], shape[1]):
  1336. self.assertEqual(lst[i][j], nd[i][j].tolist())
  1337. for k in range(-shape[2], shape[2]):
  1338. self.assertEqual(lst[i][j][k], nd[i][j][k])
  1339. # Fortran array
  1340. nd = ndarray(items, shape=shape, format=fmt,
  1341. flags=flags|ND_FORTRAN)
  1342. lst = farray(items, shape)
  1343. for i in range(-shape[0], shape[0]):
  1344. self.assertEqual(lst[i], nd[i].tolist())
  1345. for j in range(-shape[1], shape[1]):
  1346. self.assertEqual(lst[i][j], nd[i][j].tolist())
  1347. for k in range(shape[2], shape[2]):
  1348. self.assertEqual(lst[i][j][k], nd[i][j][k])
  1349. def test_ndarray_sequence(self):
  1350. nd = ndarray(1, shape=())
  1351. self.assertRaises(TypeError, eval, "1 in nd", locals())
  1352. mv = memoryview(nd)
  1353. self.assertEqual(mv, nd)
  1354. self.assertRaises(TypeError, eval, "1 in mv", locals())
  1355. for fmt, items, _ in iter_format(5):
  1356. nd = ndarray(items, shape=[5], format=fmt)
  1357. for i, v in enumerate(nd):
  1358. self.assertEqual(v, items[i])
  1359. self.assertTrue(v in nd)
  1360. if is_memoryview_format(fmt):
  1361. mv = memoryview(nd)
  1362. for i, v in enumerate(mv):
  1363. self.assertEqual(v, items[i])
  1364. self.assertTrue(v in mv)
  1365. def test_ndarray_slice_invalid(self):
  1366. items = [1,2,3,4,5,6,7,8]
  1367. # rvalue is not an exporter
  1368. xl = ndarray(items, shape=[8], flags=ND_WRITABLE)
  1369. ml = memoryview(xl)
  1370. self.assertRaises(TypeError, xl.__setitem__, slice(0,8,1), items)
  1371. self.assertRaises(TypeError, ml.__setitem__, slice(0,8,1), items)
  1372. # rvalue is not a full exporter
  1373. xl = ndarray(items, shape=[8], flags=ND_WRITABLE)
  1374. ex = ndarray(items, shape=[8], flags=ND_WRITABLE)
  1375. xr = ndarray(ex, getbuf=PyBUF_ND)
  1376. self.assertRaises(BufferError, xl.__setitem__, slice(0,8,1), xr)
  1377. # zero step
  1378. nd = ndarray(items, shape=[8], format="L", flags=ND_WRITABLE)
  1379. mv = memoryview(nd)
  1380. self.assertRaises(ValueError, nd.__getitem__, slice(0,1,0))
  1381. self.assertRaises(ValueError, mv.__getitem__, slice(0,1,0))
  1382. nd = ndarray(items, shape=[2,4], format="L", flags=ND_WRITABLE)
  1383. mv = memoryview(nd)
  1384. self.assertRaises(ValueError, nd.__getitem__,
  1385. (slice(0,1,1), slice(0,1,0)))
  1386. self.assertRaises(ValueError, nd.__getitem__,
  1387. (slice(0,1,0), slice(0,1,1)))
  1388. self.assertRaises(TypeError, nd.__getitem__, "@%$")
  1389. self.assertRaises(TypeError, nd.__getitem__, ("@%$", slice(0,1,1)))
  1390. self.assertRaises(TypeError, nd.__getitem__, (slice(0,1,1), {}))
  1391. # memoryview: not implemented
  1392. self.assertRaises(NotImplementedError, mv.__getitem__,
  1393. (slice(0,1,1), slice(0,1,0)))
  1394. self.assertRaises(TypeError, mv.__getitem__, "@%$")
  1395. # differing format
  1396. xl = ndarray(items, shape=[8], format="B", flags=ND_WRITABLE)
  1397. xr = ndarray(items, shape=[8], format="b")
  1398. ml = memoryview(xl)
  1399. mr = memoryview(xr)
  1400. self.assertRaises(ValueError, xl.__setitem__, slice(0,1,1), xr[7:8])
  1401. self.assertEqual(xl.tolist(), items)
  1402. self.assertRaises(ValueError, ml.__setitem__, slice(0,1,1), mr[7:8])
  1403. self.assertEqual(ml.tolist(), items)
  1404. # differing itemsize
  1405. xl = ndarray(items, shape=[8], format="B", flags=ND_WRITABLE)
  1406. yr = ndarray(items, shape=[8], format="L")
  1407. ml = memoryview(xl)
  1408. mr = memoryview(xr)
  1409. self.assertRaises(ValueError, xl.__setitem__, slice(0,1,1), xr[7:8])
  1410. self.assertEqual(xl.tolist(), items)
  1411. self.assertRaises(ValueError, ml.__setitem__, slice(0,1,1), mr[7:8])
  1412. self.assertEqual(ml.tolist(), items)
  1413. # differing ndim
  1414. xl = ndarray(items, shape=[2, 4], format="b", flags=ND_WRITABLE)
  1415. xr = ndarray(items, shape=[8], format="b")
  1416. ml = memoryview(xl)
  1417. mr = memoryview(xr)
  1418. self.assertRaises(ValueError, xl.__setitem__, slice(0,1,1), xr[7:8])
  1419. self.assertEqual(xl.tolist(), [[1,2,3,4], [5,6,7,8]])
  1420. self.assertRaises(NotImplementedError, ml.__setitem__, slice(0,1,1),
  1421. mr[7:8])
  1422. # differing shape
  1423. xl = ndarray(items, shape=[8], format="b", flags=ND_WRITABLE)
  1424. xr = ndarray(items, shape=[8], format="b")
  1425. ml = memoryview(xl)
  1426. mr = memoryview(xr)
  1427. self.assertRaises(ValueError, xl.__setitem__, slice(0,2,1), xr[7:8])
  1428. self.assertEqual(xl.tolist(), items)
  1429. self.assertRaises(ValueError, ml.__setitem__, slice(0,2,1), mr[7:8])
  1430. self.assertEqual(ml.tolist(), items)
  1431. # _testbuffer.c module functions
  1432. self.assertRaises(TypeError, slice_indices, slice(0,1,2), {})
  1433. self.assertRaises(TypeError, slice_indices, "###########", 1)
  1434. self.assertRaises(ValueError, slice_indices, slice(0,1,0), 4)
  1435. x = ndarray(items, shape=[8], format="b", flags=ND_PIL)
  1436. self.assertRaises(TypeError, x.add_suboffsets)
  1437. ex = ndarray(items, shape=[8], format="B")
  1438. x = ndarray(ex, getbuf=PyBUF_SIMPLE)
  1439. self.assertRaises(TypeError, x.add_suboffsets)
  1440. def test_ndarray_slice_zero_shape(self):
  1441. items = [1,2,3,4,5,6,7,8,9,10,11,12]
  1442. x = ndarray(items, shape=[12], format="L", flags=ND_WRITABLE)
  1443. y = ndarray(items, shape=[12], format="L")
  1444. x[4:4] = y[9:9]
  1445. self.assertEqual(x.tolist(), items)
  1446. ml = memoryview(x)
  1447. mr = memoryview(y)
  1448. self.assertEqual(ml, x)
  1449. self.assertEqual(ml, y)
  1450. ml[4:4] = mr[9:9]
  1451. self.assertEqual(ml.tolist(), items)
  1452. x = ndarray(items, shape=[3, 4], format="L", flags=ND_WRITABLE)
  1453. y = ndarray(items, shape=[4, 3], format="L")
  1454. x[1:2, 2:2] = y[1:2, 3:3]
  1455. self.assertEqual(x.tolist(), carray(items, [3, 4]))
  1456. def test_ndarray_slice_multidim(self):
  1457. shape_t = (2, 3, 5)
  1458. ndim = len(shape_t)
  1459. nitems = prod(shape_t)
  1460. for shape in permutations(shape_t):
  1461. fmt, items, _ = randitems(nitems)
  1462. itemsize = struct.calcsize(fmt)
  1463. for flags in (0, ND_PIL):
  1464. nd = ndarray(items, shape=shape, format=fmt, flags=flags)
  1465. lst = carray(items, shape)
  1466. for slices in rslices_ndim(ndim, shape):
  1467. listerr = None
  1468. try:
  1469. sliced = multislice(lst, slices)
  1470. except Exception as e:
  1471. listerr = e.__class__
  1472. nderr = None
  1473. try:
  1474. ndsliced = nd[slices]
  1475. except Exception as e:
  1476. nderr = e.__class__
  1477. if nderr or listerr:
  1478. self.assertIs(nderr, listerr)
  1479. else:
  1480. self.assertEqual(ndsliced.tolist(), sliced)
  1481. def test_ndarray_slice_redundant_suboffsets(self):
  1482. shape_t = (2, 3, 5, 2)
  1483. ndim = len(shape_t)
  1484. nitems = prod(shape_t)
  1485. for shape in permutations(shape_t):
  1486. fmt, items, _ = randitems(nitems)
  1487. itemsize = struct.calcsize(fmt)
  1488. nd = ndarray(items, shape=shape, format=fmt)
  1489. nd.add_suboffsets()
  1490. ex = ndarray(items, shape=shape, format=fmt)
  1491. ex.add_suboffsets()
  1492. mv = memoryview(ex)
  1493. lst = carray(items, shape)
  1494. for slices in rslices_ndim(ndim, shape):
  1495. listerr = None
  1496. try:
  1497. sliced = multislice(lst, slices)
  1498. except Exception as e:
  1499. listerr = e.__class__
  1500. nderr = None
  1501. try:
  1502. ndsliced = nd[slices]
  1503. except Exception as e:
  1504. nderr = e.__class__
  1505. if nderr or listerr:
  1506. self.assertIs(nderr, listerr)
  1507. else:
  1508. self.assertEqual(ndsliced.tolist(), sliced)
  1509. def test_ndarray_slice_assign_single(self):
  1510. for fmt, items, _ in iter_format(5):
  1511. for lslice in genslices(5):
  1512. for rslice in genslices(5):
  1513. for flags in (0, ND_PIL):
  1514. f = flags|ND_WRITABLE
  1515. nd = ndarray(items, shape=[5], format=fmt, flags=f)
  1516. ex = ndarray(items, shape=[5], format=fmt, flags=f)
  1517. mv = memoryview(ex)
  1518. lsterr = None
  1519. diff_structure = None
  1520. lst = items[:]
  1521. try:
  1522. lval = lst[lslice]
  1523. rval = lst[rslice]
  1524. lst[lslice] = lst[rslice]
  1525. diff_structure = len(lval) != len(rval)
  1526. except Exception as e:
  1527. lsterr = e.__class__
  1528. nderr = None
  1529. try:
  1530. nd[lslice] = nd[rslice]
  1531. except Exception as e:
  1532. nderr = e.__class__
  1533. if diff_structure: # ndarray cannot change shape
  1534. self.assertIs(nderr, ValueError)
  1535. else:
  1536. self.assertEqual(nd.tolist(), lst)
  1537. self.assertIs(nderr, lsterr)
  1538. if not is_memoryview_format(fmt):
  1539. continue
  1540. mverr = None
  1541. try:
  1542. mv[lslice] = mv[rslice]
  1543. except Exception as e:
  1544. mverr = e.__class__
  1545. if diff_structure: # memoryview cannot change shape
  1546. self.assertIs(mverr, ValueError)
  1547. else:
  1548. self.assertEqual(mv.tolist(), lst)
  1549. self.assertEqual(mv, nd)
  1550. self.assertIs(mverr, lsterr)
  1551. self.verify(mv, obj=ex,
  1552. itemsize=nd.itemsize, fmt=fmt, readonly=False,
  1553. ndim=nd.ndim, shape=nd.shape, strides=nd.strides,
  1554. lst=nd.tolist())
  1555. def test_ndarray_slice_assign_multidim(self):
  1556. shape_t = (2, 3, 5)
  1557. ndim = len(shape_t)
  1558. nitems = prod(shape_t)
  1559. for shape in permutations(shape_t):
  1560. fmt, items, _ = randitems(nitems)
  1561. for flags in (0, ND_PIL):
  1562. for _ in range(ITERATIONS):
  1563. lslices, rslices = randslice_from_shape(ndim, shape)
  1564. nd = ndarray(items, shape=shape, format=fmt,
  1565. flags=flags|ND_WRITABLE)
  1566. lst = carray(items, shape)
  1567. listerr = None
  1568. try:
  1569. result = multislice_assign(lst, lst, lslices, rslices)
  1570. except Exception as e:
  1571. listerr = e.__class__
  1572. nderr = None
  1573. try:
  1574. nd[lslices] = nd[rslices]
  1575. except Exception as e:
  1576. nderr = e.__class__
  1577. if nderr or listerr:
  1578. self.assertIs(nderr, listerr)
  1579. else:
  1580. self.assertEqual(nd.tolist(), result)
  1581. def test_ndarray_random(self):
  1582. # construction of valid arrays
  1583. for _ in range(ITERATIONS):
  1584. for fmt in fmtdict['@']:
  1585. itemsize = struct.calcsize(fmt)
  1586. t = rand_structure(itemsize, True, maxdim=MAXDIM,
  1587. maxshape=MAXSHAPE)
  1588. self.assertTrue(verify_structure(*t))
  1589. items = randitems_from_structure(fmt, t)
  1590. x = ndarray_from_structure(items, fmt, t)
  1591. xlist = x.tolist()
  1592. mv = memoryview(x)
  1593. if is_memoryview_format(fmt):
  1594. mvlist = mv.tolist()
  1595. self.assertEqual(mvlist, xlist)
  1596. if t[2] > 0:
  1597. # ndim > 0: test against suboffsets representation.
  1598. y = ndarray_from_structure(items, fmt, t, flags=ND_PIL)
  1599. ylist = y.tolist()
  1600. self.assertEqual(xlist, ylist)
  1601. mv = memoryview(y)
  1602. if is_memoryview_format(fmt):
  1603. self.assertEqual(mv, y)
  1604. mvlist = mv.tolist()
  1605. self.assertEqual(mvlist, ylist)
  1606. if numpy_array:
  1607. shape = t[3]
  1608. if 0 in shape:
  1609. continue # http://projects.scipy.org/numpy/ticket/1910
  1610. z = numpy_array_from_structure(items, fmt, t)
  1611. self.verify(x, obj=None,
  1612. itemsize=z.itemsize, fmt=fmt, readonly=False,
  1613. ndim=z.ndim, shape=z.shape, strides=z.strides,
  1614. lst=z.tolist())
  1615. def test_ndarray_random_invalid(self):
  1616. # exceptions during construction of invalid arrays
  1617. for _ in range(ITERATIONS):
  1618. for fmt in fmtdict['@']:
  1619. itemsize = struct.calcsize(fmt)
  1620. t = rand_structure(itemsize, False, maxdim=MAXDIM,
  1621. maxshape=MAXSHAPE)
  1622. self.assertFalse(verify_structure(*t))
  1623. items = randitems_from_structure(fmt, t)
  1624. nderr = False
  1625. try:
  1626. x = ndarray_from_structure(items, fmt, t)
  1627. except Exception as e:
  1628. nderr = e.__class__
  1629. self.assertTrue(nderr)
  1630. if numpy_array:
  1631. numpy_err = False
  1632. try:
  1633. y = numpy_array_from_structure(items, fmt, t)
  1634. except Exception as e:
  1635. numpy_err = e.__class__
  1636. if 0: # http://projects.scipy.org/numpy/ticket/1910
  1637. self.assertTrue(numpy_err)
  1638. def test_ndarray_random_slice_assign(self):
  1639. # valid slice assignments
  1640. for _ in range(ITERATIONS):
  1641. for fmt in fmtdict['@']:
  1642. itemsize = struct.calcsize(fmt)
  1643. lshape, rshape, lslices, rslices = \
  1644. rand_aligned_slices(maxdim=MAXDIM, maxshape=MAXSHAPE)
  1645. tl = rand_structure(itemsize, True, shape=lshape)
  1646. tr = rand_structure(itemsize, True, shape=rshape)
  1647. self.assertTrue(verify_structure(*tl))
  1648. self.assertTrue(verify_structure(*tr))
  1649. litems = randitems_from_structure(fmt, tl)
  1650. ritems = randitems_from_structure(fmt, tr)
  1651. xl = ndarray_from_structure(litems, fmt, tl)
  1652. xr = ndarray_from_structure(ritems, fmt, tr)
  1653. xl[lslices] = xr[rslices]
  1654. xllist = xl.tolist()
  1655. xrlist = xr.tolist()
  1656. ml = memoryview(xl)
  1657. mr = memoryview(xr)
  1658. self.assertEqual(ml.tolist(), xllist)
  1659. self.assertEqual(mr.tolist(), xrlist)
  1660. if tl[2] > 0 and tr[2] > 0:
  1661. # ndim > 0: test against suboffsets representation.
  1662. yl = ndarray_from_structure(litems, fmt, tl, flags=ND_PIL)
  1663. yr = ndarray_from_structure(ritems, fmt, tr, flags=ND_PIL)
  1664. yl[lslices] = yr[rslices]
  1665. yllist = yl.tolist()
  1666. yrlist = yr.tolist()
  1667. self.assertEqual(xllist, yllist)
  1668. self.assertEqual(xrlist, yrlist)
  1669. ml = memoryview(yl)
  1670. mr = memoryview(yr)
  1671. self.assertEqual(ml.tolist(), yllist)
  1672. self.assertEqual(mr.tolist(), yrlist)
  1673. if numpy_array:
  1674. if 0 in lshape or 0 in rshape:
  1675. continue # http://projects.scipy.org/numpy/ticket/1910
  1676. zl = numpy_array_from_structure(litems, fmt, tl)
  1677. zr = numpy_array_from_structure(ritems, fmt, tr)
  1678. zl[lslices] = zr[rslices]
  1679. if not is_overlapping(tl) and not is_overlapping(tr):
  1680. # Slice assignment of overlapping structures
  1681. # is undefined in NumPy.
  1682. self.verify(xl, obj=None,
  1683. itemsize=zl.itemsize, fmt=fmt, readonly=False,
  1684. ndim=zl.ndim, shape=zl.shape,
  1685. strides=zl.strides, lst=zl.tolist())
  1686. self.verify(xr, obj=None,
  1687. itemsize=zr.itemsize, fmt=fmt, readonly=False,
  1688. ndim=zr.ndim, shape=zr.shape,
  1689. strides=zr.strides, lst=zr.tolist())
  1690. def test_ndarray_re_export(self):
  1691. items = [1,2,3,4,5,6,7,8,9,10,11,12]
  1692. nd = ndarray(items, shape=[3,4], flags=ND_PIL)
  1693. ex = ndarray(nd)
  1694. self.assertTrue(ex.flags & ND_PIL)
  1695. self.assertIs(ex.obj, nd)
  1696. self.assertEqual(ex.suboffsets, (0, -1))
  1697. self.assertFalse(ex.c_contiguous)
  1698. self.assertFalse(ex.f_contiguous)
  1699. self.assertFalse(ex.contiguous)
  1700. def test_ndarray_zero_shape(self):
  1701. # zeros in shape
  1702. for flags in (0, ND_PIL):
  1703. nd = ndarray([1,2,3], shape=[0], flags=flags)
  1704. mv = memoryview(nd)
  1705. self.assertEqual(mv, nd)
  1706. self.assertEqual(nd.tolist(), [])
  1707. self.assertEqual(mv.tolist(), [])
  1708. nd = ndarray([1,2,3], shape=[0,3,3], flags=flags)
  1709. self.assertEqual(nd.tolist(), [])
  1710. nd = ndarray([1,2,3], shape=[3,0,3], flags=flags)
  1711. self.assertEqual(nd.tolist(), [[], [], []])
  1712. nd = ndarray([1,2,3], shape=[3,3,0], flags=flags)
  1713. self.assertEqual(nd.tolist(),
  1714. [[[], [], []], [[], [], []], [[], [], []]])
  1715. def test_ndarray_zero_strides(self):
  1716. # zero strides
  1717. for flags in (0, ND_PIL):
  1718. nd = ndarray([1], shape=[5], strides=[0], flags=flags)
  1719. mv = memoryview(nd)
  1720. self.assertEqual(mv, nd)
  1721. self.assertEqual(nd.tolist(), [1, 1, 1, 1, 1])
  1722. self.assertEqual(mv.tolist(), [1, 1, 1, 1, 1])
  1723. def test_ndarray_offset(self):
  1724. nd = ndarray(list(range(20)), shape=[3], offset=7)
  1725. self.assertEqual(nd.offset, 7)
  1726. self.assertEqual(nd.tolist(), [7,8,9])
  1727. def test_ndarray_memoryview_from_buffer(self):
  1728. for flags in (0, ND_PIL):
  1729. nd = ndarray(list(range(3)), shape=[3], flags=flags)
  1730. m = nd.memoryview_from_buffer()
  1731. self.assertEqual(m, nd)
  1732. def test_ndarray_get_pointer(self):
  1733. for flags in (0, ND_PIL):
  1734. nd = ndarray(list(range(3)), shape=[3], flags=flags)
  1735. for i in range(3):
  1736. self.assertEqual(nd[i], get_pointer(nd, [i]))
  1737. def test_ndarray_tolist_null_strides(self):
  1738. ex = ndarray(list(range(20)), shape=[2,2,5])
  1739. nd = ndarray(ex, getbuf=PyBUF_ND|PyBUF_FORMAT)
  1740. self.assertEqual(nd.tolist(), ex.tolist())
  1741. m = memoryview(ex)
  1742. self.assertEqual(m.tolist(), ex.tolist())
  1743. def test_ndarray_cmp_contig(self):
  1744. self.assertFalse(cmp_contig(b"123", b"456"))
  1745. x = ndarray(list(range(12)), shape=[3,4])
  1746. y = ndarray(list(range(12)), shape=[4,3])
  1747. self.assertFalse(cmp_contig(x, y))
  1748. x = ndarray([1], shape=[1], format="B")
  1749. self.assertTrue(cmp_contig(x, b'\x01'))
  1750. self.assertTrue(cmp_contig(b'\x01', x))
  1751. def test_ndarray_hash(self):
  1752. a = array.array('L', [1,2,3])
  1753. nd = ndarray(a)
  1754. self.assertRaises(ValueError, hash, nd)
  1755. # one-dimensional
  1756. b = bytes(list(range(12)))
  1757. nd = ndarray(list(range(12)), shape=[12])
  1758. self.assertEqual(hash(nd), hash(b))
  1759. # C-contiguous
  1760. nd = ndarray(list(range(12)), shape=[3,4])
  1761. self.assertEqual(hash(nd), hash(b))
  1762. nd = ndarray(list(range(12)), shape=[3,2,2])
  1763. self.assertEqual(hash(nd), hash(b))
  1764. # Fortran contiguous
  1765. b = bytes(transpose(list(range(12)), shape=[4,3]))
  1766. nd = ndarray(list(range(12)), shape=[3,4], flags=ND_FORTRAN)
  1767. self.assertEqual(hash(nd), hash(b))
  1768. b = bytes(transpose(list(range(12)), shape=[2,3,2]))
  1769. nd = ndarray(list(range(12)), shape=[2,3,2], flags=ND_FORTRAN)
  1770. self.assertEqual(hash(nd), hash(b))
  1771. # suboffsets
  1772. b = bytes(list(range(12)))
  1773. nd = ndarray(list(range(12)), shape=[2,2,3], flags=ND_PIL)
  1774. self.assertEqual(hash(nd), hash(b))
  1775. # non-byte formats
  1776. nd = ndarray(list(range(12)), shape=[2,2,3], format='L')
  1777. self.assertEqual(hash(nd), hash(nd.tobytes()))
  1778. def test_py_buffer_to_contiguous(self):
  1779. # The requests are used in _testbuffer.c:py_buffer_to_contiguous
  1780. # to generate buffers without full information for testing.
  1781. requests = (
  1782. # distinct flags
  1783. PyBUF_INDIRECT, PyBUF_STRIDES, PyBUF_ND, PyBUF_SIMPLE,
  1784. # compound requests
  1785. PyBUF_FULL, PyBUF_FULL_RO,
  1786. PyBUF_RECORDS, PyBUF_RECORDS_RO,
  1787. PyBUF_STRIDED, PyBUF_STRIDED_RO,
  1788. PyBUF_CONTIG, PyBUF_CONTIG_RO,
  1789. )
  1790. # no buffer interface
  1791. self.assertRaises(TypeError, py_buffer_to_contiguous, {}, 'F',
  1792. PyBUF_FULL_RO)
  1793. # scalar, read-only request
  1794. nd = ndarray(9, shape=(), format="L", flags=ND_WRITABLE)
  1795. for order in ['C', 'F', 'A']:
  1796. for request in requests:
  1797. b = py_buffer_to_contiguous(nd, order, request)
  1798. self.assertEqual(b, nd.tobytes())
  1799. # zeros in shape
  1800. nd = ndarray([1], shape=[0], format="L", flags=ND_WRITABLE)
  1801. for order in ['C', 'F', 'A']:
  1802. for request in requests:
  1803. b = py_buffer_to_contiguous(nd, order, request)
  1804. self.assertEqual(b, b'')
  1805. nd = ndarray(list(range(8)), shape=[2, 0, 7], format="L",
  1806. flags=ND_WRITABLE)
  1807. for order in ['C', 'F', 'A']:
  1808. for request in requests:
  1809. b = py_buffer_to_contiguous(nd, order, request)
  1810. self.assertEqual(b, b'')
  1811. ### One-dimensional arrays are trivial, since Fortran and C order
  1812. ### are the same.
  1813. # one-dimensional
  1814. for f in [0, ND_FORTRAN]:
  1815. nd = ndarray([1], shape=[1], format="h", flags=f|ND_WRITABLE)
  1816. ndbytes = nd.tobytes()
  1817. for order in ['C', 'F', 'A']:
  1818. for request in requests:
  1819. b = py_buffer_to_contiguous(nd, order, request)
  1820. self.assertEqual(b, ndbytes)
  1821. nd = ndarray([1, 2, 3], shape=[3], format="b", flags=f|ND_WRITABLE)
  1822. ndbytes = nd.tobytes()
  1823. for order in ['C', 'F', 'A']:
  1824. for request in requests:
  1825. b = py_buffer_to_contiguous(nd, order, request)
  1826. self.assertEqual(b, ndbytes)
  1827. # one-dimensional, non-contiguous input
  1828. nd = ndarray([1, 2, 3], shape=[2], strides=[2], flags=ND_WRITABLE)
  1829. ndbytes = nd.tobytes()
  1830. for order in ['C', 'F', 'A']:
  1831. for request in [PyBUF_STRIDES, PyBUF_FULL]:
  1832. b = py_buffer_to_contiguous(nd, order, request)
  1833. self.assertEqual(b, ndbytes)
  1834. nd = nd[::-1]
  1835. ndbytes = nd.tobytes()
  1836. for order in ['C', 'F', 'A']:
  1837. for request in requests:
  1838. try:
  1839. b = py_buffer_to_contiguous(nd, order, request)
  1840. except BufferError:
  1841. continue
  1842. self.assertEqual(b, ndbytes)
  1843. ###
  1844. ### Multi-dimensional arrays:
  1845. ###
  1846. ### The goal here is to preserve the logical representation of the
  1847. ### input array but change the physical representation if necessary.
  1848. ###
  1849. ### _testbuffer example:
  1850. ### ====================
  1851. ###
  1852. ### C input array:
  1853. ### --------------
  1854. ### >>> nd = ndarray(list(range(12)), shape=[3, 4])
  1855. ### >>> nd.tolist()
  1856. ### [[0, 1, 2, 3],
  1857. ### [4, 5, 6, 7],
  1858. ### [8, 9, 10, 11]]
  1859. ###
  1860. ### Fortran output:
  1861. ### ---------------
  1862. ### >>> py_buffer_to_contiguous(nd, 'F', PyBUF_FULL_RO)
  1863. ### >>> b'\x00\x04\x08\x01\x05\t\x02\x06\n\x03\x07\x0b'
  1864. ###
  1865. ### The return value corresponds to this input list for
  1866. ### _testbuffer's ndarray:
  1867. ### >>> nd = ndarray([0,4,8,1,5,9,2,6,10,3,7,11], shape=[3,4],
  1868. ### flags=ND_FORTRAN)
  1869. ### >>> nd.tolist()
  1870. ### [[0, 1, 2, 3],
  1871. ### [4, 5, 6, 7],
  1872. ### [8, 9, 10, 11]]
  1873. ###
  1874. ### The logical array is the same, but the values in memory are now
  1875. ### in Fortran order.
  1876. ###
  1877. ### NumPy example:
  1878. ### ==============
  1879. ### _testbuffer's ndarray takes lists to initialize the memory.
  1880. ### Here's the same sequence in NumPy:
  1881. ###
  1882. ### C input:
  1883. ### --------
  1884. ### >>> nd = ndarray(buffer=bytearray(list(range(12))),
  1885. ### shape=[3, 4], dtype='B')
  1886. ### >>> nd
  1887. ### array([[ 0, 1, 2, 3],
  1888. ### [ 4, 5, 6, 7],
  1889. ### [ 8, 9, 10, 11]], dtype=uint8)
  1890. ###
  1891. ### Fortran output:
  1892. ### ---------------
  1893. ### >>> fortran_buf = nd.tostring(order='F')
  1894. ### >>> fortran_buf
  1895. ### b'\x00\x04\x08\x01\x05\t\x02\x06\n\x03\x07\x0b'
  1896. ###
  1897. ### >>> nd = ndarray(buffer=fortran_buf, shape=[3, 4],
  1898. ### dtype='B', order='F')
  1899. ###
  1900. ### >>> nd
  1901. ### array([[ 0, 1, 2, 3],
  1902. ### [ 4, 5, 6, 7],
  1903. ### [ 8, 9, 10, 11]], dtype=uint8)
  1904. ###
  1905. # multi-dimensional, contiguous input
  1906. lst = list(range(12))
  1907. for f in [0, ND_FORTRAN]:
  1908. nd = ndarray(lst, shape=[3, 4], flags=f|ND_WRITABLE)
  1909. if numpy_array:
  1910. na = numpy_array(buffer=bytearray(lst),
  1911. shape=[3, 4], dtype='B',
  1912. order='C' if f == 0 else 'F')
  1913. # 'C' request
  1914. if f == ND_FORTRAN: # 'F' to 'C'
  1915. x = ndarray(transpose(lst, [4, 3]), shape=[3, 4],
  1916. flags=ND_WRITABLE)
  1917. expected = x.tobytes()
  1918. else:
  1919. expected = nd.tobytes()
  1920. for request in requests:
  1921. try:
  1922. b = py_buffer_to_contiguous(nd, 'C', request)
  1923. except BufferError:
  1924. continue
  1925. self.assertEqual(b, expected)
  1926. # Check that output can be used as the basis for constructing
  1927. # a C array that is logically identical to the input array.
  1928. y = ndarray([v for v in b], shape=[3, 4], flags=ND_WRITABLE)
  1929. self.assertEqual(memoryview(y), memoryview(nd))
  1930. if numpy_array:
  1931. self.assertEqual(b, na.tostring(order='C'))
  1932. # 'F' request
  1933. if f == 0: # 'C' to 'F'
  1934. x = ndarray(transpose(lst, [3, 4]), shape=[4, 3],
  1935. flags=ND_WRITABLE)
  1936. else:
  1937. x = ndarray(lst, shape=[3, 4], flags=ND_WRITABLE)
  1938. expected = x.tobytes()
  1939. for request in [PyBUF_FULL, PyBUF_FULL_RO, PyBUF_INDIRECT,
  1940. PyBUF_STRIDES, PyBUF_ND]:
  1941. try:
  1942. b = py_buffer_to_contiguous(nd, 'F', request)
  1943. except BufferError:
  1944. continue
  1945. self.assertEqual(b, expected)
  1946. # Check that output can be used as the basis for constructing
  1947. # a Fortran array that is logically identical to the input array.
  1948. y = ndarray([v for v in b], shape=[3, 4], flags=ND_FORTRAN|ND_WRITABLE)
  1949. self.assertEqual(memoryview(y), memoryview(nd))
  1950. if numpy_array:
  1951. self.assertEqual(b, na.tostring(order='F'))
  1952. # 'A' request
  1953. if f == ND_FORTRAN:
  1954. x = ndarray(lst, shape=[3, 4], flags=ND_WRITABLE)
  1955. expected = x.tobytes()
  1956. else:
  1957. expected = nd.tobytes()
  1958. for request in [PyBUF_FULL, PyBUF_FULL_RO, PyBUF_INDIRECT,
  1959. PyBUF_STRIDES, PyBUF_ND]:
  1960. try:
  1961. b = py_buffer_to_contiguous(nd, 'A', request)
  1962. except BufferError:
  1963. continue
  1964. self.assertEqual(b, expected)
  1965. # Check that output can be used as the basis for constructing
  1966. # an array with order=f that is logically identical to the input
  1967. # array.
  1968. y = ndarray([v for v in b], shape=[3, 4], flags=f|ND_WRITABLE)
  1969. self.assertEqual(memoryview(y), memoryview(nd))
  1970. if numpy_array:
  1971. self.assertEqual(b, na.tostring(order='A'))
  1972. # multi-dimensional, non-contiguous input
  1973. nd = ndarray(list(range(12)), shape=[3, 4], flags=ND_WRITABLE|ND_PIL)
  1974. # 'C'
  1975. b = py_buffer_to_contiguous(nd, 'C', PyBUF_FULL_RO)
  1976. self.assertEqual(b, nd.tobytes())
  1977. y = ndarray([v for v in b], shape=[3, 4], flags=ND_WRITABLE)
  1978. self.assertEqual(memoryview(y), memoryview(nd))
  1979. # 'F'
  1980. b = py_buffer_to_contiguous(nd, 'F', PyBUF_FULL_RO)
  1981. x = ndarray(transpose(lst, [3, 4]), shape=[4, 3], flags=ND_WRITABLE)
  1982. self.assertEqual(b, x.tobytes())
  1983. y = ndarray([v for v in b], shape=[3, 4], flags=ND_FORTRAN|ND_WRITABLE)
  1984. self.assertEqual(memoryview(y), memoryview(nd))
  1985. # 'A'
  1986. b = py_buffer_to_contiguous(nd, 'A', PyBUF_FULL_RO)
  1987. self.assertEqual(b, nd.tobytes())
  1988. y = ndarray([v for v in b], shape=[3, 4], flags=ND_WRITABLE)
  1989. self.assertEqual(memoryview(y), memoryview(nd))
  1990. def test_memoryview_construction(self):
  1991. items_shape = [(9, []), ([1,2,3], [3]), (list(range(2*3*5)), [2,3,5])]
  1992. # NumPy style, C-contiguous:
  1993. for items, shape in items_shape:
  1994. # From PEP-3118 compliant exporter:
  1995. ex = ndarray(items, shape=shape)
  1996. m = memoryview(ex)
  1997. self.assertTrue(m.c_contiguous)
  1998. self.assertTrue(m.contiguous)
  1999. ndim = len(shape)
  2000. strides = strides_from_shape(ndim, shape, 1, 'C')
  2001. lst = carray(items, shape)
  2002. self.verify(m, obj=ex,
  2003. itemsize=1, fmt='B', readonly=True,
  2004. ndim=ndim, shape=shape, strides=strides,
  2005. lst=lst)
  2006. # From memoryview:
  2007. m2 = memoryview(m)
  2008. self.verify(m2, obj=ex,
  2009. itemsize=1, fmt='B', readonly=True,
  2010. ndim=ndim, shape=shape, strides=strides,
  2011. lst=lst)
  2012. # PyMemoryView_FromBuffer(): no strides
  2013. nd = ndarray(ex, getbuf=PyBUF_CONTIG_RO|PyBUF_FORMAT)
  2014. self.assertEqual(nd.strides, ())
  2015. m = nd.memoryview_from_buffer()
  2016. self.verify(m, obj=None,
  2017. itemsize=1, fmt='B', readonly=True,
  2018. ndim=ndim, shape=shape, strides=strides,
  2019. lst=lst)
  2020. # PyMemoryView_FromBuffer(): no format, shape, strides
  2021. nd = ndarray(ex, getbuf=PyBUF_SIMPLE)
  2022. self.assertEqual(nd.format, '')
  2023. self.assertEqual(nd.shape, ())
  2024. self.assertEqual(nd.strides, ())
  2025. m = nd.memoryview_from_buffer()
  2026. lst = [items] if ndim == 0 else items
  2027. self.verify(m, obj=None,
  2028. itemsize=1, fmt='B', readonly=True,
  2029. ndim=1, shape=[ex.nbytes], strides=(1,),
  2030. lst=lst)
  2031. # NumPy style, Fortran contiguous:
  2032. for items, shape in items_shape:
  2033. # From PEP-3118 compliant exporter:
  2034. ex = ndarray(items, shape=shape, flags=ND_FORTRAN)
  2035. m = memoryview(ex)
  2036. self.assertTrue(m.f_contiguous)
  2037. self.assertTrue(m.contiguous)
  2038. ndim = len(shape)
  2039. strides = strides_from_shape(ndim, shape, 1, 'F')
  2040. lst = farray(items, shape)
  2041. self.verify(m, obj=ex,
  2042. itemsize=1, fmt='B', readonly=True,
  2043. ndim=ndim, shape=shape, strides=strides,
  2044. lst=lst)
  2045. # From memoryview:
  2046. m2 = memoryview(m)
  2047. self.verify(m2, obj=ex,
  2048. itemsize=1, fmt='B', readonly=True,
  2049. ndim=ndim, shape=shape, strides=strides,
  2050. lst=lst)
  2051. # PIL style:
  2052. for items, shape in items_shape[1:]:
  2053. # From PEP-3118 compliant exporter:
  2054. ex = ndarray(items, shape=shape, flags=ND_PIL)
  2055. m = memoryview(ex)
  2056. ndim = len(shape)
  2057. lst = carray(items, shape)
  2058. self.verify(m, obj=ex,
  2059. itemsize=1, fmt='B', readonly=True,
  2060. ndim=ndim, shape=shape, strides=ex.strides,
  2061. lst=lst)
  2062. # From memoryview:
  2063. m2 = memoryview(m)
  2064. self.verify(m2, obj=ex,
  2065. itemsize=1, fmt='B', readonly=True,
  2066. ndim=ndim, shape=shape, strides=ex.strides,
  2067. lst=lst)
  2068. # Invalid number of arguments:
  2069. self.assertRaises(TypeError, memoryview, b'9', 'x')
  2070. # Not a buffer provider:
  2071. self.assertRaises(TypeError, memoryview, {})
  2072. # Non-compliant buffer provider:
  2073. ex = ndarray([1,2,3], shape=[3])
  2074. nd = ndarray(ex, getbuf=PyBUF_SIMPLE)
  2075. self.assertRaises(BufferError, memoryview, nd)
  2076. nd = ndarray(ex, getbuf=PyBUF_CONTIG_RO|PyBUF_FORMAT)
  2077. self.assertRaises(BufferError, memoryview, nd)
  2078. # ndim > 64
  2079. nd = ndarray([1]*128, shape=[1]*128, format='L')
  2080. self.assertRaises(ValueError, memoryview, nd)
  2081. self.assertRaises(ValueError, nd.memoryview_from_buffer)
  2082. self.assertRaises(ValueError, get_contiguous, nd, PyBUF_READ, 'C')
  2083. self.assertRaises(ValueError, get_contiguous, nd, PyBUF_READ, 'F')
  2084. self.assertRaises(ValueError, get_contiguous, nd[::-1], PyBUF_READ, 'C')
  2085. def test_memoryview_cast_zero_shape(self):
  2086. # Casts are undefined if buffer is multidimensional and shape
  2087. # contains zeros. These arrays are regarded as C-contiguous by
  2088. # Numpy and PyBuffer_GetContiguous(), so they are not caught by
  2089. # the test for C-contiguity in memory_cast().
  2090. items = [1,2,3]
  2091. for shape in ([0,3,3], [3,0,3], [0,3,3]):
  2092. ex = ndarray(items, shape=shape)
  2093. self.assertTrue(ex.c_contiguous)
  2094. msrc = memoryview(ex)
  2095. self.assertRaises(TypeError, msrc.cast, 'c')
  2096. # Monodimensional empty view can be cast (issue #19014).
  2097. for fmt, _, _ in iter_format(1, 'memoryview'):
  2098. msrc = memoryview(b'')
  2099. m = msrc.cast(fmt)
  2100. self.assertEqual(m.tobytes(), b'')
  2101. self.assertEqual(m.tolist(), [])
  2102. check_sizeof = support.check_sizeof
  2103. def test_memoryview_sizeof(self):
  2104. check = self.check_sizeof
  2105. vsize = support.calcvobjsize
  2106. base_struct = 'Pnin 2P2n2i5P P'
  2107. per_dim = '3n'
  2108. items = list(range(8))
  2109. check(memoryview(b''), vsize(base_struct + 1 * per_dim))
  2110. a = ndarray(items, shape=[2, 4], format="b")
  2111. check(memoryview(a), vsize(base_struct + 2 * per_dim))
  2112. a = ndarray(items, shape=[2, 2, 2], format="b")
  2113. check(memoryview(a), vsize(base_struct + 3 * per_dim))
  2114. def test_memoryview_struct_module(self):
  2115. class INT(object):
  2116. def __init__(self, val):
  2117. self.val = val
  2118. def __int__(self):
  2119. return self.val
  2120. class IDX(object):
  2121. def __init__(self, val):
  2122. self.val = val
  2123. def __index__(self):
  2124. return self.val
  2125. def f(): return 7
  2126. values = [INT(9), IDX(9),
  2127. 2.2+3j, Decimal("-21.1"), 12.2, Fraction(5, 2),
  2128. [1,2,3], {4,5,6}, {7:8}, (), (9,),
  2129. True, False, None, Ellipsis,
  2130. b'a', b'abc', bytearray(b'a'), bytearray(b'abc'),
  2131. 'a', 'abc', r'a', r'abc',
  2132. f, lambda x: x]
  2133. for fmt, items, item in iter_format(10, 'memoryview'):
  2134. ex = ndarray(items, shape=[10], format=fmt, flags=ND_WRITABLE)
  2135. nd = ndarray(items, shape=[10], format=fmt, flags=ND_WRITABLE)
  2136. m = memoryview(ex)
  2137. struct.pack_into(fmt, nd, 0, item)
  2138. m[0] = item
  2139. self.assertEqual(m[0], nd[0])
  2140. itemsize = struct.calcsize(fmt)
  2141. if 'P' in fmt:
  2142. continue
  2143. for v in values:
  2144. struct_err = None
  2145. try:
  2146. struct.pack_into(fmt, nd, itemsize, v)
  2147. except struct.error:
  2148. struct_err = struct.error
  2149. mv_err = None
  2150. try:
  2151. m[1] = v
  2152. except (TypeError, ValueError) as e:
  2153. mv_err = e.__class__
  2154. if struct_err or mv_err:
  2155. self.assertIsNot(struct_err, None)
  2156. self.assertIsNot(mv_err, None)
  2157. else:
  2158. self.assertEqual(m[1], nd[1])
  2159. def test_memoryview_cast_zero_strides(self):
  2160. # Casts are undefined if strides contains zeros. These arrays are
  2161. # (sometimes!) regarded as C-contiguous by Numpy, but not by
  2162. # PyBuffer_GetContiguous().
  2163. ex = ndarray([1,2,3], shape=[3], strides=[0])
  2164. self.assertFalse(ex.c_contiguous)
  2165. msrc = memoryview(ex)
  2166. self.assertRaises(TypeError, msrc.cast, 'c')
  2167. def test_memoryview_cast_invalid(self):
  2168. # invalid format
  2169. for sfmt in NON_BYTE_FORMAT:
  2170. sformat = '@' + sfmt if randrange(2) else sfmt
  2171. ssize = struct.calcsize(sformat)
  2172. for dfmt in NON_BYTE_FORMAT:
  2173. dformat = '@' + dfmt if randrange(2) else dfmt
  2174. dsize = struct.calcsize(dformat)
  2175. ex = ndarray(list(range(32)), shape=[32//ssize], format=sformat)
  2176. msrc = memoryview(ex)
  2177. self.assertRaises(TypeError, msrc.cast, dfmt, [32//dsize])
  2178. for sfmt, sitems, _ in iter_format(1):
  2179. ex = ndarray(sitems, shape=[1], format=sfmt)
  2180. msrc = memoryview(ex)
  2181. for dfmt, _, _ in iter_format(1):
  2182. if not is_memoryview_format(dfmt):
  2183. self.assertRaises(ValueError, msrc.cast, dfmt,
  2184. [32//dsize])
  2185. else:
  2186. if not is_byte_format(sfmt) and not is_byte_format(dfmt):
  2187. self.assertRaises(TypeError, msrc.cast, dfmt,
  2188. [32//dsize])
  2189. # invalid shape
  2190. size_h = struct.calcsize('h')
  2191. size_d = struct.calcsize('d')
  2192. ex = ndarray(list(range(2*2*size_d)), shape=[2,2,size_d], format='h')
  2193. msrc = memoryview(ex)
  2194. self.assertRaises(TypeError, msrc.cast, shape=[2,2,size_h], format='d')
  2195. ex = ndarray(list(range(120)), shape=[1,2,3,4,5])
  2196. m = memoryview(ex)
  2197. # incorrect number of args
  2198. self.assertRaises(TypeError, m.cast)
  2199. self.assertRaises(TypeError, m.cast, 1, 2, 3)
  2200. # incorrect dest format type
  2201. self.assertRaises(TypeError, m.cast, {})
  2202. # incorrect dest format
  2203. self.assertRaises(ValueError, m.cast, "X")
  2204. self.assertRaises(ValueError, m.cast, "@X")
  2205. self.assertRaises(ValueError, m.cast, "@XY")
  2206. # dest format not implemented
  2207. self.assertRaises(ValueError, m.cast, "=B")
  2208. self.assertRaises(ValueError, m.cast, "!L")
  2209. self.assertRaises(ValueError, m.cast, "<P")
  2210. self.assertRaises(ValueError, m.cast, ">l")
  2211. self.assertRaises(ValueError, m.cast, "BI")
  2212. self.assertRaises(ValueError, m.cast, "xBI")
  2213. # src format not implemented
  2214. ex = ndarray([(1,2), (3,4)], shape=[2], format="II")
  2215. m = memoryview(ex)
  2216. self.assertRaises(NotImplementedError, m.__getitem__, 0)
  2217. self.assertRaises(NotImplementedError, m.__setitem__, 0, 8)
  2218. self.assertRaises(NotImplementedError, m.tolist)
  2219. # incorrect shape type
  2220. ex = ndarray(list(range(120)), shape=[1,2,3,4,5])
  2221. m = memoryview(ex)
  2222. self.assertRaises(TypeError, m.cast, "B", shape={})
  2223. # incorrect shape elements
  2224. ex = ndarray(list(range(120)), shape=[2*3*4*5])
  2225. m = memoryview(ex)
  2226. self.assertRaises(OverflowError, m.cast, "B", shape=[2**64])
  2227. self.assertRaises(ValueError, m.cast, "B", shape=[-1])
  2228. self.assertRaises(ValueError, m.cast, "B", shape=[2,3,4,5,6,7,-1])
  2229. self.assertRaises(ValueError, m.cast, "B", shape=[2,3,4,5,6,7,0])
  2230. self.assertRaises(TypeError, m.cast, "B", shape=[2,3,4,5,6,7,'x'])
  2231. # N-D -> N-D cast
  2232. ex = ndarray(list([9 for _ in range(3*5*7*11)]), shape=[3,5,7,11])
  2233. m = memoryview(ex)
  2234. self.assertRaises(TypeError, m.cast, "I", shape=[2,3,4,5])
  2235. # cast with ndim > 64
  2236. nd = ndarray(list(range(128)), shape=[128], format='I')
  2237. m = memoryview(nd)
  2238. self.assertRaises(ValueError, m.cast, 'I', [1]*128)
  2239. # view->len not a multiple of itemsize
  2240. ex = ndarray(list([9 for _ in range(3*5*7*11)]), shape=[3*5*7*11])
  2241. m = memoryview(ex)
  2242. self.assertRaises(TypeError, m.cast, "I", shape=[2,3,4,5])
  2243. # product(shape) * itemsize != buffer size
  2244. ex = ndarray(list([9 for _ in range(3*5*7*11)]), shape=[3*5*7*11])
  2245. m = memoryview(ex)
  2246. self.assertRaises(TypeError, m.cast, "B", shape=[2,3,4,5])
  2247. # product(shape) * itemsize overflow
  2248. nd = ndarray(list(range(128)), shape=[128], format='I')
  2249. m1 = memoryview(nd)
  2250. nd = ndarray(list(range(128)), shape=[128], format='B')
  2251. m2 = memoryview(nd)
  2252. if sys.maxsize == 2**63-1:
  2253. self.assertRaises(TypeError, m1.cast, 'B',
  2254. [7, 7, 73, 127, 337, 92737, 649657])
  2255. self.assertRaises(ValueError, m1.cast, 'B',
  2256. [2**20, 2**20, 2**10, 2**10, 2**3])
  2257. self.assertRaises(ValueError, m2.cast, 'I',
  2258. [2**20, 2**20, 2**10, 2**10, 2**1])
  2259. else:
  2260. self.assertRaises(TypeError, m1.cast, 'B',
  2261. [1, 2147483647])
  2262. self.assertRaises(ValueError, m1.cast, 'B',
  2263. [2**10, 2**10, 2**5, 2**5, 2**1])
  2264. self.assertRaises(ValueError, m2.cast, 'I',
  2265. [2**10, 2**10, 2**5, 2**3, 2**1])
  2266. def test_memoryview_cast(self):
  2267. bytespec = (
  2268. ('B', lambda ex: list(ex.tobytes())),
  2269. ('b', lambda ex: [x-256 if x > 127 else x for x in list(ex.tobytes())]),
  2270. ('c', lambda ex: [bytes(chr(x), 'latin-1') for x in list(ex.tobytes())]),
  2271. )
  2272. def iter_roundtrip(ex, m, items, fmt):
  2273. srcsize = struct.calcsize(fmt)
  2274. for bytefmt, to_bytelist in bytespec:
  2275. m2 = m.cast(bytefmt)
  2276. lst = to_bytelist(ex)
  2277. self.verify(m2, obj=ex,
  2278. itemsize=1, fmt=bytefmt, readonly=False,
  2279. ndim=1, shape=[31*srcsize], strides=(1,),
  2280. lst=lst, cast=True)
  2281. m3 = m2.cast(fmt)
  2282. self.assertEqual(m3, ex)
  2283. lst = ex.tolist()
  2284. self.verify(m3, obj=ex,
  2285. itemsize=srcsize, fmt=fmt, readonly=False,
  2286. ndim=1, shape=[31], strides=(srcsize,),
  2287. lst=lst, cast=True)
  2288. # cast from ndim = 0 to ndim = 1
  2289. srcsize = struct.calcsize('I')
  2290. ex = ndarray(9, shape=[], format='I')
  2291. destitems, destshape = cast_items(ex, 'B', 1)
  2292. m = memoryview(ex)
  2293. m2 = m.cast('B')
  2294. self.verify(m2, obj=ex,
  2295. itemsize=1, fmt='B', readonly=True,
  2296. ndim=1, shape=destshape, strides=(1,),
  2297. lst=destitems, cast=True)
  2298. # cast from ndim = 1 to ndim = 0
  2299. destsize = struct.calcsize('I')
  2300. ex = ndarray([9]*destsize, shape=[destsize], format='B')
  2301. destitems, destshape = cast_items(ex, 'I', destsize, shape=[])
  2302. m = memoryview(ex)
  2303. m2 = m.cast('I', shape=[])
  2304. self.verify(m2, obj=ex,
  2305. itemsize=destsize, fmt='I', readonly=True,
  2306. ndim=0, shape=(), strides=(),
  2307. lst=destitems, cast=True)
  2308. # array.array: roundtrip to/from bytes
  2309. for fmt, items, _ in iter_format(31, 'array'):
  2310. ex = array.array(fmt, items)
  2311. m = memoryview(ex)
  2312. iter_roundtrip(ex, m, items, fmt)
  2313. # ndarray: roundtrip to/from bytes
  2314. for fmt, items, _ in iter_format(31, 'memoryview'):
  2315. ex = ndarray(items, shape=[31], format=fmt, flags=ND_WRITABLE)
  2316. m = memoryview(ex)
  2317. iter_roundtrip(ex, m, items, fmt)
  2318. def test_memoryview_cast_1D_ND(self):
  2319. # Cast between C-contiguous buffers. At least one buffer must
  2320. # be 1D, at least one format must be 'c', 'b' or 'B'.
  2321. for _tshape in gencastshapes():
  2322. for char in fmtdict['@']:
  2323. # Casts to _Bool are undefined if the source contains values
  2324. # other than 0 or 1.
  2325. if char == "?":
  2326. continue
  2327. tfmt = ('', '@')[randrange(2)] + char
  2328. tsize = struct.calcsize(tfmt)
  2329. n = prod(_tshape) * tsize
  2330. obj = 'memoryview' if is_byte_format(tfmt) else 'bytefmt'
  2331. for fmt, items, _ in iter_format(n, obj):
  2332. size = struct.calcsize(fmt)
  2333. shape = [n] if n > 0 else []
  2334. tshape = _tshape + [size]
  2335. ex = ndarray(items, shape=shape, format=fmt)
  2336. m = memoryview(ex)
  2337. titems, tshape = cast_items(ex, tfmt, tsize, shape=tshape)
  2338. if titems is None:
  2339. self.assertRaises(TypeError, m.cast, tfmt, tshape)
  2340. continue
  2341. if titems == 'nan':
  2342. continue # NaNs in lists are a recipe for trouble.
  2343. # 1D -> ND
  2344. nd = ndarray(titems, shape=tshape, format=tfmt)
  2345. m2 = m.cast(tfmt, shape=tshape)
  2346. ndim = len(tshape)
  2347. strides = nd.strides
  2348. lst = nd.tolist()
  2349. self.verify(m2, obj=ex,
  2350. itemsize=tsize, fmt=tfmt, readonly=True,
  2351. ndim=ndim, shape=tshape, strides=strides,
  2352. lst=lst, cast=True)
  2353. # ND -> 1D
  2354. m3 = m2.cast(fmt)
  2355. m4 = m2.cast(fmt, shape=shape)
  2356. ndim = len(shape)
  2357. strides = ex.strides
  2358. lst = ex.tolist()
  2359. self.verify(m3, obj=ex,
  2360. itemsize=size, fmt=fmt, readonly=True,
  2361. ndim=ndim, shape=shape, strides=strides,
  2362. lst=lst, cast=True)
  2363. self.verify(m4, obj=ex,
  2364. itemsize=size, fmt=fmt, readonly=True,
  2365. ndim=ndim, shape=shape, strides=strides,
  2366. lst=lst, cast=True)
  2367. if ctypes:
  2368. # format: "T{>l:x:>d:y:}"
  2369. class BEPoint(ctypes.BigEndianStructure):
  2370. _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_double)]
  2371. point = BEPoint(100, 200.1)
  2372. m1 = memoryview(point)
  2373. m2 = m1.cast('B')
  2374. self.assertEqual(m2.obj, point)
  2375. self.assertEqual(m2.itemsize, 1)
  2376. self.assertIs(m2.readonly, False)
  2377. self.assertEqual(m2.ndim, 1)
  2378. self.assertEqual(m2.shape, (m2.nbytes,))
  2379. self.assertEqual(m2.strides, (1,))
  2380. self.assertEqual(m2.suboffsets, ())
  2381. x = ctypes.c_double(1.2)
  2382. m1 = memoryview(x)
  2383. m2 = m1.cast('c')
  2384. self.assertEqual(m2.obj, x)
  2385. self.assertEqual(m2.itemsize, 1)
  2386. self.assertIs(m2.readonly, False)
  2387. self.assertEqual(m2.ndim, 1)
  2388. self.assertEqual(m2.shape, (m2.nbytes,))
  2389. self.assertEqual(m2.strides, (1,))
  2390. self.assertEqual(m2.suboffsets, ())
  2391. def test_memoryview_tolist(self):
  2392. # Most tolist() tests are in self.verify() etc.
  2393. a = array.array('h', list(range(-6, 6)))
  2394. m = memoryview(a)
  2395. self.assertEqual(m, a)
  2396. self.assertEqual(m.tolist(), a.tolist())
  2397. a = a[2::3]
  2398. m = m[2::3]
  2399. self.assertEqual(m, a)
  2400. self.assertEqual(m.tolist(), a.tolist())
  2401. ex = ndarray(list(range(2*3*5*7*11)), shape=[11,2,7,3,5], format='L')
  2402. m = memoryview(ex)
  2403. self.assertEqual(m.tolist(), ex.tolist())
  2404. ex = ndarray([(2, 5), (7, 11)], shape=[2], format='lh')
  2405. m = memoryview(ex)
  2406. self.assertRaises(NotImplementedError, m.tolist)
  2407. ex = ndarray([b'12345'], shape=[1], format="s")
  2408. m = memoryview(ex)
  2409. self.assertRaises(NotImplementedError, m.tolist)
  2410. ex = ndarray([b"a",b"b",b"c",b"d",b"e",b"f"], shape=[2,3], format='s')
  2411. m = memoryview(ex)
  2412. self.assertRaises(NotImplementedError, m.tolist)
  2413. def test_memoryview_repr(self):
  2414. m = memoryview(bytearray(9))
  2415. r = m.__repr__()
  2416. self.assertTrue(r.startswith("<memory"))
  2417. m.release()
  2418. r = m.__repr__()
  2419. self.assertTrue(r.startswith("<released"))
  2420. def test_memoryview_sequence(self):
  2421. for fmt in ('d', 'f'):
  2422. inf = float(3e400)
  2423. ex = array.array(fmt, [1.0, inf, 3.0])
  2424. m = memoryview(ex)
  2425. self.assertIn(1.0, m)
  2426. self.assertIn(5e700, m)
  2427. self.assertIn(3.0, m)
  2428. ex = ndarray(9.0, [], format='f')
  2429. m = memoryview(ex)
  2430. self.assertRaises(TypeError, eval, "9.0 in m", locals())
  2431. @contextlib.contextmanager
  2432. def assert_out_of_bounds_error(self, dim):
  2433. with self.assertRaises(IndexError) as cm:
  2434. yield
  2435. self.assertEqual(str(cm.exception),
  2436. "index out of bounds on dimension %d" % (dim,))
  2437. def test_memoryview_index(self):
  2438. # ndim = 0
  2439. ex = ndarray(12.5, shape=[], format='d')
  2440. m = memoryview(ex)
  2441. self.assertEqual(m[()], 12.5)
  2442. self.assertEqual(m[...], m)
  2443. self.assertEqual(m[...], ex)
  2444. self.assertRaises(TypeError, m.__getitem__, 0)
  2445. ex = ndarray((1,2,3), shape=[], format='iii')
  2446. m = memoryview(ex)
  2447. self.assertRaises(NotImplementedError, m.__getitem__, ())
  2448. # range
  2449. ex = ndarray(list(range(7)), shape=[7], flags=ND_WRITABLE)
  2450. m = memoryview(ex)
  2451. self.assertRaises(IndexError, m.__getitem__, 2**64)
  2452. self.assertRaises(TypeError, m.__getitem__, 2.0)
  2453. self.assertRaises(TypeError, m.__getitem__, 0.0)
  2454. # out of bounds
  2455. self.assertRaises(IndexError, m.__getitem__, -8)
  2456. self.assertRaises(IndexError, m.__getitem__, 8)
  2457. # multi-dimensional
  2458. ex = ndarray(list(range(12)), shape=[3,4], flags=ND_WRITABLE)
  2459. m = memoryview(ex)
  2460. self.assertEqual(m[0, 0], 0)
  2461. self.assertEqual(m[2, 0], 8)
  2462. self.assertEqual(m[2, 3], 11)
  2463. self.assertEqual(m[-1, -1], 11)
  2464. self.assertEqual(m[-3, -4], 0)
  2465. # out of bounds
  2466. for index in (3, -4):
  2467. with self.assert_out_of_bounds_error(dim=1):
  2468. m[index, 0]
  2469. for index in (4, -5):
  2470. with self.assert_out_of_bounds_error(dim=2):
  2471. m[0, index]
  2472. self.assertRaises(IndexError, m.__getitem__, (2**64, 0))
  2473. self.assertRaises(IndexError, m.__getitem__, (0, 2**64))
  2474. self.assertRaises(TypeError, m.__getitem__, (0, 0, 0))
  2475. self.assertRaises(TypeError, m.__getitem__, (0.0, 0.0))
  2476. # Not implemented: multidimensional sub-views
  2477. self.assertRaises(NotImplementedError, m.__getitem__, ())
  2478. self.assertRaises(NotImplementedError, m.__getitem__, 0)
  2479. def test_memoryview_assign(self):
  2480. # ndim = 0
  2481. ex = ndarray(12.5, shape=[], format='f', flags=ND_WRITABLE)
  2482. m = memoryview(ex)
  2483. m[()] = 22.5
  2484. self.assertEqual(m[()], 22.5)
  2485. m[...] = 23.5
  2486. self.assertEqual(m[()], 23.5)
  2487. self.assertRaises(TypeError, m.__setitem__, 0, 24.7)
  2488. # read-only
  2489. ex = ndarray(list(range(7)), shape=[7])
  2490. m = memoryview(ex)
  2491. self.assertRaises(TypeError, m.__setitem__, 2, 10)
  2492. # range
  2493. ex = ndarray(list(range(7)), shape=[7], flags=ND_WRITABLE)
  2494. m = memoryview(ex)
  2495. self.assertRaises(IndexError, m.__setitem__, 2**64, 9)
  2496. self.assertRaises(TypeError, m.__setitem__, 2.0, 10)
  2497. self.assertRaises(TypeError, m.__setitem__, 0.0, 11)
  2498. # out of bounds
  2499. self.assertRaises(IndexError, m.__setitem__, -8, 20)
  2500. self.assertRaises(IndexError, m.__setitem__, 8, 25)
  2501. # pack_single() success:
  2502. for fmt in fmtdict['@']:
  2503. if fmt == 'c' or fmt == '?':
  2504. continue
  2505. ex = ndarray([1,2,3], shape=[3], format=fmt, flags=ND_WRITABLE)
  2506. m = memoryview(ex)
  2507. i = randrange(-3, 3)
  2508. m[i] = 8
  2509. self.assertEqual(m[i], 8)
  2510. self.assertEqual(m[i], ex[i])
  2511. ex = ndarray([b'1', b'2', b'3'], shape=[3], format='c',
  2512. flags=ND_WRITABLE)
  2513. m = memoryview(ex)
  2514. m[2] = b'9'
  2515. self.assertEqual(m[2], b'9')
  2516. ex = ndarray([True, False, True], shape=[3], format='?',
  2517. flags=ND_WRITABLE)
  2518. m = memoryview(ex)
  2519. m[1] = True
  2520. self.assertIs(m[1], True)
  2521. # pack_single() exceptions:
  2522. nd = ndarray([b'x'], shape=[1], format='c', flags=ND_WRITABLE)
  2523. m = memoryview(nd)
  2524. self.assertRaises(TypeError, m.__setitem__, 0, 100)
  2525. ex = ndarray(list(range(120)), shape=[1,2,3,4,5], flags=ND_WRITABLE)
  2526. m1 = memoryview(ex)
  2527. for fmt, _range in fmtdict['@'].items():
  2528. if (fmt == '?'): # PyObject_IsTrue() accepts anything
  2529. continue
  2530. if fmt == 'c': # special case tested above
  2531. continue
  2532. m2 = m1.cast(fmt)
  2533. lo, hi = _range
  2534. if fmt == 'd' or fmt == 'f':
  2535. lo, hi = -2**1024, 2**1024
  2536. if fmt != 'P': # PyLong_AsVoidPtr() accepts negative numbers
  2537. self.assertRaises(ValueError, m2.__setitem__, 0, lo-1)
  2538. self.assertRaises(TypeError, m2.__setitem__, 0, "xyz")
  2539. self.assertRaises(ValueError, m2.__setitem__, 0, hi)
  2540. # invalid item
  2541. m2 = m1.cast('c')
  2542. self.assertRaises(ValueError, m2.__setitem__, 0, b'\xff\xff')
  2543. # format not implemented
  2544. ex = ndarray(list(range(1)), shape=[1], format="xL", flags=ND_WRITABLE)
  2545. m = memoryview(ex)
  2546. self.assertRaises(NotImplementedError, m.__setitem__, 0, 1)
  2547. ex = ndarray([b'12345'], shape=[1], format="s", flags=ND_WRITABLE)
  2548. m = memoryview(ex)
  2549. self.assertRaises(NotImplementedError, m.__setitem__, 0, 1)
  2550. # multi-dimensional
  2551. ex = ndarray(list(range(12)), shape=[3,4], flags=ND_WRITABLE)
  2552. m = memoryview(ex)
  2553. m[0,1] = 42
  2554. self.assertEqual(ex[0][1], 42)
  2555. m[-1,-1] = 43
  2556. self.assertEqual(ex[2][3], 43)
  2557. # errors
  2558. for index in (3, -4):
  2559. with self.assert_out_of_bounds_error(dim=1):
  2560. m[index, 0] = 0
  2561. for index in (4, -5):
  2562. with self.assert_out_of_bounds_error(dim=2):
  2563. m[0, index] = 0
  2564. self.assertRaises(IndexError, m.__setitem__, (2**64, 0), 0)
  2565. self.assertRaises(IndexError, m.__setitem__, (0, 2**64), 0)
  2566. self.assertRaises(TypeError, m.__setitem__, (0, 0, 0), 0)
  2567. self.assertRaises(TypeError, m.__setitem__, (0.0, 0.0), 0)
  2568. # Not implemented: multidimensional sub-views
  2569. self.assertRaises(NotImplementedError, m.__setitem__, 0, [2, 3])
  2570. def test_memoryview_slice(self):
  2571. ex = ndarray(list(range(12)), shape=[12], flags=ND_WRITABLE)
  2572. m = memoryview(ex)
  2573. # zero step
  2574. self.assertRaises(ValueError, m.__getitem__, slice(0,2,0))
  2575. self.assertRaises(ValueError, m.__setitem__, slice(0,2,0),
  2576. bytearray([1,2]))
  2577. # 0-dim slicing (identity function)
  2578. self.assertRaises(NotImplementedError, m.__getitem__, ())
  2579. # multidimensional slices
  2580. ex = ndarray(list(range(12)), shape=[12], flags=ND_WRITABLE)
  2581. m = memoryview(ex)
  2582. self.assertRaises(NotImplementedError, m.__getitem__,
  2583. (slice(0,2,1), slice(0,2,1)))
  2584. self.assertRaises(NotImplementedError, m.__setitem__,
  2585. (slice(0,2,1), slice(0,2,1)), bytearray([1,2]))
  2586. # invalid slice tuple
  2587. self.assertRaises(TypeError, m.__getitem__, (slice(0,2,1), {}))
  2588. self.assertRaises(TypeError, m.__setitem__, (slice(0,2,1), {}),
  2589. bytearray([1,2]))
  2590. # rvalue is not an exporter
  2591. self.assertRaises(TypeError, m.__setitem__, slice(0,1,1), [1])
  2592. # non-contiguous slice assignment
  2593. for flags in (0, ND_PIL):
  2594. ex1 = ndarray(list(range(12)), shape=[12], strides=[-1], offset=11,
  2595. flags=ND_WRITABLE|flags)
  2596. ex2 = ndarray(list(range(24)), shape=[12], strides=[2], flags=flags)
  2597. m1 = memoryview(ex1)
  2598. m2 = memoryview(ex2)
  2599. ex1[2:5] = ex1[2:5]
  2600. m1[2:5] = m2[2:5]
  2601. self.assertEqual(m1, ex1)
  2602. self.assertEqual(m2, ex2)
  2603. ex1[1:3][::-1] = ex2[0:2][::1]
  2604. m1[1:3][::-1] = m2[0:2][::1]
  2605. self.assertEqual(m1, ex1)
  2606. self.assertEqual(m2, ex2)
  2607. ex1[4:1:-2][::-1] = ex1[1:4:2][::1]
  2608. m1[4:1:-2][::-1] = m1[1:4:2][::1]
  2609. self.assertEqual(m1, ex1)
  2610. self.assertEqual(m2, ex2)
  2611. def test_memoryview_array(self):
  2612. def cmptest(testcase, a, b, m, singleitem):
  2613. for i, _ in enumerate(a):
  2614. ai = a[i]
  2615. mi = m[i]
  2616. testcase.assertEqual(ai, mi)
  2617. a[i] = singleitem
  2618. if singleitem != ai:
  2619. testcase.assertNotEqual(a, m)
  2620. testcase.assertNotEqual(a, b)
  2621. else:
  2622. testcase.assertEqual(a, m)
  2623. testcase.assertEqual(a, b)
  2624. m[i] = singleitem
  2625. testcase.assertEqual(a, m)
  2626. testcase.assertEqual(b, m)
  2627. a[i] = ai
  2628. m[i] = mi
  2629. for n in range(1, 5):
  2630. for fmt, items, singleitem in iter_format(n, 'array'):
  2631. for lslice in genslices(n):
  2632. for rslice in genslices(n):
  2633. a = array.array(fmt, items)
  2634. b = array.array(fmt, items)
  2635. m = memoryview(b)
  2636. self.assertEqual(m, a)
  2637. self.assertEqual(m.tolist(), a.tolist())
  2638. self.assertEqual(m.tobytes(), a.tobytes())
  2639. self.assertEqual(len(m), len(a))
  2640. cmptest(self, a, b, m, singleitem)
  2641. array_err = None
  2642. have_resize = None
  2643. try:
  2644. al = a[lslice]
  2645. ar = a[rslice]
  2646. a[lslice] = a[rslice]
  2647. have_resize = len(al) != len(ar)
  2648. except Exception as e:
  2649. array_err = e.__class__
  2650. m_err = None
  2651. try:
  2652. m[lslice] = m[rslice]
  2653. except Exception as e:
  2654. m_err = e.__class__
  2655. if have_resize: # memoryview cannot change shape
  2656. self.assertIs(m_err, ValueError)
  2657. elif m_err or array_err:
  2658. self.assertIs(m_err, array_err)
  2659. else:
  2660. self.assertEqual(m, a)
  2661. self.assertEqual(m.tolist(), a.tolist())
  2662. self.assertEqual(m.tobytes(), a.tobytes())
  2663. cmptest(self, a, b, m, singleitem)
  2664. def test_memoryview_compare_special_cases(self):
  2665. a = array.array('L', [1, 2, 3])
  2666. b = array.array('L', [1, 2, 7])
  2667. # Ordering comparisons raise:
  2668. v = memoryview(a)
  2669. w = memoryview(b)
  2670. for attr in ('__lt__', '__le__', '__gt__', '__ge__'):
  2671. self.assertIs(getattr(v, attr)(w), NotImplemented)
  2672. self.assertIs(getattr(a, attr)(v), NotImplemented)
  2673. # Released views compare equal to themselves:
  2674. v = memoryview(a)
  2675. v.release()
  2676. self.assertEqual(v, v)
  2677. self.assertNotEqual(v, a)
  2678. self.assertNotEqual(a, v)
  2679. v = memoryview(a)
  2680. w = memoryview(a)
  2681. w.release()
  2682. self.assertNotEqual(v, w)
  2683. self.assertNotEqual(w, v)
  2684. # Operand does not implement the buffer protocol:
  2685. v = memoryview(a)
  2686. self.assertNotEqual(v, [1, 2, 3])
  2687. # NaNs
  2688. nd = ndarray([(0, 0)], shape=[1], format='l x d x', flags=ND_WRITABLE)
  2689. nd[0] = (-1, float('nan'))
  2690. self.assertNotEqual(memoryview(nd), nd)
  2691. # Depends on issue #15625: the struct module does not understand 'u'.
  2692. a = array.array('u', 'xyz')
  2693. v = memoryview(a)
  2694. self.assertNotEqual(a, v)
  2695. self.assertNotEqual(v, a)
  2696. # Some ctypes format strings are unknown to the struct module.
  2697. if ctypes:
  2698. # format: "T{>l:x:>l:y:}"
  2699. class BEPoint(ctypes.BigEndianStructure):
  2700. _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_long)]
  2701. point = BEPoint(100, 200)
  2702. a = memoryview(point)
  2703. b = memoryview(point)
  2704. self.assertNotEqual(a, b)
  2705. self.assertNotEqual(a, point)
  2706. self.assertNotEqual(point, a)
  2707. self.assertRaises(NotImplementedError, a.tolist)
  2708. def test_memoryview_compare_ndim_zero(self):
  2709. nd1 = ndarray(1729, shape=[], format='@L')
  2710. nd2 = ndarray(1729, shape=[], format='L', flags=ND_WRITABLE)
  2711. v = memoryview(nd1)
  2712. w = memoryview(nd2)
  2713. self.assertEqual(v, w)
  2714. self.assertEqual(w, v)
  2715. self.assertEqual(v, nd2)
  2716. self.assertEqual(nd2, v)
  2717. self.assertEqual(w, nd1)
  2718. self.assertEqual(nd1, w)
  2719. self.assertFalse(v.__ne__(w))
  2720. self.assertFalse(w.__ne__(v))
  2721. w[()] = 1728
  2722. self.assertNotEqual(v, w)
  2723. self.assertNotEqual(w, v)
  2724. self.assertNotEqual(v, nd2)
  2725. self.assertNotEqual(nd2, v)
  2726. self.assertNotEqual(w, nd1)
  2727. self.assertNotEqual(nd1, w)
  2728. self.assertFalse(v.__eq__(w))
  2729. self.assertFalse(w.__eq__(v))
  2730. nd = ndarray(list(range(12)), shape=[12], flags=ND_WRITABLE|ND_PIL)
  2731. ex = ndarray(list(range(12)), shape=[12], flags=ND_WRITABLE|ND_PIL)
  2732. m = memoryview(ex)
  2733. self.assertEqual(m, nd)
  2734. m[9] = 100
  2735. self.assertNotEqual(m, nd)
  2736. # struct module: equal
  2737. nd1 = ndarray((1729, 1.2, b'12345'), shape=[], format='Lf5s')
  2738. nd2 = ndarray((1729, 1.2, b'12345'), shape=[], format='hf5s',
  2739. flags=ND_WRITABLE)
  2740. v = memoryview(nd1)
  2741. w = memoryview(nd2)
  2742. self.assertEqual(v, w)
  2743. self.assertEqual(w, v)
  2744. self.assertEqual(v, nd2)
  2745. self.assertEqual(nd2, v)
  2746. self.assertEqual(w, nd1)
  2747. self.assertEqual(nd1, w)
  2748. # struct module: not equal
  2749. nd1 = ndarray((1729, 1.2, b'12345'), shape=[], format='Lf5s')
  2750. nd2 = ndarray((-1729, 1.2, b'12345'), shape=[], format='hf5s',
  2751. flags=ND_WRITABLE)
  2752. v = memoryview(nd1)
  2753. w = memoryview(nd2)
  2754. self.assertNotEqual(v, w)
  2755. self.assertNotEqual(w, v)
  2756. self.assertNotEqual(v, nd2)
  2757. self.assertNotEqual(nd2, v)
  2758. self.assertNotEqual(w, nd1)
  2759. self.assertNotEqual(nd1, w)
  2760. self.assertEqual(v, nd1)
  2761. self.assertEqual(w, nd2)
  2762. def test_memoryview_compare_ndim_one(self):
  2763. # contiguous
  2764. nd1 = ndarray([-529, 576, -625, 676, -729], shape=[5], format='@h')
  2765. nd2 = ndarray([-529, 576, -625, 676, 729], shape=[5], format='@h')
  2766. v = memoryview(nd1)
  2767. w = memoryview(nd2)
  2768. self.assertEqual(v, nd1)
  2769. self.assertEqual(w, nd2)
  2770. self.assertNotEqual(v, nd2)
  2771. self.assertNotEqual(w, nd1)
  2772. self.assertNotEqual(v, w)
  2773. # contiguous, struct module
  2774. nd1 = ndarray([-529, 576, -625, 676, -729], shape=[5], format='<i')
  2775. nd2 = ndarray([-529, 576, -625, 676, 729], shape=[5], format='>h')
  2776. v = memoryview(nd1)
  2777. w = memoryview(nd2)
  2778. self.assertEqual(v, nd1)
  2779. self.assertEqual(w, nd2)
  2780. self.assertNotEqual(v, nd2)
  2781. self.assertNotEqual(w, nd1)
  2782. self.assertNotEqual(v, w)
  2783. # non-contiguous
  2784. nd1 = ndarray([-529, -625, -729], shape=[3], format='@h')
  2785. nd2 = ndarray([-529, 576, -625, 676, -729], shape=[5], format='@h')
  2786. v = memoryview(nd1)
  2787. w = memoryview(nd2)
  2788. self.assertEqual(v, nd2[::2])
  2789. self.assertEqual(w[::2], nd1)
  2790. self.assertEqual(v, w[::2])
  2791. self.assertEqual(v[::-1], w[::-2])
  2792. # non-contiguous, struct module
  2793. nd1 = ndarray([-529, -625, -729], shape=[3], format='!h')
  2794. nd2 = ndarray([-529, 576, -625, 676, -729], shape=[5], format='<l')
  2795. v = memoryview(nd1)
  2796. w = memoryview(nd2)
  2797. self.assertEqual(v, nd2[::2])
  2798. self.assertEqual(w[::2], nd1)
  2799. self.assertEqual(v, w[::2])
  2800. self.assertEqual(v[::-1], w[::-2])
  2801. # non-contiguous, suboffsets
  2802. nd1 = ndarray([-529, -625, -729], shape=[3], format='@h')
  2803. nd2 = ndarray([-529, 576, -625, 676, -729], shape=[5], format='@h',
  2804. flags=ND_PIL)
  2805. v = memoryview(nd1)
  2806. w = memoryview(nd2)
  2807. self.assertEqual(v, nd2[::2])
  2808. self.assertEqual(w[::2], nd1)
  2809. self.assertEqual(v, w[::2])
  2810. self.assertEqual(v[::-1], w[::-2])
  2811. # non-contiguous, suboffsets, struct module
  2812. nd1 = ndarray([-529, -625, -729], shape=[3], format='h 0c')
  2813. nd2 = ndarray([-529, 576, -625, 676, -729], shape=[5], format='> h',
  2814. flags=ND_PIL)
  2815. v = memoryview(nd1)
  2816. w = memoryview(nd2)
  2817. self.assertEqual(v, nd2[::2])
  2818. self.assertEqual(w[::2], nd1)
  2819. self.assertEqual(v, w[::2])
  2820. self.assertEqual(v[::-1], w[::-2])
  2821. def test_memoryview_compare_zero_shape(self):
  2822. # zeros in shape
  2823. nd1 = ndarray([900, 961], shape=[0], format='@h')
  2824. nd2 = ndarray([-900, -961], shape=[0], format='@h')
  2825. v = memoryview(nd1)
  2826. w = memoryview(nd2)
  2827. self.assertEqual(v, nd1)
  2828. self.assertEqual(w, nd2)
  2829. self.assertEqual(v, nd2)
  2830. self.assertEqual(w, nd1)
  2831. self.assertEqual(v, w)
  2832. # zeros in shape, struct module
  2833. nd1 = ndarray([900, 961], shape=[0], format='= h0c')
  2834. nd2 = ndarray([-900, -961], shape=[0], format='@ i')
  2835. v = memoryview(nd1)
  2836. w = memoryview(nd2)
  2837. self.assertEqual(v, nd1)
  2838. self.assertEqual(w, nd2)
  2839. self.assertEqual(v, nd2)
  2840. self.assertEqual(w, nd1)
  2841. self.assertEqual(v, w)
  2842. def test_memoryview_compare_zero_strides(self):
  2843. # zero strides
  2844. nd1 = ndarray([900, 900, 900, 900], shape=[4], format='@L')
  2845. nd2 = ndarray([900], shape=[4], strides=[0], format='L')
  2846. v = memoryview(nd1)
  2847. w = memoryview(nd2)
  2848. self.assertEqual(v, nd1)
  2849. self.assertEqual(w, nd2)
  2850. self.assertEqual(v, nd2)
  2851. self.assertEqual(w, nd1)
  2852. self.assertEqual(v, w)
  2853. # zero strides, struct module
  2854. nd1 = ndarray([(900, 900)]*4, shape=[4], format='@ Li')
  2855. nd2 = ndarray([(900, 900)], shape=[4], strides=[0], format='!L h')
  2856. v = memoryview(nd1)
  2857. w = memoryview(nd2)
  2858. self.assertEqual(v, nd1)
  2859. self.assertEqual(w, nd2)
  2860. self.assertEqual(v, nd2)
  2861. self.assertEqual(w, nd1)
  2862. self.assertEqual(v, w)
  2863. def test_memoryview_compare_random_formats(self):
  2864. # random single character native formats
  2865. n = 10
  2866. for char in fmtdict['@m']:
  2867. fmt, items, singleitem = randitems(n, 'memoryview', '@', char)
  2868. for flags in (0, ND_PIL):
  2869. nd = ndarray(items, shape=[n], format=fmt, flags=flags)
  2870. m = memoryview(nd)
  2871. self.assertEqual(m, nd)
  2872. nd = nd[::-3]
  2873. m = memoryview(nd)
  2874. self.assertEqual(m, nd)
  2875. # random formats
  2876. n = 10
  2877. for _ in range(100):
  2878. fmt, items, singleitem = randitems(n)
  2879. for flags in (0, ND_PIL):
  2880. nd = ndarray(items, shape=[n], format=fmt, flags=flags)
  2881. m = memoryview(nd)
  2882. self.assertEqual(m, nd)
  2883. nd = nd[::-3]
  2884. m = memoryview(nd)
  2885. self.assertEqual(m, nd)
  2886. def test_memoryview_compare_multidim_c(self):
  2887. # C-contiguous, different values
  2888. nd1 = ndarray(list(range(-15, 15)), shape=[3, 2, 5], format='@h')
  2889. nd2 = ndarray(list(range(0, 30)), shape=[3, 2, 5], format='@h')
  2890. v = memoryview(nd1)
  2891. w = memoryview(nd2)
  2892. self.assertEqual(v, nd1)
  2893. self.assertEqual(w, nd2)
  2894. self.assertNotEqual(v, nd2)
  2895. self.assertNotEqual(w, nd1)
  2896. self.assertNotEqual(v, w)
  2897. # C-contiguous, different values, struct module
  2898. nd1 = ndarray([(0, 1, 2)]*30, shape=[3, 2, 5], format='=f q xxL')
  2899. nd2 = ndarray([(-1.2, 1, 2)]*30, shape=[3, 2, 5], format='< f 2Q')
  2900. v = memoryview(nd1)
  2901. w = memoryview(nd2)
  2902. self.assertEqual(v, nd1)
  2903. self.assertEqual(w, nd2)
  2904. self.assertNotEqual(v, nd2)
  2905. self.assertNotEqual(w, nd1)
  2906. self.assertNotEqual(v, w)
  2907. # C-contiguous, different shape
  2908. nd1 = ndarray(list(range(30)), shape=[2, 3, 5], format='L')
  2909. nd2 = ndarray(list(range(30)), shape=[3, 2, 5], format='L')
  2910. v = memoryview(nd1)
  2911. w = memoryview(nd2)
  2912. self.assertEqual(v, nd1)
  2913. self.assertEqual(w, nd2)
  2914. self.assertNotEqual(v, nd2)
  2915. self.assertNotEqual(w, nd1)
  2916. self.assertNotEqual(v, w)
  2917. # C-contiguous, different shape, struct module
  2918. nd1 = ndarray([(0, 1, 2)]*21, shape=[3, 7], format='! b B xL')
  2919. nd2 = ndarray([(0, 1, 2)]*21, shape=[7, 3], format='= Qx l xxL')
  2920. v = memoryview(nd1)
  2921. w = memoryview(nd2)
  2922. self.assertEqual(v, nd1)
  2923. self.assertEqual(w, nd2)
  2924. self.assertNotEqual(v, nd2)
  2925. self.assertNotEqual(w, nd1)
  2926. self.assertNotEqual(v, w)
  2927. # C-contiguous, different format, struct module
  2928. nd1 = ndarray(list(range(30)), shape=[2, 3, 5], format='L')
  2929. nd2 = ndarray(list(range(30)), shape=[2, 3, 5], format='l')
  2930. v = memoryview(nd1)
  2931. w = memoryview(nd2)
  2932. self.assertEqual(v, nd1)
  2933. self.assertEqual(w, nd2)
  2934. self.assertEqual(v, nd2)
  2935. self.assertEqual(w, nd1)
  2936. self.assertEqual(v, w)
  2937. def test_memoryview_compare_multidim_fortran(self):
  2938. # Fortran-contiguous, different values
  2939. nd1 = ndarray(list(range(-15, 15)), shape=[5, 2, 3], format='@h',
  2940. flags=ND_FORTRAN)
  2941. nd2 = ndarray(list(range(0, 30)), shape=[5, 2, 3], format='@h',
  2942. flags=ND_FORTRAN)
  2943. v = memoryview(nd1)
  2944. w = memoryview(nd2)
  2945. self.assertEqual(v, nd1)
  2946. self.assertEqual(w, nd2)
  2947. self.assertNotEqual(v, nd2)
  2948. self.assertNotEqual(w, nd1)
  2949. self.assertNotEqual(v, w)
  2950. # Fortran-contiguous, different values, struct module
  2951. nd1 = ndarray([(2**64-1, -1)]*6, shape=[2, 3], format='=Qq',
  2952. flags=ND_FORTRAN)
  2953. nd2 = ndarray([(-1, 2**64-1)]*6, shape=[2, 3], format='=qQ',
  2954. flags=ND_FORTRAN)
  2955. v = memoryview(nd1)
  2956. w = memoryview(nd2)
  2957. self.assertEqual(v, nd1)
  2958. self.assertEqual(w, nd2)
  2959. self.assertNotEqual(v, nd2)
  2960. self.assertNotEqual(w, nd1)
  2961. self.assertNotEqual(v, w)
  2962. # Fortran-contiguous, different shape
  2963. nd1 = ndarray(list(range(-15, 15)), shape=[2, 3, 5], format='l',
  2964. flags=ND_FORTRAN)
  2965. nd2 = ndarray(list(range(-15, 15)), shape=[3, 2, 5], format='l',
  2966. flags=ND_FORTRAN)
  2967. v = memoryview(nd1)
  2968. w = memoryview(nd2)
  2969. self.assertEqual(v, nd1)
  2970. self.assertEqual(w, nd2)
  2971. self.assertNotEqual(v, nd2)
  2972. self.assertNotEqual(w, nd1)
  2973. self.assertNotEqual(v, w)
  2974. # Fortran-contiguous, different shape, struct module
  2975. nd1 = ndarray(list(range(-15, 15)), shape=[2, 3, 5], format='0ll',
  2976. flags=ND_FORTRAN)
  2977. nd2 = ndarray(list(range(-15, 15)), shape=[3, 2, 5], format='l',
  2978. flags=ND_FORTRAN)
  2979. v = memoryview(nd1)
  2980. w = memoryview(nd2)
  2981. self.assertEqual(v, nd1)
  2982. self.assertEqual(w, nd2)
  2983. self.assertNotEqual(v, nd2)
  2984. self.assertNotEqual(w, nd1)
  2985. self.assertNotEqual(v, w)
  2986. # Fortran-contiguous, different format, struct module
  2987. nd1 = ndarray(list(range(30)), shape=[5, 2, 3], format='@h',
  2988. flags=ND_FORTRAN)
  2989. nd2 = ndarray(list(range(30)), shape=[5, 2, 3], format='@b',
  2990. flags=ND_FORTRAN)
  2991. v = memoryview(nd1)
  2992. w = memoryview(nd2)
  2993. self.assertEqual(v, nd1)
  2994. self.assertEqual(w, nd2)
  2995. self.assertEqual(v, nd2)
  2996. self.assertEqual(w, nd1)
  2997. self.assertEqual(v, w)
  2998. def test_memoryview_compare_multidim_mixed(self):
  2999. # mixed C/Fortran contiguous
  3000. lst1 = list(range(-15, 15))
  3001. lst2 = transpose(lst1, [3, 2, 5])
  3002. nd1 = ndarray(lst1, shape=[3, 2, 5], format='@l')
  3003. nd2 = ndarray(lst2, shape=[3, 2, 5], format='l', flags=ND_FORTRAN)
  3004. v = memoryview(nd1)
  3005. w = memoryview(nd2)
  3006. self.assertEqual(v, nd1)
  3007. self.assertEqual(w, nd2)
  3008. self.assertEqual(v, w)
  3009. # mixed C/Fortran contiguous, struct module
  3010. lst1 = [(-3.3, -22, b'x')]*30
  3011. lst1[5] = (-2.2, -22, b'x')
  3012. lst2 = transpose(lst1, [3, 2, 5])
  3013. nd1 = ndarray(lst1, shape=[3, 2, 5], format='d b c')
  3014. nd2 = ndarray(lst2, shape=[3, 2, 5], format='d h c', flags=ND_FORTRAN)
  3015. v = memoryview(nd1)
  3016. w = memoryview(nd2)
  3017. self.assertEqual(v, nd1)
  3018. self.assertEqual(w, nd2)
  3019. self.assertEqual(v, w)
  3020. # different values, non-contiguous
  3021. ex1 = ndarray(list(range(40)), shape=[5, 8], format='@I')
  3022. nd1 = ex1[3:1:-1, ::-2]
  3023. ex2 = ndarray(list(range(40)), shape=[5, 8], format='I')
  3024. nd2 = ex2[1:3:1, ::-2]
  3025. v = memoryview(nd1)
  3026. w = memoryview(nd2)
  3027. self.assertEqual(v, nd1)
  3028. self.assertEqual(w, nd2)
  3029. self.assertNotEqual(v, nd2)
  3030. self.assertNotEqual(w, nd1)
  3031. self.assertNotEqual(v, w)
  3032. # same values, non-contiguous, struct module
  3033. ex1 = ndarray([(2**31-1, -2**31)]*22, shape=[11, 2], format='=ii')
  3034. nd1 = ex1[3:1:-1, ::-2]
  3035. ex2 = ndarray([(2**31-1, -2**31)]*22, shape=[11, 2], format='>ii')
  3036. nd2 = ex2[1:3:1, ::-2]
  3037. v = memoryview(nd1)
  3038. w = memoryview(nd2)
  3039. self.assertEqual(v, nd1)
  3040. self.assertEqual(w, nd2)
  3041. self.assertEqual(v, nd2)
  3042. self.assertEqual(w, nd1)
  3043. self.assertEqual(v, w)
  3044. # different shape
  3045. ex1 = ndarray(list(range(30)), shape=[2, 3, 5], format='b')
  3046. nd1 = ex1[1:3:, ::-2]
  3047. nd2 = ndarray(list(range(30)), shape=[3, 2, 5], format='b')
  3048. nd2 = ex2[1:3:, ::-2]
  3049. v = memoryview(nd1)
  3050. w = memoryview(nd2)
  3051. self.assertEqual(v, nd1)
  3052. self.assertEqual(w, nd2)
  3053. self.assertNotEqual(v, nd2)
  3054. self.assertNotEqual(w, nd1)
  3055. self.assertNotEqual(v, w)
  3056. # different shape, struct module
  3057. ex1 = ndarray(list(range(30)), shape=[2, 3, 5], format='B')
  3058. nd1 = ex1[1:3:, ::-2]
  3059. nd2 = ndarray(list(range(30)), shape=[3, 2, 5], format='b')
  3060. nd2 = ex2[1:3:, ::-2]
  3061. v = memoryview(nd1)
  3062. w = memoryview(nd2)
  3063. self.assertEqual(v, nd1)
  3064. self.assertEqual(w, nd2)
  3065. self.assertNotEqual(v, nd2)
  3066. self.assertNotEqual(w, nd1)
  3067. self.assertNotEqual(v, w)
  3068. # different format, struct module
  3069. ex1 = ndarray([(2, b'123')]*30, shape=[5, 3, 2], format='b3s')
  3070. nd1 = ex1[1:3:, ::-2]
  3071. nd2 = ndarray([(2, b'123')]*30, shape=[5, 3, 2], format='i3s')
  3072. nd2 = ex2[1:3:, ::-2]
  3073. v = memoryview(nd1)
  3074. w = memoryview(nd2)
  3075. self.assertEqual(v, nd1)
  3076. self.assertEqual(w, nd2)
  3077. self.assertNotEqual(v, nd2)
  3078. self.assertNotEqual(w, nd1)
  3079. self.assertNotEqual(v, w)
  3080. def test_memoryview_compare_multidim_zero_shape(self):
  3081. # zeros in shape
  3082. nd1 = ndarray(list(range(30)), shape=[0, 3, 2], format='i')
  3083. nd2 = ndarray(list(range(30)), shape=[5, 0, 2], format='@i')
  3084. v = memoryview(nd1)
  3085. w = memoryview(nd2)
  3086. self.assertEqual(v, nd1)
  3087. self.assertEqual(w, nd2)
  3088. self.assertNotEqual(v, nd2)
  3089. self.assertNotEqual(w, nd1)
  3090. self.assertNotEqual(v, w)
  3091. # zeros in shape, struct module
  3092. nd1 = ndarray(list(range(30)), shape=[0, 3, 2], format='i')
  3093. nd2 = ndarray(list(range(30)), shape=[5, 0, 2], format='@i')
  3094. v = memoryview(nd1)
  3095. w = memoryview(nd2)
  3096. self.assertEqual(v, nd1)
  3097. self.assertEqual(w, nd2)
  3098. self.assertNotEqual(v, nd2)
  3099. self.assertNotEqual(w, nd1)
  3100. self.assertNotEqual(v, w)
  3101. def test_memoryview_compare_multidim_zero_strides(self):
  3102. # zero strides
  3103. nd1 = ndarray([900]*80, shape=[4, 5, 4], format='@L')
  3104. nd2 = ndarray([900], shape=[4, 5, 4], strides=[0, 0, 0], format='L')
  3105. v = memoryview(nd1)
  3106. w = memoryview(nd2)
  3107. self.assertEqual(v, nd1)
  3108. self.assertEqual(w, nd2)
  3109. self.assertEqual(v, nd2)
  3110. self.assertEqual(w, nd1)
  3111. self.assertEqual(v, w)
  3112. self.assertEqual(v.tolist(), w.tolist())
  3113. # zero strides, struct module
  3114. nd1 = ndarray([(1, 2)]*10, shape=[2, 5], format='=lQ')
  3115. nd2 = ndarray([(1, 2)], shape=[2, 5], strides=[0, 0], format='<lQ')
  3116. v = memoryview(nd1)
  3117. w = memoryview(nd2)
  3118. self.assertEqual(v, nd1)
  3119. self.assertEqual(w, nd2)
  3120. self.assertEqual(v, nd2)
  3121. self.assertEqual(w, nd1)
  3122. self.assertEqual(v, w)
  3123. def test_memoryview_compare_multidim_suboffsets(self):
  3124. # suboffsets
  3125. ex1 = ndarray(list(range(40)), shape=[5, 8], format='@I')
  3126. nd1 = ex1[3:1:-1, ::-2]
  3127. ex2 = ndarray(list(range(40)), shape=[5, 8], format='I', flags=ND_PIL)
  3128. nd2 = ex2[1:3:1, ::-2]
  3129. v = memoryview(nd1)
  3130. w = memoryview(nd2)
  3131. self.assertEqual(v, nd1)
  3132. self.assertEqual(w, nd2)
  3133. self.assertNotEqual(v, nd2)
  3134. self.assertNotEqual(w, nd1)
  3135. self.assertNotEqual(v, w)
  3136. # suboffsets, struct module
  3137. ex1 = ndarray([(2**64-1, -1)]*40, shape=[5, 8], format='=Qq',
  3138. flags=ND_WRITABLE)
  3139. ex1[2][7] = (1, -2)
  3140. nd1 = ex1[3:1:-1, ::-2]
  3141. ex2 = ndarray([(2**64-1, -1)]*40, shape=[5, 8], format='>Qq',
  3142. flags=ND_PIL|ND_WRITABLE)
  3143. ex2[2][7] = (1, -2)
  3144. nd2 = ex2[1:3:1, ::-2]
  3145. v = memoryview(nd1)
  3146. w = memoryview(nd2)
  3147. self.assertEqual(v, nd1)
  3148. self.assertEqual(w, nd2)
  3149. self.assertEqual(v, nd2)
  3150. self.assertEqual(w, nd1)
  3151. self.assertEqual(v, w)
  3152. # suboffsets, different shape
  3153. ex1 = ndarray(list(range(30)), shape=[2, 3, 5], format='b',
  3154. flags=ND_PIL)
  3155. nd1 = ex1[1:3:, ::-2]
  3156. nd2 = ndarray(list(range(30)), shape=[3, 2, 5], format='b')
  3157. nd2 = ex2[1:3:, ::-2]
  3158. v = memoryview(nd1)
  3159. w = memoryview(nd2)
  3160. self.assertEqual(v, nd1)
  3161. self.assertEqual(w, nd2)
  3162. self.assertNotEqual(v, nd2)
  3163. self.assertNotEqual(w, nd1)
  3164. self.assertNotEqual(v, w)
  3165. # suboffsets, different shape, struct module
  3166. ex1 = ndarray([(2**8-1, -1)]*40, shape=[2, 3, 5], format='Bb',
  3167. flags=ND_PIL|ND_WRITABLE)
  3168. nd1 = ex1[1:2:, ::-2]
  3169. ex2 = ndarray([(2**8-1, -1)]*40, shape=[3, 2, 5], format='Bb')
  3170. nd2 = ex2[1:2:, ::-2]
  3171. v = memoryview(nd1)
  3172. w = memoryview(nd2)
  3173. self.assertEqual(v, nd1)
  3174. self.assertEqual(w, nd2)
  3175. self.assertNotEqual(v, nd2)
  3176. self.assertNotEqual(w, nd1)
  3177. self.assertNotEqual(v, w)
  3178. # suboffsets, different format
  3179. ex1 = ndarray(list(range(30)), shape=[5, 3, 2], format='i', flags=ND_PIL)
  3180. nd1 = ex1[1:3:, ::-2]
  3181. ex2 = ndarray(list(range(30)), shape=[5, 3, 2], format='@I', flags=ND_PIL)
  3182. nd2 = ex2[1:3:, ::-2]
  3183. v = memoryview(nd1)
  3184. w = memoryview(nd2)
  3185. self.assertEqual(v, nd1)
  3186. self.assertEqual(w, nd2)
  3187. self.assertEqual(v, nd2)
  3188. self.assertEqual(w, nd1)
  3189. self.assertEqual(v, w)
  3190. # suboffsets, different format, struct module
  3191. ex1 = ndarray([(b'hello', b'', 1)]*27, shape=[3, 3, 3], format='5s0sP',
  3192. flags=ND_PIL|ND_WRITABLE)
  3193. ex1[1][2][2] = (b'sushi', b'', 1)
  3194. nd1 = ex1[1:3:, ::-2]
  3195. ex2 = ndarray([(b'hello', b'', 1)]*27, shape=[3, 3, 3], format='5s0sP',
  3196. flags=ND_PIL|ND_WRITABLE)
  3197. ex1[1][2][2] = (b'sushi', b'', 1)
  3198. nd2 = ex2[1:3:, ::-2]
  3199. v = memoryview(nd1)
  3200. w = memoryview(nd2)
  3201. self.assertEqual(v, nd1)
  3202. self.assertEqual(w, nd2)
  3203. self.assertNotEqual(v, nd2)
  3204. self.assertNotEqual(w, nd1)
  3205. self.assertNotEqual(v, w)
  3206. # initialize mixed C/Fortran + suboffsets
  3207. lst1 = list(range(-15, 15))
  3208. lst2 = transpose(lst1, [3, 2, 5])
  3209. nd1 = ndarray(lst1, shape=[3, 2, 5], format='@l', flags=ND_PIL)
  3210. nd2 = ndarray(lst2, shape=[3, 2, 5], format='l', flags=ND_FORTRAN|ND_PIL)
  3211. v = memoryview(nd1)
  3212. w = memoryview(nd2)
  3213. self.assertEqual(v, nd1)
  3214. self.assertEqual(w, nd2)
  3215. self.assertEqual(v, w)
  3216. # initialize mixed C/Fortran + suboffsets, struct module
  3217. lst1 = [(b'sashimi', b'sliced', 20.05)]*30
  3218. lst1[11] = (b'ramen', b'spicy', 9.45)
  3219. lst2 = transpose(lst1, [3, 2, 5])
  3220. nd1 = ndarray(lst1, shape=[3, 2, 5], format='< 10p 9p d', flags=ND_PIL)
  3221. nd2 = ndarray(lst2, shape=[3, 2, 5], format='> 10p 9p d',
  3222. flags=ND_FORTRAN|ND_PIL)
  3223. v = memoryview(nd1)
  3224. w = memoryview(nd2)
  3225. self.assertEqual(v, nd1)
  3226. self.assertEqual(w, nd2)
  3227. self.assertEqual(v, w)
  3228. def test_memoryview_compare_not_equal(self):
  3229. # items not equal
  3230. for byteorder in ['=', '<', '>', '!']:
  3231. x = ndarray([2**63]*120, shape=[3,5,2,2,2], format=byteorder+'Q')
  3232. y = ndarray([2**63]*120, shape=[3,5,2,2,2], format=byteorder+'Q',
  3233. flags=ND_WRITABLE|ND_FORTRAN)
  3234. y[2][3][1][1][1] = 1
  3235. a = memoryview(x)
  3236. b = memoryview(y)
  3237. self.assertEqual(a, x)
  3238. self.assertEqual(b, y)
  3239. self.assertNotEqual(a, b)
  3240. self.assertNotEqual(a, y)
  3241. self.assertNotEqual(b, x)
  3242. x = ndarray([(2**63, 2**31, 2**15)]*120, shape=[3,5,2,2,2],
  3243. format=byteorder+'QLH')
  3244. y = ndarray([(2**63, 2**31, 2**15)]*120, shape=[3,5,2,2,2],
  3245. format=byteorder+'QLH', flags=ND_WRITABLE|ND_FORTRAN)
  3246. y[2][3][1][1][1] = (1, 1, 1)
  3247. a = memoryview(x)
  3248. b = memoryview(y)
  3249. self.assertEqual(a, x)
  3250. self.assertEqual(b, y)
  3251. self.assertNotEqual(a, b)
  3252. self.assertNotEqual(a, y)
  3253. self.assertNotEqual(b, x)
  3254. def test_memoryview_check_released(self):
  3255. a = array.array('d', [1.1, 2.2, 3.3])
  3256. m = memoryview(a)
  3257. m.release()
  3258. # PyMemoryView_FromObject()
  3259. self.assertRaises(ValueError, memoryview, m)
  3260. # memoryview.cast()
  3261. self.assertRaises(ValueError, m.cast, 'c')
  3262. # getbuffer()
  3263. self.assertRaises(ValueError, ndarray, m)
  3264. # memoryview.tolist()
  3265. self.assertRaises(ValueError, m.tolist)
  3266. # memoryview.tobytes()
  3267. self.assertRaises(ValueError, m.tobytes)
  3268. # sequence
  3269. self.assertRaises(ValueError, eval, "1.0 in m", locals())
  3270. # subscript
  3271. self.assertRaises(ValueError, m.__getitem__, 0)
  3272. # assignment
  3273. self.assertRaises(ValueError, m.__setitem__, 0, 1)
  3274. for attr in ('obj', 'nbytes', 'readonly', 'itemsize', 'format', 'ndim',
  3275. 'shape', 'strides', 'suboffsets', 'c_contiguous',
  3276. 'f_contiguous', 'contiguous'):
  3277. self.assertRaises(ValueError, m.__getattribute__, attr)
  3278. # richcompare
  3279. b = array.array('d', [1.1, 2.2, 3.3])
  3280. m1 = memoryview(a)
  3281. m2 = memoryview(b)
  3282. self.assertEqual(m1, m2)
  3283. m1.release()
  3284. self.assertNotEqual(m1, m2)
  3285. self.assertNotEqual(m1, a)
  3286. self.assertEqual(m1, m1)
  3287. def test_memoryview_tobytes(self):
  3288. # Many implicit tests are already in self.verify().
  3289. t = (-529, 576, -625, 676, -729)
  3290. nd = ndarray(t, shape=[5], format='@h')
  3291. m = memoryview(nd)
  3292. self.assertEqual(m, nd)
  3293. self.assertEqual(m.tobytes(), nd.tobytes())
  3294. nd = ndarray([t], shape=[1], format='>hQiLl')
  3295. m = memoryview(nd)
  3296. self.assertEqual(m, nd)
  3297. self.assertEqual(m.tobytes(), nd.tobytes())
  3298. nd = ndarray([t for _ in range(12)], shape=[2,2,3], format='=hQiLl')
  3299. m = memoryview(nd)
  3300. self.assertEqual(m, nd)
  3301. self.assertEqual(m.tobytes(), nd.tobytes())
  3302. nd = ndarray([t for _ in range(120)], shape=[5,2,2,3,2],
  3303. format='<hQiLl')
  3304. m = memoryview(nd)
  3305. self.assertEqual(m, nd)
  3306. self.assertEqual(m.tobytes(), nd.tobytes())
  3307. # Unknown formats are handled: tobytes() purely depends on itemsize.
  3308. if ctypes:
  3309. # format: "T{>l:x:>l:y:}"
  3310. class BEPoint(ctypes.BigEndianStructure):
  3311. _fields_ = [("x", ctypes.c_long), ("y", ctypes.c_long)]
  3312. point = BEPoint(100, 200)
  3313. a = memoryview(point)
  3314. self.assertEqual(a.tobytes(), bytes(point))
  3315. def test_memoryview_get_contiguous(self):
  3316. # Many implicit tests are already in self.verify().
  3317. # no buffer interface
  3318. self.assertRaises(TypeError, get_contiguous, {}, PyBUF_READ, 'F')
  3319. # writable request to read-only object
  3320. self.assertRaises(BufferError, get_contiguous, b'x', PyBUF_WRITE, 'C')
  3321. # writable request to non-contiguous object
  3322. nd = ndarray([1, 2, 3], shape=[2], strides=[2])
  3323. self.assertRaises(BufferError, get_contiguous, nd, PyBUF_WRITE, 'A')
  3324. # scalar, read-only request from read-only exporter
  3325. nd = ndarray(9, shape=(), format="L")
  3326. for order in ['C', 'F', 'A']:
  3327. m = get_contiguous(nd, PyBUF_READ, order)
  3328. self.assertEqual(m, nd)
  3329. self.assertEqual(m[()], 9)
  3330. # scalar, read-only request from writable exporter
  3331. nd = ndarray(9, shape=(), format="L", flags=ND_WRITABLE)
  3332. for order in ['C', 'F', 'A']:
  3333. m = get_contiguous(nd, PyBUF_READ, order)
  3334. self.assertEqual(m, nd)
  3335. self.assertEqual(m[()], 9)
  3336. # scalar, writable request
  3337. for order in ['C', 'F', 'A']:
  3338. nd[()] = 9
  3339. m = get_contiguous(nd, PyBUF_WRITE, order)
  3340. self.assertEqual(m, nd)
  3341. self.assertEqual(m[()], 9)
  3342. m[()] = 10
  3343. self.assertEqual(m[()], 10)
  3344. self.assertEqual(nd[()], 10)
  3345. # zeros in shape
  3346. nd = ndarray([1], shape=[0], format="L", flags=ND_WRITABLE)
  3347. for order in ['C', 'F', 'A']:
  3348. m = get_contiguous(nd, PyBUF_READ, order)
  3349. self.assertRaises(IndexError, m.__getitem__, 0)
  3350. self.assertEqual(m, nd)
  3351. self.assertEqual(m.tolist(), [])
  3352. nd = ndarray(list(range(8)), shape=[2, 0, 7], format="L",
  3353. flags=ND_WRITABLE)
  3354. for order in ['C', 'F', 'A']:
  3355. m = get_contiguous(nd, PyBUF_READ, order)
  3356. self.assertEqual(ndarray(m).tolist(), [[], []])
  3357. # one-dimensional
  3358. nd = ndarray([1], shape=[1], format="h", flags=ND_WRITABLE)
  3359. for order in ['C', 'F', 'A']:
  3360. m = get_contiguous(nd, PyBUF_WRITE, order)
  3361. self.assertEqual(m, nd)
  3362. self.assertEqual(m.tolist(), nd.tolist())
  3363. nd = ndarray([1, 2, 3], shape=[3], format="b", flags=ND_WRITABLE)
  3364. for order in ['C', 'F', 'A']:
  3365. m = get_contiguous(nd, PyBUF_WRITE, order)
  3366. self.assertEqual(m, nd)
  3367. self.assertEqual(m.tolist(), nd.tolist())
  3368. # one-dimensional, non-contiguous
  3369. nd = ndarray([1, 2, 3], shape=[2], strides=[2], flags=ND_WRITABLE)
  3370. for order in ['C', 'F', 'A']:
  3371. m = get_contiguous(nd, PyBUF_READ, order)
  3372. self.assertEqual(m, nd)
  3373. self.assertEqual(m.tolist(), nd.tolist())
  3374. self.assertRaises(TypeError, m.__setitem__, 1, 20)
  3375. self.assertEqual(m[1], 3)
  3376. self.assertEqual(nd[1], 3)
  3377. nd = nd[::-1]
  3378. for order in ['C', 'F', 'A']:
  3379. m = get_contiguous(nd, PyBUF_READ, order)
  3380. self.assertEqual(m, nd)
  3381. self.assertEqual(m.tolist(), nd.tolist())
  3382. self.assertRaises(TypeError, m.__setitem__, 1, 20)
  3383. self.assertEqual(m[1], 1)
  3384. self.assertEqual(nd[1], 1)
  3385. # multi-dimensional, contiguous input
  3386. nd = ndarray(list(range(12)), shape=[3, 4], flags=ND_WRITABLE)
  3387. for order in ['C', 'A']:
  3388. m = get_contiguous(nd, PyBUF_WRITE, order)
  3389. self.assertEqual(ndarray(m).tolist(), nd.tolist())
  3390. self.assertRaises(BufferError, get_contiguous, nd, PyBUF_WRITE, 'F')
  3391. m = get_contiguous(nd, PyBUF_READ, order)
  3392. self.assertEqual(ndarray(m).tolist(), nd.tolist())
  3393. nd = ndarray(list(range(12)), shape=[3, 4],
  3394. flags=ND_WRITABLE|ND_FORTRAN)
  3395. for order in ['F', 'A']:
  3396. m = get_contiguous(nd, PyBUF_WRITE, order)
  3397. self.assertEqual(ndarray(m).tolist(), nd.tolist())
  3398. self.assertRaises(BufferError, get_contiguous, nd, PyBUF_WRITE, 'C')
  3399. m = get_contiguous(nd, PyBUF_READ, order)
  3400. self.assertEqual(ndarray(m).tolist(), nd.tolist())
  3401. # multi-dimensional, non-contiguous input
  3402. nd = ndarray(list(range(12)), shape=[3, 4], flags=ND_WRITABLE|ND_PIL)
  3403. for order in ['C', 'F', 'A']:
  3404. self.assertRaises(BufferError, get_contiguous, nd, PyBUF_WRITE,
  3405. order)
  3406. m = get_contiguous(nd, PyBUF_READ, order)
  3407. self.assertEqual(ndarray(m).tolist(), nd.tolist())
  3408. # flags
  3409. nd = ndarray([1,2,3,4,5], shape=[3], strides=[2])
  3410. m = get_contiguous(nd, PyBUF_READ, 'C')
  3411. self.assertTrue(m.c_contiguous)
  3412. def test_memoryview_serializing(self):
  3413. # C-contiguous
  3414. size = struct.calcsize('i')
  3415. a = array.array('i', [1,2,3,4,5])
  3416. m = memoryview(a)
  3417. buf = io.BytesIO(m)
  3418. b = bytearray(5*size)
  3419. buf.readinto(b)
  3420. self.assertEqual(m.tobytes(), b)
  3421. # C-contiguous, multi-dimensional
  3422. size = struct.calcsize('L')
  3423. nd = ndarray(list(range(12)), shape=[2,3,2], format="L")
  3424. m = memoryview(nd)
  3425. buf = io.BytesIO(m)
  3426. b = bytearray(2*3*2*size)
  3427. buf.readinto(b)
  3428. self.assertEqual(m.tobytes(), b)
  3429. # Fortran contiguous, multi-dimensional
  3430. #size = struct.calcsize('L')
  3431. #nd = ndarray(list(range(12)), shape=[2,3,2], format="L",
  3432. # flags=ND_FORTRAN)
  3433. #m = memoryview(nd)
  3434. #buf = io.BytesIO(m)
  3435. #b = bytearray(2*3*2*size)
  3436. #buf.readinto(b)
  3437. #self.assertEqual(m.tobytes(), b)
  3438. def test_memoryview_hash(self):
  3439. # bytes exporter
  3440. b = bytes(list(range(12)))
  3441. m = memoryview(b)
  3442. self.assertEqual(hash(b), hash(m))
  3443. # C-contiguous
  3444. mc = m.cast('c', shape=[3,4])
  3445. self.assertEqual(hash(mc), hash(b))
  3446. # non-contiguous
  3447. mx = m[::-2]
  3448. b = bytes(list(range(12))[::-2])
  3449. self.assertEqual(hash(mx), hash(b))
  3450. # Fortran contiguous
  3451. nd = ndarray(list(range(30)), shape=[3,2,5], flags=ND_FORTRAN)
  3452. m = memoryview(nd)
  3453. self.assertEqual(hash(m), hash(nd))
  3454. # multi-dimensional slice
  3455. nd = ndarray(list(range(30)), shape=[3,2,5])
  3456. x = nd[::2, ::, ::-1]
  3457. m = memoryview(x)
  3458. self.assertEqual(hash(m), hash(x))
  3459. # multi-dimensional slice with suboffsets
  3460. nd = ndarray(list(range(30)), shape=[2,5,3], flags=ND_PIL)
  3461. x = nd[::2, ::, ::-1]
  3462. m = memoryview(x)
  3463. self.assertEqual(hash(m), hash(x))
  3464. # equality-hash invariant
  3465. x = ndarray(list(range(12)), shape=[12], format='B')
  3466. a = memoryview(x)
  3467. y = ndarray(list(range(12)), shape=[12], format='b')
  3468. b = memoryview(y)
  3469. self.assertEqual(a, b)
  3470. self.assertEqual(hash(a), hash(b))
  3471. # non-byte formats
  3472. nd = ndarray(list(range(12)), shape=[2,2,3], format='L')
  3473. m = memoryview(nd)
  3474. self.assertRaises(ValueError, m.__hash__)
  3475. nd = ndarray(list(range(-6, 6)), shape=[2,2,3], format='h')
  3476. m = memoryview(nd)
  3477. self.assertRaises(ValueError, m.__hash__)
  3478. nd = ndarray(list(range(12)), shape=[2,2,3], format='= L')
  3479. m = memoryview(nd)
  3480. self.assertRaises(ValueError, m.__hash__)
  3481. nd = ndarray(list(range(-6, 6)), shape=[2,2,3], format='< h')
  3482. m = memoryview(nd)
  3483. self.assertRaises(ValueError, m.__hash__)
  3484. def test_memoryview_release(self):
  3485. # Create re-exporter from getbuffer(memoryview), then release the view.
  3486. a = bytearray([1,2,3])
  3487. m = memoryview(a)
  3488. nd = ndarray(m) # re-exporter
  3489. self.assertRaises(BufferError, m.release)
  3490. del nd
  3491. m.release()
  3492. a = bytearray([1,2,3])
  3493. m = memoryview(a)
  3494. nd1 = ndarray(m, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
  3495. nd2 = ndarray(nd1, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
  3496. self.assertIs(nd2.obj, m)
  3497. self.assertRaises(BufferError, m.release)
  3498. del nd1, nd2
  3499. m.release()
  3500. # chained views
  3501. a = bytearray([1,2,3])
  3502. m1 = memoryview(a)
  3503. m2 = memoryview(m1)
  3504. nd = ndarray(m2) # re-exporter
  3505. m1.release()
  3506. self.assertRaises(BufferError, m2.release)
  3507. del nd
  3508. m2.release()
  3509. a = bytearray([1,2,3])
  3510. m1 = memoryview(a)
  3511. m2 = memoryview(m1)
  3512. nd1 = ndarray(m2, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
  3513. nd2 = ndarray(nd1, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
  3514. self.assertIs(nd2.obj, m2)
  3515. m1.release()
  3516. self.assertRaises(BufferError, m2.release)
  3517. del nd1, nd2
  3518. m2.release()
  3519. # Allow changing layout while buffers are exported.
  3520. nd = ndarray([1,2,3], shape=[3], flags=ND_VAREXPORT)
  3521. m1 = memoryview(nd)
  3522. nd.push([4,5,6,7,8], shape=[5]) # mutate nd
  3523. m2 = memoryview(nd)
  3524. x = memoryview(m1)
  3525. self.assertEqual(x.tolist(), m1.tolist())
  3526. y = memoryview(m2)
  3527. self.assertEqual(y.tolist(), m2.tolist())
  3528. self.assertEqual(y.tolist(), nd.tolist())
  3529. m2.release()
  3530. y.release()
  3531. nd.pop() # pop the current view
  3532. self.assertEqual(x.tolist(), nd.tolist())
  3533. del nd
  3534. m1.release()
  3535. x.release()
  3536. # If multiple memoryviews share the same managed buffer, implicit
  3537. # release() in the context manager's __exit__() method should still
  3538. # work.
  3539. def catch22(b):
  3540. with memoryview(b) as m2:
  3541. pass
  3542. x = bytearray(b'123')
  3543. with memoryview(x) as m1:
  3544. catch22(m1)
  3545. self.assertEqual(m1[0], ord(b'1'))
  3546. x = ndarray(list(range(12)), shape=[2,2,3], format='l')
  3547. y = ndarray(x, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
  3548. z = ndarray(y, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
  3549. self.assertIs(z.obj, x)
  3550. with memoryview(z) as m:
  3551. catch22(m)
  3552. self.assertEqual(m[0:1].tolist(), [[[0, 1, 2], [3, 4, 5]]])
  3553. # Test garbage collection.
  3554. for flags in (0, ND_REDIRECT):
  3555. x = bytearray(b'123')
  3556. with memoryview(x) as m1:
  3557. del x
  3558. y = ndarray(m1, getbuf=PyBUF_FULL_RO, flags=flags)
  3559. with memoryview(y) as m2:
  3560. del y
  3561. z = ndarray(m2, getbuf=PyBUF_FULL_RO, flags=flags)
  3562. with memoryview(z) as m3:
  3563. del z
  3564. catch22(m3)
  3565. catch22(m2)
  3566. catch22(m1)
  3567. self.assertEqual(m1[0], ord(b'1'))
  3568. self.assertEqual(m2[1], ord(b'2'))
  3569. self.assertEqual(m3[2], ord(b'3'))
  3570. del m3
  3571. del m2
  3572. del m1
  3573. x = bytearray(b'123')
  3574. with memoryview(x) as m1:
  3575. del x
  3576. y = ndarray(m1, getbuf=PyBUF_FULL_RO, flags=flags)
  3577. with memoryview(y) as m2:
  3578. del y
  3579. z = ndarray(m2, getbuf=PyBUF_FULL_RO, flags=flags)
  3580. with memoryview(z) as m3:
  3581. del z
  3582. catch22(m1)
  3583. catch22(m2)
  3584. catch22(m3)
  3585. self.assertEqual(m1[0], ord(b'1'))
  3586. self.assertEqual(m2[1], ord(b'2'))
  3587. self.assertEqual(m3[2], ord(b'3'))
  3588. del m1, m2, m3
  3589. # memoryview.release() fails if the view has exported buffers.
  3590. x = bytearray(b'123')
  3591. with self.assertRaises(BufferError):
  3592. with memoryview(x) as m:
  3593. ex = ndarray(m)
  3594. m[0] == ord(b'1')
  3595. def test_memoryview_redirect(self):
  3596. nd = ndarray([1.0 * x for x in range(12)], shape=[12], format='d')
  3597. a = array.array('d', [1.0 * x for x in range(12)])
  3598. for x in (nd, a):
  3599. y = ndarray(x, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
  3600. z = ndarray(y, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
  3601. m = memoryview(z)
  3602. self.assertIs(y.obj, x)
  3603. self.assertIs(z.obj, x)
  3604. self.assertIs(m.obj, x)
  3605. self.assertEqual(m, x)
  3606. self.assertEqual(m, y)
  3607. self.assertEqual(m, z)
  3608. self.assertEqual(m[1:3], x[1:3])
  3609. self.assertEqual(m[1:3], y[1:3])
  3610. self.assertEqual(m[1:3], z[1:3])
  3611. del y, z
  3612. self.assertEqual(m[1:3], x[1:3])
  3613. def test_memoryview_from_static_exporter(self):
  3614. fmt = 'B'
  3615. lst = [0,1,2,3,4,5,6,7,8,9,10,11]
  3616. # exceptions
  3617. self.assertRaises(TypeError, staticarray, 1, 2, 3)
  3618. # view.obj==x
  3619. x = staticarray()
  3620. y = memoryview(x)
  3621. self.verify(y, obj=x,
  3622. itemsize=1, fmt=fmt, readonly=True,
  3623. ndim=1, shape=[12], strides=[1],
  3624. lst=lst)
  3625. for i in range(12):
  3626. self.assertEqual(y[i], i)
  3627. del x
  3628. del y
  3629. x = staticarray()
  3630. y = memoryview(x)
  3631. del y
  3632. del x
  3633. x = staticarray()
  3634. y = ndarray(x, getbuf=PyBUF_FULL_RO)
  3635. z = ndarray(y, getbuf=PyBUF_FULL_RO)
  3636. m = memoryview(z)
  3637. self.assertIs(y.obj, x)
  3638. self.assertIs(m.obj, z)
  3639. self.verify(m, obj=z,
  3640. itemsize=1, fmt=fmt, readonly=True,
  3641. ndim=1, shape=[12], strides=[1],
  3642. lst=lst)
  3643. del x, y, z, m
  3644. x = staticarray()
  3645. y = ndarray(x, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
  3646. z = ndarray(y, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
  3647. m = memoryview(z)
  3648. self.assertIs(y.obj, x)
  3649. self.assertIs(z.obj, x)
  3650. self.assertIs(m.obj, x)
  3651. self.verify(m, obj=x,
  3652. itemsize=1, fmt=fmt, readonly=True,
  3653. ndim=1, shape=[12], strides=[1],
  3654. lst=lst)
  3655. del x, y, z, m
  3656. # view.obj==NULL
  3657. x = staticarray(legacy_mode=True)
  3658. y = memoryview(x)
  3659. self.verify(y, obj=None,
  3660. itemsize=1, fmt=fmt, readonly=True,
  3661. ndim=1, shape=[12], strides=[1],
  3662. lst=lst)
  3663. for i in range(12):
  3664. self.assertEqual(y[i], i)
  3665. del x
  3666. del y
  3667. x = staticarray(legacy_mode=True)
  3668. y = memoryview(x)
  3669. del y
  3670. del x
  3671. x = staticarray(legacy_mode=True)
  3672. y = ndarray(x, getbuf=PyBUF_FULL_RO)
  3673. z = ndarray(y, getbuf=PyBUF_FULL_RO)
  3674. m = memoryview(z)
  3675. self.assertIs(y.obj, None)
  3676. self.assertIs(m.obj, z)
  3677. self.verify(m, obj=z,
  3678. itemsize=1, fmt=fmt, readonly=True,
  3679. ndim=1, shape=[12], strides=[1],
  3680. lst=lst)
  3681. del x, y, z, m
  3682. x = staticarray(legacy_mode=True)
  3683. y = ndarray(x, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
  3684. z = ndarray(y, getbuf=PyBUF_FULL_RO, flags=ND_REDIRECT)
  3685. m = memoryview(z)
  3686. # Clearly setting view.obj==NULL is inferior, since it
  3687. # messes up the redirection chain:
  3688. self.assertIs(y.obj, None)
  3689. self.assertIs(z.obj, y)
  3690. self.assertIs(m.obj, y)
  3691. self.verify(m, obj=y,
  3692. itemsize=1, fmt=fmt, readonly=True,
  3693. ndim=1, shape=[12], strides=[1],
  3694. lst=lst)
  3695. del x, y, z, m
  3696. def test_memoryview_getbuffer_undefined(self):
  3697. # getbufferproc does not adhere to the new documentation
  3698. nd = ndarray([1,2,3], [3], flags=ND_GETBUF_FAIL|ND_GETBUF_UNDEFINED)
  3699. self.assertRaises(BufferError, memoryview, nd)
  3700. def test_issue_7385(self):
  3701. x = ndarray([1,2,3], shape=[3], flags=ND_GETBUF_FAIL)
  3702. self.assertRaises(BufferError, memoryview, x)
  3703. @support.cpython_only
  3704. def test_pybuffer_size_from_format(self):
  3705. # basic tests
  3706. for format in ('', 'ii', '3s'):
  3707. self.assertEqual(_testcapi.PyBuffer_SizeFromFormat(format),
  3708. struct.calcsize(format))
  3709. if __name__ == "__main__":
  3710. unittest.main()