test_declarations.py 89 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678
  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 zope.interface._compat import _skip_under_py3k
  18. from zope.interface._compat import PYTHON3
  19. from __tests__.tests import OptimizationTestMixin
  20. from __tests__.tests import MissingSomeAttrs
  21. from __tests__.tests.test_interface import NameAndModuleComparisonTestsMixin
  22. # pylint:disable=inherit-non-class,too-many-lines,protected-access
  23. # pylint:disable=blacklisted-name,attribute-defined-outside-init
  24. class _Py3ClassAdvice(object):
  25. def _run_generated_code(self, code, globs, locs,
  26. fails_under_py3k=True,
  27. ):
  28. # pylint:disable=exec-used,no-member
  29. import warnings
  30. with warnings.catch_warnings(record=True) as log:
  31. warnings.resetwarnings()
  32. if not PYTHON3:
  33. exec(code, globs, locs)
  34. self.assertEqual(len(log), 0) # no longer warn
  35. return True
  36. try:
  37. exec(code, globs, locs)
  38. except TypeError:
  39. return False
  40. else:
  41. if fails_under_py3k:
  42. self.fail("Didn't raise TypeError")
  43. return None
  44. class NamedTests(unittest.TestCase):
  45. def test_class(self):
  46. from zope.interface.declarations import named
  47. @named(u'foo')
  48. class Foo(object):
  49. pass
  50. self.assertEqual(Foo.__component_name__, u'foo') # pylint:disable=no-member
  51. def test_function(self):
  52. from zope.interface.declarations import named
  53. @named(u'foo')
  54. def doFoo(o):
  55. raise NotImplementedError()
  56. self.assertEqual(doFoo.__component_name__, u'foo')
  57. def test_instance(self):
  58. from zope.interface.declarations import named
  59. class Foo(object):
  60. pass
  61. foo = Foo()
  62. named(u'foo')(foo)
  63. self.assertEqual(foo.__component_name__, u'foo') # 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. l = list(decl.interfaces())
  90. self.assertEqual(l, [])
  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.interface import InterfaceClass
  248. from __tests__.tests.test_ro import C3Setting
  249. from zope.interface import ro
  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 __tests__.tests.test_ro import C3Setting
  267. from zope.interface import ro
  268. class IBase(Interface):
  269. pass
  270. class IDerived(IBase):
  271. pass
  272. @implementer(IBase)
  273. class Base(object):
  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(object):
  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. class A(object):
  360. pass
  361. class B(object):
  362. pass
  363. from zope.interface.interface import InterfaceClass
  364. IFoo = InterfaceClass('IFoo')
  365. self.assertEqual(implementedBy(A), implementedBy(A))
  366. self.assertEqual(hash(implementedBy(A)), hash(implementedBy(A)))
  367. self.assertTrue(implementedBy(A) < None)
  368. self.assertTrue(None > implementedBy(A)) # pylint:disable=misplaced-comparison-constant
  369. self.assertTrue(implementedBy(A) < implementedBy(B))
  370. self.assertTrue(implementedBy(A) > IFoo)
  371. self.assertTrue(implementedBy(A) <= implementedBy(B))
  372. self.assertTrue(implementedBy(A) >= IFoo)
  373. self.assertTrue(implementedBy(A) != IFoo)
  374. def test_proxy_equality(self):
  375. # https://github.com/zopefoundation/zope.interface/issues/55
  376. class Proxy(object):
  377. def __init__(self, wrapped):
  378. self._wrapped = wrapped
  379. def __getattr__(self, name):
  380. raise NotImplementedError()
  381. def __eq__(self, other):
  382. return self._wrapped == other
  383. def __ne__(self, other):
  384. return self._wrapped != other
  385. from zope.interface.declarations import implementedBy
  386. class A(object):
  387. pass
  388. class B(object):
  389. pass
  390. implementedByA = implementedBy(A)
  391. implementedByB = implementedBy(B)
  392. proxy = Proxy(implementedByA)
  393. # The order of arguments to the operators matters,
  394. # test both
  395. self.assertTrue(implementedByA == implementedByA) # pylint:disable=comparison-with-itself
  396. self.assertTrue(implementedByA != implementedByB)
  397. self.assertTrue(implementedByB != implementedByA)
  398. self.assertTrue(proxy == implementedByA)
  399. self.assertTrue(implementedByA == proxy)
  400. self.assertFalse(proxy != implementedByA)
  401. self.assertFalse(implementedByA != proxy)
  402. self.assertTrue(proxy != implementedByB)
  403. self.assertTrue(implementedByB != proxy)
  404. def test_changed_deletes_super_cache(self):
  405. impl = self._makeOne()
  406. self.assertIsNone(impl._super_cache)
  407. self.assertNotIn('_super_cache', impl.__dict__)
  408. impl._super_cache = 42
  409. self.assertIn('_super_cache', impl.__dict__)
  410. impl.changed(None)
  411. self.assertIsNone(impl._super_cache)
  412. self.assertNotIn('_super_cache', impl.__dict__)
  413. def test_changed_does_not_add_super_cache(self):
  414. impl = self._makeOne()
  415. self.assertIsNone(impl._super_cache)
  416. self.assertNotIn('_super_cache', impl.__dict__)
  417. impl.changed(None)
  418. self.assertIsNone(impl._super_cache)
  419. self.assertNotIn('_super_cache', impl.__dict__)
  420. class Test_implementedByFallback(unittest.TestCase):
  421. def _getTargetClass(self):
  422. # pylint:disable=no-name-in-module
  423. from zope.interface.declarations import implementedByFallback
  424. return implementedByFallback
  425. _getFallbackClass = _getTargetClass
  426. def _callFUT(self, *args, **kw):
  427. return self._getTargetClass()(*args, **kw)
  428. def test_dictless_wo_existing_Implements_wo_registrations(self):
  429. class Foo(object):
  430. __slots__ = ('__implemented__',)
  431. foo = Foo()
  432. foo.__implemented__ = None
  433. self.assertEqual(list(self._callFUT(foo)), [])
  434. def test_dictless_wo_existing_Implements_cant_assign___implemented__(self):
  435. class Foo(object):
  436. def _get_impl(self):
  437. raise NotImplementedError()
  438. def _set_impl(self, val):
  439. raise TypeError
  440. __implemented__ = property(_get_impl, _set_impl)
  441. def __call__(self):
  442. # act like a factory
  443. raise NotImplementedError()
  444. foo = Foo()
  445. self.assertRaises(TypeError, self._callFUT, foo)
  446. def test_dictless_wo_existing_Implements_w_registrations(self):
  447. from zope.interface import declarations
  448. class Foo(object):
  449. __slots__ = ('__implemented__',)
  450. foo = Foo()
  451. foo.__implemented__ = None
  452. reg = object()
  453. with _MonkeyDict(declarations,
  454. 'BuiltinImplementationSpecifications') as specs:
  455. specs[foo] = reg
  456. self.assertTrue(self._callFUT(foo) is reg)
  457. def test_dictless_w_existing_Implements(self):
  458. from zope.interface.declarations import Implements
  459. impl = Implements()
  460. class Foo(object):
  461. __slots__ = ('__implemented__',)
  462. foo = Foo()
  463. foo.__implemented__ = impl
  464. self.assertTrue(self._callFUT(foo) is impl)
  465. def test_dictless_w_existing_not_Implements(self):
  466. from zope.interface.interface import InterfaceClass
  467. class Foo(object):
  468. __slots__ = ('__implemented__',)
  469. foo = Foo()
  470. IFoo = InterfaceClass('IFoo')
  471. foo.__implemented__ = (IFoo,)
  472. self.assertEqual(list(self._callFUT(foo)), [IFoo])
  473. def test_w_existing_attr_as_Implements(self):
  474. from zope.interface.declarations import Implements
  475. impl = Implements()
  476. class Foo(object):
  477. __implemented__ = impl
  478. self.assertTrue(self._callFUT(Foo) is impl)
  479. def test_builtins_added_to_cache(self):
  480. from zope.interface import declarations
  481. from zope.interface.declarations import Implements
  482. with _MonkeyDict(declarations,
  483. 'BuiltinImplementationSpecifications') as specs:
  484. self.assertEqual(list(self._callFUT(tuple)), [])
  485. self.assertEqual(list(self._callFUT(list)), [])
  486. self.assertEqual(list(self._callFUT(dict)), [])
  487. for typ in (tuple, list, dict):
  488. spec = specs[typ]
  489. self.assertIsInstance(spec, Implements)
  490. self.assertEqual(repr(spec),
  491. 'classImplements(%s)'
  492. % (typ.__name__,))
  493. def test_builtins_w_existing_cache(self):
  494. from zope.interface import declarations
  495. t_spec, l_spec, d_spec = object(), object(), object()
  496. with _MonkeyDict(declarations,
  497. 'BuiltinImplementationSpecifications') as specs:
  498. specs[tuple] = t_spec
  499. specs[list] = l_spec
  500. specs[dict] = d_spec
  501. self.assertTrue(self._callFUT(tuple) is t_spec)
  502. self.assertTrue(self._callFUT(list) is l_spec)
  503. self.assertTrue(self._callFUT(dict) is d_spec)
  504. def test_oldstyle_class_no_assertions(self):
  505. # TODO: Figure out P3 story
  506. class Foo:
  507. pass
  508. self.assertEqual(list(self._callFUT(Foo)), [])
  509. def test_no_assertions(self):
  510. # TODO: Figure out P3 story
  511. class Foo(object):
  512. pass
  513. self.assertEqual(list(self._callFUT(Foo)), [])
  514. def test_w_None_no_bases_not_factory(self):
  515. class Foo(object):
  516. __implemented__ = None
  517. foo = Foo()
  518. self.assertRaises(TypeError, self._callFUT, foo)
  519. def test_w_None_no_bases_w_factory(self):
  520. from zope.interface.declarations import objectSpecificationDescriptor
  521. class Foo(object):
  522. __implemented__ = None
  523. def __call__(self):
  524. raise NotImplementedError()
  525. foo = Foo()
  526. foo.__name__ = 'foo'
  527. spec = self._callFUT(foo)
  528. self.assertEqual(spec.__name__,
  529. '__tests__.tests.test_declarations.foo')
  530. self.assertIs(spec.inherit, foo)
  531. self.assertIs(foo.__implemented__, spec)
  532. self.assertIs(foo.__providedBy__, objectSpecificationDescriptor) # pylint:disable=no-member
  533. self.assertNotIn('__provides__', foo.__dict__)
  534. def test_w_None_no_bases_w_class(self):
  535. from zope.interface.declarations import ClassProvides
  536. class Foo(object):
  537. __implemented__ = None
  538. spec = self._callFUT(Foo)
  539. self.assertEqual(spec.__name__,
  540. '__tests__.tests.test_declarations.Foo')
  541. self.assertIs(spec.inherit, Foo)
  542. self.assertIs(Foo.__implemented__, spec)
  543. self.assertIsInstance(Foo.__providedBy__, ClassProvides) # pylint:disable=no-member
  544. self.assertIsInstance(Foo.__provides__, ClassProvides) # pylint:disable=no-member
  545. self.assertEqual(Foo.__provides__, Foo.__providedBy__) # pylint:disable=no-member
  546. def test_w_existing_Implements(self):
  547. from zope.interface.declarations import Implements
  548. impl = Implements()
  549. class Foo(object):
  550. __implemented__ = impl
  551. self.assertTrue(self._callFUT(Foo) is impl)
  552. def test_super_when_base_implements_interface(self):
  553. from zope.interface import Interface
  554. from zope.interface.declarations import implementer
  555. class IBase(Interface):
  556. pass
  557. class IDerived(IBase):
  558. pass
  559. @implementer(IBase)
  560. class Base(object):
  561. pass
  562. @implementer(IDerived)
  563. class Derived(Base):
  564. pass
  565. self.assertEqual(list(self._callFUT(Derived)), [IDerived, IBase])
  566. sup = super(Derived, Derived)
  567. self.assertEqual(list(self._callFUT(sup)), [IBase])
  568. def test_super_when_base_implements_interface_diamond(self):
  569. from zope.interface import Interface
  570. from zope.interface.declarations import implementer
  571. class IBase(Interface):
  572. pass
  573. class IDerived(IBase):
  574. pass
  575. @implementer(IBase)
  576. class Base(object):
  577. pass
  578. class Child1(Base):
  579. pass
  580. class Child2(Base):
  581. pass
  582. @implementer(IDerived)
  583. class Derived(Child1, Child2):
  584. pass
  585. self.assertEqual(list(self._callFUT(Derived)), [IDerived, IBase])
  586. sup = super(Derived, Derived)
  587. self.assertEqual(list(self._callFUT(sup)), [IBase])
  588. def test_super_when_parent_implements_interface_diamond(self):
  589. from zope.interface import Interface
  590. from zope.interface.declarations import implementer
  591. class IBase(Interface):
  592. pass
  593. class IDerived(IBase):
  594. pass
  595. class Base(object):
  596. pass
  597. class Child1(Base):
  598. pass
  599. @implementer(IBase)
  600. class Child2(Base):
  601. pass
  602. @implementer(IDerived)
  603. class Derived(Child1, Child2):
  604. pass
  605. self.assertEqual(Derived.__mro__, (Derived, Child1, Child2, Base, object))
  606. self.assertEqual(list(self._callFUT(Derived)), [IDerived, IBase])
  607. sup = super(Derived, Derived)
  608. fut = self._callFUT(sup)
  609. self.assertEqual(list(fut), [IBase])
  610. self.assertIsNone(fut._dependents)
  611. def test_super_when_base_doesnt_implement_interface(self):
  612. from zope.interface import Interface
  613. from zope.interface.declarations import implementer
  614. class IBase(Interface):
  615. pass
  616. class IDerived(IBase):
  617. pass
  618. class Base(object):
  619. pass
  620. @implementer(IDerived)
  621. class Derived(Base):
  622. pass
  623. self.assertEqual(list(self._callFUT(Derived)), [IDerived])
  624. sup = super(Derived, Derived)
  625. self.assertEqual(list(self._callFUT(sup)), [])
  626. def test_super_when_base_is_object(self):
  627. from zope.interface import Interface
  628. from zope.interface.declarations import implementer
  629. class IBase(Interface):
  630. pass
  631. class IDerived(IBase):
  632. pass
  633. @implementer(IDerived)
  634. class Derived(object):
  635. pass
  636. self.assertEqual(list(self._callFUT(Derived)), [IDerived])
  637. sup = super(Derived, Derived)
  638. self.assertEqual(list(self._callFUT(sup)), [])
  639. def test_super_multi_level_multi_inheritance(self):
  640. from zope.interface.declarations import implementer
  641. from zope.interface import Interface
  642. class IBase(Interface):
  643. pass
  644. class IM1(Interface):
  645. pass
  646. class IM2(Interface):
  647. pass
  648. class IDerived(IBase):
  649. pass
  650. class IUnrelated(Interface):
  651. pass
  652. @implementer(IBase)
  653. class Base(object):
  654. pass
  655. @implementer(IM1)
  656. class M1(Base):
  657. pass
  658. @implementer(IM2)
  659. class M2(Base):
  660. pass
  661. @implementer(IDerived, IUnrelated)
  662. class Derived(M1, M2):
  663. pass
  664. d = Derived
  665. sd = super(Derived, Derived)
  666. sm1 = super(M1, Derived)
  667. sm2 = super(M2, Derived)
  668. self.assertEqual(list(self._callFUT(d)),
  669. [IDerived, IUnrelated, IM1, IBase, IM2])
  670. self.assertEqual(list(self._callFUT(sd)),
  671. [IM1, IBase, IM2])
  672. self.assertEqual(list(self._callFUT(sm1)),
  673. [IM2, IBase])
  674. self.assertEqual(list(self._callFUT(sm2)),
  675. [IBase])
  676. class Test_implementedBy(Test_implementedByFallback,
  677. OptimizationTestMixin):
  678. # Repeat tests for C optimizations
  679. def _getTargetClass(self):
  680. from zope.interface.declarations import implementedBy
  681. return implementedBy
  682. class _ImplementsTestMixin(object):
  683. FUT_SETS_PROVIDED_BY = True
  684. def _callFUT(self, cls, iface):
  685. # Declare that *cls* implements *iface*; return *cls*
  686. raise NotImplementedError
  687. def _check_implementer(self, Foo,
  688. orig_spec=None,
  689. spec_name=__name__ + '.Foo',
  690. inherit="not given"):
  691. from zope.interface.declarations import ClassProvides
  692. from zope.interface.interface import InterfaceClass
  693. IFoo = InterfaceClass('IFoo')
  694. returned = self._callFUT(Foo, IFoo)
  695. self.assertIs(returned, Foo)
  696. spec = Foo.__implemented__
  697. if orig_spec is not None:
  698. self.assertIs(spec, orig_spec)
  699. self.assertEqual(spec.__name__,
  700. spec_name)
  701. inherit = Foo if inherit == "not given" else inherit
  702. self.assertIs(spec.inherit, inherit)
  703. self.assertIs(Foo.__implemented__, spec)
  704. if self.FUT_SETS_PROVIDED_BY:
  705. self.assertIsInstance(Foo.__providedBy__, ClassProvides)
  706. self.assertIsInstance(Foo.__provides__, ClassProvides)
  707. self.assertEqual(Foo.__provides__, Foo.__providedBy__)
  708. return Foo, IFoo
  709. def test_oldstyle_class(self):
  710. # This only matters on Python 2
  711. class Foo:
  712. pass
  713. self._check_implementer(Foo)
  714. def test_newstyle_class(self):
  715. class Foo(object):
  716. pass
  717. self._check_implementer(Foo)
  718. class Test_classImplementsOnly(_ImplementsTestMixin, unittest.TestCase):
  719. FUT_SETS_PROVIDED_BY = False
  720. def _callFUT(self, cls, iface):
  721. from zope.interface.declarations import classImplementsOnly
  722. classImplementsOnly(cls, iface)
  723. return cls
  724. def test_w_existing_Implements(self):
  725. from zope.interface.declarations import Implements
  726. from zope.interface.interface import InterfaceClass
  727. IFoo = InterfaceClass('IFoo')
  728. IBar = InterfaceClass('IBar')
  729. impl = Implements(IFoo)
  730. impl.declared = (IFoo,)
  731. class Foo(object):
  732. __implemented__ = impl
  733. impl.inherit = Foo
  734. self._callFUT(Foo, IBar)
  735. # Same spec, now different values
  736. self.assertTrue(Foo.__implemented__ is impl)
  737. self.assertEqual(impl.inherit, None)
  738. self.assertEqual(impl.declared, (IBar,))
  739. def test_oldstyle_class(self):
  740. from zope.interface.declarations import Implements
  741. from zope.interface.interface import InterfaceClass
  742. IBar = InterfaceClass('IBar')
  743. old_spec = Implements(IBar)
  744. class Foo:
  745. __implemented__ = old_spec
  746. self._check_implementer(Foo, old_spec, '?', inherit=None)
  747. def test_newstyle_class(self):
  748. from zope.interface.declarations import Implements
  749. from zope.interface.interface import InterfaceClass
  750. IBar = InterfaceClass('IBar')
  751. old_spec = Implements(IBar)
  752. class Foo(object):
  753. __implemented__ = old_spec
  754. self._check_implementer(Foo, old_spec, '?', inherit=None)
  755. def test_redundant_with_super_still_implements(self):
  756. Base, IBase = self._check_implementer(
  757. type('Foo', (object,), {}),
  758. inherit=None,
  759. )
  760. class Child(Base):
  761. pass
  762. self._callFUT(Child, IBase)
  763. self.assertTrue(IBase.implementedBy(Child))
  764. class Test_classImplements(_ImplementsTestMixin, unittest.TestCase):
  765. def _callFUT(self, cls, iface):
  766. from zope.interface.declarations import classImplements
  767. result = classImplements(cls, iface) # pylint:disable=assignment-from-no-return
  768. self.assertIsNone(result)
  769. return cls
  770. def __check_implementer_redundant(self, Base):
  771. # If we @implementer exactly what was already present, we write
  772. # no declared attributes on the parent (we still set everything, though)
  773. Base, IBase = self._check_implementer(Base)
  774. class Child(Base):
  775. pass
  776. returned = self._callFUT(Child, IBase)
  777. self.assertIn('__implemented__', returned.__dict__)
  778. self.assertNotIn('__providedBy__', returned.__dict__)
  779. self.assertIn('__provides__', returned.__dict__)
  780. spec = Child.__implemented__
  781. self.assertEqual(spec.declared, ())
  782. self.assertEqual(spec.inherit, Child)
  783. self.assertTrue(IBase.providedBy(Child()))
  784. def test_redundant_implementer_empty_class_declarations_newstyle(self):
  785. self.__check_implementer_redundant(type('Foo', (object,), {}))
  786. def test_redundant_implementer_empty_class_declarations_oldstyle(self):
  787. # This only matters on Python 2
  788. class Foo:
  789. pass
  790. self.__check_implementer_redundant(Foo)
  791. def test_redundant_implementer_Interface(self):
  792. from zope.interface import Interface
  793. from zope.interface import implementedBy
  794. from zope.interface import ro
  795. from __tests__.tests.test_ro import C3Setting
  796. class Foo(object):
  797. pass
  798. with C3Setting(ro.C3.STRICT_IRO, False):
  799. self._callFUT(Foo, Interface)
  800. self.assertEqual(list(implementedBy(Foo)), [Interface])
  801. class Baz(Foo):
  802. pass
  803. self._callFUT(Baz, Interface)
  804. self.assertEqual(list(implementedBy(Baz)), [Interface])
  805. def _order_for_two(self, applied_first, applied_second):
  806. return (applied_first, applied_second)
  807. def test_w_existing_Implements(self):
  808. from zope.interface.declarations import Implements
  809. from zope.interface.interface import InterfaceClass
  810. IFoo = InterfaceClass('IFoo')
  811. IBar = InterfaceClass('IBar')
  812. impl = Implements(IFoo)
  813. impl.declared = (IFoo,)
  814. class Foo(object):
  815. __implemented__ = impl
  816. impl.inherit = Foo
  817. self._callFUT(Foo, IBar)
  818. # Same spec, now different values
  819. self.assertIs(Foo.__implemented__, impl)
  820. self.assertEqual(impl.inherit, Foo)
  821. self.assertEqual(impl.declared,
  822. self._order_for_two(IFoo, IBar))
  823. def test_w_existing_Implements_w_bases(self):
  824. from zope.interface.declarations import Implements
  825. from zope.interface.interface import InterfaceClass
  826. IRoot = InterfaceClass('IRoot')
  827. ISecondRoot = InterfaceClass('ISecondRoot')
  828. IExtendsRoot = InterfaceClass('IExtendsRoot', (IRoot,))
  829. impl_root = Implements.named('Root', IRoot)
  830. impl_root.declared = (IRoot,)
  831. class Root1(object):
  832. __implemented__ = impl_root
  833. class Root2(object):
  834. __implemented__ = impl_root
  835. impl_extends_root = Implements.named('ExtendsRoot1', IExtendsRoot)
  836. impl_extends_root.declared = (IExtendsRoot,)
  837. class ExtendsRoot(Root1, Root2):
  838. __implemented__ = impl_extends_root
  839. impl_extends_root.inherit = ExtendsRoot
  840. self._callFUT(ExtendsRoot, ISecondRoot)
  841. # Same spec, now different values
  842. self.assertIs(ExtendsRoot.__implemented__, impl_extends_root)
  843. self.assertEqual(impl_extends_root.inherit, ExtendsRoot)
  844. self.assertEqual(impl_extends_root.declared,
  845. self._order_for_two(IExtendsRoot, ISecondRoot,))
  846. self.assertEqual(impl_extends_root.__bases__,
  847. self._order_for_two(IExtendsRoot, ISecondRoot) + (impl_root,))
  848. class Test_classImplementsFirst(Test_classImplements):
  849. def _callFUT(self, cls, iface):
  850. from zope.interface.declarations import classImplementsFirst
  851. result = classImplementsFirst(cls, iface) # pylint:disable=assignment-from-no-return
  852. self.assertIsNone(result)
  853. return cls
  854. def _order_for_two(self, applied_first, applied_second):
  855. return (applied_second, applied_first)
  856. class Test__implements_advice(unittest.TestCase):
  857. def _callFUT(self, *args, **kw):
  858. from zope.interface.declarations import _implements_advice
  859. return _implements_advice(*args, **kw)
  860. def test_no_existing_implements(self):
  861. from zope.interface.declarations import classImplements
  862. from zope.interface.declarations import Implements
  863. from zope.interface.interface import InterfaceClass
  864. IFoo = InterfaceClass('IFoo')
  865. class Foo(object):
  866. __implements_advice_data__ = ((IFoo,), classImplements)
  867. self._callFUT(Foo)
  868. self.assertNotIn('__implements_advice_data__', Foo.__dict__)
  869. self.assertIsInstance(Foo.__implemented__, Implements) # pylint:disable=no-member
  870. self.assertEqual(list(Foo.__implemented__), [IFoo]) # pylint:disable=no-member
  871. class Test_implementer(Test_classImplements):
  872. def _getTargetClass(self):
  873. from zope.interface.declarations import implementer
  874. return implementer
  875. def _makeOne(self, *args, **kw):
  876. return self._getTargetClass()(*args, **kw)
  877. def _callFUT(self, cls, *ifaces):
  878. decorator = self._makeOne(*ifaces)
  879. return decorator(cls)
  880. def test_nonclass_cannot_assign_attr(self):
  881. from zope.interface.interface import InterfaceClass
  882. IFoo = InterfaceClass('IFoo')
  883. decorator = self._makeOne(IFoo)
  884. self.assertRaises(TypeError, decorator, object())
  885. def test_nonclass_can_assign_attr(self):
  886. from zope.interface.interface import InterfaceClass
  887. IFoo = InterfaceClass('IFoo')
  888. class Foo(object):
  889. pass
  890. foo = Foo()
  891. decorator = self._makeOne(IFoo)
  892. returned = decorator(foo)
  893. self.assertTrue(returned is foo)
  894. spec = foo.__implemented__ # pylint:disable=no-member
  895. self.assertEqual(spec.__name__, '__tests__.tests.test_declarations.?')
  896. self.assertIsNone(spec.inherit,)
  897. self.assertIs(foo.__implemented__, spec) # pylint:disable=no-member
  898. def test_does_not_leak_on_unique_classes(self):
  899. # Make sure nothing is hanging on to the class or Implements
  900. # object after they go out of scope. There was briefly a bug
  901. # in 5.x that caused SpecificationBase._bases (in C) to not be
  902. # traversed or cleared.
  903. # https://github.com/zopefoundation/zope.interface/issues/216
  904. import gc
  905. from zope.interface.interface import InterfaceClass
  906. IFoo = InterfaceClass('IFoo')
  907. begin_count = len(gc.get_objects())
  908. for _ in range(1900):
  909. class TestClass(object):
  910. pass
  911. self._callFUT(TestClass, IFoo)
  912. gc.collect()
  913. end_count = len(gc.get_objects())
  914. # How many new objects might still be around? In all currently
  915. # tested interpreters, there aren't any, so our counts should
  916. # match exactly. When the bug existed, in a steady state, the loop
  917. # would grow by two objects each iteration
  918. fudge_factor = 0
  919. self.assertLessEqual(end_count, begin_count + fudge_factor)
  920. class Test_implementer_only(Test_classImplementsOnly):
  921. def _getTargetClass(self):
  922. from zope.interface.declarations import implementer_only
  923. return implementer_only
  924. def _makeOne(self, *args, **kw):
  925. return self._getTargetClass()(*args, **kw)
  926. def _callFUT(self, cls, iface):
  927. decorator = self._makeOne(iface)
  928. return decorator(cls)
  929. def test_function(self):
  930. from zope.interface.interface import InterfaceClass
  931. IFoo = InterfaceClass('IFoo')
  932. decorator = self._makeOne(IFoo)
  933. def _function():
  934. raise NotImplementedError()
  935. self.assertRaises(ValueError, decorator, _function)
  936. def test_method(self):
  937. from zope.interface.interface import InterfaceClass
  938. IFoo = InterfaceClass('IFoo')
  939. decorator = self._makeOne(IFoo)
  940. class Bar:
  941. def _method(self):
  942. raise NotImplementedError()
  943. self.assertRaises(ValueError, decorator, Bar._method)
  944. # Test '_implements' by way of 'implements{,Only}', its only callers.
  945. class Test_implementsOnly(unittest.TestCase, _Py3ClassAdvice):
  946. def test_simple(self):
  947. import warnings
  948. from zope.interface.declarations import implementsOnly
  949. from zope.interface.interface import InterfaceClass
  950. IFoo = InterfaceClass("IFoo")
  951. globs = {'implementsOnly': implementsOnly,
  952. 'IFoo': IFoo,
  953. }
  954. locs = {}
  955. CODE = "\n".join([
  956. 'class Foo(object):'
  957. ' implementsOnly(IFoo)',
  958. ])
  959. with warnings.catch_warnings(record=True) as log:
  960. warnings.resetwarnings()
  961. try:
  962. exec(CODE, globs, locs) # pylint:disable=exec-used
  963. except TypeError:
  964. self.assertTrue(PYTHON3, "Must be Python 3")
  965. else:
  966. if PYTHON3:
  967. self.fail("Didn't raise TypeError")
  968. Foo = locs['Foo']
  969. spec = Foo.__implemented__
  970. self.assertEqual(list(spec), [IFoo])
  971. self.assertEqual(len(log), 0) # no longer warn
  972. def test_called_once_from_class_w_bases(self):
  973. from zope.interface.declarations import implements
  974. from zope.interface.declarations import implementsOnly
  975. from zope.interface.interface import InterfaceClass
  976. IFoo = InterfaceClass("IFoo")
  977. IBar = InterfaceClass("IBar")
  978. globs = {'implements': implements,
  979. 'implementsOnly': implementsOnly,
  980. 'IFoo': IFoo,
  981. 'IBar': IBar,
  982. }
  983. locs = {}
  984. CODE = "\n".join([
  985. 'class Foo(object):',
  986. ' implements(IFoo)',
  987. 'class Bar(Foo):'
  988. ' implementsOnly(IBar)',
  989. ])
  990. if self._run_generated_code(CODE, globs, locs):
  991. Bar = locs['Bar']
  992. spec = Bar.__implemented__
  993. self.assertEqual(list(spec), [IBar])
  994. class Test_implements(unittest.TestCase, _Py3ClassAdvice):
  995. def test_called_from_function(self):
  996. import warnings
  997. from zope.interface.declarations import implements
  998. from zope.interface.interface import InterfaceClass
  999. IFoo = InterfaceClass("IFoo")
  1000. globs = {'implements': implements, 'IFoo': IFoo}
  1001. locs = {}
  1002. CODE = "\n".join([
  1003. 'def foo():',
  1004. ' implements(IFoo)'
  1005. ])
  1006. if self._run_generated_code(CODE, globs, locs, False):
  1007. foo = locs['foo']
  1008. with warnings.catch_warnings(record=True) as log:
  1009. warnings.resetwarnings()
  1010. self.assertRaises(TypeError, foo)
  1011. self.assertEqual(len(log), 0) # no longer warn
  1012. def test_called_twice_from_class(self):
  1013. import warnings
  1014. from zope.interface.declarations import implements
  1015. from zope.interface.interface import InterfaceClass
  1016. IFoo = InterfaceClass("IFoo")
  1017. IBar = InterfaceClass("IBar")
  1018. globs = {'implements': implements, 'IFoo': IFoo, 'IBar': IBar}
  1019. locs = {}
  1020. CODE = "\n".join([
  1021. 'class Foo(object):',
  1022. ' implements(IFoo)',
  1023. ' implements(IBar)',
  1024. ])
  1025. with warnings.catch_warnings(record=True) as log:
  1026. warnings.resetwarnings()
  1027. try:
  1028. exec(CODE, globs, locs) # pylint:disable=exec-used
  1029. except TypeError:
  1030. if not PYTHON3:
  1031. self.assertEqual(len(log), 0) # no longer warn
  1032. else:
  1033. self.fail("Didn't raise TypeError")
  1034. def test_called_once_from_class(self):
  1035. from zope.interface.declarations import implements
  1036. from zope.interface.interface import InterfaceClass
  1037. IFoo = InterfaceClass("IFoo")
  1038. globs = {'implements': implements, 'IFoo': IFoo}
  1039. locs = {}
  1040. CODE = "\n".join([
  1041. 'class Foo(object):',
  1042. ' implements(IFoo)',
  1043. ])
  1044. if self._run_generated_code(CODE, globs, locs):
  1045. Foo = locs['Foo']
  1046. spec = Foo.__implemented__
  1047. self.assertEqual(list(spec), [IFoo])
  1048. class ProvidesClassTests(unittest.TestCase):
  1049. def _getTargetClass(self):
  1050. from zope.interface.declarations import ProvidesClass
  1051. return ProvidesClass
  1052. def _makeOne(self, *args, **kw):
  1053. return self._getTargetClass()(*args, **kw)
  1054. def test_simple_class_one_interface(self):
  1055. from zope.interface.interface import InterfaceClass
  1056. IFoo = InterfaceClass("IFoo")
  1057. class Foo(object):
  1058. pass
  1059. spec = self._makeOne(Foo, IFoo)
  1060. self.assertEqual(list(spec), [IFoo])
  1061. def test___reduce__(self):
  1062. from zope.interface.declarations import Provides # the function
  1063. from zope.interface.interface import InterfaceClass
  1064. IFoo = InterfaceClass("IFoo")
  1065. class Foo(object):
  1066. pass
  1067. spec = self._makeOne(Foo, IFoo)
  1068. klass, args = spec.__reduce__()
  1069. self.assertIs(klass, Provides)
  1070. self.assertEqual(args, (Foo, IFoo))
  1071. def test___get___class(self):
  1072. from zope.interface.interface import InterfaceClass
  1073. IFoo = InterfaceClass("IFoo")
  1074. class Foo(object):
  1075. pass
  1076. spec = self._makeOne(Foo, IFoo)
  1077. Foo.__provides__ = spec
  1078. self.assertIs(Foo.__provides__, spec)
  1079. def test___get___instance(self):
  1080. from zope.interface.interface import InterfaceClass
  1081. IFoo = InterfaceClass("IFoo")
  1082. class Foo(object):
  1083. pass
  1084. spec = self._makeOne(Foo, IFoo)
  1085. Foo.__provides__ = spec
  1086. def _test():
  1087. foo = Foo()
  1088. return foo.__provides__
  1089. self.assertRaises(AttributeError, _test)
  1090. class ProvidesClassStrictTests(ProvidesClassTests):
  1091. # Tests that require the strict C3 resolution order.
  1092. def _getTargetClass(self):
  1093. ProvidesClass = super(ProvidesClassStrictTests, self)._getTargetClass()
  1094. class StrictProvides(ProvidesClass):
  1095. def _do_calculate_ro(self, base_mros):
  1096. return ProvidesClass._do_calculate_ro(self, base_mros=base_mros, strict=True)
  1097. return StrictProvides
  1098. def test_overlapping_interfaces_corrected(self):
  1099. # Giving Provides(cls, IFace), where IFace is already
  1100. # provided by cls, doesn't produce invalid resolution orders.
  1101. from zope.interface import implementedBy
  1102. from zope.interface import Interface
  1103. from zope.interface import implementer
  1104. class IBase(Interface):
  1105. pass
  1106. @implementer(IBase)
  1107. class Base(object):
  1108. pass
  1109. spec = self._makeOne(Base, IBase)
  1110. self.assertEqual(spec.__sro__, (
  1111. spec,
  1112. implementedBy(Base),
  1113. IBase,
  1114. implementedBy(object),
  1115. Interface
  1116. ))
  1117. class TestProvidesClassRepr(unittest.TestCase):
  1118. def _getTargetClass(self):
  1119. from zope.interface.declarations import ProvidesClass
  1120. return ProvidesClass
  1121. def _makeOne(self, *args, **kw):
  1122. return self._getTargetClass()(*args, **kw)
  1123. def test__repr__(self):
  1124. from zope.interface.interface import InterfaceClass
  1125. IFoo = InterfaceClass("IFoo")
  1126. assert IFoo.__name__ == 'IFoo'
  1127. assert IFoo.__module__ == __name__
  1128. assert repr(IFoo) == '<InterfaceClass %s.IFoo>' % (__name__,)
  1129. IBar = InterfaceClass("IBar")
  1130. inst = self._makeOne(type(self), IFoo, IBar)
  1131. self.assertEqual(
  1132. repr(inst),
  1133. "directlyProvides(TestProvidesClassRepr, IFoo, IBar)"
  1134. )
  1135. def test__repr__module_provides_typical_use(self):
  1136. # as created through a ``moduleProvides()`` statement
  1137. # in a module body
  1138. from __tests__.tests import dummy
  1139. provides = dummy.__provides__ # pylint:disable=no-member
  1140. self.assertEqual(
  1141. repr(provides),
  1142. "directlyProvides(sys.modules['__tests__.tests.dummy'], IDummyModule)"
  1143. )
  1144. def test__repr__module_after_pickle(self):
  1145. # It doesn't matter, these objects can't be pickled.
  1146. import pickle
  1147. from __tests__.tests import dummy
  1148. provides = dummy.__provides__ # pylint:disable=no-member
  1149. for proto in range(pickle.HIGHEST_PROTOCOL + 1):
  1150. with self.assertRaises(pickle.PicklingError):
  1151. pickle.dumps(provides, proto)
  1152. def test__repr__directlyProvides_module(self):
  1153. import sys
  1154. from __tests__.tests import dummy
  1155. from zope.interface.declarations import directlyProvides
  1156. from zope.interface.declarations import alsoProvides
  1157. from zope.interface.interface import InterfaceClass
  1158. IFoo = InterfaceClass('IFoo')
  1159. IBar = InterfaceClass('IBar')
  1160. orig_provides = dummy.__provides__ # pylint:disable=no-member
  1161. del dummy.__provides__ # pylint:disable=no-member
  1162. self.addCleanup(setattr, dummy, '__provides__', orig_provides)
  1163. directlyProvides(dummy, IFoo)
  1164. provides = dummy.__provides__ # pylint:disable=no-member
  1165. self.assertEqual(
  1166. repr(provides),
  1167. "directlyProvides(sys.modules['__tests__.tests.dummy'], IFoo)"
  1168. )
  1169. alsoProvides(dummy, IBar)
  1170. provides = dummy.__provides__ # pylint:disable=no-member
  1171. self.assertEqual(
  1172. repr(provides),
  1173. "directlyProvides(sys.modules['__tests__.tests.dummy'], IFoo, IBar)"
  1174. )
  1175. # If we make this module also provide IFoo and IBar, then the repr
  1176. # lists both names.
  1177. my_module = sys.modules[__name__]
  1178. assert not hasattr(my_module, '__provides__')
  1179. directlyProvides(my_module, IFoo, IBar)
  1180. self.addCleanup(delattr, my_module, '__provides__')
  1181. self.assertIs(my_module.__provides__, provides)
  1182. self.assertEqual(
  1183. repr(provides),
  1184. "directlyProvides(('__tests__.tests.dummy', "
  1185. "'__tests__.tests.test_declarations'), "
  1186. "IFoo, IBar)"
  1187. )
  1188. def test__repr__module_provides_cached_shared(self):
  1189. from zope.interface.interface import InterfaceClass
  1190. from zope.interface.declarations import ModuleType
  1191. IFoo = InterfaceClass("IFoo")
  1192. inst = self._makeOne(ModuleType, IFoo)
  1193. inst._v_module_names += ('some.module',)
  1194. inst._v_module_names += ('another.module',)
  1195. self.assertEqual(
  1196. repr(inst),
  1197. "directlyProvides(('some.module', 'another.module'), IFoo)"
  1198. )
  1199. def test__repr__duplicate_names(self):
  1200. from zope.interface.interface import InterfaceClass
  1201. IFoo = InterfaceClass("IFoo", __module__='mod1')
  1202. IFoo2 = InterfaceClass("IFoo", __module__='mod2')
  1203. IBaz = InterfaceClass("IBaz")
  1204. inst = self._makeOne(type(self), IFoo, IBaz, IFoo2)
  1205. self.assertEqual(
  1206. repr(inst),
  1207. "directlyProvides(TestProvidesClassRepr, IFoo, IBaz, mod2.IFoo)"
  1208. )
  1209. def test__repr__implementedBy_in_interfaces(self):
  1210. from zope.interface import Interface
  1211. from zope.interface import implementedBy
  1212. class IFoo(Interface):
  1213. "Does nothing"
  1214. class Bar(object):
  1215. "Does nothing"
  1216. impl = implementedBy(type(self))
  1217. inst = self._makeOne(Bar, IFoo, impl)
  1218. self.assertEqual(
  1219. repr(inst),
  1220. 'directlyProvides(Bar, IFoo, classImplements(TestProvidesClassRepr))'
  1221. )
  1222. def test__repr__empty_interfaces(self):
  1223. inst = self._makeOne(type(self))
  1224. self.assertEqual(
  1225. repr(inst),
  1226. 'directlyProvides(TestProvidesClassRepr)',
  1227. )
  1228. def test__repr__non_class(self):
  1229. class Object(object):
  1230. __bases__ = ()
  1231. __str__ = lambda _: self.fail("Should not call str")
  1232. def __repr__(self):
  1233. return '<Object>'
  1234. inst = self._makeOne(Object())
  1235. self.assertEqual(
  1236. repr(inst),
  1237. 'directlyProvides(<Object>)',
  1238. )
  1239. def test__repr__providedBy_from_class(self):
  1240. from zope.interface.declarations import implementer
  1241. from zope.interface.declarations import providedBy
  1242. from zope.interface.interface import InterfaceClass
  1243. IFoo = InterfaceClass("IFoo")
  1244. @implementer(IFoo)
  1245. class Foo(object):
  1246. pass
  1247. inst = providedBy(Foo())
  1248. self.assertEqual(
  1249. repr(inst),
  1250. 'classImplements(Foo, IFoo)'
  1251. )
  1252. def test__repr__providedBy_alsoProvides(self):
  1253. from zope.interface.declarations import implementer
  1254. from zope.interface.declarations import providedBy
  1255. from zope.interface.declarations import alsoProvides
  1256. from zope.interface.interface import InterfaceClass
  1257. IFoo = InterfaceClass("IFoo")
  1258. IBar = InterfaceClass("IBar")
  1259. @implementer(IFoo)
  1260. class Foo(object):
  1261. pass
  1262. foo = Foo()
  1263. alsoProvides(foo, IBar)
  1264. inst = providedBy(foo)
  1265. self.assertEqual(
  1266. repr(inst),
  1267. "directlyProvides(Foo, IBar, classImplements(Foo, IFoo))"
  1268. )
  1269. class Test_Provides(unittest.TestCase):
  1270. def _callFUT(self, *args, **kw):
  1271. from zope.interface.declarations import Provides
  1272. return Provides(*args, **kw)
  1273. def test_no_cached_spec(self):
  1274. from zope.interface import declarations
  1275. from zope.interface.interface import InterfaceClass
  1276. IFoo = InterfaceClass("IFoo")
  1277. cache = {}
  1278. class Foo(object):
  1279. pass
  1280. with _Monkey(declarations, InstanceDeclarations=cache):
  1281. spec = self._callFUT(Foo, IFoo)
  1282. self.assertEqual(list(spec), [IFoo])
  1283. self.assertTrue(cache[(Foo, IFoo)] is spec)
  1284. def test_w_cached_spec(self):
  1285. from zope.interface import declarations
  1286. from zope.interface.interface import InterfaceClass
  1287. IFoo = InterfaceClass("IFoo")
  1288. prior = object()
  1289. class Foo(object):
  1290. pass
  1291. cache = {(Foo, IFoo): prior}
  1292. with _Monkey(declarations, InstanceDeclarations=cache):
  1293. spec = self._callFUT(Foo, IFoo)
  1294. self.assertTrue(spec is prior)
  1295. class Test_directlyProvides(unittest.TestCase):
  1296. def _callFUT(self, *args, **kw):
  1297. from zope.interface.declarations import directlyProvides
  1298. return directlyProvides(*args, **kw)
  1299. def test_w_normal_object(self):
  1300. from zope.interface.declarations import ProvidesClass
  1301. from zope.interface.interface import InterfaceClass
  1302. IFoo = InterfaceClass("IFoo")
  1303. class Foo(object):
  1304. pass
  1305. obj = Foo()
  1306. self._callFUT(obj, IFoo)
  1307. self.assertIsInstance(obj.__provides__, ProvidesClass) # pylint:disable=no-member
  1308. self.assertEqual(list(obj.__provides__), [IFoo]) # pylint:disable=no-member
  1309. def test_w_class(self):
  1310. from zope.interface.declarations import ClassProvides
  1311. from zope.interface.interface import InterfaceClass
  1312. IFoo = InterfaceClass("IFoo")
  1313. class Foo(object):
  1314. pass
  1315. self._callFUT(Foo, IFoo)
  1316. self.assertIsInstance(Foo.__provides__, ClassProvides) # pylint:disable=no-member
  1317. self.assertEqual(list(Foo.__provides__), [IFoo]) # pylint:disable=no-member
  1318. @_skip_under_py3k
  1319. def test_w_non_descriptor_aware_metaclass(self):
  1320. # There are no non-descriptor-aware types in Py3k
  1321. from zope.interface.interface import InterfaceClass
  1322. IFoo = InterfaceClass("IFoo")
  1323. class MetaClass(type):
  1324. def __getattribute__(cls, name):
  1325. # Emulate metaclass whose base is not the type object.
  1326. if name == '__class__':
  1327. return cls
  1328. # Under certain circumstances, the implementedByFallback
  1329. # can get here for __dict__
  1330. return type.__getattribute__(cls, name) # pragma: no cover
  1331. class Foo(object):
  1332. __metaclass__ = MetaClass
  1333. obj = Foo()
  1334. self.assertRaises(TypeError, self._callFUT, obj, IFoo)
  1335. def test_w_classless_object(self):
  1336. from zope.interface.declarations import ProvidesClass
  1337. from zope.interface.interface import InterfaceClass
  1338. IFoo = InterfaceClass("IFoo")
  1339. the_dict = {}
  1340. class Foo(object):
  1341. def __getattribute__(self, name):
  1342. # Emulate object w/o any class
  1343. if name == '__class__':
  1344. return None
  1345. raise NotImplementedError(name)
  1346. def __setattr__(self, name, value):
  1347. the_dict[name] = value
  1348. obj = Foo()
  1349. self._callFUT(obj, IFoo)
  1350. self.assertIsInstance(the_dict['__provides__'], ProvidesClass)
  1351. self.assertEqual(list(the_dict['__provides__']), [IFoo])
  1352. class Test_alsoProvides(unittest.TestCase):
  1353. def _callFUT(self, *args, **kw):
  1354. from zope.interface.declarations import alsoProvides
  1355. return alsoProvides(*args, **kw)
  1356. def test_wo_existing_provides(self):
  1357. from zope.interface.declarations import ProvidesClass
  1358. from zope.interface.interface import InterfaceClass
  1359. IFoo = InterfaceClass("IFoo")
  1360. class Foo(object):
  1361. pass
  1362. obj = Foo()
  1363. self._callFUT(obj, IFoo)
  1364. self.assertIsInstance(obj.__provides__, ProvidesClass) # pylint:disable=no-member
  1365. self.assertEqual(list(obj.__provides__), [IFoo]) # pylint:disable=no-member
  1366. def test_w_existing_provides(self):
  1367. from zope.interface.declarations import directlyProvides
  1368. from zope.interface.declarations import ProvidesClass
  1369. from zope.interface.interface import InterfaceClass
  1370. IFoo = InterfaceClass("IFoo")
  1371. IBar = InterfaceClass("IBar")
  1372. class Foo(object):
  1373. pass
  1374. obj = Foo()
  1375. directlyProvides(obj, IFoo)
  1376. self._callFUT(obj, IBar)
  1377. self.assertIsInstance(obj.__provides__, ProvidesClass) # pylint:disable=no-member
  1378. self.assertEqual(list(obj.__provides__), [IFoo, IBar]) # pylint:disable=no-member
  1379. class Test_noLongerProvides(unittest.TestCase):
  1380. def _callFUT(self, *args, **kw):
  1381. from zope.interface.declarations import noLongerProvides
  1382. return noLongerProvides(*args, **kw)
  1383. def test_wo_existing_provides(self):
  1384. from zope.interface.interface import InterfaceClass
  1385. IFoo = InterfaceClass("IFoo")
  1386. class Foo(object):
  1387. pass
  1388. obj = Foo()
  1389. self._callFUT(obj, IFoo)
  1390. self.assertEqual(list(obj.__provides__), []) # pylint:disable=no-member
  1391. def test_w_existing_provides_hit(self):
  1392. from zope.interface.declarations import directlyProvides
  1393. from zope.interface.interface import InterfaceClass
  1394. IFoo = InterfaceClass("IFoo")
  1395. class Foo(object):
  1396. pass
  1397. obj = Foo()
  1398. directlyProvides(obj, IFoo)
  1399. self._callFUT(obj, IFoo)
  1400. self.assertEqual(list(obj.__provides__), []) # pylint:disable=no-member
  1401. def test_w_existing_provides_miss(self):
  1402. from zope.interface.declarations import directlyProvides
  1403. from zope.interface.interface import InterfaceClass
  1404. IFoo = InterfaceClass("IFoo")
  1405. IBar = InterfaceClass("IBar")
  1406. class Foo(object):
  1407. pass
  1408. obj = Foo()
  1409. directlyProvides(obj, IFoo)
  1410. self._callFUT(obj, IBar)
  1411. self.assertEqual(list(obj.__provides__), [IFoo]) # pylint:disable=no-member
  1412. def test_w_iface_implemented_by_class(self):
  1413. from zope.interface.declarations import implementer
  1414. from zope.interface.interface import InterfaceClass
  1415. IFoo = InterfaceClass("IFoo")
  1416. @implementer(IFoo)
  1417. class Foo(object):
  1418. pass
  1419. obj = Foo()
  1420. self.assertRaises(ValueError, self._callFUT, obj, IFoo)
  1421. class ClassProvidesBaseFallbackTests(unittest.TestCase):
  1422. def _getTargetClass(self):
  1423. # pylint:disable=no-name-in-module
  1424. from zope.interface.declarations import ClassProvidesBaseFallback
  1425. return ClassProvidesBaseFallback
  1426. def _makeOne(self, klass, implements):
  1427. # Don't instantiate directly: the C version can't have attributes
  1428. # assigned.
  1429. class Derived(self._getTargetClass()):
  1430. def __init__(self, k, i):
  1431. self._cls = k
  1432. self._implements = i
  1433. return Derived(klass, implements)
  1434. def test_w_same_class_via_class(self):
  1435. from zope.interface.interface import InterfaceClass
  1436. IFoo = InterfaceClass("IFoo")
  1437. class Foo(object):
  1438. pass
  1439. cpbp = Foo.__provides__ = self._makeOne(Foo, IFoo)
  1440. self.assertTrue(Foo.__provides__ is cpbp)
  1441. def test_w_same_class_via_instance(self):
  1442. from zope.interface.interface import InterfaceClass
  1443. IFoo = InterfaceClass("IFoo")
  1444. class Foo(object):
  1445. pass
  1446. foo = Foo()
  1447. Foo.__provides__ = self._makeOne(Foo, IFoo)
  1448. self.assertIs(foo.__provides__, IFoo)
  1449. def test_w_different_class(self):
  1450. from zope.interface.interface import InterfaceClass
  1451. IFoo = InterfaceClass("IFoo")
  1452. class Foo(object):
  1453. pass
  1454. class Bar(Foo):
  1455. pass
  1456. bar = Bar()
  1457. Foo.__provides__ = self._makeOne(Foo, IFoo)
  1458. self.assertRaises(AttributeError, getattr, Bar, '__provides__')
  1459. self.assertRaises(AttributeError, getattr, bar, '__provides__')
  1460. class ClassProvidesBaseTests(OptimizationTestMixin,
  1461. ClassProvidesBaseFallbackTests):
  1462. # Repeat tests for C optimizations
  1463. def _getTargetClass(self):
  1464. from zope.interface.declarations import ClassProvidesBase
  1465. return ClassProvidesBase
  1466. def _getFallbackClass(self):
  1467. # pylint:disable=no-name-in-module
  1468. from zope.interface.declarations import ClassProvidesBaseFallback
  1469. return ClassProvidesBaseFallback
  1470. class ClassProvidesTests(unittest.TestCase):
  1471. def _getTargetClass(self):
  1472. from zope.interface.declarations import ClassProvides
  1473. return ClassProvides
  1474. def _makeOne(self, *args, **kw):
  1475. return self._getTargetClass()(*args, **kw)
  1476. def test_w_simple_metaclass(self):
  1477. from zope.interface.declarations import implementer
  1478. from zope.interface.interface import InterfaceClass
  1479. IFoo = InterfaceClass("IFoo")
  1480. IBar = InterfaceClass("IBar")
  1481. @implementer(IFoo)
  1482. class Foo(object):
  1483. pass
  1484. cp = Foo.__provides__ = self._makeOne(Foo, type(Foo), IBar)
  1485. self.assertTrue(Foo.__provides__ is cp)
  1486. self.assertEqual(list(Foo().__provides__), [IFoo])
  1487. def test___reduce__(self):
  1488. from zope.interface.declarations import implementer
  1489. from zope.interface.interface import InterfaceClass
  1490. IFoo = InterfaceClass("IFoo")
  1491. IBar = InterfaceClass("IBar")
  1492. @implementer(IFoo)
  1493. class Foo(object):
  1494. pass
  1495. cp = Foo.__provides__ = self._makeOne(Foo, type(Foo), IBar)
  1496. self.assertEqual(cp.__reduce__(),
  1497. (type(cp), (Foo, type(Foo), IBar)))
  1498. class ClassProvidesStrictTests(ClassProvidesTests):
  1499. # Tests that require the strict C3 resolution order.
  1500. def _getTargetClass(self):
  1501. ClassProvides = super(ClassProvidesStrictTests, self)._getTargetClass()
  1502. class StrictClassProvides(ClassProvides):
  1503. def _do_calculate_ro(self, base_mros):
  1504. return ClassProvides._do_calculate_ro(self, base_mros=base_mros, strict=True)
  1505. return StrictClassProvides
  1506. def test_overlapping_interfaces_corrected(self):
  1507. # Giving ClassProvides(cls, metaclass, IFace), where IFace is already
  1508. # provided by metacls, doesn't produce invalid resolution orders.
  1509. from zope.interface import implementedBy
  1510. from zope.interface import Interface
  1511. from zope.interface import implementer
  1512. class IBase(Interface):
  1513. pass
  1514. @implementer(IBase)
  1515. class metaclass(type):
  1516. pass
  1517. cls = metaclass(
  1518. 'cls',
  1519. (object,),
  1520. {}
  1521. )
  1522. spec = self._makeOne(cls, metaclass, IBase)
  1523. self.assertEqual(spec.__sro__, (
  1524. spec,
  1525. implementedBy(metaclass),
  1526. IBase,
  1527. implementedBy(type),
  1528. implementedBy(object),
  1529. Interface
  1530. ))
  1531. class TestClassProvidesRepr(unittest.TestCase):
  1532. def _getTargetClass(self):
  1533. from zope.interface.declarations import ClassProvides
  1534. return ClassProvides
  1535. def _makeOne(self, *args, **kw):
  1536. return self._getTargetClass()(*args, **kw)
  1537. def test__repr__empty(self):
  1538. inst = self._makeOne(type(self), type)
  1539. self.assertEqual(
  1540. repr(inst),
  1541. "directlyProvides(TestClassProvidesRepr)"
  1542. )
  1543. def test__repr__providing_one(self):
  1544. from zope.interface import Interface
  1545. class IFoo(Interface):
  1546. "Does nothing"
  1547. inst = self._makeOne(type(self), type, IFoo)
  1548. self.assertEqual(
  1549. repr(inst),
  1550. "directlyProvides(TestClassProvidesRepr, IFoo)"
  1551. )
  1552. def test__repr__duplicate_names(self):
  1553. from zope.interface.interface import InterfaceClass
  1554. IFoo = InterfaceClass("IFoo", __module__='mod1')
  1555. IFoo2 = InterfaceClass("IFoo", __module__='mod2')
  1556. IBaz = InterfaceClass("IBaz")
  1557. inst = self._makeOne(type(self), type, IFoo, IBaz, IFoo2)
  1558. self.assertEqual(
  1559. repr(inst),
  1560. "directlyProvides(TestClassProvidesRepr, IFoo, IBaz, mod2.IFoo)"
  1561. )
  1562. def test__repr__implementedBy(self):
  1563. from zope.interface.declarations import implementer
  1564. from zope.interface.declarations import implementedBy
  1565. from zope.interface.interface import InterfaceClass
  1566. IFoo = InterfaceClass("IFoo")
  1567. @implementer(IFoo)
  1568. class Foo(object):
  1569. pass
  1570. inst = implementedBy(Foo)
  1571. self.assertEqual(
  1572. repr(inst),
  1573. 'classImplements(Foo, IFoo)'
  1574. )
  1575. def test__repr__implementedBy_generic_callable(self):
  1576. from zope.interface.declarations import implementedBy
  1577. # We can't get a __name__ by default, so we get a
  1578. # module name and a question mark
  1579. class Callable(object):
  1580. def __call__(self):
  1581. return self
  1582. inst = implementedBy(Callable())
  1583. self.assertEqual(
  1584. repr(inst),
  1585. 'classImplements(%s.?)' % (__name__,)
  1586. )
  1587. c = Callable()
  1588. c.__name__ = 'Callable'
  1589. inst = implementedBy(c)
  1590. self.assertEqual(
  1591. repr(inst),
  1592. 'classImplements(Callable)'
  1593. )
  1594. class Test_directlyProvidedBy(unittest.TestCase):
  1595. def _callFUT(self, *args, **kw):
  1596. from zope.interface.declarations import directlyProvidedBy
  1597. return directlyProvidedBy(*args, **kw)
  1598. def test_wo_declarations_in_class_or_instance(self):
  1599. class Foo(object):
  1600. pass
  1601. foo = Foo()
  1602. self.assertEqual(list(self._callFUT(foo)), [])
  1603. def test_w_declarations_in_class_but_not_instance(self):
  1604. from zope.interface.declarations import implementer
  1605. from zope.interface.interface import InterfaceClass
  1606. IFoo = InterfaceClass("IFoo")
  1607. @implementer(IFoo)
  1608. class Foo(object):
  1609. pass
  1610. foo = Foo()
  1611. self.assertEqual(list(self._callFUT(foo)), [])
  1612. def test_w_declarations_in_instance_but_not_class(self):
  1613. from zope.interface.declarations import directlyProvides
  1614. from zope.interface.interface import InterfaceClass
  1615. IFoo = InterfaceClass("IFoo")
  1616. class Foo(object):
  1617. pass
  1618. foo = Foo()
  1619. directlyProvides(foo, IFoo)
  1620. self.assertEqual(list(self._callFUT(foo)), [IFoo])
  1621. def test_w_declarations_in_instance_and_class(self):
  1622. from zope.interface.declarations import directlyProvides
  1623. from zope.interface.declarations import implementer
  1624. from zope.interface.interface import InterfaceClass
  1625. IFoo = InterfaceClass("IFoo")
  1626. IBar = InterfaceClass("IBar")
  1627. @implementer(IFoo)
  1628. class Foo(object):
  1629. pass
  1630. foo = Foo()
  1631. directlyProvides(foo, IBar)
  1632. self.assertEqual(list(self._callFUT(foo)), [IBar])
  1633. class Test_classProvides(unittest.TestCase, _Py3ClassAdvice):
  1634. # pylint:disable=exec-used
  1635. def test_called_from_function(self):
  1636. import warnings
  1637. from zope.interface.declarations import classProvides
  1638. from zope.interface.interface import InterfaceClass
  1639. IFoo = InterfaceClass("IFoo")
  1640. globs = {'classProvides': classProvides, 'IFoo': IFoo}
  1641. locs = {}
  1642. CODE = "\n".join([
  1643. 'def foo():',
  1644. ' classProvides(IFoo)'
  1645. ])
  1646. exec(CODE, globs, locs)
  1647. foo = locs['foo']
  1648. with warnings.catch_warnings(record=True) as log:
  1649. warnings.resetwarnings()
  1650. self.assertRaises(TypeError, foo)
  1651. if not PYTHON3:
  1652. self.assertEqual(len(log), 0) # no longer warn
  1653. def test_called_twice_from_class(self):
  1654. import warnings
  1655. from zope.interface.declarations import classProvides
  1656. from zope.interface.interface import InterfaceClass
  1657. IFoo = InterfaceClass("IFoo")
  1658. IBar = InterfaceClass("IBar")
  1659. globs = {'classProvides': classProvides, 'IFoo': IFoo, 'IBar': IBar}
  1660. locs = {}
  1661. CODE = "\n".join([
  1662. 'class Foo(object):',
  1663. ' classProvides(IFoo)',
  1664. ' classProvides(IBar)',
  1665. ])
  1666. with warnings.catch_warnings(record=True) as log:
  1667. warnings.resetwarnings()
  1668. try:
  1669. exec(CODE, globs, locs)
  1670. except TypeError:
  1671. if not PYTHON3:
  1672. self.assertEqual(len(log), 0) # no longer warn
  1673. else:
  1674. self.fail("Didn't raise TypeError")
  1675. def test_called_once_from_class(self):
  1676. from zope.interface.declarations import classProvides
  1677. from zope.interface.interface import InterfaceClass
  1678. IFoo = InterfaceClass("IFoo")
  1679. globs = {'classProvides': classProvides, 'IFoo': IFoo}
  1680. locs = {}
  1681. CODE = "\n".join([
  1682. 'class Foo(object):',
  1683. ' classProvides(IFoo)',
  1684. ])
  1685. if self._run_generated_code(CODE, globs, locs):
  1686. Foo = locs['Foo']
  1687. spec = Foo.__providedBy__
  1688. self.assertEqual(list(spec), [IFoo])
  1689. # Test _classProvides_advice through classProvides, its only caller.
  1690. class Test_provider(unittest.TestCase):
  1691. def _getTargetClass(self):
  1692. from zope.interface.declarations import provider
  1693. return provider
  1694. def _makeOne(self, *args, **kw):
  1695. return self._getTargetClass()(*args, **kw)
  1696. def test_w_class(self):
  1697. from zope.interface.declarations import ClassProvides
  1698. from zope.interface.interface import InterfaceClass
  1699. IFoo = InterfaceClass("IFoo")
  1700. @self._makeOne(IFoo)
  1701. class Foo(object):
  1702. pass
  1703. self.assertIsInstance(Foo.__provides__, ClassProvides) # pylint:disable=no-member
  1704. self.assertEqual(list(Foo.__provides__), [IFoo]) # pylint:disable=no-member
  1705. class Test_moduleProvides(unittest.TestCase):
  1706. # pylint:disable=exec-used
  1707. def test_called_from_function(self):
  1708. from zope.interface.declarations import moduleProvides
  1709. from zope.interface.interface import InterfaceClass
  1710. IFoo = InterfaceClass("IFoo")
  1711. globs = {'__name__': '__tests__.tests.tests.foo',
  1712. 'moduleProvides': moduleProvides, 'IFoo': IFoo}
  1713. locs = {}
  1714. CODE = "\n".join([
  1715. 'def foo():',
  1716. ' moduleProvides(IFoo)'
  1717. ])
  1718. exec(CODE, globs, locs)
  1719. foo = locs['foo']
  1720. self.assertRaises(TypeError, foo)
  1721. def test_called_from_class(self):
  1722. from zope.interface.declarations import moduleProvides
  1723. from zope.interface.interface import InterfaceClass
  1724. IFoo = InterfaceClass("IFoo")
  1725. globs = {'__name__': '__tests__.tests.tests.foo',
  1726. 'moduleProvides': moduleProvides, 'IFoo': IFoo}
  1727. locs = {}
  1728. CODE = "\n".join([
  1729. 'class Foo(object):',
  1730. ' moduleProvides(IFoo)',
  1731. ])
  1732. with self.assertRaises(TypeError):
  1733. exec(CODE, globs, locs)
  1734. def test_called_once_from_module_scope(self):
  1735. from zope.interface.declarations import moduleProvides
  1736. from zope.interface.interface import InterfaceClass
  1737. IFoo = InterfaceClass("IFoo")
  1738. globs = {'__name__': '__tests__.tests.tests.foo',
  1739. 'moduleProvides': moduleProvides, 'IFoo': IFoo}
  1740. CODE = "\n".join([
  1741. 'moduleProvides(IFoo)',
  1742. ])
  1743. exec(CODE, globs)
  1744. spec = globs['__provides__']
  1745. self.assertEqual(list(spec), [IFoo])
  1746. def test_called_twice_from_module_scope(self):
  1747. from zope.interface.declarations import moduleProvides
  1748. from zope.interface.interface import InterfaceClass
  1749. IFoo = InterfaceClass("IFoo")
  1750. globs = {'__name__': '__tests__.tests.tests.foo',
  1751. 'moduleProvides': moduleProvides, 'IFoo': IFoo}
  1752. CODE = "\n".join([
  1753. 'moduleProvides(IFoo)',
  1754. 'moduleProvides(IFoo)',
  1755. ])
  1756. with self.assertRaises(TypeError):
  1757. exec(CODE, globs)
  1758. class Test_getObjectSpecificationFallback(unittest.TestCase):
  1759. def _getFallbackClass(self):
  1760. # pylint:disable=no-name-in-module
  1761. from zope.interface.declarations import getObjectSpecificationFallback
  1762. return getObjectSpecificationFallback
  1763. _getTargetClass = _getFallbackClass
  1764. def _callFUT(self, *args, **kw):
  1765. return self._getTargetClass()(*args, **kw)
  1766. def test_wo_existing_provides_classless(self):
  1767. the_dict = {}
  1768. class Foo(object):
  1769. def __getattribute__(self, name):
  1770. # Emulate object w/o any class
  1771. if name == '__class__':
  1772. raise AttributeError(name)
  1773. try:
  1774. return the_dict[name]
  1775. except KeyError:
  1776. raise AttributeError(name)
  1777. def __setattr__(self, name, value):
  1778. raise NotImplementedError()
  1779. foo = Foo()
  1780. spec = self._callFUT(foo)
  1781. self.assertEqual(list(spec), [])
  1782. def test_existing_provides_is_spec(self):
  1783. from zope.interface.declarations import directlyProvides
  1784. from zope.interface.interface import InterfaceClass
  1785. IFoo = InterfaceClass("IFoo")
  1786. def foo():
  1787. raise NotImplementedError()
  1788. directlyProvides(foo, IFoo)
  1789. spec = self._callFUT(foo)
  1790. self.assertIs(spec, foo.__provides__) # pylint:disable=no-member
  1791. def test_existing_provides_is_not_spec(self):
  1792. def foo():
  1793. raise NotImplementedError()
  1794. foo.__provides__ = object() # not a valid spec
  1795. spec = self._callFUT(foo)
  1796. self.assertEqual(list(spec), [])
  1797. def test_existing_provides(self):
  1798. from zope.interface.declarations import directlyProvides
  1799. from zope.interface.interface import InterfaceClass
  1800. IFoo = InterfaceClass("IFoo")
  1801. class Foo(object):
  1802. pass
  1803. foo = Foo()
  1804. directlyProvides(foo, IFoo)
  1805. spec = self._callFUT(foo)
  1806. self.assertEqual(list(spec), [IFoo])
  1807. def test_wo_provides_on_class_w_implements(self):
  1808. from zope.interface.declarations import implementer
  1809. from zope.interface.interface import InterfaceClass
  1810. IFoo = InterfaceClass("IFoo")
  1811. @implementer(IFoo)
  1812. class Foo(object):
  1813. pass
  1814. foo = Foo()
  1815. spec = self._callFUT(foo)
  1816. self.assertEqual(list(spec), [IFoo])
  1817. def test_wo_provides_on_class_wo_implements(self):
  1818. class Foo(object):
  1819. pass
  1820. foo = Foo()
  1821. spec = self._callFUT(foo)
  1822. self.assertEqual(list(spec), [])
  1823. def test_catches_only_AttributeError_on_provides(self):
  1824. MissingSomeAttrs.test_raises(self, self._callFUT, expected_missing='__provides__')
  1825. def test_catches_only_AttributeError_on_class(self):
  1826. MissingSomeAttrs.test_raises(self, self._callFUT, expected_missing='__class__',
  1827. __provides__=None)
  1828. def test_raises_AttributeError_when_provides_fails_type_check_AttributeError(self):
  1829. # isinstance(ob.__provides__, SpecificationBase) is not
  1830. # protected inside any kind of block.
  1831. class Foo(object):
  1832. __provides__ = MissingSomeAttrs(AttributeError)
  1833. # isinstance() ignores AttributeError on __class__
  1834. self._callFUT(Foo())
  1835. def test_raises_AttributeError_when_provides_fails_type_check_RuntimeError(self):
  1836. # isinstance(ob.__provides__, SpecificationBase) is not
  1837. # protected inside any kind of block.
  1838. class Foo(object):
  1839. __provides__ = MissingSomeAttrs(RuntimeError)
  1840. if PYTHON3:
  1841. with self.assertRaises(RuntimeError) as exc:
  1842. self._callFUT(Foo())
  1843. self.assertEqual('__class__', exc.exception.args[0])
  1844. else:
  1845. # Python 2 catches everything.
  1846. self._callFUT(Foo())
  1847. class Test_getObjectSpecification(Test_getObjectSpecificationFallback,
  1848. OptimizationTestMixin):
  1849. # Repeat tests for C optimizations
  1850. def _getTargetClass(self):
  1851. from zope.interface.declarations import getObjectSpecification
  1852. return getObjectSpecification
  1853. class Test_providedByFallback(unittest.TestCase):
  1854. def _getFallbackClass(self):
  1855. # pylint:disable=no-name-in-module
  1856. from zope.interface.declarations import providedByFallback
  1857. return providedByFallback
  1858. _getTargetClass = _getFallbackClass
  1859. def _callFUT(self, *args, **kw):
  1860. return self._getTargetClass()(*args, **kw)
  1861. def test_wo_providedBy_on_class_wo_implements(self):
  1862. class Foo(object):
  1863. pass
  1864. foo = Foo()
  1865. spec = self._callFUT(foo)
  1866. self.assertEqual(list(spec), [])
  1867. def test_w_providedBy_valid_spec(self):
  1868. from zope.interface.declarations import Provides
  1869. from zope.interface.interface import InterfaceClass
  1870. IFoo = InterfaceClass("IFoo")
  1871. class Foo(object):
  1872. pass
  1873. foo = Foo()
  1874. foo.__providedBy__ = Provides(Foo, IFoo)
  1875. spec = self._callFUT(foo)
  1876. self.assertEqual(list(spec), [IFoo])
  1877. def test_w_providedBy_invalid_spec(self):
  1878. class Foo(object):
  1879. pass
  1880. foo = Foo()
  1881. foo.__providedBy__ = object()
  1882. spec = self._callFUT(foo)
  1883. self.assertEqual(list(spec), [])
  1884. def test_w_providedBy_invalid_spec_class_w_implements(self):
  1885. from zope.interface.declarations import implementer
  1886. from zope.interface.interface import InterfaceClass
  1887. IFoo = InterfaceClass("IFoo")
  1888. @implementer(IFoo)
  1889. class Foo(object):
  1890. pass
  1891. foo = Foo()
  1892. foo.__providedBy__ = object()
  1893. spec = self._callFUT(foo)
  1894. self.assertEqual(list(spec), [IFoo])
  1895. def test_w_providedBy_invalid_spec_w_provides_no_provides_on_class(self):
  1896. class Foo(object):
  1897. pass
  1898. foo = Foo()
  1899. foo.__providedBy__ = object()
  1900. expected = foo.__provides__ = object()
  1901. spec = self._callFUT(foo)
  1902. self.assertTrue(spec is expected)
  1903. def test_w_providedBy_invalid_spec_w_provides_diff_provides_on_class(self):
  1904. class Foo(object):
  1905. pass
  1906. foo = Foo()
  1907. foo.__providedBy__ = object()
  1908. expected = foo.__provides__ = object()
  1909. Foo.__provides__ = object()
  1910. spec = self._callFUT(foo)
  1911. self.assertTrue(spec is expected)
  1912. def test_w_providedBy_invalid_spec_w_provides_same_provides_on_class(self):
  1913. from zope.interface.declarations import implementer
  1914. from zope.interface.interface import InterfaceClass
  1915. IFoo = InterfaceClass("IFoo")
  1916. @implementer(IFoo)
  1917. class Foo(object):
  1918. pass
  1919. foo = Foo()
  1920. foo.__providedBy__ = object()
  1921. foo.__provides__ = Foo.__provides__ = object()
  1922. spec = self._callFUT(foo)
  1923. self.assertEqual(list(spec), [IFoo])
  1924. def test_super_when_base_implements_interface(self):
  1925. from zope.interface import Interface
  1926. from zope.interface.declarations import implementer
  1927. class IBase(Interface):
  1928. pass
  1929. class IDerived(IBase):
  1930. pass
  1931. @implementer(IBase)
  1932. class Base(object):
  1933. pass
  1934. @implementer(IDerived)
  1935. class Derived(Base):
  1936. pass
  1937. derived = Derived()
  1938. self.assertEqual(list(self._callFUT(derived)), [IDerived, IBase])
  1939. sup = super(Derived, derived)
  1940. fut = self._callFUT(sup)
  1941. self.assertIsNone(fut._dependents)
  1942. self.assertEqual(list(fut), [IBase])
  1943. def test_super_when_base_doesnt_implement_interface(self):
  1944. from zope.interface import Interface
  1945. from zope.interface.declarations import implementer
  1946. class IBase(Interface):
  1947. pass
  1948. class IDerived(IBase):
  1949. pass
  1950. class Base(object):
  1951. pass
  1952. @implementer(IDerived)
  1953. class Derived(Base):
  1954. pass
  1955. derived = Derived()
  1956. self.assertEqual(list(self._callFUT(derived)), [IDerived])
  1957. sup = super(Derived, derived)
  1958. self.assertEqual(list(self._callFUT(sup)), [])
  1959. def test_super_when_base_is_object(self):
  1960. from zope.interface import Interface
  1961. from zope.interface.declarations import implementer
  1962. class IBase(Interface):
  1963. pass
  1964. class IDerived(IBase):
  1965. pass
  1966. @implementer(IDerived)
  1967. class Derived(object):
  1968. pass
  1969. derived = Derived()
  1970. self.assertEqual(list(self._callFUT(derived)), [IDerived])
  1971. sup = super(Derived, derived)
  1972. fut = self._callFUT(sup)
  1973. self.assertIsNone(fut._dependents)
  1974. self.assertEqual(list(fut), [])
  1975. def test_super_when_object_directly_provides(self):
  1976. from zope.interface import Interface
  1977. from zope.interface.declarations import implementer
  1978. from zope.interface.declarations import directlyProvides
  1979. class IBase(Interface):
  1980. pass
  1981. class IDerived(IBase):
  1982. pass
  1983. @implementer(IBase)
  1984. class Base(object):
  1985. pass
  1986. class Derived(Base):
  1987. pass
  1988. derived = Derived()
  1989. self.assertEqual(list(self._callFUT(derived)), [IBase])
  1990. directlyProvides(derived, IDerived)
  1991. self.assertEqual(list(self._callFUT(derived)), [IDerived, IBase])
  1992. sup = super(Derived, derived)
  1993. fut = self._callFUT(sup)
  1994. self.assertIsNone(fut._dependents)
  1995. self.assertEqual(list(fut), [IBase])
  1996. def test_super_multi_level_multi_inheritance(self):
  1997. from zope.interface.declarations import implementer
  1998. from zope.interface import Interface
  1999. class IBase(Interface):
  2000. pass
  2001. class IM1(Interface):
  2002. pass
  2003. class IM2(Interface):
  2004. pass
  2005. class IDerived(IBase):
  2006. pass
  2007. class IUnrelated(Interface):
  2008. pass
  2009. @implementer(IBase)
  2010. class Base(object):
  2011. pass
  2012. @implementer(IM1)
  2013. class M1(Base):
  2014. pass
  2015. @implementer(IM2)
  2016. class M2(Base):
  2017. pass
  2018. @implementer(IDerived, IUnrelated)
  2019. class Derived(M1, M2):
  2020. pass
  2021. d = Derived()
  2022. sd = super(Derived, d)
  2023. sm1 = super(M1, d)
  2024. sm2 = super(M2, d)
  2025. self.assertEqual(list(self._callFUT(d)),
  2026. [IDerived, IUnrelated, IM1, IBase, IM2])
  2027. self.assertEqual(list(self._callFUT(sd)),
  2028. [IM1, IBase, IM2])
  2029. self.assertEqual(list(self._callFUT(sm1)),
  2030. [IM2, IBase])
  2031. self.assertEqual(list(self._callFUT(sm2)),
  2032. [IBase])
  2033. def test_catches_only_AttributeError_on_providedBy(self):
  2034. MissingSomeAttrs.test_raises(self, self._callFUT,
  2035. expected_missing='__providedBy__',
  2036. __class__=object)
  2037. def test_catches_only_AttributeError_on_class(self):
  2038. # isinstance() tries to get the __class__, which is non-obvious,
  2039. # so it must be protected too.
  2040. PY3 = str is not bytes
  2041. MissingSomeAttrs.test_raises(self, self._callFUT,
  2042. expected_missing='__class__' if PY3 else '__providedBy__')
  2043. class Test_providedBy(Test_providedByFallback,
  2044. OptimizationTestMixin):
  2045. # Repeat tests for C optimizations
  2046. def _getTargetClass(self):
  2047. from zope.interface.declarations import providedBy
  2048. return providedBy
  2049. class ObjectSpecificationDescriptorFallbackTests(unittest.TestCase):
  2050. def _getFallbackClass(self):
  2051. # pylint:disable=no-name-in-module
  2052. from zope.interface.declarations \
  2053. import ObjectSpecificationDescriptorFallback
  2054. return ObjectSpecificationDescriptorFallback
  2055. _getTargetClass = _getFallbackClass
  2056. def _makeOne(self, *args, **kw):
  2057. return self._getTargetClass()(*args, **kw)
  2058. def test_accessed_via_class(self):
  2059. from zope.interface.declarations import Provides
  2060. from zope.interface.interface import InterfaceClass
  2061. IFoo = InterfaceClass("IFoo")
  2062. class Foo(object):
  2063. pass
  2064. Foo.__provides__ = Provides(Foo, IFoo)
  2065. Foo.__providedBy__ = self._makeOne()
  2066. self.assertEqual(list(Foo.__providedBy__), [IFoo])
  2067. def test_accessed_via_inst_wo_provides(self):
  2068. from zope.interface.declarations import implementer
  2069. from zope.interface.declarations import Provides
  2070. from zope.interface.interface import InterfaceClass
  2071. IFoo = InterfaceClass("IFoo")
  2072. IBar = InterfaceClass("IBar")
  2073. @implementer(IFoo)
  2074. class Foo(object):
  2075. pass
  2076. Foo.__provides__ = Provides(Foo, IBar)
  2077. Foo.__providedBy__ = self._makeOne()
  2078. foo = Foo()
  2079. self.assertEqual(list(foo.__providedBy__), [IFoo])
  2080. def test_accessed_via_inst_w_provides(self):
  2081. from zope.interface.declarations import directlyProvides
  2082. from zope.interface.declarations import implementer
  2083. from zope.interface.declarations import Provides
  2084. from zope.interface.interface import InterfaceClass
  2085. IFoo = InterfaceClass("IFoo")
  2086. IBar = InterfaceClass("IBar")
  2087. IBaz = InterfaceClass("IBaz")
  2088. @implementer(IFoo)
  2089. class Foo(object):
  2090. pass
  2091. Foo.__provides__ = Provides(Foo, IBar)
  2092. Foo.__providedBy__ = self._makeOne()
  2093. foo = Foo()
  2094. directlyProvides(foo, IBaz)
  2095. self.assertEqual(list(foo.__providedBy__), [IBaz, IFoo])
  2096. def test_arbitrary_exception_accessing_provides_not_caught(self):
  2097. class MyException(Exception):
  2098. pass
  2099. class Foo(object):
  2100. __providedBy__ = self._makeOne()
  2101. @property
  2102. def __provides__(self):
  2103. raise MyException
  2104. foo = Foo()
  2105. with self.assertRaises(MyException):
  2106. getattr(foo, '__providedBy__')
  2107. def test_AttributeError_accessing_provides_caught(self):
  2108. class MyException(Exception):
  2109. pass
  2110. class Foo(object):
  2111. __providedBy__ = self._makeOne()
  2112. @property
  2113. def __provides__(self):
  2114. raise AttributeError
  2115. foo = Foo()
  2116. provided = getattr(foo, '__providedBy__')
  2117. self.assertIsNotNone(provided)
  2118. def test_None_in__provides__overrides(self):
  2119. from zope.interface import Interface
  2120. from zope.interface import implementer
  2121. class IFoo(Interface):
  2122. pass
  2123. @implementer(IFoo)
  2124. class Foo(object):
  2125. @property
  2126. def __provides__(self):
  2127. return None
  2128. Foo.__providedBy__ = self._makeOne()
  2129. provided = getattr(Foo(), '__providedBy__')
  2130. self.assertIsNone(provided)
  2131. class ObjectSpecificationDescriptorTests(
  2132. ObjectSpecificationDescriptorFallbackTests,
  2133. OptimizationTestMixin):
  2134. # Repeat tests for C optimizations
  2135. def _getTargetClass(self):
  2136. from zope.interface.declarations import ObjectSpecificationDescriptor
  2137. return ObjectSpecificationDescriptor
  2138. # Test _normalizeargs through its callers.
  2139. class _Monkey(object):
  2140. # context-manager for replacing module names in the scope of a test.
  2141. def __init__(self, module, **kw):
  2142. self.module = module
  2143. self.to_restore = {key: getattr(module, key) for key in kw}
  2144. for key, value in kw.items():
  2145. setattr(module, key, value)
  2146. def __enter__(self):
  2147. return self
  2148. def __exit__(self, exc_type, exc_val, exc_tb):
  2149. for key, value in self.to_restore.items():
  2150. setattr(self.module, key, value)
  2151. class _MonkeyDict(object):
  2152. # context-manager for restoring a dict w/in a module in the scope of a test.
  2153. def __init__(self, module, attrname, **kw):
  2154. self.module = module
  2155. self.target = getattr(module, attrname)
  2156. self.to_restore = self.target.copy()
  2157. self.target.clear()
  2158. self.target.update(kw)
  2159. def __enter__(self):
  2160. return self.target
  2161. def __exit__(self, exc_type, exc_val, exc_tb):
  2162. self.target.clear()
  2163. self.target.update(self.to_restore)