test_declarations.py 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685
  1. ##############################################################################
  2. #
  3. # Copyright (c) 2003 Zope Foundation and Contributors.
  4. # All Rights Reserved.
  5. #
  6. # This software is subject to the provisions of the Zope Public License,
  7. # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
  8. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  9. # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  10. # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  11. # FOR A PARTICULAR PURPOSE.
  12. #
  13. ##############################################################################
  14. """Test the new API for making and checking interface declarations
  15. """
  16. import unittest
  17. from __tests__.tests import MissingSomeAttrs
  18. from __tests__.tests import OptimizationTestMixin
  19. from __tests__.tests import SubclassableMixin
  20. from __tests__.tests.test_interface import \
  21. NameAndModuleComparisonTestsMixin
  22. # pylint:disable=inherit-non-class,too-many-lines,protected-access
  23. # pylint:disable=blacklisted-name,attribute-defined-outside-init
  24. class _Py3ClassAdvice:
  25. def _run_generated_code(
  26. self, code, globs, locs, fails_under_py3k=True,
  27. ):
  28. # pylint:disable=exec-used,no-member
  29. import warnings
  30. with warnings.catch_warnings(record=True) as _:
  31. warnings.resetwarnings()
  32. try:
  33. exec(code, globs, locs)
  34. except TypeError:
  35. return False
  36. else:
  37. if fails_under_py3k:
  38. self.fail("Didn't raise TypeError")
  39. return None
  40. class NamedTests(unittest.TestCase):
  41. def test_class(self):
  42. from zope.interface.declarations import named
  43. @named('foo')
  44. class Foo:
  45. pass
  46. self.assertEqual(
  47. Foo.__component_name__, 'foo'
  48. ) # pylint:disable=no-member
  49. def test_function(self):
  50. from zope.interface.declarations import named
  51. @named('foo')
  52. def doFoo(o):
  53. raise NotImplementedError()
  54. self.assertEqual(doFoo.__component_name__, 'foo')
  55. def test_instance(self):
  56. from zope.interface.declarations import named
  57. class Foo:
  58. pass
  59. foo = Foo()
  60. named('foo')(foo)
  61. self.assertEqual(
  62. foo.__component_name__, 'foo'
  63. ) # pylint:disable=no-member
  64. class EmptyDeclarationTests(unittest.TestCase):
  65. # Tests that should pass for all objects that are empty
  66. # declarations. This includes a Declaration explicitly created
  67. # that way, and the empty ImmutableDeclaration.
  68. def _getEmpty(self):
  69. from zope.interface.declarations import Declaration
  70. return Declaration()
  71. def test___iter___empty(self):
  72. decl = self._getEmpty()
  73. self.assertEqual(list(decl), [])
  74. def test_flattened_empty(self):
  75. from zope.interface.interface import Interface
  76. decl = self._getEmpty()
  77. self.assertEqual(list(decl.flattened()), [Interface])
  78. def test___contains___empty(self):
  79. from zope.interface.interface import Interface
  80. decl = self._getEmpty()
  81. self.assertNotIn(Interface, decl)
  82. def test_extends_empty(self):
  83. from zope.interface.interface import Interface
  84. decl = self._getEmpty()
  85. self.assertTrue(decl.extends(Interface))
  86. self.assertTrue(decl.extends(Interface, strict=True))
  87. def test_interfaces_empty(self):
  88. decl = self._getEmpty()
  89. iface_list = list(decl.interfaces())
  90. self.assertEqual(iface_list, [])
  91. def test___sro___(self):
  92. from zope.interface.interface import Interface
  93. decl = self._getEmpty()
  94. self.assertEqual(decl.__sro__, (decl, Interface,))
  95. def test___iro___(self):
  96. from zope.interface.interface import Interface
  97. decl = self._getEmpty()
  98. self.assertEqual(decl.__iro__, (Interface,))
  99. def test_get(self):
  100. decl = self._getEmpty()
  101. self.assertIsNone(decl.get('attr'))
  102. self.assertEqual(decl.get('abc', 'def'), 'def')
  103. # It's a positive cache only (when it even exists)
  104. # so this added nothing.
  105. self.assertFalse(decl._v_attrs)
  106. def test_changed_w_existing__v_attrs(self):
  107. decl = self._getEmpty()
  108. decl._v_attrs = object()
  109. decl.changed(decl)
  110. self.assertFalse(decl._v_attrs)
  111. class DeclarationTests(EmptyDeclarationTests):
  112. def _getTargetClass(self):
  113. from zope.interface.declarations import Declaration
  114. return Declaration
  115. def _makeOne(self, *args, **kw):
  116. return self._getTargetClass()(*args, **kw)
  117. def test_ctor_no_bases(self):
  118. decl = self._makeOne()
  119. self.assertEqual(list(decl.__bases__), [])
  120. def test_ctor_w_interface_in_bases(self):
  121. from zope.interface.interface import InterfaceClass
  122. IFoo = InterfaceClass('IFoo')
  123. decl = self._makeOne(IFoo)
  124. self.assertEqual(list(decl.__bases__), [IFoo])
  125. def test_ctor_w_implements_in_bases(self):
  126. from zope.interface.declarations import Implements
  127. impl = Implements()
  128. decl = self._makeOne(impl)
  129. self.assertEqual(list(decl.__bases__), [impl])
  130. def test_changed_wo_existing__v_attrs(self):
  131. decl = self._makeOne()
  132. decl.changed(decl) # doesn't raise
  133. self.assertIsNone(decl._v_attrs)
  134. def test___contains__w_self(self):
  135. decl = self._makeOne()
  136. self.assertNotIn(decl, decl)
  137. def test___contains__w_unrelated_iface(self):
  138. from zope.interface.interface import InterfaceClass
  139. IFoo = InterfaceClass('IFoo')
  140. decl = self._makeOne()
  141. self.assertNotIn(IFoo, decl)
  142. def test___contains__w_base_interface(self):
  143. from zope.interface.interface import InterfaceClass
  144. IFoo = InterfaceClass('IFoo')
  145. decl = self._makeOne(IFoo)
  146. self.assertIn(IFoo, decl)
  147. def test___iter___single_base(self):
  148. from zope.interface.interface import InterfaceClass
  149. IFoo = InterfaceClass('IFoo')
  150. decl = self._makeOne(IFoo)
  151. self.assertEqual(list(decl), [IFoo])
  152. def test___iter___multiple_bases(self):
  153. from zope.interface.interface import InterfaceClass
  154. IFoo = InterfaceClass('IFoo')
  155. IBar = InterfaceClass('IBar')
  156. decl = self._makeOne(IFoo, IBar)
  157. self.assertEqual(list(decl), [IFoo, IBar])
  158. def test___iter___inheritance(self):
  159. from zope.interface.interface import InterfaceClass
  160. IFoo = InterfaceClass('IFoo')
  161. IBar = InterfaceClass('IBar', (IFoo,))
  162. decl = self._makeOne(IBar)
  163. self.assertEqual(list(decl), [IBar]) # IBar.interfaces() omits bases
  164. def test___iter___w_nested_sequence_overlap(self):
  165. from zope.interface.interface import InterfaceClass
  166. IFoo = InterfaceClass('IFoo')
  167. IBar = InterfaceClass('IBar')
  168. decl = self._makeOne(IBar, (IFoo, IBar))
  169. self.assertEqual(list(decl), [IBar, IFoo])
  170. def test_flattened_single_base(self):
  171. from zope.interface.interface import Interface
  172. from zope.interface.interface import InterfaceClass
  173. IFoo = InterfaceClass('IFoo')
  174. decl = self._makeOne(IFoo)
  175. self.assertEqual(list(decl.flattened()), [IFoo, Interface])
  176. def test_flattened_multiple_bases(self):
  177. from zope.interface.interface import Interface
  178. from zope.interface.interface import InterfaceClass
  179. IFoo = InterfaceClass('IFoo')
  180. IBar = InterfaceClass('IBar')
  181. decl = self._makeOne(IFoo, IBar)
  182. self.assertEqual(list(decl.flattened()), [IFoo, IBar, Interface])
  183. def test_flattened_inheritance(self):
  184. from zope.interface.interface import Interface
  185. from zope.interface.interface import InterfaceClass
  186. IFoo = InterfaceClass('IFoo')
  187. IBar = InterfaceClass('IBar', (IFoo,))
  188. decl = self._makeOne(IBar)
  189. self.assertEqual(list(decl.flattened()), [IBar, IFoo, Interface])
  190. def test_flattened_w_nested_sequence_overlap(self):
  191. from zope.interface.interface import Interface
  192. from zope.interface.interface import InterfaceClass
  193. IFoo = InterfaceClass('IFoo')
  194. IBar = InterfaceClass('IBar')
  195. # This is the same as calling ``Declaration(IBar, IFoo, IBar)``
  196. # which doesn't make much sense, but here it is. In older
  197. # versions of zope.interface, the __iro__ would have been
  198. # IFoo, IBar, Interface, which especially makes no sense.
  199. decl = self._makeOne(IBar, (IFoo, IBar))
  200. # Note that decl.__iro__ has IFoo first.
  201. self.assertEqual(list(decl.flattened()), [IBar, IFoo, Interface])
  202. def test___sub___unrelated_interface(self):
  203. from zope.interface.interface import InterfaceClass
  204. IFoo = InterfaceClass('IFoo')
  205. IBar = InterfaceClass('IBar')
  206. before = self._makeOne(IFoo)
  207. after = before - IBar
  208. self.assertIsInstance(after, self._getTargetClass())
  209. self.assertEqual(list(after), [IFoo])
  210. def test___sub___related_interface(self):
  211. from zope.interface.interface import InterfaceClass
  212. IFoo = InterfaceClass('IFoo')
  213. before = self._makeOne(IFoo)
  214. after = before - IFoo
  215. self.assertEqual(list(after), [])
  216. def test___sub___related_interface_by_inheritance(self):
  217. from zope.interface.interface import InterfaceClass
  218. IFoo = InterfaceClass('IFoo')
  219. IBar = InterfaceClass('IBar', (IFoo,))
  220. before = self._makeOne(IBar)
  221. after = before - IBar
  222. self.assertEqual(list(after), [])
  223. def test___add___unrelated_interface(self):
  224. from zope.interface.interface import InterfaceClass
  225. IFoo = InterfaceClass('IFoo')
  226. IBar = InterfaceClass('IBar')
  227. before = self._makeOne(IFoo)
  228. after = before + IBar
  229. self.assertIsInstance(after, self._getTargetClass())
  230. self.assertEqual(list(after), [IFoo, IBar])
  231. def test___add___related_interface(self):
  232. from zope.interface.interface import InterfaceClass
  233. IFoo = InterfaceClass('IFoo')
  234. IBar = InterfaceClass('IBar')
  235. IBaz = InterfaceClass('IBaz')
  236. before = self._makeOne(IFoo, IBar)
  237. other = self._makeOne(IBar, IBaz)
  238. after = before + other
  239. self.assertEqual(list(after), [IFoo, IBar, IBaz])
  240. def test___add___overlapping_interface(self):
  241. # The derived interfaces end up with higher priority, and
  242. # don't produce a C3 resolution order violation. This
  243. # example produced a C3 error, and the resulting legacy order
  244. # used to be wrong ([IBase, IDerived] instead of
  245. # the other way).
  246. from zope.interface import Interface
  247. from zope.interface import ro
  248. from zope.interface.interface import InterfaceClass
  249. from __tests__.tests.test_ro import C3Setting
  250. IBase = InterfaceClass('IBase')
  251. IDerived = InterfaceClass('IDerived', (IBase,))
  252. with C3Setting(ro.C3.STRICT_IRO, True):
  253. base = self._makeOne(IBase)
  254. after = base + IDerived
  255. self.assertEqual(after.__iro__, (IDerived, IBase, Interface))
  256. self.assertEqual(after.__bases__, (IDerived, IBase))
  257. self.assertEqual(list(after), [IDerived, IBase])
  258. def test___add___overlapping_interface_implementedBy(self):
  259. # Like test___add___overlapping_interface, but pulling
  260. # in a realistic example. This one previously produced a
  261. # C3 error, but the resulting legacy order was (somehow)
  262. # correct.
  263. from zope.interface import Interface
  264. from zope.interface import implementedBy
  265. from zope.interface import implementer
  266. from zope.interface import ro
  267. from __tests__.tests.test_ro import C3Setting
  268. class IBase(Interface):
  269. pass
  270. class IDerived(IBase):
  271. pass
  272. @implementer(IBase)
  273. class Base:
  274. pass
  275. with C3Setting(ro.C3.STRICT_IRO, True):
  276. after = implementedBy(Base) + IDerived
  277. self.assertEqual(after.__sro__, (after, IDerived, IBase, Interface))
  278. self.assertEqual(after.__bases__, (IDerived, IBase))
  279. self.assertEqual(list(after), [IDerived, IBase])
  280. class TestImmutableDeclaration(EmptyDeclarationTests):
  281. def _getTargetClass(self):
  282. from zope.interface.declarations import _ImmutableDeclaration
  283. return _ImmutableDeclaration
  284. def _getEmpty(self):
  285. from zope.interface.declarations import _empty
  286. return _empty
  287. def test_pickle(self):
  288. import pickle
  289. copied = pickle.loads(pickle.dumps(self._getEmpty()))
  290. self.assertIs(copied, self._getEmpty())
  291. def test_singleton(self):
  292. self.assertIs(
  293. self._getTargetClass()(),
  294. self._getEmpty()
  295. )
  296. def test__bases__(self):
  297. self.assertEqual(self._getEmpty().__bases__, ())
  298. def test_change__bases__(self):
  299. empty = self._getEmpty()
  300. empty.__bases__ = ()
  301. self.assertEqual(self._getEmpty().__bases__, ())
  302. with self.assertRaises(TypeError):
  303. empty.__bases__ = (1,)
  304. def test_dependents(self):
  305. empty = self._getEmpty()
  306. deps = empty.dependents
  307. self.assertEqual({}, deps)
  308. # Doesn't change the return.
  309. deps[1] = 2
  310. self.assertEqual({}, empty.dependents)
  311. def test_changed(self):
  312. # Does nothing, has no visible side-effects
  313. self._getEmpty().changed(None)
  314. def test_extends_always_false(self):
  315. self.assertFalse(self._getEmpty().extends(self))
  316. self.assertFalse(self._getEmpty().extends(self, strict=True))
  317. self.assertFalse(self._getEmpty().extends(self, strict=False))
  318. def test_get_always_default(self):
  319. self.assertIsNone(self._getEmpty().get('name'))
  320. self.assertEqual(self._getEmpty().get('name', 42), 42)
  321. def test_v_attrs(self):
  322. decl = self._getEmpty()
  323. self.assertEqual(decl._v_attrs, {})
  324. decl._v_attrs['attr'] = 42
  325. self.assertEqual(decl._v_attrs, {})
  326. self.assertIsNone(decl.get('attr'))
  327. attrs = decl._v_attrs = {}
  328. attrs['attr'] = 42
  329. self.assertEqual(decl._v_attrs, {})
  330. self.assertIsNone(decl.get('attr'))
  331. class TestImplements(NameAndModuleComparisonTestsMixin,
  332. unittest.TestCase):
  333. def _getTargetClass(self):
  334. from zope.interface.declarations import Implements
  335. return Implements
  336. def _makeOne(self, *args, **kw):
  337. return self._getTargetClass()(*args, **kw)
  338. def _makeOneToCompare(self):
  339. from zope.interface.declarations import implementedBy
  340. class A:
  341. pass
  342. return implementedBy(A)
  343. def test_ctor_no_bases(self):
  344. impl = self._makeOne()
  345. self.assertEqual(impl.inherit, None)
  346. self.assertEqual(impl.declared, ())
  347. self.assertEqual(impl.__name__, '?')
  348. self.assertEqual(list(impl.__bases__), [])
  349. def test___repr__(self):
  350. impl = self._makeOne()
  351. impl.__name__ = 'Testing'
  352. self.assertEqual(repr(impl), 'classImplements(Testing)')
  353. def test___reduce__(self):
  354. from zope.interface.declarations import implementedBy
  355. impl = self._makeOne()
  356. self.assertEqual(impl.__reduce__(), (implementedBy, (None,)))
  357. def test_sort(self):
  358. from zope.interface.declarations import implementedBy
  359. from zope.interface.interface import InterfaceClass
  360. class A:
  361. pass
  362. class B:
  363. pass
  364. IFoo = InterfaceClass('IFoo')
  365. self.assertEqual(implementedBy(A), implementedBy(A))
  366. self.assertEqual(hash(implementedBy(A)), hash(implementedBy(A)))
  367. self.assertLess(implementedBy(A), None)
  368. self.assertGreater(
  369. None,
  370. implementedBy(A)
  371. )
  372. self.assertLess(implementedBy(A), implementedBy(B))
  373. self.assertGreater(implementedBy(A), IFoo)
  374. self.assertLessEqual(implementedBy(A), implementedBy(B))
  375. self.assertGreaterEqual(implementedBy(A), IFoo)
  376. self.assertNotEqual(implementedBy(A), IFoo)
  377. def test_proxy_equality(self):
  378. # https://github.com/zopefoundation/zope.interface/issues/55
  379. from zope.interface.declarations import implementedBy
  380. class Proxy:
  381. def __init__(self, wrapped):
  382. self._wrapped = wrapped
  383. def __getattr__(self, name):
  384. raise NotImplementedError()
  385. def __eq__(self, other):
  386. return self._wrapped == other
  387. def __ne__(self, other):
  388. return self._wrapped != other
  389. class A:
  390. pass
  391. class B:
  392. pass
  393. implementedByA = implementedBy(A)
  394. implementedByB = implementedBy(B)
  395. proxy = Proxy(implementedByA)
  396. # The order of arguments to the operators matters,
  397. # test both
  398. self.assertEqual(
  399. implementedByA,
  400. implementedByA
  401. )
  402. self.assertNotEqual(implementedByA, implementedByB)
  403. self.assertNotEqual(implementedByB, implementedByA)
  404. self.assertEqual(proxy, implementedByA)
  405. self.assertEqual(implementedByA, proxy)
  406. self.assertEqual(proxy, implementedByA)
  407. self.assertEqual(implementedByA, proxy)
  408. self.assertNotEqual(proxy, implementedByB)
  409. self.assertNotEqual(implementedByB, proxy)
  410. def test_changed_deletes_super_cache(self):
  411. impl = self._makeOne()
  412. self.assertIsNone(impl._super_cache)
  413. self.assertNotIn('_super_cache', impl.__dict__)
  414. impl._super_cache = 42
  415. self.assertIn('_super_cache', impl.__dict__)
  416. impl.changed(None)
  417. self.assertIsNone(impl._super_cache)
  418. self.assertNotIn('_super_cache', impl.__dict__)
  419. def test_changed_does_not_add_super_cache(self):
  420. impl = self._makeOne()
  421. self.assertIsNone(impl._super_cache)
  422. self.assertNotIn('_super_cache', impl.__dict__)
  423. impl.changed(None)
  424. self.assertIsNone(impl._super_cache)
  425. self.assertNotIn('_super_cache', impl.__dict__)
  426. class Test_implementedByFallback(unittest.TestCase):
  427. def _getTargetClass(self):
  428. # pylint:disable=no-name-in-module
  429. from zope.interface.declarations import implementedByFallback
  430. return implementedByFallback
  431. _getFallbackClass = _getTargetClass
  432. def _callFUT(self, *args, **kw):
  433. return self._getTargetClass()(*args, **kw)
  434. def test_dictless_wo_existing_Implements_wo_registrations(self):
  435. class Foo:
  436. __slots__ = ('__implemented__',)
  437. foo = Foo()
  438. foo.__implemented__ = None
  439. self.assertEqual(list(self._callFUT(foo)), [])
  440. def test_dictless_wo_existing_Implements_cant_assign___implemented__(self):
  441. class Foo:
  442. def _get_impl(self):
  443. raise NotImplementedError()
  444. def _set_impl(self, val):
  445. raise TypeError
  446. __implemented__ = property(_get_impl, _set_impl)
  447. def __call__(self):
  448. # act like a factory
  449. raise NotImplementedError()
  450. foo = Foo()
  451. self.assertRaises(TypeError, self._callFUT, foo)
  452. def test_dictless_wo_existing_Implements_w_registrations(self):
  453. from zope.interface import declarations
  454. class Foo:
  455. __slots__ = ('__implemented__',)
  456. foo = Foo()
  457. foo.__implemented__ = None
  458. reg = object()
  459. with _MonkeyDict(declarations,
  460. 'BuiltinImplementationSpecifications') as specs:
  461. specs[foo] = reg
  462. self.assertIs(self._callFUT(foo), reg)
  463. def test_dictless_w_existing_Implements(self):
  464. from zope.interface.declarations import Implements
  465. impl = Implements()
  466. class Foo:
  467. __slots__ = ('__implemented__',)
  468. foo = Foo()
  469. foo.__implemented__ = impl
  470. self.assertIs(self._callFUT(foo), impl)
  471. def test_dictless_w_existing_not_Implements(self):
  472. from zope.interface.interface import InterfaceClass
  473. class Foo:
  474. __slots__ = ('__implemented__',)
  475. foo = Foo()
  476. IFoo = InterfaceClass('IFoo')
  477. foo.__implemented__ = (IFoo,)
  478. self.assertEqual(list(self._callFUT(foo)), [IFoo])
  479. def test_w_existing_attr_as_Implements(self):
  480. from zope.interface.declarations import Implements
  481. impl = Implements()
  482. class Foo:
  483. __implemented__ = impl
  484. self.assertIs(self._callFUT(Foo), impl)
  485. def test_builtins_added_to_cache(self):
  486. from zope.interface import declarations
  487. from zope.interface.declarations import Implements
  488. with _MonkeyDict(declarations,
  489. 'BuiltinImplementationSpecifications') as specs:
  490. self.assertEqual(list(self._callFUT(tuple)), [])
  491. self.assertEqual(list(self._callFUT(list)), [])
  492. self.assertEqual(list(self._callFUT(dict)), [])
  493. for typ in (tuple, list, dict):
  494. spec = specs[typ]
  495. self.assertIsInstance(spec, Implements)
  496. self.assertEqual(repr(spec),
  497. 'classImplements(%s)'
  498. % (typ.__name__,))
  499. def test_builtins_w_existing_cache(self):
  500. from zope.interface import declarations
  501. t_spec, l_spec, d_spec = object(), object(), object()
  502. with _MonkeyDict(declarations,
  503. 'BuiltinImplementationSpecifications') as specs:
  504. specs[tuple] = t_spec
  505. specs[list] = l_spec
  506. specs[dict] = d_spec
  507. self.assertIs(self._callFUT(tuple), t_spec)
  508. self.assertIs(self._callFUT(list), l_spec)
  509. self.assertIs(self._callFUT(dict), d_spec)
  510. def test_oldstyle_class_no_assertions(self):
  511. # TODO: Figure out P3 story
  512. class Foo:
  513. pass
  514. self.assertEqual(list(self._callFUT(Foo)), [])
  515. def test_no_assertions(self):
  516. # TODO: Figure out P3 story
  517. class Foo:
  518. pass
  519. self.assertEqual(list(self._callFUT(Foo)), [])
  520. def test_w_None_no_bases_not_factory(self):
  521. class Foo:
  522. __implemented__ = None
  523. foo = Foo()
  524. self.assertRaises(TypeError, self._callFUT, foo)
  525. def test_w_None_no_bases_w_factory(self):
  526. from zope.interface.declarations import objectSpecificationDescriptor
  527. class Foo:
  528. __implemented__ = None
  529. def __call__(self):
  530. raise NotImplementedError()
  531. foo = Foo()
  532. foo.__name__ = 'foo'
  533. spec = self._callFUT(foo)
  534. self.assertEqual(spec.__name__,
  535. '__tests__.tests.test_declarations.foo')
  536. self.assertIs(spec.inherit, foo)
  537. self.assertIs(foo.__implemented__, spec)
  538. self.assertIs(
  539. foo.__providedBy__, objectSpecificationDescriptor
  540. ) # pylint:disable=no-member
  541. self.assertNotIn('__provides__', foo.__dict__)
  542. def test_w_None_no_bases_w_class(self):
  543. from zope.interface.declarations import ClassProvides
  544. class Foo:
  545. __implemented__ = None
  546. spec = self._callFUT(Foo)
  547. self.assertEqual(spec.__name__,
  548. '__tests__.tests.test_declarations.Foo')
  549. self.assertIs(spec.inherit, Foo)
  550. self.assertIs(Foo.__implemented__, spec)
  551. self.assertIsInstance(
  552. Foo.__providedBy__, ClassProvides
  553. ) # pylint:disable=no-member
  554. self.assertIsInstance(
  555. Foo.__provides__, ClassProvides
  556. ) # pylint:disable=no-member
  557. self.assertEqual(
  558. Foo.__provides__, Foo.__providedBy__
  559. ) # pylint:disable=no-member
  560. def test_w_existing_Implements(self):
  561. from zope.interface.declarations import Implements
  562. impl = Implements()
  563. class Foo:
  564. __implemented__ = impl
  565. self.assertIs(self._callFUT(Foo), impl)
  566. def test_super_when_base_implements_interface(self):
  567. from zope.interface import Interface
  568. from zope.interface.declarations import implementer
  569. class IBase(Interface):
  570. pass
  571. class IDerived(IBase):
  572. pass
  573. @implementer(IBase)
  574. class Base:
  575. pass
  576. @implementer(IDerived)
  577. class Derived(Base):
  578. pass
  579. self.assertEqual(list(self._callFUT(Derived)), [IDerived, IBase])
  580. sup = super(Derived, Derived)
  581. self.assertEqual(list(self._callFUT(sup)), [IBase])
  582. def test_super_when_base_implements_interface_diamond(self):
  583. from zope.interface import Interface
  584. from zope.interface.declarations import implementer
  585. class IBase(Interface):
  586. pass
  587. class IDerived(IBase):
  588. pass
  589. @implementer(IBase)
  590. class Base:
  591. pass
  592. class Child1(Base):
  593. pass
  594. class Child2(Base):
  595. pass
  596. @implementer(IDerived)
  597. class Derived(Child1, Child2):
  598. pass
  599. self.assertEqual(list(self._callFUT(Derived)), [IDerived, IBase])
  600. sup = super(Derived, Derived)
  601. self.assertEqual(list(self._callFUT(sup)), [IBase])
  602. def test_super_when_parent_implements_interface_diamond(self):
  603. from zope.interface import Interface
  604. from zope.interface.declarations import implementer
  605. class IBase(Interface):
  606. pass
  607. class IDerived(IBase):
  608. pass
  609. class Base:
  610. pass
  611. class Child1(Base):
  612. pass
  613. @implementer(IBase)
  614. class Child2(Base):
  615. pass
  616. @implementer(IDerived)
  617. class Derived(Child1, Child2):
  618. pass
  619. self.assertEqual(
  620. Derived.__mro__, (Derived, Child1, Child2, Base, object)
  621. )
  622. self.assertEqual(list(self._callFUT(Derived)), [IDerived, IBase])
  623. sup = super(Derived, Derived)
  624. fut = self._callFUT(sup)
  625. self.assertEqual(list(fut), [IBase])
  626. self.assertIsNone(fut._dependents)
  627. def test_super_when_base_doesnt_implement_interface(self):
  628. from zope.interface import Interface
  629. from zope.interface.declarations import implementer
  630. class IBase(Interface):
  631. pass
  632. class IDerived(IBase):
  633. pass
  634. class Base:
  635. pass
  636. @implementer(IDerived)
  637. class Derived(Base):
  638. pass
  639. self.assertEqual(list(self._callFUT(Derived)), [IDerived])
  640. sup = super(Derived, Derived)
  641. self.assertEqual(list(self._callFUT(sup)), [])
  642. def test_super_when_base_is_object(self):
  643. from zope.interface import Interface
  644. from zope.interface.declarations import implementer
  645. class IBase(Interface):
  646. pass
  647. class IDerived(IBase):
  648. pass
  649. @implementer(IDerived)
  650. class Derived:
  651. pass
  652. self.assertEqual(list(self._callFUT(Derived)), [IDerived])
  653. sup = super(Derived, Derived)
  654. self.assertEqual(list(self._callFUT(sup)), [])
  655. def test_super_multi_level_multi_inheritance(self):
  656. from zope.interface import Interface
  657. from zope.interface.declarations import implementer
  658. class IBase(Interface):
  659. pass
  660. class IM1(Interface):
  661. pass
  662. class IM2(Interface):
  663. pass
  664. class IDerived(IBase):
  665. pass
  666. class IUnrelated(Interface):
  667. pass
  668. @implementer(IBase)
  669. class Base:
  670. pass
  671. @implementer(IM1)
  672. class M1(Base):
  673. pass
  674. @implementer(IM2)
  675. class M2(Base):
  676. pass
  677. @implementer(IDerived, IUnrelated)
  678. class Derived(M1, M2):
  679. pass
  680. d = Derived
  681. sd = super(Derived, Derived)
  682. sm1 = super(M1, Derived)
  683. sm2 = super(M2, Derived)
  684. self.assertEqual(list(self._callFUT(d)),
  685. [IDerived, IUnrelated, IM1, IBase, IM2])
  686. self.assertEqual(list(self._callFUT(sd)),
  687. [IM1, IBase, IM2])
  688. self.assertEqual(list(self._callFUT(sm1)),
  689. [IM2, IBase])
  690. self.assertEqual(list(self._callFUT(sm2)),
  691. [IBase])
  692. class Test_implementedBy(Test_implementedByFallback,
  693. OptimizationTestMixin):
  694. # Repeat tests for C optimizations
  695. def _getTargetClass(self):
  696. from zope.interface.declarations import implementedBy
  697. return implementedBy
  698. class _ImplementsTestMixin:
  699. FUT_SETS_PROVIDED_BY = True
  700. def _callFUT(self, cls, iface):
  701. # Declare that *cls* implements *iface*; return *cls*
  702. raise NotImplementedError
  703. def _check_implementer(self, Foo,
  704. orig_spec=None,
  705. spec_name=__name__ + '.Foo',
  706. inherit="not given"):
  707. from zope.interface.declarations import ClassProvides
  708. from zope.interface.interface import InterfaceClass
  709. IFoo = InterfaceClass('IFoo')
  710. returned = self._callFUT(Foo, IFoo)
  711. self.assertIs(returned, Foo)
  712. spec = Foo.__implemented__
  713. if orig_spec is not None:
  714. self.assertIs(spec, orig_spec)
  715. self.assertEqual(spec.__name__,
  716. spec_name)
  717. inherit = Foo if inherit == "not given" else inherit
  718. self.assertIs(spec.inherit, inherit)
  719. self.assertIs(Foo.__implemented__, spec)
  720. if self.FUT_SETS_PROVIDED_BY:
  721. self.assertIsInstance(Foo.__providedBy__, ClassProvides)
  722. self.assertIsInstance(Foo.__provides__, ClassProvides)
  723. self.assertEqual(Foo.__provides__, Foo.__providedBy__)
  724. return Foo, IFoo
  725. def test_class(self):
  726. class Foo:
  727. pass
  728. self._check_implementer(Foo)
  729. class Test_classImplementsOnly(_ImplementsTestMixin, unittest.TestCase):
  730. FUT_SETS_PROVIDED_BY = False
  731. def _callFUT(self, cls, iface):
  732. from zope.interface.declarations import classImplementsOnly
  733. classImplementsOnly(cls, iface)
  734. return cls
  735. def test_w_existing_Implements(self):
  736. from zope.interface.declarations import Implements
  737. from zope.interface.interface import InterfaceClass
  738. IFoo = InterfaceClass('IFoo')
  739. IBar = InterfaceClass('IBar')
  740. impl = Implements(IFoo)
  741. impl.declared = (IFoo,)
  742. class Foo:
  743. __implemented__ = impl
  744. impl.inherit = Foo
  745. self._callFUT(Foo, IBar)
  746. # Same spec, now different values
  747. self.assertIs(Foo.__implemented__, impl)
  748. self.assertEqual(impl.inherit, None)
  749. self.assertEqual(impl.declared, (IBar,))
  750. def test_class(self):
  751. from zope.interface.declarations import Implements
  752. from zope.interface.interface import InterfaceClass
  753. IBar = InterfaceClass('IBar')
  754. old_spec = Implements(IBar)
  755. class Foo:
  756. __implemented__ = old_spec
  757. self._check_implementer(Foo, old_spec, '?', inherit=None)
  758. def test_redundant_with_super_still_implements(self):
  759. Base, IBase = self._check_implementer(
  760. type('Foo', (object,), {}),
  761. inherit=None,
  762. )
  763. class Child(Base):
  764. pass
  765. self._callFUT(Child, IBase)
  766. self.assertTrue(IBase.implementedBy(Child))
  767. class Test_classImplements(_ImplementsTestMixin, unittest.TestCase):
  768. def _callFUT(self, cls, iface):
  769. from zope.interface.declarations import classImplements
  770. result = classImplements(
  771. cls, iface
  772. ) # pylint:disable=assignment-from-no-return
  773. self.assertIsNone(result)
  774. return cls
  775. def __check_implementer_redundant(self, Base):
  776. # If we @implementer exactly what was already present, we write no
  777. # declared attributes on the parent (we still set everything, though)
  778. Base, IBase = self._check_implementer(Base)
  779. class Child(Base):
  780. pass
  781. returned = self._callFUT(Child, IBase)
  782. self.assertIn('__implemented__', returned.__dict__)
  783. self.assertNotIn('__providedBy__', returned.__dict__)
  784. self.assertIn('__provides__', returned.__dict__)
  785. spec = Child.__implemented__
  786. self.assertEqual(spec.declared, ())
  787. self.assertEqual(spec.inherit, Child)
  788. self.assertTrue(IBase.providedBy(Child()))
  789. def test_redundant_implementer_empty_class_declarations(self):
  790. class Foo:
  791. pass
  792. self.__check_implementer_redundant(Foo)
  793. def test_redundant_implementer_Interface(self):
  794. from zope.interface import Interface
  795. from zope.interface import implementedBy
  796. from zope.interface import ro
  797. from __tests__.tests.test_ro import C3Setting
  798. class Foo:
  799. pass
  800. with C3Setting(ro.C3.STRICT_IRO, False):
  801. self._callFUT(Foo, Interface)
  802. self.assertEqual(list(implementedBy(Foo)), [Interface])
  803. class Baz(Foo):
  804. pass
  805. self._callFUT(Baz, Interface)
  806. self.assertEqual(list(implementedBy(Baz)), [Interface])
  807. def _order_for_two(self, applied_first, applied_second):
  808. return (applied_first, applied_second)
  809. def test_w_existing_Implements(self):
  810. from zope.interface.declarations import Implements
  811. from zope.interface.interface import InterfaceClass
  812. IFoo = InterfaceClass('IFoo')
  813. IBar = InterfaceClass('IBar')
  814. impl = Implements(IFoo)
  815. impl.declared = (IFoo,)
  816. class Foo:
  817. __implemented__ = impl
  818. impl.inherit = Foo
  819. self._callFUT(Foo, IBar)
  820. # Same spec, now different values
  821. self.assertIs(Foo.__implemented__, impl)
  822. self.assertEqual(impl.inherit, Foo)
  823. self.assertEqual(impl.declared,
  824. self._order_for_two(IFoo, IBar))
  825. def test_w_existing_Implements_w_bases(self):
  826. from zope.interface.declarations import Implements
  827. from zope.interface.interface import InterfaceClass
  828. IRoot = InterfaceClass('IRoot')
  829. ISecondRoot = InterfaceClass('ISecondRoot')
  830. IExtendsRoot = InterfaceClass('IExtendsRoot', (IRoot,))
  831. impl_root = Implements.named('Root', IRoot)
  832. impl_root.declared = (IRoot,)
  833. class Root1:
  834. __implemented__ = impl_root
  835. class Root2:
  836. __implemented__ = impl_root
  837. impl_extends_root = Implements.named('ExtendsRoot1', IExtendsRoot)
  838. impl_extends_root.declared = (IExtendsRoot,)
  839. class ExtendsRoot(Root1, Root2):
  840. __implemented__ = impl_extends_root
  841. impl_extends_root.inherit = ExtendsRoot
  842. self._callFUT(ExtendsRoot, ISecondRoot)
  843. # Same spec, now different values
  844. self.assertIs(ExtendsRoot.__implemented__, impl_extends_root)
  845. self.assertEqual(impl_extends_root.inherit, ExtendsRoot)
  846. self.assertEqual(impl_extends_root.declared,
  847. self._order_for_two(IExtendsRoot, ISecondRoot,))
  848. self.assertEqual(
  849. impl_extends_root.__bases__,
  850. self._order_for_two(IExtendsRoot, ISecondRoot) + (impl_root,)
  851. )
  852. class Test_classImplementsFirst(Test_classImplements):
  853. def _callFUT(self, cls, iface):
  854. from zope.interface.declarations import classImplementsFirst
  855. result = classImplementsFirst(
  856. cls, iface
  857. ) # pylint:disable=assignment-from-no-return
  858. self.assertIsNone(result)
  859. return cls
  860. def _order_for_two(self, applied_first, applied_second):
  861. return (applied_second, applied_first)
  862. class Test__implements_advice(unittest.TestCase):
  863. def _callFUT(self, *args, **kw):
  864. from zope.interface.declarations import _implements_advice
  865. return _implements_advice(*args, **kw)
  866. def test_no_existing_implements(self):
  867. from zope.interface.declarations import Implements
  868. from zope.interface.declarations import classImplements
  869. from zope.interface.interface import InterfaceClass
  870. IFoo = InterfaceClass('IFoo')
  871. class Foo:
  872. __implements_advice_data__ = ((IFoo,), classImplements)
  873. self._callFUT(Foo)
  874. self.assertNotIn('__implements_advice_data__', Foo.__dict__)
  875. self.assertIsInstance(
  876. Foo.__implemented__, Implements
  877. ) # pylint:disable=no-member
  878. self.assertEqual(
  879. list(Foo.__implemented__), [IFoo]
  880. ) # pylint:disable=no-member
  881. class Test_implementer(Test_classImplements):
  882. def _getTargetClass(self):
  883. from zope.interface.declarations import implementer
  884. return implementer
  885. def _makeOne(self, *args, **kw):
  886. return self._getTargetClass()(*args, **kw)
  887. def _callFUT(self, cls, *ifaces):
  888. decorator = self._makeOne(*ifaces)
  889. return decorator(cls)
  890. def test_nonclass_cannot_assign_attr(self):
  891. from zope.interface.interface import InterfaceClass
  892. IFoo = InterfaceClass('IFoo')
  893. decorator = self._makeOne(IFoo)
  894. self.assertRaises(TypeError, decorator, object())
  895. def test_nonclass_can_assign_attr(self):
  896. from zope.interface.interface import InterfaceClass
  897. IFoo = InterfaceClass('IFoo')
  898. class Foo:
  899. pass
  900. foo = Foo()
  901. decorator = self._makeOne(IFoo)
  902. returned = decorator(foo)
  903. self.assertIs(returned, foo)
  904. spec = foo.__implemented__ # pylint:disable=no-member
  905. self.assertEqual(
  906. spec.__name__, '__tests__.tests.test_declarations.?'
  907. )
  908. self.assertIsNone(spec.inherit,)
  909. self.assertIs(foo.__implemented__, spec) # pylint:disable=no-member
  910. def test_does_not_leak_on_unique_classes(self):
  911. # Make sure nothing is hanging on to the class or Implements
  912. # object after they go out of scope. There was briefly a bug
  913. # in 5.x that caused SpecificationBase._bases (in C) to not be
  914. # traversed or cleared.
  915. # https://github.com/zopefoundation/zope.interface/issues/216
  916. import gc
  917. from zope.interface.interface import InterfaceClass
  918. IFoo = InterfaceClass('IFoo')
  919. begin_count = len(gc.get_objects())
  920. for _ in range(1900):
  921. class TestClass:
  922. pass
  923. self._callFUT(TestClass, IFoo)
  924. gc.collect()
  925. end_count = len(gc.get_objects())
  926. # How many new objects might still be around? In all currently
  927. # tested interpreters, there aren't any, so our counts should
  928. # match exactly. When the bug existed, in a steady state, the loop
  929. # would grow by two objects each iteration
  930. fudge_factor = 0
  931. self.assertLessEqual(end_count, begin_count + fudge_factor)
  932. class Test_implementer_only(Test_classImplementsOnly):
  933. def _getTargetClass(self):
  934. from zope.interface.declarations import implementer_only
  935. return implementer_only
  936. def _makeOne(self, *args, **kw):
  937. return self._getTargetClass()(*args, **kw)
  938. def _callFUT(self, cls, iface):
  939. decorator = self._makeOne(iface)
  940. return decorator(cls)
  941. def test_function(self):
  942. from zope.interface.interface import InterfaceClass
  943. IFoo = InterfaceClass('IFoo')
  944. decorator = self._makeOne(IFoo)
  945. def _function():
  946. raise NotImplementedError()
  947. self.assertRaises(ValueError, decorator, _function)
  948. def test_method(self):
  949. from zope.interface.interface import InterfaceClass
  950. IFoo = InterfaceClass('IFoo')
  951. decorator = self._makeOne(IFoo)
  952. class Bar:
  953. def _method(self):
  954. raise NotImplementedError()
  955. self.assertRaises(ValueError, decorator, Bar._method)
  956. class ProvidesClassTests(unittest.TestCase):
  957. def _getTargetClass(self):
  958. from zope.interface.declarations import ProvidesClass
  959. return ProvidesClass
  960. def _makeOne(self, *args, **kw):
  961. return self._getTargetClass()(*args, **kw)
  962. def test_simple_class_one_interface(self):
  963. from zope.interface.interface import InterfaceClass
  964. IFoo = InterfaceClass("IFoo")
  965. class Foo:
  966. pass
  967. spec = self._makeOne(Foo, IFoo)
  968. self.assertEqual(list(spec), [IFoo])
  969. def test___reduce__(self):
  970. from zope.interface.declarations import Provides # the function
  971. from zope.interface.interface import InterfaceClass
  972. IFoo = InterfaceClass("IFoo")
  973. class Foo:
  974. pass
  975. spec = self._makeOne(Foo, IFoo)
  976. klass, args = spec.__reduce__()
  977. self.assertIs(klass, Provides)
  978. self.assertEqual(args, (Foo, IFoo))
  979. def test___get___class(self):
  980. from zope.interface.interface import InterfaceClass
  981. IFoo = InterfaceClass("IFoo")
  982. class Foo:
  983. pass
  984. spec = self._makeOne(Foo, IFoo)
  985. Foo.__provides__ = spec
  986. self.assertIs(Foo.__provides__, spec)
  987. def test___get___instance(self):
  988. from zope.interface.interface import InterfaceClass
  989. IFoo = InterfaceClass("IFoo")
  990. class Foo:
  991. pass
  992. spec = self._makeOne(Foo, IFoo)
  993. Foo.__provides__ = spec
  994. def _test():
  995. foo = Foo()
  996. return foo.__provides__
  997. self.assertRaises(AttributeError, _test)
  998. class ProvidesClassStrictTests(ProvidesClassTests):
  999. # Tests that require the strict C3 resolution order.
  1000. def _getTargetClass(self):
  1001. ProvidesClass = super()._getTargetClass()
  1002. class StrictProvides(ProvidesClass):
  1003. def _do_calculate_ro(self, base_mros):
  1004. return ProvidesClass._do_calculate_ro(
  1005. self, base_mros=base_mros, strict=True,
  1006. )
  1007. return StrictProvides
  1008. def test_overlapping_interfaces_corrected(self):
  1009. # Giving Provides(cls, IFace), where IFace is already
  1010. # provided by cls, doesn't produce invalid resolution orders.
  1011. from zope.interface import Interface
  1012. from zope.interface import implementedBy
  1013. from zope.interface import implementer
  1014. class IBase(Interface):
  1015. pass
  1016. @implementer(IBase)
  1017. class Base:
  1018. pass
  1019. spec = self._makeOne(Base, IBase)
  1020. self.assertEqual(spec.__sro__, (
  1021. spec,
  1022. implementedBy(Base),
  1023. IBase,
  1024. implementedBy(object),
  1025. Interface
  1026. ))
  1027. class TestProvidesClassRepr(unittest.TestCase):
  1028. def _getTargetClass(self):
  1029. from zope.interface.declarations import ProvidesClass
  1030. return ProvidesClass
  1031. def _makeOne(self, *args, **kw):
  1032. return self._getTargetClass()(*args, **kw)
  1033. def test__repr__(self):
  1034. from zope.interface.interface import InterfaceClass
  1035. IFoo = InterfaceClass("IFoo")
  1036. assert IFoo.__name__ == 'IFoo'
  1037. assert IFoo.__module__ == __name__
  1038. assert repr(IFoo) == f'<InterfaceClass {__name__}.IFoo>'
  1039. IBar = InterfaceClass("IBar")
  1040. inst = self._makeOne(type(self), IFoo, IBar)
  1041. self.assertEqual(
  1042. repr(inst),
  1043. "directlyProvides(TestProvidesClassRepr, IFoo, IBar)"
  1044. )
  1045. def test__repr__module_provides_typical_use(self):
  1046. # as created through a ``moduleProvides()`` statement
  1047. # in a module body
  1048. from . import dummy
  1049. provides = dummy.__provides__ # pylint:disable=no-member
  1050. self.assertEqual(
  1051. repr(provides),
  1052. "directlyProvides("
  1053. "sys.modules['__tests__.tests.dummy'], "
  1054. "IDummyModule)"
  1055. )
  1056. def test__repr__module_after_pickle(self):
  1057. # It doesn't matter, these objects can't be pickled.
  1058. import pickle
  1059. from . import dummy
  1060. provides = dummy.__provides__ # pylint:disable=no-member
  1061. for proto in range(pickle.HIGHEST_PROTOCOL + 1):
  1062. with self.assertRaises(pickle.PicklingError):
  1063. pickle.dumps(provides, proto)
  1064. def test__repr__directlyProvides_module(self):
  1065. import sys
  1066. from zope.interface.declarations import alsoProvides
  1067. from zope.interface.declarations import directlyProvides
  1068. from zope.interface.interface import InterfaceClass
  1069. from __tests__.tests import dummy
  1070. IFoo = InterfaceClass('IFoo')
  1071. IBar = InterfaceClass('IBar')
  1072. orig_provides = dummy.__provides__ # pylint:disable=no-member
  1073. del dummy.__provides__ # pylint:disable=no-member
  1074. self.addCleanup(setattr, dummy, '__provides__', orig_provides)
  1075. directlyProvides(dummy, IFoo)
  1076. provides = dummy.__provides__ # pylint:disable=no-member
  1077. self.assertEqual(
  1078. repr(provides),
  1079. "directlyProvides(sys.modules['__tests__.tests.dummy'], IFoo)"
  1080. )
  1081. alsoProvides(dummy, IBar)
  1082. provides = dummy.__provides__ # pylint:disable=no-member
  1083. self.assertEqual(
  1084. repr(provides),
  1085. "directlyProvides("
  1086. "sys.modules['__tests__.tests.dummy'], "
  1087. "IFoo, IBar)"
  1088. )
  1089. # If we make this module also provide IFoo and IBar, then the repr
  1090. # lists both names.
  1091. my_module = sys.modules[__name__]
  1092. assert not hasattr(my_module, '__provides__')
  1093. directlyProvides(my_module, IFoo, IBar)
  1094. self.addCleanup(delattr, my_module, '__provides__')
  1095. self.assertIs(my_module.__provides__, provides)
  1096. self.assertEqual(
  1097. repr(provides),
  1098. "directlyProvides(('__tests__.tests.dummy', "
  1099. "'__tests__.tests.test_declarations'), "
  1100. "IFoo, IBar)"
  1101. )
  1102. def test__repr__module_provides_cached_shared(self):
  1103. from zope.interface.declarations import ModuleType
  1104. from zope.interface.interface import InterfaceClass
  1105. IFoo = InterfaceClass("IFoo")
  1106. inst = self._makeOne(ModuleType, IFoo)
  1107. inst._v_module_names += ('some.module',)
  1108. inst._v_module_names += ('another.module',)
  1109. self.assertEqual(
  1110. repr(inst),
  1111. "directlyProvides(('some.module', 'another.module'), IFoo)"
  1112. )
  1113. def test__repr__duplicate_names(self):
  1114. from zope.interface.interface import InterfaceClass
  1115. IFoo = InterfaceClass("IFoo", __module__='mod1')
  1116. IFoo2 = InterfaceClass("IFoo", __module__='mod2')
  1117. IBaz = InterfaceClass("IBaz")
  1118. inst = self._makeOne(type(self), IFoo, IBaz, IFoo2)
  1119. self.assertEqual(
  1120. repr(inst),
  1121. "directlyProvides(TestProvidesClassRepr, IFoo, IBaz, mod2.IFoo)"
  1122. )
  1123. def test__repr__implementedBy_in_interfaces(self):
  1124. from zope.interface import Interface
  1125. from zope.interface import implementedBy
  1126. class IFoo(Interface):
  1127. "Does nothing"
  1128. class Bar:
  1129. "Does nothing"
  1130. impl = implementedBy(type(self))
  1131. inst = self._makeOne(Bar, IFoo, impl)
  1132. self.assertEqual(
  1133. repr(inst),
  1134. 'directlyProvides('
  1135. 'Bar, IFoo, '
  1136. 'classImplements(TestProvidesClassRepr))'
  1137. )
  1138. def test__repr__empty_interfaces(self):
  1139. inst = self._makeOne(type(self))
  1140. self.assertEqual(
  1141. repr(inst),
  1142. 'directlyProvides(TestProvidesClassRepr)',
  1143. )
  1144. def test__repr__non_class(self):
  1145. def str___dont_call_me():
  1146. self.fail("Should not call str")
  1147. class Object:
  1148. __bases__ = ()
  1149. __str__ = str___dont_call_me
  1150. def __repr__(self):
  1151. return '<Object>'
  1152. inst = self._makeOne(Object())
  1153. self.assertEqual(
  1154. repr(inst),
  1155. 'directlyProvides(<Object>)',
  1156. )
  1157. def test__repr__providedBy_from_class(self):
  1158. from zope.interface.declarations import implementer
  1159. from zope.interface.declarations import providedBy
  1160. from zope.interface.interface import InterfaceClass
  1161. IFoo = InterfaceClass("IFoo")
  1162. @implementer(IFoo)
  1163. class Foo:
  1164. pass
  1165. inst = providedBy(Foo())
  1166. self.assertEqual(
  1167. repr(inst),
  1168. 'classImplements(Foo, IFoo)'
  1169. )
  1170. def test__repr__providedBy_alsoProvides(self):
  1171. from zope.interface.declarations import alsoProvides
  1172. from zope.interface.declarations import implementer
  1173. from zope.interface.declarations import providedBy
  1174. from zope.interface.interface import InterfaceClass
  1175. IFoo = InterfaceClass("IFoo")
  1176. IBar = InterfaceClass("IBar")
  1177. @implementer(IFoo)
  1178. class Foo:
  1179. pass
  1180. foo = Foo()
  1181. alsoProvides(foo, IBar)
  1182. inst = providedBy(foo)
  1183. self.assertEqual(
  1184. repr(inst),
  1185. "directlyProvides(Foo, IBar, classImplements(Foo, IFoo))"
  1186. )
  1187. class Test_Provides(unittest.TestCase):
  1188. def _callFUT(self, *args, **kw):
  1189. from zope.interface.declarations import Provides
  1190. return Provides(*args, **kw)
  1191. def test_no_cached_spec(self):
  1192. from zope.interface import declarations
  1193. from zope.interface.interface import InterfaceClass
  1194. IFoo = InterfaceClass("IFoo")
  1195. cache = {}
  1196. class Foo:
  1197. pass
  1198. with _Monkey(declarations, InstanceDeclarations=cache):
  1199. spec = self._callFUT(Foo, IFoo)
  1200. self.assertEqual(list(spec), [IFoo])
  1201. self.assertIs(cache[(Foo, IFoo)], spec)
  1202. def test_w_cached_spec(self):
  1203. from zope.interface import declarations
  1204. from zope.interface.interface import InterfaceClass
  1205. IFoo = InterfaceClass("IFoo")
  1206. prior = object()
  1207. class Foo:
  1208. pass
  1209. cache = {(Foo, IFoo): prior}
  1210. with _Monkey(declarations, InstanceDeclarations=cache):
  1211. spec = self._callFUT(Foo, IFoo)
  1212. self.assertIs(spec, prior)
  1213. class Test_directlyProvides(unittest.TestCase):
  1214. def _callFUT(self, *args, **kw):
  1215. from zope.interface.declarations import directlyProvides
  1216. return directlyProvides(*args, **kw)
  1217. def test_w_normal_object(self):
  1218. from zope.interface.declarations import ProvidesClass
  1219. from zope.interface.interface import InterfaceClass
  1220. IFoo = InterfaceClass("IFoo")
  1221. class Foo:
  1222. pass
  1223. obj = Foo()
  1224. self._callFUT(obj, IFoo)
  1225. self.assertIsInstance(
  1226. obj.__provides__, ProvidesClass
  1227. ) # pylint:disable=no-member
  1228. self.assertEqual(
  1229. list(obj.__provides__), [IFoo]
  1230. ) # pylint:disable=no-member
  1231. def test_w_class(self):
  1232. from zope.interface.declarations import ClassProvides
  1233. from zope.interface.interface import InterfaceClass
  1234. IFoo = InterfaceClass("IFoo")
  1235. class Foo:
  1236. pass
  1237. self._callFUT(Foo, IFoo)
  1238. self.assertIsInstance(
  1239. Foo.__provides__, ClassProvides
  1240. ) # pylint:disable=no-member
  1241. self.assertEqual(
  1242. list(Foo.__provides__), [IFoo]
  1243. ) # pylint:disable=no-member
  1244. def test_w_classless_object(self):
  1245. from zope.interface.declarations import ProvidesClass
  1246. from zope.interface.interface import InterfaceClass
  1247. IFoo = InterfaceClass("IFoo")
  1248. the_dict = {}
  1249. class Foo:
  1250. def __getattribute__(self, name):
  1251. # Emulate object w/o any class
  1252. if name == '__class__':
  1253. return None
  1254. raise NotImplementedError(name)
  1255. def __setattr__(self, name, value):
  1256. the_dict[name] = value
  1257. obj = Foo()
  1258. self._callFUT(obj, IFoo)
  1259. self.assertIsInstance(the_dict['__provides__'], ProvidesClass)
  1260. self.assertEqual(list(the_dict['__provides__']), [IFoo])
  1261. class Test_alsoProvides(unittest.TestCase):
  1262. def _callFUT(self, *args, **kw):
  1263. from zope.interface.declarations import alsoProvides
  1264. return alsoProvides(*args, **kw)
  1265. def test_wo_existing_provides(self):
  1266. from zope.interface.declarations import ProvidesClass
  1267. from zope.interface.interface import InterfaceClass
  1268. IFoo = InterfaceClass("IFoo")
  1269. class Foo:
  1270. pass
  1271. obj = Foo()
  1272. self._callFUT(obj, IFoo)
  1273. self.assertIsInstance(
  1274. obj.__provides__, ProvidesClass
  1275. ) # pylint:disable=no-member
  1276. self.assertEqual(
  1277. list(obj.__provides__), [IFoo]
  1278. ) # pylint:disable=no-member
  1279. def test_w_existing_provides(self):
  1280. from zope.interface.declarations import ProvidesClass
  1281. from zope.interface.declarations import directlyProvides
  1282. from zope.interface.interface import InterfaceClass
  1283. IFoo = InterfaceClass("IFoo")
  1284. IBar = InterfaceClass("IBar")
  1285. class Foo:
  1286. pass
  1287. obj = Foo()
  1288. directlyProvides(obj, IFoo)
  1289. self._callFUT(obj, IBar)
  1290. self.assertIsInstance(
  1291. obj.__provides__, ProvidesClass
  1292. ) # pylint:disable=no-member
  1293. self.assertEqual(
  1294. list(obj.__provides__), [IFoo, IBar]
  1295. ) # pylint:disable=no-member
  1296. class Test_noLongerProvides(unittest.TestCase):
  1297. def _callFUT(self, *args, **kw):
  1298. from zope.interface.declarations import noLongerProvides
  1299. return noLongerProvides(*args, **kw)
  1300. def test_wo_existing_provides(self):
  1301. from zope.interface.interface import InterfaceClass
  1302. IFoo = InterfaceClass("IFoo")
  1303. class Foo:
  1304. pass
  1305. obj = Foo()
  1306. self._callFUT(obj, IFoo)
  1307. self.assertEqual(
  1308. list(obj.__provides__), []
  1309. ) # pylint:disable=no-member
  1310. def test_w_existing_provides_hit(self):
  1311. from zope.interface.declarations import directlyProvides
  1312. from zope.interface.interface import InterfaceClass
  1313. IFoo = InterfaceClass("IFoo")
  1314. class Foo:
  1315. pass
  1316. obj = Foo()
  1317. directlyProvides(obj, IFoo)
  1318. self._callFUT(obj, IFoo)
  1319. self.assertEqual(
  1320. list(obj.__provides__), []
  1321. ) # pylint:disable=no-member
  1322. def test_w_existing_provides_miss(self):
  1323. from zope.interface.declarations import directlyProvides
  1324. from zope.interface.interface import InterfaceClass
  1325. IFoo = InterfaceClass("IFoo")
  1326. IBar = InterfaceClass("IBar")
  1327. class Foo:
  1328. pass
  1329. obj = Foo()
  1330. directlyProvides(obj, IFoo)
  1331. self._callFUT(obj, IBar)
  1332. self.assertEqual(
  1333. list(obj.__provides__), [IFoo]
  1334. ) # pylint:disable=no-member
  1335. def test_w_iface_implemented_by_class(self):
  1336. from zope.interface.declarations import implementer
  1337. from zope.interface.interface import InterfaceClass
  1338. IFoo = InterfaceClass("IFoo")
  1339. @implementer(IFoo)
  1340. class Foo:
  1341. pass
  1342. obj = Foo()
  1343. self.assertRaises(ValueError, self._callFUT, obj, IFoo)
  1344. class ClassProvidesBaseFallbackTests(unittest.TestCase):
  1345. def _getTargetClass(self):
  1346. # pylint:disable=no-name-in-module
  1347. from zope.interface.declarations import ClassProvidesBaseFallback
  1348. return ClassProvidesBaseFallback
  1349. def _makeOne(self, klass, implements):
  1350. # Don't instantiate directly: the C version can't have attributes
  1351. # assigned.
  1352. class Derived(self._getTargetClass()):
  1353. def __init__(self, k, i):
  1354. self._cls = k
  1355. self._implements = i
  1356. return Derived(klass, implements)
  1357. def test_w_same_class_via_class(self):
  1358. from zope.interface.interface import InterfaceClass
  1359. IFoo = InterfaceClass("IFoo")
  1360. class Foo:
  1361. pass
  1362. cpbp = Foo.__provides__ = self._makeOne(Foo, IFoo)
  1363. self.assertIs(Foo.__provides__, cpbp)
  1364. def test_w_same_class_via_instance(self):
  1365. from zope.interface.interface import InterfaceClass
  1366. IFoo = InterfaceClass("IFoo")
  1367. class Foo:
  1368. pass
  1369. foo = Foo()
  1370. Foo.__provides__ = self._makeOne(Foo, IFoo)
  1371. self.assertIs(foo.__provides__, IFoo)
  1372. def test_w_different_class(self):
  1373. from zope.interface.interface import InterfaceClass
  1374. IFoo = InterfaceClass("IFoo")
  1375. class Foo:
  1376. pass
  1377. class Bar(Foo):
  1378. pass
  1379. bar = Bar()
  1380. Foo.__provides__ = self._makeOne(Foo, IFoo)
  1381. self.assertRaises(AttributeError, getattr, Bar, '__provides__')
  1382. self.assertRaises(AttributeError, getattr, bar, '__provides__')
  1383. class ClassProvidesBaseTests(
  1384. OptimizationTestMixin,
  1385. ClassProvidesBaseFallbackTests,
  1386. SubclassableMixin,
  1387. ):
  1388. # Repeat tests for C optimizations
  1389. def _getTargetClass(self):
  1390. from zope.interface.declarations import ClassProvidesBase
  1391. return ClassProvidesBase
  1392. def _getFallbackClass(self):
  1393. # pylint:disable=no-name-in-module
  1394. from zope.interface.declarations import ClassProvidesBaseFallback
  1395. return ClassProvidesBaseFallback
  1396. class ClassProvidesTests(unittest.TestCase):
  1397. def _getTargetClass(self):
  1398. from zope.interface.declarations import ClassProvides
  1399. return ClassProvides
  1400. def _makeOne(self, *args, **kw):
  1401. return self._getTargetClass()(*args, **kw)
  1402. def test_w_simple_metaclass(self):
  1403. from zope.interface.declarations import implementer
  1404. from zope.interface.interface import InterfaceClass
  1405. IFoo = InterfaceClass("IFoo")
  1406. IBar = InterfaceClass("IBar")
  1407. @implementer(IFoo)
  1408. class Foo:
  1409. pass
  1410. cp = Foo.__provides__ = self._makeOne(Foo, type(Foo), IBar)
  1411. self.assertIs(Foo.__provides__, cp)
  1412. self.assertEqual(list(Foo().__provides__), [IFoo])
  1413. def test___reduce__(self):
  1414. from zope.interface.declarations import implementer
  1415. from zope.interface.interface import InterfaceClass
  1416. IFoo = InterfaceClass("IFoo")
  1417. IBar = InterfaceClass("IBar")
  1418. @implementer(IFoo)
  1419. class Foo:
  1420. pass
  1421. cp = Foo.__provides__ = self._makeOne(Foo, type(Foo), IBar)
  1422. self.assertEqual(cp.__reduce__(),
  1423. (type(cp), (Foo, type(Foo), IBar)))
  1424. class ClassProvidesStrictTests(ClassProvidesTests):
  1425. # Tests that require the strict C3 resolution order.
  1426. def _getTargetClass(self):
  1427. ClassProvides = super()._getTargetClass()
  1428. class StrictClassProvides(ClassProvides):
  1429. def _do_calculate_ro(self, base_mros):
  1430. return ClassProvides._do_calculate_ro(
  1431. self, base_mros=base_mros, strict=True
  1432. )
  1433. return StrictClassProvides
  1434. def test_overlapping_interfaces_corrected(self):
  1435. # Giving ClassProvides(cls, metaclass, IFace), where IFace is already
  1436. # provided by metacls, doesn't produce invalid resolution orders.
  1437. from zope.interface import Interface
  1438. from zope.interface import implementedBy
  1439. from zope.interface import implementer
  1440. class IBase(Interface):
  1441. pass
  1442. @implementer(IBase)
  1443. class metaclass(type):
  1444. pass
  1445. cls = metaclass(
  1446. 'cls',
  1447. (object,),
  1448. {}
  1449. )
  1450. spec = self._makeOne(cls, metaclass, IBase)
  1451. self.assertEqual(spec.__sro__, (
  1452. spec,
  1453. implementedBy(metaclass),
  1454. IBase,
  1455. implementedBy(type),
  1456. implementedBy(object),
  1457. Interface
  1458. ))
  1459. class TestClassProvidesRepr(unittest.TestCase):
  1460. def _getTargetClass(self):
  1461. from zope.interface.declarations import ClassProvides
  1462. return ClassProvides
  1463. def _makeOne(self, *args, **kw):
  1464. return self._getTargetClass()(*args, **kw)
  1465. def test__repr__empty(self):
  1466. inst = self._makeOne(type(self), type)
  1467. self.assertEqual(
  1468. repr(inst),
  1469. "directlyProvides(TestClassProvidesRepr)"
  1470. )
  1471. def test__repr__providing_one(self):
  1472. from zope.interface import Interface
  1473. class IFoo(Interface):
  1474. "Does nothing"
  1475. inst = self._makeOne(type(self), type, IFoo)
  1476. self.assertEqual(
  1477. repr(inst),
  1478. "directlyProvides(TestClassProvidesRepr, IFoo)"
  1479. )
  1480. def test__repr__duplicate_names(self):
  1481. from zope.interface.interface import InterfaceClass
  1482. IFoo = InterfaceClass("IFoo", __module__='mod1')
  1483. IFoo2 = InterfaceClass("IFoo", __module__='mod2')
  1484. IBaz = InterfaceClass("IBaz")
  1485. inst = self._makeOne(type(self), type, IFoo, IBaz, IFoo2)
  1486. self.assertEqual(
  1487. repr(inst),
  1488. "directlyProvides(TestClassProvidesRepr, IFoo, IBaz, mod2.IFoo)"
  1489. )
  1490. def test__repr__implementedBy(self):
  1491. from zope.interface.declarations import implementedBy
  1492. from zope.interface.declarations import implementer
  1493. from zope.interface.interface import InterfaceClass
  1494. IFoo = InterfaceClass("IFoo")
  1495. @implementer(IFoo)
  1496. class Foo:
  1497. pass
  1498. inst = implementedBy(Foo)
  1499. self.assertEqual(
  1500. repr(inst),
  1501. 'classImplements(Foo, IFoo)'
  1502. )
  1503. def test__repr__implementedBy_generic_callable(self):
  1504. from zope.interface.declarations import implementedBy
  1505. # We can't get a __name__ by default, so we get a
  1506. # module name and a question mark
  1507. class Callable:
  1508. def __call__(self):
  1509. return self
  1510. inst = implementedBy(Callable())
  1511. self.assertEqual(
  1512. repr(inst),
  1513. f'classImplements({__name__}.?)'
  1514. )
  1515. c = Callable()
  1516. c.__name__ = 'Callable'
  1517. inst = implementedBy(c)
  1518. self.assertEqual(
  1519. repr(inst),
  1520. 'classImplements(Callable)'
  1521. )
  1522. class Test_directlyProvidedBy(unittest.TestCase):
  1523. def _callFUT(self, *args, **kw):
  1524. from zope.interface.declarations import directlyProvidedBy
  1525. return directlyProvidedBy(*args, **kw)
  1526. def test_wo_declarations_in_class_or_instance(self):
  1527. class Foo:
  1528. pass
  1529. foo = Foo()
  1530. self.assertEqual(list(self._callFUT(foo)), [])
  1531. def test_w_declarations_in_class_but_not_instance(self):
  1532. from zope.interface.declarations import implementer
  1533. from zope.interface.interface import InterfaceClass
  1534. IFoo = InterfaceClass("IFoo")
  1535. @implementer(IFoo)
  1536. class Foo:
  1537. pass
  1538. foo = Foo()
  1539. self.assertEqual(list(self._callFUT(foo)), [])
  1540. def test_w_declarations_in_instance_but_not_class(self):
  1541. from zope.interface.declarations import directlyProvides
  1542. from zope.interface.interface import InterfaceClass
  1543. IFoo = InterfaceClass("IFoo")
  1544. class Foo:
  1545. pass
  1546. foo = Foo()
  1547. directlyProvides(foo, IFoo)
  1548. self.assertEqual(list(self._callFUT(foo)), [IFoo])
  1549. def test_w_declarations_in_instance_and_class(self):
  1550. from zope.interface.declarations import directlyProvides
  1551. from zope.interface.declarations import implementer
  1552. from zope.interface.interface import InterfaceClass
  1553. IFoo = InterfaceClass("IFoo")
  1554. IBar = InterfaceClass("IBar")
  1555. @implementer(IFoo)
  1556. class Foo:
  1557. pass
  1558. foo = Foo()
  1559. directlyProvides(foo, IBar)
  1560. self.assertEqual(list(self._callFUT(foo)), [IBar])
  1561. class Test_provider(unittest.TestCase):
  1562. def _getTargetClass(self):
  1563. from zope.interface.declarations import provider
  1564. return provider
  1565. def _makeOne(self, *args, **kw):
  1566. return self._getTargetClass()(*args, **kw)
  1567. def test_w_class(self):
  1568. from zope.interface.declarations import ClassProvides
  1569. from zope.interface.interface import InterfaceClass
  1570. IFoo = InterfaceClass("IFoo")
  1571. @self._makeOne(IFoo)
  1572. class Foo:
  1573. pass
  1574. self.assertIsInstance(
  1575. Foo.__provides__, ClassProvides
  1576. ) # pylint:disable=no-member
  1577. self.assertEqual(
  1578. list(Foo.__provides__), [IFoo]
  1579. ) # pylint:disable=no-member
  1580. class Test_moduleProvides(unittest.TestCase):
  1581. # pylint:disable=exec-used
  1582. def test_called_from_function(self):
  1583. from zope.interface.declarations import moduleProvides
  1584. from zope.interface.interface import InterfaceClass
  1585. IFoo = InterfaceClass("IFoo")
  1586. globs = {'__name__': '__tests__.tests.tests.foo',
  1587. 'moduleProvides': moduleProvides, 'IFoo': IFoo}
  1588. locs = {}
  1589. CODE = "\n".join([
  1590. 'def foo():',
  1591. ' moduleProvides(IFoo)'
  1592. ])
  1593. exec(CODE, globs, locs)
  1594. foo = locs['foo']
  1595. self.assertRaises(TypeError, foo)
  1596. def test_called_from_class(self):
  1597. from zope.interface.declarations import moduleProvides
  1598. from zope.interface.interface import InterfaceClass
  1599. IFoo = InterfaceClass("IFoo")
  1600. globs = {'__name__': 'zope.interface.tests.foo',
  1601. 'moduleProvides': moduleProvides, 'IFoo': IFoo}
  1602. locs = {}
  1603. CODE = "\n".join([
  1604. 'class Foo(object):',
  1605. ' moduleProvides(IFoo)',
  1606. ])
  1607. with self.assertRaises(TypeError):
  1608. exec(CODE, globs, locs)
  1609. def test_called_once_from_module_scope(self):
  1610. from zope.interface.declarations import moduleProvides
  1611. from zope.interface.interface import InterfaceClass
  1612. IFoo = InterfaceClass("IFoo")
  1613. globs = {'__name__': '__tests__.tests.tests.foo',
  1614. 'moduleProvides': moduleProvides, 'IFoo': IFoo}
  1615. CODE = "\n".join([
  1616. 'moduleProvides(IFoo)',
  1617. ])
  1618. exec(CODE, globs)
  1619. spec = globs['__provides__']
  1620. self.assertEqual(list(spec), [IFoo])
  1621. def test_called_twice_from_module_scope(self):
  1622. from zope.interface.declarations import moduleProvides
  1623. from zope.interface.interface import InterfaceClass
  1624. IFoo = InterfaceClass("IFoo")
  1625. globs = {'__name__': '__tests__.tests.tests.foo',
  1626. 'moduleProvides': moduleProvides, 'IFoo': IFoo}
  1627. CODE = "\n".join([
  1628. 'moduleProvides(IFoo)',
  1629. 'moduleProvides(IFoo)',
  1630. ])
  1631. with self.assertRaises(TypeError):
  1632. exec(CODE, globs)
  1633. class Test_getObjectSpecificationFallback(unittest.TestCase):
  1634. def _getFallbackClass(self):
  1635. # pylint:disable=no-name-in-module
  1636. from zope.interface.declarations import getObjectSpecificationFallback
  1637. return getObjectSpecificationFallback
  1638. _getTargetClass = _getFallbackClass
  1639. def _callFUT(self, *args, **kw):
  1640. return self._getTargetClass()(*args, **kw)
  1641. def test_wo_existing_provides_classless(self):
  1642. the_dict = {}
  1643. class Foo:
  1644. def __getattribute__(self, name):
  1645. # Emulate object w/o any class
  1646. if name == '__class__':
  1647. raise AttributeError(name)
  1648. try:
  1649. return the_dict[name]
  1650. except KeyError:
  1651. raise AttributeError(name)
  1652. def __setattr__(self, name, value):
  1653. raise NotImplementedError()
  1654. foo = Foo()
  1655. spec = self._callFUT(foo)
  1656. self.assertEqual(list(spec), [])
  1657. def test_existing_provides_is_spec(self):
  1658. from zope.interface.declarations import directlyProvides
  1659. from zope.interface.interface import InterfaceClass
  1660. IFoo = InterfaceClass("IFoo")
  1661. def foo():
  1662. raise NotImplementedError()
  1663. directlyProvides(foo, IFoo)
  1664. spec = self._callFUT(foo)
  1665. self.assertIs(spec, foo.__provides__) # pylint:disable=no-member
  1666. def test_existing_provides_is_not_spec(self):
  1667. def foo():
  1668. raise NotImplementedError()
  1669. foo.__provides__ = object() # not a valid spec
  1670. spec = self._callFUT(foo)
  1671. self.assertEqual(list(spec), [])
  1672. def test_existing_provides(self):
  1673. from zope.interface.declarations import directlyProvides
  1674. from zope.interface.interface import InterfaceClass
  1675. IFoo = InterfaceClass("IFoo")
  1676. class Foo:
  1677. pass
  1678. foo = Foo()
  1679. directlyProvides(foo, IFoo)
  1680. spec = self._callFUT(foo)
  1681. self.assertEqual(list(spec), [IFoo])
  1682. def test_wo_provides_on_class_w_implements(self):
  1683. from zope.interface.declarations import implementer
  1684. from zope.interface.interface import InterfaceClass
  1685. IFoo = InterfaceClass("IFoo")
  1686. @implementer(IFoo)
  1687. class Foo:
  1688. pass
  1689. foo = Foo()
  1690. spec = self._callFUT(foo)
  1691. self.assertEqual(list(spec), [IFoo])
  1692. def test_wo_provides_on_class_wo_implements(self):
  1693. class Foo:
  1694. pass
  1695. foo = Foo()
  1696. spec = self._callFUT(foo)
  1697. self.assertEqual(list(spec), [])
  1698. def test_catches_only_AttributeError_on_provides(self):
  1699. MissingSomeAttrs.test_raises(
  1700. self, self._callFUT, expected_missing='__provides__'
  1701. )
  1702. def test_catches_only_AttributeError_on_class(self):
  1703. MissingSomeAttrs.test_raises(
  1704. self,
  1705. self._callFUT,
  1706. expected_missing='__class__',
  1707. __provides__=None,
  1708. )
  1709. def test_raises_AttrError_w_provides_fails_type_check_AttrError(self):
  1710. # isinstance(ob.__provides__, SpecificationBase) is not
  1711. # protected inside any kind of block.
  1712. class Foo:
  1713. __provides__ = MissingSomeAttrs(AttributeError)
  1714. # isinstance() ignores AttributeError on __class__
  1715. self._callFUT(Foo())
  1716. def test_raises_AttrError_w_provides_fails_type_check_RuntimeError(self):
  1717. # isinstance(ob.__provides__, SpecificationBase) is not
  1718. # protected inside any kind of block.
  1719. class Foo:
  1720. __provides__ = MissingSomeAttrs(RuntimeError)
  1721. with self.assertRaises(RuntimeError) as exc:
  1722. self._callFUT(Foo())
  1723. self.assertEqual('__class__', exc.exception.args[0])
  1724. class Test_getObjectSpecification(Test_getObjectSpecificationFallback,
  1725. OptimizationTestMixin):
  1726. # Repeat tests for C optimizations
  1727. def _getTargetClass(self):
  1728. from zope.interface.declarations import getObjectSpecification
  1729. return getObjectSpecification
  1730. class Test_providedByFallback(unittest.TestCase):
  1731. def _getFallbackClass(self):
  1732. # pylint:disable=no-name-in-module
  1733. from zope.interface.declarations import providedByFallback
  1734. return providedByFallback
  1735. _getTargetClass = _getFallbackClass
  1736. def _callFUT(self, *args, **kw):
  1737. return self._getTargetClass()(*args, **kw)
  1738. def test_wo_providedBy_on_class_wo_implements(self):
  1739. class Foo:
  1740. pass
  1741. foo = Foo()
  1742. spec = self._callFUT(foo)
  1743. self.assertEqual(list(spec), [])
  1744. def test_w_providedBy_valid_spec(self):
  1745. from zope.interface.declarations import Provides
  1746. from zope.interface.interface import InterfaceClass
  1747. IFoo = InterfaceClass("IFoo")
  1748. class Foo:
  1749. pass
  1750. foo = Foo()
  1751. foo.__providedBy__ = Provides(Foo, IFoo)
  1752. spec = self._callFUT(foo)
  1753. self.assertEqual(list(spec), [IFoo])
  1754. def test_w_providedBy_invalid_spec(self):
  1755. class Foo:
  1756. pass
  1757. foo = Foo()
  1758. foo.__providedBy__ = object()
  1759. spec = self._callFUT(foo)
  1760. self.assertEqual(list(spec), [])
  1761. def test_w_providedBy_invalid_spec_class_w_implements(self):
  1762. from zope.interface.declarations import implementer
  1763. from zope.interface.interface import InterfaceClass
  1764. IFoo = InterfaceClass("IFoo")
  1765. @implementer(IFoo)
  1766. class Foo:
  1767. pass
  1768. foo = Foo()
  1769. foo.__providedBy__ = object()
  1770. spec = self._callFUT(foo)
  1771. self.assertEqual(list(spec), [IFoo])
  1772. def test_w_providedBy_invalid_spec_w_provides_no_provides_on_class(self):
  1773. class Foo:
  1774. pass
  1775. foo = Foo()
  1776. foo.__providedBy__ = object()
  1777. expected = foo.__provides__ = object()
  1778. spec = self._callFUT(foo)
  1779. self.assertIs(spec, expected)
  1780. def test_w_providedBy_invalid_spec_w_provides_diff_provides_on_class(self):
  1781. class Foo:
  1782. pass
  1783. foo = Foo()
  1784. foo.__providedBy__ = object()
  1785. expected = foo.__provides__ = object()
  1786. Foo.__provides__ = object()
  1787. spec = self._callFUT(foo)
  1788. self.assertIs(spec, expected)
  1789. def test_w_providedBy_invalid_spec_w_provides_same_provides_on_class(self):
  1790. from zope.interface.declarations import implementer
  1791. from zope.interface.interface import InterfaceClass
  1792. IFoo = InterfaceClass("IFoo")
  1793. @implementer(IFoo)
  1794. class Foo:
  1795. pass
  1796. foo = Foo()
  1797. foo.__providedBy__ = object()
  1798. foo.__provides__ = Foo.__provides__ = object()
  1799. spec = self._callFUT(foo)
  1800. self.assertEqual(list(spec), [IFoo])
  1801. def test_super_when_base_implements_interface(self):
  1802. from zope.interface import Interface
  1803. from zope.interface.declarations import implementer
  1804. class IBase(Interface):
  1805. pass
  1806. class IDerived(IBase):
  1807. pass
  1808. @implementer(IBase)
  1809. class Base:
  1810. pass
  1811. @implementer(IDerived)
  1812. class Derived(Base):
  1813. pass
  1814. derived = Derived()
  1815. self.assertEqual(list(self._callFUT(derived)), [IDerived, IBase])
  1816. sup = super(Derived, derived)
  1817. fut = self._callFUT(sup)
  1818. self.assertIsNone(fut._dependents)
  1819. self.assertEqual(list(fut), [IBase])
  1820. def test_super_when_base_doesnt_implement_interface(self):
  1821. from zope.interface import Interface
  1822. from zope.interface.declarations import implementer
  1823. class IBase(Interface):
  1824. pass
  1825. class IDerived(IBase):
  1826. pass
  1827. class Base:
  1828. pass
  1829. @implementer(IDerived)
  1830. class Derived(Base):
  1831. pass
  1832. derived = Derived()
  1833. self.assertEqual(list(self._callFUT(derived)), [IDerived])
  1834. sup = super(Derived, derived)
  1835. self.assertEqual(list(self._callFUT(sup)), [])
  1836. def test_super_when_base_is_object(self):
  1837. from zope.interface import Interface
  1838. from zope.interface.declarations import implementer
  1839. class IBase(Interface):
  1840. pass
  1841. class IDerived(IBase):
  1842. pass
  1843. @implementer(IDerived)
  1844. class Derived:
  1845. pass
  1846. derived = Derived()
  1847. self.assertEqual(list(self._callFUT(derived)), [IDerived])
  1848. sup = super(Derived, derived)
  1849. fut = self._callFUT(sup)
  1850. self.assertIsNone(fut._dependents)
  1851. self.assertEqual(list(fut), [])
  1852. def test_super_when_object_directly_provides(self):
  1853. from zope.interface import Interface
  1854. from zope.interface.declarations import directlyProvides
  1855. from zope.interface.declarations import implementer
  1856. class IBase(Interface):
  1857. pass
  1858. class IDerived(IBase):
  1859. pass
  1860. @implementer(IBase)
  1861. class Base:
  1862. pass
  1863. class Derived(Base):
  1864. pass
  1865. derived = Derived()
  1866. self.assertEqual(list(self._callFUT(derived)), [IBase])
  1867. directlyProvides(derived, IDerived)
  1868. self.assertEqual(list(self._callFUT(derived)), [IDerived, IBase])
  1869. sup = super(Derived, derived)
  1870. fut = self._callFUT(sup)
  1871. self.assertIsNone(fut._dependents)
  1872. self.assertEqual(list(fut), [IBase])
  1873. def test_super_multi_level_multi_inheritance(self):
  1874. from zope.interface import Interface
  1875. from zope.interface.declarations import implementer
  1876. class IBase(Interface):
  1877. pass
  1878. class IM1(Interface):
  1879. pass
  1880. class IM2(Interface):
  1881. pass
  1882. class IDerived(IBase):
  1883. pass
  1884. class IUnrelated(Interface):
  1885. pass
  1886. @implementer(IBase)
  1887. class Base:
  1888. pass
  1889. @implementer(IM1)
  1890. class M1(Base):
  1891. pass
  1892. @implementer(IM2)
  1893. class M2(Base):
  1894. pass
  1895. @implementer(IDerived, IUnrelated)
  1896. class Derived(M1, M2):
  1897. pass
  1898. d = Derived()
  1899. sd = super(Derived, d)
  1900. sm1 = super(M1, d)
  1901. sm2 = super(M2, d)
  1902. self.assertEqual(list(self._callFUT(d)),
  1903. [IDerived, IUnrelated, IM1, IBase, IM2])
  1904. self.assertEqual(list(self._callFUT(sd)),
  1905. [IM1, IBase, IM2])
  1906. self.assertEqual(list(self._callFUT(sm1)),
  1907. [IM2, IBase])
  1908. self.assertEqual(list(self._callFUT(sm2)),
  1909. [IBase])
  1910. def test_catches_only_AttributeError_on_providedBy(self):
  1911. MissingSomeAttrs.test_raises(self, self._callFUT,
  1912. expected_missing='__providedBy__',
  1913. __class__=object)
  1914. def test_catches_only_AttributeError_on_class(self):
  1915. # isinstance() tries to get the __class__, which is non-obvious,
  1916. # so it must be protected too.
  1917. MissingSomeAttrs.test_raises(
  1918. self, self._callFUT, expected_missing='__class__')
  1919. class Test_providedBy(Test_providedByFallback,
  1920. OptimizationTestMixin):
  1921. # Repeat tests for C optimizations
  1922. def _getTargetClass(self):
  1923. from zope.interface.declarations import providedBy
  1924. return providedBy
  1925. class ObjectSpecificationDescriptorFallbackTests(unittest.TestCase):
  1926. def _getFallbackClass(self):
  1927. # pylint:disable=no-name-in-module
  1928. from zope.interface.declarations import \
  1929. ObjectSpecificationDescriptorFallback
  1930. return ObjectSpecificationDescriptorFallback
  1931. _getTargetClass = _getFallbackClass
  1932. def _makeOne(self, *args, **kw):
  1933. return self._getTargetClass()(*args, **kw)
  1934. def test_accessed_via_class(self):
  1935. from zope.interface.declarations import Provides
  1936. from zope.interface.interface import InterfaceClass
  1937. IFoo = InterfaceClass("IFoo")
  1938. class Foo:
  1939. pass
  1940. Foo.__provides__ = Provides(Foo, IFoo)
  1941. Foo.__providedBy__ = self._makeOne()
  1942. self.assertEqual(list(Foo.__providedBy__), [IFoo])
  1943. def test_accessed_via_inst_wo_provides(self):
  1944. from zope.interface.declarations import Provides
  1945. from zope.interface.declarations import implementer
  1946. from zope.interface.interface import InterfaceClass
  1947. IFoo = InterfaceClass("IFoo")
  1948. IBar = InterfaceClass("IBar")
  1949. @implementer(IFoo)
  1950. class Foo:
  1951. pass
  1952. Foo.__provides__ = Provides(Foo, IBar)
  1953. Foo.__providedBy__ = self._makeOne()
  1954. foo = Foo()
  1955. self.assertEqual(list(foo.__providedBy__), [IFoo])
  1956. def test_accessed_via_inst_w_provides(self):
  1957. from zope.interface.declarations import Provides
  1958. from zope.interface.declarations import directlyProvides
  1959. from zope.interface.declarations import implementer
  1960. from zope.interface.interface import InterfaceClass
  1961. IFoo = InterfaceClass("IFoo")
  1962. IBar = InterfaceClass("IBar")
  1963. IBaz = InterfaceClass("IBaz")
  1964. @implementer(IFoo)
  1965. class Foo:
  1966. pass
  1967. Foo.__provides__ = Provides(Foo, IBar)
  1968. Foo.__providedBy__ = self._makeOne()
  1969. foo = Foo()
  1970. directlyProvides(foo, IBaz)
  1971. self.assertEqual(list(foo.__providedBy__), [IBaz, IFoo])
  1972. def test_arbitrary_exception_accessing_provides_not_caught(self):
  1973. class MyException(Exception):
  1974. pass
  1975. class Foo:
  1976. __providedBy__ = self._makeOne()
  1977. @property
  1978. def __provides__(self):
  1979. raise MyException
  1980. foo = Foo()
  1981. with self.assertRaises(MyException):
  1982. getattr(foo, '__providedBy__')
  1983. def test_AttributeError_accessing_provides_caught(self):
  1984. class MyException(Exception):
  1985. pass
  1986. class Foo:
  1987. __providedBy__ = self._makeOne()
  1988. @property
  1989. def __provides__(self):
  1990. raise AttributeError
  1991. foo = Foo()
  1992. provided = getattr(foo, '__providedBy__')
  1993. self.assertIsNotNone(provided)
  1994. def test_None_in__provides__overrides(self):
  1995. from zope.interface import Interface
  1996. from zope.interface import implementer
  1997. class IFoo(Interface):
  1998. pass
  1999. @implementer(IFoo)
  2000. class Foo:
  2001. @property
  2002. def __provides__(self):
  2003. return None
  2004. Foo.__providedBy__ = self._makeOne()
  2005. provided = getattr(Foo(), '__providedBy__')
  2006. self.assertIsNone(provided)
  2007. class ObjectSpecificationDescriptorTests(
  2008. ObjectSpecificationDescriptorFallbackTests,
  2009. OptimizationTestMixin,
  2010. SubclassableMixin,
  2011. ):
  2012. # Repeat tests for C optimizations
  2013. def _getTargetClass(self):
  2014. from zope.interface.declarations import ObjectSpecificationDescriptor
  2015. return ObjectSpecificationDescriptor
  2016. # Test _normalizeargs through its callers.
  2017. class _Monkey:
  2018. # context-manager for replacing module names in the scope of a test.
  2019. def __init__(self, module, **kw):
  2020. self.module = module
  2021. self.to_restore = {key: getattr(module, key) for key in kw}
  2022. for key, value in kw.items():
  2023. setattr(module, key, value)
  2024. def __enter__(self):
  2025. return self
  2026. def __exit__(self, exc_type, exc_val, exc_tb):
  2027. for key, value in self.to_restore.items():
  2028. setattr(self.module, key, value)
  2029. class _MonkeyDict:
  2030. # context-manager for restoring a dict w/in a module in the scope of a
  2031. # test.
  2032. def __init__(self, module, attrname, **kw):
  2033. self.module = module
  2034. self.target = getattr(module, attrname)
  2035. self.to_restore = self.target.copy()
  2036. self.target.clear()
  2037. self.target.update(kw)
  2038. def __enter__(self):
  2039. return self.target
  2040. def __exit__(self, exc_type, exc_val, exc_tb):
  2041. self.target.clear()
  2042. self.target.update(self.to_restore)