test_interface.py 91 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871
  1. ##############################################################################
  2. #
  3. # Copyright (c) 2001, 2002 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 Interface implementation
  15. """
  16. # Things we let slide because it's a test
  17. # pylint:disable=protected-access
  18. # pylint:disable=blacklisted-name
  19. # pylint:disable=attribute-defined-outside-init
  20. # pylint:disable=too-many-public-methods
  21. # pylint:disable=too-many-lines
  22. # pylint:disable=abstract-method
  23. # pylint:disable=redefined-builtin
  24. # pylint:disable=signature-differs
  25. # pylint:disable=arguments-differ
  26. # Things you get inheriting from Interface
  27. # pylint:disable=inherit-non-class
  28. # pylint:disable=no-self-argument
  29. # pylint:disable=no-method-argument
  30. # Things you get using methods of an Interface 'subclass'
  31. # pylint:disable=no-value-for-parameter
  32. import unittest
  33. from __tests__.tests import CleanUp
  34. from __tests__.tests import MissingSomeAttrs
  35. from __tests__.tests import OptimizationTestMixin
  36. from __tests__.tests import SubclassableMixin
  37. _marker = object()
  38. class Test_invariant(unittest.TestCase):
  39. def test_w_single(self):
  40. from zope.interface.interface import TAGGED_DATA
  41. from zope.interface.interface import invariant
  42. def _check(*args, **kw):
  43. raise NotImplementedError()
  44. class Foo:
  45. invariant(_check)
  46. self.assertEqual(getattr(Foo, TAGGED_DATA, None),
  47. {'invariants': [_check]})
  48. def test_w_multiple(self):
  49. from zope.interface.interface import TAGGED_DATA
  50. from zope.interface.interface import invariant
  51. def _check(*args, **kw):
  52. raise NotImplementedError()
  53. def _another_check(*args, **kw):
  54. raise NotImplementedError()
  55. class Foo:
  56. invariant(_check)
  57. invariant(_another_check)
  58. self.assertEqual(getattr(Foo, TAGGED_DATA, None),
  59. {'invariants': [_check, _another_check]})
  60. class Test_taggedValue(unittest.TestCase):
  61. def test_w_single(self):
  62. from zope.interface.interface import TAGGED_DATA
  63. from zope.interface.interface import taggedValue
  64. class Foo:
  65. taggedValue('bar', ['baz'])
  66. self.assertEqual(getattr(Foo, TAGGED_DATA, None),
  67. {'bar': ['baz']})
  68. def test_w_multiple(self):
  69. from zope.interface.interface import TAGGED_DATA
  70. from zope.interface.interface import taggedValue
  71. class Foo:
  72. taggedValue('bar', ['baz'])
  73. taggedValue('qux', 'spam')
  74. self.assertEqual(getattr(Foo, TAGGED_DATA, None),
  75. {'bar': ['baz'], 'qux': 'spam'})
  76. def test_w_multiple_overwriting(self):
  77. from zope.interface.interface import TAGGED_DATA
  78. from zope.interface.interface import taggedValue
  79. class Foo:
  80. taggedValue('bar', ['baz'])
  81. taggedValue('qux', 'spam')
  82. taggedValue('bar', 'frob')
  83. self.assertEqual(getattr(Foo, TAGGED_DATA, None),
  84. {'bar': 'frob', 'qux': 'spam'})
  85. class ElementTests(unittest.TestCase):
  86. DEFAULT_NAME = 'AnElement'
  87. def _getTargetClass(self):
  88. from zope.interface.interface import Element
  89. return Element
  90. def _makeOne(self, name=None):
  91. if name is None:
  92. name = self.DEFAULT_NAME
  93. return self._getTargetClass()(name)
  94. def test_ctor_defaults(self):
  95. element = self._makeOne()
  96. self.assertEqual(element.__name__, self.DEFAULT_NAME)
  97. self.assertEqual(element.getName(), self.DEFAULT_NAME)
  98. self.assertEqual(element.__doc__, '')
  99. self.assertEqual(element.getDoc(), '')
  100. self.assertEqual(list(element.getTaggedValueTags()), [])
  101. def test_ctor_no_doc_space_in_name(self):
  102. element = self._makeOne('An Element')
  103. self.assertEqual(element.__name__, None)
  104. self.assertEqual(element.__doc__, 'An Element')
  105. def test_getTaggedValue_miss(self):
  106. element = self._makeOne()
  107. self.assertRaises(KeyError, element.getTaggedValue, 'nonesuch')
  108. def test_getDirectTaggedValueTags(self):
  109. element = self._makeOne()
  110. self.assertEqual([], list(element.getDirectTaggedValueTags()))
  111. element.setTaggedValue('foo', 'bar')
  112. self.assertEqual(['foo'], list(element.getDirectTaggedValueTags()))
  113. def test_queryTaggedValue_miss(self):
  114. element = self._makeOne()
  115. self.assertEqual(element.queryTaggedValue('nonesuch'), None)
  116. def test_queryTaggedValue_miss_w_default(self):
  117. element = self._makeOne()
  118. self.assertEqual(element.queryTaggedValue('nonesuch', 'bar'), 'bar')
  119. def test_getDirectTaggedValue_miss(self):
  120. element = self._makeOne()
  121. self.assertRaises(KeyError, element.getDirectTaggedValue, 'nonesuch')
  122. def test_queryDirectTaggedValue_miss(self):
  123. element = self._makeOne()
  124. self.assertEqual(element.queryDirectTaggedValue('nonesuch'), None)
  125. def test_queryDirectTaggedValue_miss_w_default(self):
  126. element = self._makeOne()
  127. self.assertEqual(
  128. element.queryDirectTaggedValue('nonesuch', 'bar'), 'bar'
  129. )
  130. def test_setTaggedValue(self):
  131. element = self._makeOne()
  132. element.setTaggedValue('foo', 'bar')
  133. self.assertEqual(list(element.getTaggedValueTags()), ['foo'])
  134. self.assertEqual(element.getTaggedValue('foo'), 'bar')
  135. self.assertEqual(element.queryTaggedValue('foo'), 'bar')
  136. def test_verifies(self):
  137. from zope.interface.interfaces import IElement
  138. from zope.interface.verify import verifyObject
  139. element = self._makeOne()
  140. verifyObject(IElement, element)
  141. class GenericSpecificationBaseTests(unittest.TestCase):
  142. # Tests that work with both implementations
  143. def _getFallbackClass(self):
  144. from zope.interface.interface import SpecificationBasePy
  145. return SpecificationBasePy
  146. _getTargetClass = _getFallbackClass
  147. def _makeOne(self):
  148. return self._getTargetClass()()
  149. def test_providedBy_miss(self):
  150. from zope.interface import interface
  151. from zope.interface.declarations import _empty
  152. sb = self._makeOne()
  153. def _providedBy(obj):
  154. return _empty
  155. with _Monkey(interface, providedBy=_providedBy):
  156. self.assertFalse(sb.providedBy(object()))
  157. def test_implementedBy_miss(self):
  158. from zope.interface import interface
  159. from zope.interface.declarations import _empty
  160. sb = self._makeOne()
  161. def _implementedBy(obj):
  162. return _empty
  163. with _Monkey(interface, implementedBy=_implementedBy):
  164. self.assertFalse(sb.implementedBy(object()))
  165. class SpecificationBaseTests(
  166. GenericSpecificationBaseTests,
  167. OptimizationTestMixin,
  168. SubclassableMixin,
  169. ):
  170. # Tests that use the C implementation
  171. def _getTargetClass(self):
  172. from zope.interface.interface import SpecificationBase
  173. return SpecificationBase
  174. class SpecificationBasePyTests(GenericSpecificationBaseTests):
  175. # Tests that only work with the Python implementation
  176. def test___call___miss(self):
  177. sb = self._makeOne()
  178. sb._implied = {} # not defined by SpecificationBasePy
  179. self.assertFalse(sb.isOrExtends(object()))
  180. def test___call___hit(self):
  181. sb = self._makeOne()
  182. testing = object()
  183. sb._implied = {testing: {}} # not defined by SpecificationBasePy
  184. self.assertTrue(sb(testing))
  185. def test_isOrExtends_miss(self):
  186. sb = self._makeOne()
  187. sb._implied = {} # not defined by SpecificationBasePy
  188. self.assertFalse(sb.isOrExtends(object()))
  189. def test_isOrExtends_hit(self):
  190. sb = self._makeOne()
  191. testing = object()
  192. sb._implied = {testing: {}} # not defined by SpecificationBasePy
  193. self.assertTrue(sb(testing))
  194. def test_implementedBy_hit(self):
  195. from zope.interface import interface
  196. sb = self._makeOne()
  197. class _Decl:
  198. _implied = {sb: {}}
  199. def _implementedBy(obj):
  200. return _Decl()
  201. with _Monkey(interface, implementedBy=_implementedBy):
  202. self.assertTrue(sb.implementedBy(object()))
  203. def test_providedBy_hit(self):
  204. from zope.interface import interface
  205. sb = self._makeOne()
  206. class _Decl:
  207. _implied = {sb: {}}
  208. def _providedBy(obj):
  209. return _Decl()
  210. with _Monkey(interface, providedBy=_providedBy):
  211. self.assertTrue(sb.providedBy(object()))
  212. class NameAndModuleComparisonTestsMixin(CleanUp):
  213. def _makeOneToCompare(self):
  214. return self._makeOne('a', 'b')
  215. def __check_NotImplemented_comparison(self, name):
  216. # Without the correct attributes of __name__ and __module__,
  217. # comparison switches to the reverse direction.
  218. import operator
  219. ib = self._makeOneToCompare()
  220. op = getattr(operator, name)
  221. meth = getattr(ib, '__%s__' % name)
  222. # If either the __name__ or __module__ attribute
  223. # is missing from the other object, then we return
  224. # NotImplemented.
  225. class RaisesErrorOnMissing:
  226. Exc = AttributeError
  227. def __getattribute__(self, name):
  228. try:
  229. return object.__getattribute__(self, name)
  230. except AttributeError:
  231. exc = RaisesErrorOnMissing.Exc
  232. raise exc(name)
  233. class RaisesErrorOnModule(RaisesErrorOnMissing):
  234. def __init__(self):
  235. self.__name__ = 'foo'
  236. @property
  237. def __module__(self):
  238. raise AttributeError
  239. class RaisesErrorOnName(RaisesErrorOnMissing):
  240. def __init__(self):
  241. self.__module__ = 'foo'
  242. self.assertEqual(RaisesErrorOnModule().__name__, 'foo')
  243. self.assertEqual(RaisesErrorOnName().__module__, 'foo')
  244. with self.assertRaises(AttributeError):
  245. getattr(RaisesErrorOnModule(), '__module__')
  246. with self.assertRaises(AttributeError):
  247. getattr(RaisesErrorOnName(), '__name__')
  248. for cls in RaisesErrorOnModule, RaisesErrorOnName:
  249. self.assertIs(meth(cls()), NotImplemented)
  250. # If the other object has a comparison function, returning
  251. # NotImplemented means Python calls it.
  252. class AllowsAnyComparison(RaisesErrorOnMissing):
  253. def __eq__(self, other):
  254. return True
  255. __lt__ = __eq__
  256. __le__ = __eq__
  257. __gt__ = __eq__
  258. __ge__ = __eq__
  259. __ne__ = __eq__
  260. self.assertTrue(op(ib, AllowsAnyComparison()))
  261. self.assertIs(meth(AllowsAnyComparison()), NotImplemented)
  262. # If it doesn't have the comparison, Python raises a TypeError.
  263. class AllowsNoComparison:
  264. __eq__ = None
  265. __lt__ = __eq__
  266. __le__ = __eq__
  267. __gt__ = __eq__
  268. __ge__ = __eq__
  269. __ne__ = __eq__
  270. self.assertIs(meth(AllowsNoComparison()), NotImplemented)
  271. with self.assertRaises(TypeError):
  272. op(ib, AllowsNoComparison())
  273. # Errors besides AttributeError are passed
  274. class MyException(Exception):
  275. pass
  276. RaisesErrorOnMissing.Exc = MyException
  277. with self.assertRaises(MyException):
  278. getattr(RaisesErrorOnModule(), '__module__')
  279. with self.assertRaises(MyException):
  280. getattr(RaisesErrorOnName(), '__name__')
  281. for cls in RaisesErrorOnModule, RaisesErrorOnName:
  282. with self.assertRaises(MyException):
  283. op(ib, cls())
  284. with self.assertRaises(MyException):
  285. meth(cls())
  286. def test__lt__NotImplemented(self):
  287. self.__check_NotImplemented_comparison('lt')
  288. def test__le__NotImplemented(self):
  289. self.__check_NotImplemented_comparison('le')
  290. def test__gt__NotImplemented(self):
  291. self.__check_NotImplemented_comparison('gt')
  292. def test__ge__NotImplemented(self):
  293. self.__check_NotImplemented_comparison('ge')
  294. class InterfaceBaseTestsMixin(NameAndModuleComparisonTestsMixin):
  295. # Tests for both C and Python implementation
  296. def _getTargetClass(self):
  297. raise NotImplementedError
  298. def _getFallbackClass(self):
  299. # pylint:disable=no-name-in-module
  300. from zope.interface.interface import InterfaceBasePy
  301. return InterfaceBasePy
  302. def _makeOne(self, object_should_provide=False, name=None, module=None):
  303. class IB(self._getTargetClass()):
  304. def _call_conform(self, conform):
  305. return conform(self)
  306. def providedBy(self, obj):
  307. return object_should_provide
  308. return IB(name, module)
  309. def test___call___w___conform___returning_value(self):
  310. ib = self._makeOne(False)
  311. conformed = object()
  312. class _Adapted:
  313. def __conform__(self, iface):
  314. return conformed
  315. self.assertIs(ib(_Adapted()), conformed)
  316. def test___call___wo___conform___ob_no_provides_w_alternate(self):
  317. ib = self._makeOne(False)
  318. __traceback_info__ = ib, self._getTargetClass()
  319. adapted = object()
  320. alternate = object()
  321. self.assertIs(ib(adapted, alternate), alternate)
  322. def test___call___w___conform___ob_no_provides_wo_alternate(self):
  323. ib = self._makeOne(False)
  324. with self.assertRaises(TypeError) as exc:
  325. ib(object())
  326. self.assertIn('Could not adapt', str(exc.exception))
  327. def test___call___w_no_conform_catches_only_AttributeError(self):
  328. MissingSomeAttrs.test_raises(
  329. self, self._makeOne(), expected_missing='__conform__'
  330. )
  331. class InterfaceBaseTests(
  332. InterfaceBaseTestsMixin,
  333. OptimizationTestMixin,
  334. SubclassableMixin,
  335. unittest.TestCase,
  336. ):
  337. # Tests that work with the C implementation
  338. def _getTargetClass(self):
  339. from zope.interface.interface import InterfaceBase
  340. return InterfaceBase
  341. class InterfaceBasePyTests(InterfaceBaseTestsMixin, unittest.TestCase):
  342. # Tests that only work with the Python implementation
  343. _getTargetClass = InterfaceBaseTestsMixin._getFallbackClass
  344. def test___call___w___conform___miss_ob_provides(self):
  345. ib = self._makeOne(True)
  346. class _Adapted:
  347. def __conform__(self, iface):
  348. return None
  349. adapted = _Adapted()
  350. self.assertIs(ib(adapted), adapted)
  351. def test___adapt___ob_provides(self):
  352. ib = self._makeOne(True)
  353. adapted = object()
  354. self.assertIs(ib.__adapt__(adapted), adapted)
  355. def test___adapt___ob_no_provides_uses_hooks(self):
  356. from zope.interface import interface
  357. ib = self._makeOne(False)
  358. adapted = object()
  359. _missed = []
  360. def _hook_miss(iface, obj):
  361. _missed.append((iface, obj))
  362. def _hook_hit(iface, obj):
  363. return obj
  364. with _Monkey(interface, adapter_hooks=[_hook_miss, _hook_hit]):
  365. self.assertIs(ib.__adapt__(adapted), adapted)
  366. self.assertEqual(_missed, [(ib, adapted)])
  367. class SpecificationTests(unittest.TestCase):
  368. def _getTargetClass(self):
  369. from zope.interface.interface import Specification
  370. return Specification
  371. def _makeOne(self, bases=_marker):
  372. if bases is _marker:
  373. return self._getTargetClass()()
  374. return self._getTargetClass()(bases)
  375. def test_ctor(self):
  376. from zope.interface.interface import Interface
  377. spec = self._makeOne()
  378. self.assertEqual(spec.__bases__, ())
  379. self.assertEqual(len(spec._implied), 2)
  380. self.assertIn(spec, spec._implied)
  381. self.assertIn(Interface, spec._implied)
  382. self.assertEqual(len(spec.dependents), 0)
  383. def test_subscribe_first_time(self):
  384. spec = self._makeOne()
  385. dep = DummyDependent()
  386. spec.subscribe(dep)
  387. self.assertEqual(len(spec.dependents), 1)
  388. self.assertEqual(spec.dependents[dep], 1)
  389. def test_subscribe_again(self):
  390. spec = self._makeOne()
  391. dep = DummyDependent()
  392. spec.subscribe(dep)
  393. spec.subscribe(dep)
  394. self.assertEqual(spec.dependents[dep], 2)
  395. def test_unsubscribe_miss(self):
  396. spec = self._makeOne()
  397. dep = DummyDependent()
  398. self.assertRaises(KeyError, spec.unsubscribe, dep)
  399. def test_unsubscribe(self):
  400. spec = self._makeOne()
  401. dep = DummyDependent()
  402. spec.subscribe(dep)
  403. spec.subscribe(dep)
  404. spec.unsubscribe(dep)
  405. self.assertEqual(spec.dependents[dep], 1)
  406. spec.unsubscribe(dep)
  407. self.assertNotIn(dep, spec.dependents)
  408. def test___setBases_subscribes_bases_and_notifies_dependents(self):
  409. from zope.interface.interface import Interface
  410. spec = self._makeOne()
  411. dep = DummyDependent()
  412. spec.subscribe(dep)
  413. class IFoo(Interface):
  414. pass
  415. class IBar(Interface):
  416. pass
  417. spec.__bases__ = (IFoo,)
  418. self.assertEqual(dep._changed, [spec])
  419. self.assertEqual(IFoo.dependents[spec], 1)
  420. spec.__bases__ = (IBar,)
  421. self.assertEqual(IFoo.dependents.get(spec), None)
  422. self.assertEqual(IBar.dependents[spec], 1)
  423. def test_changed_clears_volatiles_and_implied(self):
  424. from zope.interface.interface import Interface
  425. class IFoo(Interface):
  426. pass
  427. spec = self._makeOne()
  428. spec._v_attrs = 'Foo'
  429. spec._implied[IFoo] = ()
  430. spec.changed(spec)
  431. self.assertIsNone(spec._v_attrs)
  432. self.assertNotIn(IFoo, spec._implied)
  433. def test_interfaces_skips_already_seen(self):
  434. from zope.interface.interface import Interface
  435. class IFoo(Interface):
  436. pass
  437. spec = self._makeOne([IFoo, IFoo])
  438. self.assertEqual(list(spec.interfaces()), [IFoo])
  439. def test_extends_strict_wo_self(self):
  440. from zope.interface.interface import Interface
  441. class IFoo(Interface):
  442. pass
  443. spec = self._makeOne(IFoo)
  444. self.assertFalse(spec.extends(IFoo, strict=True))
  445. def test_extends_strict_w_self(self):
  446. spec = self._makeOne()
  447. self.assertFalse(spec.extends(spec, strict=True))
  448. def test_extends_non_strict_w_self(self):
  449. spec = self._makeOne()
  450. self.assertTrue(spec.extends(spec, strict=False))
  451. def test_get_hit_w__v_attrs(self):
  452. spec = self._makeOne()
  453. foo = object()
  454. spec._v_attrs = {'foo': foo}
  455. self.assertIs(spec.get('foo'), foo)
  456. def test_get_hit_from_base_wo__v_attrs(self):
  457. from zope.interface.interface import Attribute
  458. from zope.interface.interface import Interface
  459. class IFoo(Interface):
  460. foo = Attribute('foo')
  461. class IBar(Interface):
  462. bar = Attribute('bar')
  463. spec = self._makeOne([IFoo, IBar])
  464. self.assertIs(spec.get('foo'), IFoo.get('foo'))
  465. self.assertIs(spec.get('bar'), IBar.get('bar'))
  466. def test_multiple_inheritance_no_interfaces(self):
  467. # If we extend an object that implements interfaces,
  468. # plus one that doesn't, we do not interject `Interface`
  469. # early in the resolution order. It stays at the end,
  470. # like it should.
  471. # See https://github.com/zopefoundation/zope.interface/issues/8
  472. from zope.interface.declarations import implementedBy
  473. from zope.interface.declarations import implementer
  474. from zope.interface.interface import Interface
  475. class IDefaultViewName(Interface):
  476. pass
  477. class Context:
  478. pass
  479. class RDBModel(Context):
  480. pass
  481. class IOther(Interface):
  482. pass
  483. @implementer(IOther)
  484. class OtherBase:
  485. pass
  486. class Model(OtherBase, Context):
  487. pass
  488. self.assertEqual(
  489. implementedBy(Model).__sro__,
  490. (
  491. implementedBy(Model),
  492. implementedBy(OtherBase),
  493. IOther,
  494. implementedBy(Context),
  495. implementedBy(object),
  496. Interface, # This used to be wrong, it used to be 2 too high.
  497. )
  498. )
  499. class InterfaceClassTests(unittest.TestCase):
  500. def _getTargetClass(self):
  501. from zope.interface.interface import InterfaceClass
  502. return InterfaceClass
  503. def _makeOne(self, name='ITest', bases=(), attrs=None, __doc__=None,
  504. __module__=None):
  505. return self._getTargetClass()(name, bases, attrs, __doc__, __module__)
  506. def test_ctor_defaults(self):
  507. klass = self._getTargetClass()
  508. inst = klass('ITesting')
  509. self.assertEqual(inst.__name__, 'ITesting')
  510. self.assertEqual(inst.__doc__, '')
  511. self.assertEqual(inst.__bases__, ())
  512. self.assertEqual(inst.getBases(), ())
  513. def test_ctor_bad_bases(self):
  514. klass = self._getTargetClass()
  515. self.assertRaises(TypeError, klass, 'ITesting', (object(),))
  516. def test_ctor_w_attrs_attrib_methods(self):
  517. from zope.interface.interface import Attribute
  518. from zope.interface.interface import fromFunction
  519. def _bar():
  520. """DOCSTRING"""
  521. ATTRS = {
  522. 'foo': Attribute('Foo', ''),
  523. 'bar': fromFunction(_bar),
  524. }
  525. klass = self._getTargetClass()
  526. inst = klass('ITesting', attrs=ATTRS)
  527. self.assertEqual(inst.__name__, 'ITesting')
  528. self.assertEqual(inst.__doc__, '')
  529. self.assertEqual(inst.__bases__, ())
  530. self.assertEqual(inst.names(), ATTRS.keys())
  531. def test_ctor_attrs_w___locals__(self):
  532. ATTRS = {'__locals__': {}}
  533. klass = self._getTargetClass()
  534. inst = klass('ITesting', attrs=ATTRS)
  535. self.assertEqual(inst.__name__, 'ITesting')
  536. self.assertEqual(inst.__doc__, '')
  537. self.assertEqual(inst.__bases__, ())
  538. self.assertEqual(list(inst.names()), [])
  539. def test_ctor_attrs_w___annotations__(self):
  540. ATTRS = {'__annotations__': {}}
  541. klass = self._getTargetClass()
  542. inst = klass('ITesting', attrs=ATTRS)
  543. self.assertEqual(inst.__name__, 'ITesting')
  544. self.assertEqual(inst.__doc__, '')
  545. self.assertEqual(inst.__bases__, ())
  546. self.assertEqual(list(inst.names()), [])
  547. def test_ctor_attrs_w__decorator_non_return(self):
  548. from zope.interface.interface import _decorator_non_return
  549. ATTRS = {'dropme': _decorator_non_return}
  550. klass = self._getTargetClass()
  551. inst = klass('ITesting', attrs=ATTRS)
  552. self.assertEqual(inst.__name__, 'ITesting')
  553. self.assertEqual(inst.__doc__, '')
  554. self.assertEqual(inst.__bases__, ())
  555. self.assertEqual(list(inst.names()), [])
  556. def test_ctor_attrs_w_invalid_attr_type(self):
  557. from zope.interface.exceptions import InvalidInterface
  558. ATTRS = {'invalid': object()}
  559. klass = self._getTargetClass()
  560. self.assertRaises(InvalidInterface, klass, 'ITesting', attrs=ATTRS)
  561. def test_ctor_w_explicit___doc__(self):
  562. ATTRS = {'__doc__': 'ATTR'}
  563. klass = self._getTargetClass()
  564. inst = klass('ITesting', attrs=ATTRS, __doc__='EXPLICIT')
  565. self.assertEqual(inst.__doc__, 'EXPLICIT')
  566. def test_interfaces(self):
  567. iface = self._makeOne()
  568. self.assertEqual(list(iface.interfaces()), [iface])
  569. def test_getBases(self):
  570. iface = self._makeOne()
  571. sub = self._makeOne('ISub', bases=(iface,))
  572. self.assertEqual(sub.getBases(), (iface,))
  573. def test_isEqualOrExtendedBy_identity(self):
  574. iface = self._makeOne()
  575. self.assertTrue(iface.isEqualOrExtendedBy(iface))
  576. def test_isEqualOrExtendedBy_subiface(self):
  577. iface = self._makeOne()
  578. sub = self._makeOne('ISub', bases=(iface,))
  579. self.assertTrue(iface.isEqualOrExtendedBy(sub))
  580. self.assertFalse(sub.isEqualOrExtendedBy(iface))
  581. def test_isEqualOrExtendedBy_unrelated(self):
  582. one = self._makeOne('One')
  583. another = self._makeOne('Another')
  584. self.assertFalse(one.isEqualOrExtendedBy(another))
  585. self.assertFalse(another.isEqualOrExtendedBy(one))
  586. def test_names_w_all_False_ignores_bases(self):
  587. from zope.interface.interface import Attribute
  588. from zope.interface.interface import fromFunction
  589. def _bar():
  590. """DOCSTRING"""
  591. BASE_ATTRS = {
  592. 'foo': Attribute('Foo', ''),
  593. 'bar': fromFunction(_bar),
  594. }
  595. DERIVED_ATTRS = {
  596. 'baz': Attribute('Baz', ''),
  597. }
  598. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  599. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  600. self.assertEqual(sorted(derived.names(all=False)), ['baz'])
  601. def test_names_w_all_True_no_bases(self):
  602. from zope.interface.interface import Attribute
  603. from zope.interface.interface import fromFunction
  604. def _bar():
  605. """DOCSTRING"""
  606. ATTRS = {
  607. 'foo': Attribute('Foo', ''),
  608. 'bar': fromFunction(_bar),
  609. }
  610. one = self._makeOne(attrs=ATTRS)
  611. self.assertEqual(sorted(one.names(all=True)), ['bar', 'foo'])
  612. def test_names_w_all_True_w_bases_simple(self):
  613. from zope.interface.interface import Attribute
  614. from zope.interface.interface import fromFunction
  615. def _bar():
  616. """DOCSTRING"""
  617. BASE_ATTRS = {
  618. 'foo': Attribute('Foo', ''),
  619. 'bar': fromFunction(_bar),
  620. }
  621. DERIVED_ATTRS = {
  622. 'baz': Attribute('Baz', ''),
  623. }
  624. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  625. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  626. self.assertEqual(
  627. sorted(derived.names(all=True)), ['bar', 'baz', 'foo']
  628. )
  629. def test_names_w_all_True_bases_w_same_names(self):
  630. from zope.interface.interface import Attribute
  631. from zope.interface.interface import fromFunction
  632. def _bar():
  633. """DOCSTRING"""
  634. def _foo():
  635. """DOCSTRING"""
  636. BASE_ATTRS = {
  637. 'foo': Attribute('Foo', ''),
  638. 'bar': fromFunction(_bar),
  639. }
  640. DERIVED_ATTRS = {
  641. 'foo': fromFunction(_foo),
  642. 'baz': Attribute('Baz', ''),
  643. }
  644. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  645. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  646. self.assertEqual(sorted(
  647. derived.names(all=True)), ['bar', 'baz', 'foo']
  648. )
  649. def test___iter__(self):
  650. from zope.interface.interface import Attribute
  651. from zope.interface.interface import fromFunction
  652. def _bar():
  653. """DOCSTRING"""
  654. def _foo():
  655. """DOCSTRING"""
  656. BASE_ATTRS = {
  657. 'foo': Attribute('Foo', ''),
  658. 'bar': fromFunction(_bar),
  659. }
  660. DERIVED_ATTRS = {
  661. 'foo': fromFunction(_foo),
  662. 'baz': Attribute('Baz', ''),
  663. }
  664. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  665. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  666. self.assertEqual(sorted(derived), ['bar', 'baz', 'foo'])
  667. def test_namesAndDescriptions_w_all_False_ignores_bases(self):
  668. from zope.interface.interface import Attribute
  669. from zope.interface.interface import fromFunction
  670. def _bar():
  671. """DOCSTRING"""
  672. BASE_ATTRS = {
  673. 'foo': Attribute('Foo', ''),
  674. 'bar': fromFunction(_bar),
  675. }
  676. DERIVED_ATTRS = {
  677. 'baz': Attribute('Baz', ''),
  678. }
  679. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  680. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  681. self.assertEqual(
  682. sorted(derived.namesAndDescriptions(all=False)), [
  683. ('baz', DERIVED_ATTRS['baz']),
  684. ]
  685. )
  686. def test_namesAndDescriptions_w_all_True_no_bases(self):
  687. from zope.interface.interface import Attribute
  688. from zope.interface.interface import fromFunction
  689. def _bar():
  690. """DOCSTRING"""
  691. ATTRS = {
  692. 'foo': Attribute('Foo', ''),
  693. 'bar': fromFunction(_bar),
  694. }
  695. one = self._makeOne(attrs=ATTRS)
  696. self.assertEqual(
  697. sorted(one.namesAndDescriptions(all=False)), [
  698. ('bar', ATTRS['bar']),
  699. ('foo', ATTRS['foo']),
  700. ]
  701. )
  702. def test_namesAndDescriptions_w_all_True_simple(self):
  703. from zope.interface.interface import Attribute
  704. from zope.interface.interface import fromFunction
  705. def _bar():
  706. """DOCSTRING"""
  707. BASE_ATTRS = {
  708. 'foo': Attribute('Foo', ''),
  709. 'bar': fromFunction(_bar),
  710. }
  711. DERIVED_ATTRS = {
  712. 'baz': Attribute('Baz', ''),
  713. }
  714. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  715. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  716. self.assertEqual(
  717. sorted(derived.namesAndDescriptions(all=True)), [
  718. ('bar', BASE_ATTRS['bar']),
  719. ('baz', DERIVED_ATTRS['baz']),
  720. ('foo', BASE_ATTRS['foo']),
  721. ]
  722. )
  723. def test_namesAndDescriptions_w_all_True_bases_w_same_names(self):
  724. from zope.interface.interface import Attribute
  725. from zope.interface.interface import fromFunction
  726. def _bar():
  727. """DOCSTRING"""
  728. def _foo():
  729. """DOCSTRING"""
  730. BASE_ATTRS = {
  731. 'foo': Attribute('Foo', ''),
  732. 'bar': fromFunction(_bar),
  733. }
  734. DERIVED_ATTRS = {
  735. 'foo': fromFunction(_foo),
  736. 'baz': Attribute('Baz', ''),
  737. }
  738. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  739. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  740. self.assertEqual(
  741. sorted(derived.namesAndDescriptions(all=True)), [
  742. ('bar', BASE_ATTRS['bar']),
  743. ('baz', DERIVED_ATTRS['baz']),
  744. ('foo', DERIVED_ATTRS['foo']),
  745. ]
  746. )
  747. def test_getDescriptionFor_miss(self):
  748. one = self._makeOne()
  749. self.assertRaises(KeyError, one.getDescriptionFor, 'nonesuch')
  750. def test_getDescriptionFor_hit(self):
  751. from zope.interface.interface import Attribute
  752. from zope.interface.interface import fromFunction
  753. def _bar():
  754. """DOCSTRING"""
  755. ATTRS = {
  756. 'foo': Attribute('Foo', ''),
  757. 'bar': fromFunction(_bar),
  758. }
  759. one = self._makeOne(attrs=ATTRS)
  760. self.assertEqual(one.getDescriptionFor('foo'), ATTRS['foo'])
  761. self.assertEqual(one.getDescriptionFor('bar'), ATTRS['bar'])
  762. def test___getitem___miss(self):
  763. one = self._makeOne()
  764. def _test():
  765. return one['nonesuch']
  766. self.assertRaises(KeyError, _test)
  767. def test___getitem___hit(self):
  768. from zope.interface.interface import Attribute
  769. from zope.interface.interface import fromFunction
  770. def _bar():
  771. """DOCSTRING"""
  772. ATTRS = {
  773. 'foo': Attribute('Foo', ''),
  774. 'bar': fromFunction(_bar),
  775. }
  776. one = self._makeOne(attrs=ATTRS)
  777. self.assertEqual(one['foo'], ATTRS['foo'])
  778. self.assertEqual(one['bar'], ATTRS['bar'])
  779. def test___contains___miss(self):
  780. one = self._makeOne()
  781. self.assertNotIn('nonesuch', one)
  782. def test___contains___hit(self):
  783. from zope.interface.interface import Attribute
  784. from zope.interface.interface import fromFunction
  785. def _bar():
  786. """DOCSTRING"""
  787. ATTRS = {
  788. 'foo': Attribute('Foo', ''),
  789. 'bar': fromFunction(_bar),
  790. }
  791. one = self._makeOne(attrs=ATTRS)
  792. self.assertIn('foo', one)
  793. self.assertIn('bar', one)
  794. def test_direct_miss(self):
  795. one = self._makeOne()
  796. self.assertEqual(one.direct('nonesuch'), None)
  797. def test_direct_hit_local_miss_bases(self):
  798. from zope.interface.interface import Attribute
  799. from zope.interface.interface import fromFunction
  800. def _bar():
  801. """DOCSTRING"""
  802. def _foo():
  803. """DOCSTRING"""
  804. BASE_ATTRS = {
  805. 'foo': Attribute('Foo', ''),
  806. 'bar': fromFunction(_bar),
  807. }
  808. DERIVED_ATTRS = {
  809. 'foo': fromFunction(_foo),
  810. 'baz': Attribute('Baz', ''),
  811. }
  812. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  813. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  814. self.assertEqual(derived.direct('foo'), DERIVED_ATTRS['foo'])
  815. self.assertEqual(derived.direct('baz'), DERIVED_ATTRS['baz'])
  816. self.assertEqual(derived.direct('bar'), None)
  817. def test_queryDescriptionFor_miss(self):
  818. iface = self._makeOne()
  819. self.assertEqual(iface.queryDescriptionFor('nonesuch'), None)
  820. def test_queryDescriptionFor_hit(self):
  821. from zope.interface import Attribute
  822. ATTRS = {'attr': Attribute('Title', 'Description')}
  823. iface = self._makeOne(attrs=ATTRS)
  824. self.assertEqual(iface.queryDescriptionFor('attr'), ATTRS['attr'])
  825. def test_validateInvariants_pass(self):
  826. _called_with = []
  827. def _passable(*args, **kw):
  828. _called_with.append((args, kw))
  829. return True
  830. iface = self._makeOne()
  831. obj = object()
  832. iface.setTaggedValue('invariants', [_passable])
  833. self.assertEqual(iface.validateInvariants(obj), None)
  834. self.assertEqual(_called_with, [((obj,), {})])
  835. def test_validateInvariants_fail_wo_errors_passed(self):
  836. from zope.interface.exceptions import Invalid
  837. _passable_called_with = []
  838. def _passable(*args, **kw):
  839. _passable_called_with.append((args, kw))
  840. return True
  841. _fail_called_with = []
  842. def _fail(*args, **kw):
  843. _fail_called_with.append((args, kw))
  844. raise Invalid
  845. iface = self._makeOne()
  846. obj = object()
  847. iface.setTaggedValue('invariants', [_passable, _fail])
  848. self.assertRaises(Invalid, iface.validateInvariants, obj)
  849. self.assertEqual(_passable_called_with, [((obj,), {})])
  850. self.assertEqual(_fail_called_with, [((obj,), {})])
  851. def test_validateInvariants_fail_w_errors_passed(self):
  852. from zope.interface.exceptions import Invalid
  853. _errors = []
  854. _fail_called_with = []
  855. def _fail(*args, **kw):
  856. _fail_called_with.append((args, kw))
  857. raise Invalid
  858. iface = self._makeOne()
  859. obj = object()
  860. iface.setTaggedValue('invariants', [_fail])
  861. self.assertRaises(Invalid, iface.validateInvariants, obj, _errors)
  862. self.assertEqual(_fail_called_with, [((obj,), {})])
  863. self.assertEqual(len(_errors), 1)
  864. self.assertIsInstance(_errors[0], Invalid)
  865. def test_validateInvariants_fail_in_base_wo_errors_passed(self):
  866. from zope.interface.exceptions import Invalid
  867. _passable_called_with = []
  868. def _passable(*args, **kw):
  869. _passable_called_with.append((args, kw))
  870. return True
  871. _fail_called_with = []
  872. def _fail(*args, **kw):
  873. _fail_called_with.append((args, kw))
  874. raise Invalid
  875. base = self._makeOne('IBase')
  876. derived = self._makeOne('IDerived', (base,))
  877. obj = object()
  878. base.setTaggedValue('invariants', [_fail])
  879. derived.setTaggedValue('invariants', [_passable])
  880. self.assertRaises(Invalid, derived.validateInvariants, obj)
  881. self.assertEqual(_passable_called_with, [((obj,), {})])
  882. self.assertEqual(_fail_called_with, [((obj,), {})])
  883. def test_validateInvariants_fail_in_base_w_errors_passed(self):
  884. from zope.interface.exceptions import Invalid
  885. _errors = []
  886. _passable_called_with = []
  887. def _passable(*args, **kw):
  888. _passable_called_with.append((args, kw))
  889. return True
  890. _fail_called_with = []
  891. def _fail(*args, **kw):
  892. _fail_called_with.append((args, kw))
  893. raise Invalid
  894. base = self._makeOne('IBase')
  895. derived = self._makeOne('IDerived', (base,))
  896. obj = object()
  897. base.setTaggedValue('invariants', [_fail])
  898. derived.setTaggedValue('invariants', [_passable])
  899. self.assertRaises(Invalid, derived.validateInvariants, obj, _errors)
  900. self.assertEqual(_passable_called_with, [((obj,), {})])
  901. self.assertEqual(_fail_called_with, [((obj,), {})])
  902. self.assertEqual(len(_errors), 1)
  903. self.assertIsInstance(_errors[0], Invalid)
  904. def test_validateInvariants_inherited_not_called_multiple_times(self):
  905. _passable_called_with = []
  906. def _passable(*args, **kw):
  907. _passable_called_with.append((args, kw))
  908. return True
  909. obj = object()
  910. base = self._makeOne('IBase')
  911. base.setTaggedValue('invariants', [_passable])
  912. derived = self._makeOne('IDerived', (base,))
  913. derived.validateInvariants(obj)
  914. self.assertEqual(1, len(_passable_called_with))
  915. def test___reduce__(self):
  916. iface = self._makeOne('PickleMe')
  917. self.assertEqual(iface.__reduce__(), 'PickleMe')
  918. def test___hash___normal(self):
  919. iface = self._makeOne('HashMe')
  920. self.assertEqual(
  921. hash(iface),
  922. hash(('HashMe', '__tests__.tests.test_interface'))
  923. )
  924. def test___hash___missing_required_attrs(self):
  925. class Derived(self._getTargetClass()):
  926. def __init__(self): # pylint:disable=super-init-not-called
  927. pass # Don't call base class.
  928. derived = Derived()
  929. with self.assertRaises(AttributeError):
  930. hash(derived)
  931. def test_comparison_with_None(self):
  932. # pylint:disable=singleton-comparison,misplaced-comparison-constant
  933. iface = self._makeOne()
  934. self.assertLess(iface, None) # noqa E711
  935. self.assertLessEqual(iface, None) # noqa E711
  936. self.assertNotEqual(iface, None) # noqa E711
  937. self.assertNotEqual(iface, None) # noqa E711
  938. self.assertFalse(iface >= None) # noqa E711
  939. self.assertFalse(iface > None) # noqa E711
  940. self.assertFalse(None < iface) # noqa E711
  941. self.assertFalse(None <= iface) # noqa E711
  942. self.assertNotEqual(None, iface) # noqa E711
  943. self.assertNotEqual(None, iface) # noqa E711
  944. self.assertGreaterEqual(None, iface) # noqa E711
  945. self.assertGreater(None, iface) # noqa E711
  946. def test_comparison_with_same_instance(self):
  947. # pylint:disable=comparison-with-itself
  948. iface = self._makeOne()
  949. self.assertFalse(iface < iface)
  950. self.assertLessEqual(iface, iface)
  951. self.assertEqual(iface, iface)
  952. self.assertEqual(iface, iface)
  953. self.assertGreaterEqual(iface, iface)
  954. self.assertFalse(iface > iface)
  955. def test_comparison_with_same_named_instance_in_other_module(self):
  956. one = self._makeOne('IName', __module__='__tests__.tests.one')
  957. other = self._makeOne('IName', __module__='__tests__.tests.other')
  958. self.assertLess(one, other)
  959. self.assertFalse(other < one)
  960. self.assertLessEqual(one, other)
  961. self.assertFalse(other <= one)
  962. self.assertNotEqual(one, other)
  963. self.assertNotEqual(other, one)
  964. self.assertNotEqual(one, other)
  965. self.assertNotEqual(other, one)
  966. self.assertFalse(one >= other)
  967. self.assertGreaterEqual(other, one)
  968. self.assertFalse(one > other)
  969. self.assertGreater(other, one)
  970. def test_assignment_to__class__(self):
  971. # https://github.com/zopefoundation/zope.interface/issues/6
  972. class MyException(Exception):
  973. pass
  974. class MyInterfaceClass(self._getTargetClass()):
  975. def __call__(self, target):
  976. raise MyException(target)
  977. IFoo = self._makeOne('IName')
  978. self.assertIsInstance(IFoo, self._getTargetClass())
  979. self.assertIs(type(IFoo), self._getTargetClass())
  980. with self.assertRaises(TypeError):
  981. IFoo(1)
  982. IFoo.__class__ = MyInterfaceClass
  983. self.assertIsInstance(IFoo, MyInterfaceClass)
  984. self.assertIs(type(IFoo), MyInterfaceClass)
  985. with self.assertRaises(MyException):
  986. IFoo(1)
  987. def test_assignment_to__class__2(self):
  988. # https://github.com/zopefoundation/zope.interface/issues/6
  989. # This is essentially a transcription of the
  990. # test presented in the bug report.
  991. from zope.interface import Interface
  992. class MyInterfaceClass(self._getTargetClass()):
  993. def __call__(self, *args):
  994. return args
  995. IFoo = MyInterfaceClass('IFoo', (Interface,))
  996. self.assertEqual(IFoo(1), (1,))
  997. class IBar(IFoo):
  998. pass
  999. self.assertEqual(IBar(1), (1,))
  1000. class ISpam(Interface):
  1001. pass
  1002. with self.assertRaises(TypeError):
  1003. ISpam()
  1004. ISpam.__class__ = MyInterfaceClass
  1005. self.assertEqual(ISpam(1), (1,))
  1006. def test__module__is_readonly(self):
  1007. inst = self._makeOne()
  1008. with self.assertRaises(AttributeError):
  1009. inst.__module__ = 'different.module'
  1010. class InterfaceTests(unittest.TestCase):
  1011. def test_attributes_link_to_interface(self):
  1012. from zope.interface import Attribute
  1013. from zope.interface import Interface
  1014. class I1(Interface):
  1015. attr = Attribute("My attr")
  1016. self.assertIs(I1['attr'].interface, I1)
  1017. def test_methods_link_to_interface(self):
  1018. from zope.interface import Interface
  1019. class I1(Interface):
  1020. def method(foo, bar, bingo):
  1021. "A method"
  1022. self.assertIs(I1['method'].interface, I1)
  1023. def test_classImplements_simple(self):
  1024. from zope.interface import Interface
  1025. from zope.interface import implementedBy
  1026. from zope.interface import providedBy
  1027. class ICurrent(Interface):
  1028. def method1(a, b):
  1029. """docstring"""
  1030. def method2(a, b):
  1031. """docstring"""
  1032. class IOther(Interface):
  1033. pass
  1034. class Current:
  1035. __implemented__ = ICurrent
  1036. def method1(self, a, b):
  1037. raise NotImplementedError()
  1038. def method2(self, a, b):
  1039. raise NotImplementedError()
  1040. current = Current()
  1041. self.assertTrue(ICurrent.implementedBy(Current))
  1042. self.assertFalse(IOther.implementedBy(Current))
  1043. self.assertEqual(ICurrent, ICurrent)
  1044. self.assertIn(ICurrent, implementedBy(Current))
  1045. self.assertNotIn(IOther, implementedBy(Current))
  1046. self.assertIn(ICurrent, providedBy(current))
  1047. self.assertNotIn(IOther, providedBy(current))
  1048. def test_classImplements_base_not_derived(self):
  1049. from zope.interface import Interface
  1050. from zope.interface import implementedBy
  1051. from zope.interface import providedBy
  1052. class IBase(Interface):
  1053. def method():
  1054. """docstring"""
  1055. class IDerived(IBase):
  1056. pass
  1057. class Current():
  1058. __implemented__ = IBase
  1059. def method(self):
  1060. raise NotImplementedError()
  1061. current = Current()
  1062. self.assertTrue(IBase.implementedBy(Current))
  1063. self.assertFalse(IDerived.implementedBy(Current))
  1064. self.assertIn(IBase, implementedBy(Current))
  1065. self.assertNotIn(IDerived, implementedBy(Current))
  1066. self.assertIn(IBase, providedBy(current))
  1067. self.assertNotIn(IDerived, providedBy(current))
  1068. def test_classImplements_base_and_derived(self):
  1069. from zope.interface import Interface
  1070. from zope.interface import implementedBy
  1071. from zope.interface import providedBy
  1072. class IBase(Interface):
  1073. def method():
  1074. """docstring"""
  1075. class IDerived(IBase):
  1076. pass
  1077. class Current:
  1078. __implemented__ = IDerived
  1079. def method(self):
  1080. raise NotImplementedError()
  1081. current = Current()
  1082. self.assertTrue(IBase.implementedBy(Current))
  1083. self.assertTrue(IDerived.implementedBy(Current))
  1084. self.assertNotIn(IBase, implementedBy(Current))
  1085. self.assertIn(IBase, implementedBy(Current).flattened())
  1086. self.assertIn(IDerived, implementedBy(Current))
  1087. self.assertNotIn(IBase, providedBy(current))
  1088. self.assertIn(IBase, providedBy(current).flattened())
  1089. self.assertIn(IDerived, providedBy(current))
  1090. def test_classImplements_multiple(self):
  1091. from zope.interface import Interface
  1092. from zope.interface import implementedBy
  1093. from zope.interface import providedBy
  1094. class ILeft(Interface):
  1095. def method():
  1096. """docstring"""
  1097. class IRight(ILeft):
  1098. pass
  1099. class Left:
  1100. __implemented__ = ILeft
  1101. def method(self):
  1102. raise NotImplementedError()
  1103. class Right:
  1104. __implemented__ = IRight
  1105. class Ambi(Left, Right):
  1106. pass
  1107. ambi = Ambi()
  1108. self.assertTrue(ILeft.implementedBy(Ambi))
  1109. self.assertTrue(IRight.implementedBy(Ambi))
  1110. self.assertIn(ILeft, implementedBy(Ambi))
  1111. self.assertIn(IRight, implementedBy(Ambi))
  1112. self.assertIn(ILeft, providedBy(ambi))
  1113. self.assertIn(IRight, providedBy(ambi))
  1114. def test_classImplements_multiple_w_explict_implements(self):
  1115. from zope.interface import Interface
  1116. from zope.interface import implementedBy
  1117. from zope.interface import providedBy
  1118. class ILeft(Interface):
  1119. def method():
  1120. """docstring"""
  1121. class IRight(ILeft):
  1122. pass
  1123. class IOther(Interface):
  1124. pass
  1125. class Left():
  1126. __implemented__ = ILeft
  1127. def method(self):
  1128. raise NotImplementedError()
  1129. class Right:
  1130. __implemented__ = IRight
  1131. class Other:
  1132. __implemented__ = IOther
  1133. class Mixed(Left, Right):
  1134. __implemented__ = Left.__implemented__, Other.__implemented__
  1135. mixed = Mixed()
  1136. self.assertTrue(ILeft.implementedBy(Mixed))
  1137. self.assertFalse(IRight.implementedBy(Mixed))
  1138. self.assertTrue(IOther.implementedBy(Mixed))
  1139. self.assertIn(ILeft, implementedBy(Mixed))
  1140. self.assertNotIn(IRight, implementedBy(Mixed))
  1141. self.assertIn(IOther, implementedBy(Mixed))
  1142. self.assertIn(ILeft, providedBy(mixed))
  1143. self.assertNotIn(IRight, providedBy(mixed))
  1144. self.assertIn(IOther, providedBy(mixed))
  1145. def testInterfaceExtendsInterface(self):
  1146. from zope.interface import Interface
  1147. new = Interface.__class__
  1148. FunInterface = new('FunInterface')
  1149. BarInterface = new('BarInterface', (FunInterface,))
  1150. BobInterface = new('BobInterface')
  1151. BazInterface = new('BazInterface', (BobInterface, BarInterface,))
  1152. self.assertTrue(BazInterface.extends(BobInterface))
  1153. self.assertTrue(BazInterface.extends(BarInterface))
  1154. self.assertTrue(BazInterface.extends(FunInterface))
  1155. self.assertFalse(BobInterface.extends(FunInterface))
  1156. self.assertFalse(BobInterface.extends(BarInterface))
  1157. self.assertTrue(BarInterface.extends(FunInterface))
  1158. self.assertFalse(BarInterface.extends(BazInterface))
  1159. def test_verifyClass(self):
  1160. from zope.interface import Attribute
  1161. from zope.interface import Interface
  1162. from zope.interface.verify import verifyClass
  1163. class ICheckMe(Interface):
  1164. attr = Attribute('My attr')
  1165. def method():
  1166. "A method"
  1167. class CheckMe:
  1168. __implemented__ = ICheckMe
  1169. attr = 'value'
  1170. def method(self):
  1171. raise NotImplementedError()
  1172. self.assertTrue(verifyClass(ICheckMe, CheckMe))
  1173. def test_verifyObject(self):
  1174. from zope.interface import Attribute
  1175. from zope.interface import Interface
  1176. from zope.interface.verify import verifyObject
  1177. class ICheckMe(Interface):
  1178. attr = Attribute('My attr')
  1179. def method():
  1180. "A method"
  1181. class CheckMe:
  1182. __implemented__ = ICheckMe
  1183. attr = 'value'
  1184. def method(self):
  1185. raise NotImplementedError()
  1186. check_me = CheckMe()
  1187. self.assertTrue(verifyObject(ICheckMe, check_me))
  1188. def test_interface_object_provides_Interface(self):
  1189. from zope.interface import Interface
  1190. class AnInterface(Interface):
  1191. pass
  1192. self.assertTrue(Interface.providedBy(AnInterface))
  1193. def test_names_simple(self):
  1194. from zope.interface import Attribute
  1195. from zope.interface import Interface
  1196. class ISimple(Interface):
  1197. attr = Attribute('My attr')
  1198. def method():
  1199. """docstring"""
  1200. self.assertEqual(sorted(ISimple.names()), ['attr', 'method'])
  1201. def test_names_derived(self):
  1202. from zope.interface import Attribute
  1203. from zope.interface import Interface
  1204. class IBase(Interface):
  1205. attr = Attribute('My attr')
  1206. def method():
  1207. """docstring"""
  1208. class IDerived(IBase):
  1209. attr2 = Attribute('My attr2')
  1210. def method():
  1211. """docstring"""
  1212. def method2():
  1213. """docstring"""
  1214. self.assertEqual(sorted(IDerived.names()),
  1215. ['attr2', 'method', 'method2'])
  1216. self.assertEqual(sorted(IDerived.names(all=True)),
  1217. ['attr', 'attr2', 'method', 'method2'])
  1218. def test_namesAndDescriptions_simple(self):
  1219. from zope.interface import Attribute
  1220. from zope.interface import Interface
  1221. from zope.interface.interface import Method
  1222. class ISimple(Interface):
  1223. attr = Attribute('My attr')
  1224. def method():
  1225. "My method"
  1226. name_values = sorted(ISimple.namesAndDescriptions())
  1227. self.assertEqual(len(name_values), 2)
  1228. self.assertEqual(name_values[0][0], 'attr')
  1229. self.assertIsInstance(name_values[0][1], Attribute)
  1230. self.assertEqual(name_values[0][1].__name__, 'attr')
  1231. self.assertEqual(name_values[0][1].__doc__, 'My attr')
  1232. self.assertEqual(name_values[1][0], 'method')
  1233. self.assertIsInstance(name_values[1][1], Method)
  1234. self.assertEqual(name_values[1][1].__name__, 'method')
  1235. self.assertEqual(name_values[1][1].__doc__, 'My method')
  1236. def test_namesAndDescriptions_derived(self):
  1237. from zope.interface import Attribute
  1238. from zope.interface import Interface
  1239. from zope.interface.interface import Method
  1240. class IBase(Interface):
  1241. attr = Attribute('My attr')
  1242. def method():
  1243. "My method"
  1244. class IDerived(IBase):
  1245. attr2 = Attribute('My attr2')
  1246. def method():
  1247. "My method, overridden"
  1248. def method2():
  1249. "My method2"
  1250. name_values = sorted(IDerived.namesAndDescriptions())
  1251. self.assertEqual(len(name_values), 3)
  1252. self.assertEqual(name_values[0][0], 'attr2')
  1253. self.assertIsInstance(name_values[0][1], Attribute)
  1254. self.assertEqual(name_values[0][1].__name__, 'attr2')
  1255. self.assertEqual(name_values[0][1].__doc__, 'My attr2')
  1256. self.assertEqual(name_values[1][0], 'method')
  1257. self.assertIsInstance(name_values[1][1], Method)
  1258. self.assertEqual(name_values[1][1].__name__, 'method')
  1259. self.assertEqual(name_values[1][1].__doc__, 'My method, overridden')
  1260. self.assertEqual(name_values[2][0], 'method2')
  1261. self.assertIsInstance(name_values[2][1], Method)
  1262. self.assertEqual(name_values[2][1].__name__, 'method2')
  1263. self.assertEqual(name_values[2][1].__doc__, 'My method2')
  1264. name_values = sorted(IDerived.namesAndDescriptions(all=True))
  1265. self.assertEqual(len(name_values), 4)
  1266. self.assertEqual(name_values[0][0], 'attr')
  1267. self.assertIsInstance(name_values[0][1], Attribute)
  1268. self.assertEqual(name_values[0][1].__name__, 'attr')
  1269. self.assertEqual(name_values[0][1].__doc__, 'My attr')
  1270. self.assertEqual(name_values[1][0], 'attr2')
  1271. self.assertIsInstance(name_values[1][1], Attribute)
  1272. self.assertEqual(name_values[1][1].__name__, 'attr2')
  1273. self.assertEqual(name_values[1][1].__doc__, 'My attr2')
  1274. self.assertEqual(name_values[2][0], 'method')
  1275. self.assertIsInstance(name_values[2][1], Method)
  1276. self.assertEqual(name_values[2][1].__name__, 'method')
  1277. self.assertEqual(name_values[2][1].__doc__, 'My method, overridden')
  1278. self.assertEqual(name_values[3][0], 'method2')
  1279. self.assertIsInstance(name_values[3][1], Method)
  1280. self.assertEqual(name_values[3][1].__name__, 'method2')
  1281. self.assertEqual(name_values[3][1].__doc__, 'My method2')
  1282. def test_getDescriptionFor_nonesuch_no_default(self):
  1283. from zope.interface import Interface
  1284. class IEmpty(Interface):
  1285. pass
  1286. self.assertRaises(KeyError, IEmpty.getDescriptionFor, 'nonesuch')
  1287. def test_getDescriptionFor_simple(self):
  1288. from zope.interface import Attribute
  1289. from zope.interface import Interface
  1290. from zope.interface.interface import Method
  1291. class ISimple(Interface):
  1292. attr = Attribute('My attr')
  1293. def method():
  1294. "My method"
  1295. a_desc = ISimple.getDescriptionFor('attr')
  1296. self.assertIsInstance(a_desc, Attribute)
  1297. self.assertEqual(a_desc.__name__, 'attr')
  1298. self.assertEqual(a_desc.__doc__, 'My attr')
  1299. m_desc = ISimple.getDescriptionFor('method')
  1300. self.assertIsInstance(m_desc, Method)
  1301. self.assertEqual(m_desc.__name__, 'method')
  1302. self.assertEqual(m_desc.__doc__, 'My method')
  1303. def test_getDescriptionFor_derived(self):
  1304. from zope.interface import Attribute
  1305. from zope.interface import Interface
  1306. from zope.interface.interface import Method
  1307. class IBase(Interface):
  1308. attr = Attribute('My attr')
  1309. def method():
  1310. "My method"
  1311. class IDerived(IBase):
  1312. attr2 = Attribute('My attr2')
  1313. def method():
  1314. "My method, overridden"
  1315. def method2():
  1316. "My method2"
  1317. a_desc = IDerived.getDescriptionFor('attr')
  1318. self.assertIsInstance(a_desc, Attribute)
  1319. self.assertEqual(a_desc.__name__, 'attr')
  1320. self.assertEqual(a_desc.__doc__, 'My attr')
  1321. m_desc = IDerived.getDescriptionFor('method')
  1322. self.assertIsInstance(m_desc, Method)
  1323. self.assertEqual(m_desc.__name__, 'method')
  1324. self.assertEqual(m_desc.__doc__, 'My method, overridden')
  1325. a2_desc = IDerived.getDescriptionFor('attr2')
  1326. self.assertIsInstance(a2_desc, Attribute)
  1327. self.assertEqual(a2_desc.__name__, 'attr2')
  1328. self.assertEqual(a2_desc.__doc__, 'My attr2')
  1329. m2_desc = IDerived.getDescriptionFor('method2')
  1330. self.assertIsInstance(m2_desc, Method)
  1331. self.assertEqual(m2_desc.__name__, 'method2')
  1332. self.assertEqual(m2_desc.__doc__, 'My method2')
  1333. def test___getitem__nonesuch(self):
  1334. from zope.interface import Interface
  1335. class IEmpty(Interface):
  1336. pass
  1337. self.assertRaises(KeyError, IEmpty.__getitem__, 'nonesuch')
  1338. def test___getitem__simple(self):
  1339. from zope.interface import Attribute
  1340. from zope.interface import Interface
  1341. from zope.interface.interface import Method
  1342. class ISimple(Interface):
  1343. attr = Attribute('My attr')
  1344. def method():
  1345. "My method"
  1346. a_desc = ISimple['attr']
  1347. self.assertIsInstance(a_desc, Attribute)
  1348. self.assertEqual(a_desc.__name__, 'attr')
  1349. self.assertEqual(a_desc.__doc__, 'My attr')
  1350. m_desc = ISimple['method']
  1351. self.assertIsInstance(m_desc, Method)
  1352. self.assertEqual(m_desc.__name__, 'method')
  1353. self.assertEqual(m_desc.__doc__, 'My method')
  1354. def test___getitem___derived(self):
  1355. from zope.interface import Attribute
  1356. from zope.interface import Interface
  1357. from zope.interface.interface import Method
  1358. class IBase(Interface):
  1359. attr = Attribute('My attr')
  1360. def method():
  1361. "My method"
  1362. class IDerived(IBase):
  1363. attr2 = Attribute('My attr2')
  1364. def method():
  1365. "My method, overridden"
  1366. def method2():
  1367. "My method2"
  1368. a_desc = IDerived['attr']
  1369. self.assertIsInstance(a_desc, Attribute)
  1370. self.assertEqual(a_desc.__name__, 'attr')
  1371. self.assertEqual(a_desc.__doc__, 'My attr')
  1372. m_desc = IDerived['method']
  1373. self.assertIsInstance(m_desc, Method)
  1374. self.assertEqual(m_desc.__name__, 'method')
  1375. self.assertEqual(m_desc.__doc__, 'My method, overridden')
  1376. a2_desc = IDerived['attr2']
  1377. self.assertIsInstance(a2_desc, Attribute)
  1378. self.assertEqual(a2_desc.__name__, 'attr2')
  1379. self.assertEqual(a2_desc.__doc__, 'My attr2')
  1380. m2_desc = IDerived['method2']
  1381. self.assertIsInstance(m2_desc, Method)
  1382. self.assertEqual(m2_desc.__name__, 'method2')
  1383. self.assertEqual(m2_desc.__doc__, 'My method2')
  1384. def test___contains__nonesuch(self):
  1385. from zope.interface import Interface
  1386. class IEmpty(Interface):
  1387. pass
  1388. self.assertNotIn('nonesuch', IEmpty)
  1389. def test___contains__simple(self):
  1390. from zope.interface import Attribute
  1391. from zope.interface import Interface
  1392. class ISimple(Interface):
  1393. attr = Attribute('My attr')
  1394. def method():
  1395. "My method"
  1396. self.assertIn('attr', ISimple)
  1397. self.assertIn('method', ISimple)
  1398. def test___contains__derived(self):
  1399. from zope.interface import Attribute
  1400. from zope.interface import Interface
  1401. class IBase(Interface):
  1402. attr = Attribute('My attr')
  1403. def method():
  1404. "My method"
  1405. class IDerived(IBase):
  1406. attr2 = Attribute('My attr2')
  1407. def method():
  1408. "My method, overridden"
  1409. def method2():
  1410. "My method2"
  1411. self.assertIn('attr', IDerived)
  1412. self.assertIn('method', IDerived)
  1413. self.assertIn('attr2', IDerived)
  1414. self.assertIn('method2', IDerived)
  1415. def test___iter__empty(self):
  1416. from zope.interface import Interface
  1417. class IEmpty(Interface):
  1418. pass
  1419. self.assertEqual(list(IEmpty), [])
  1420. def test___iter__simple(self):
  1421. from zope.interface import Attribute
  1422. from zope.interface import Interface
  1423. class ISimple(Interface):
  1424. attr = Attribute('My attr')
  1425. def method():
  1426. "My method"
  1427. self.assertEqual(sorted(list(ISimple)), ['attr', 'method'])
  1428. def test___iter__derived(self):
  1429. from zope.interface import Attribute
  1430. from zope.interface import Interface
  1431. class IBase(Interface):
  1432. attr = Attribute('My attr')
  1433. def method():
  1434. "My method"
  1435. class IDerived(IBase):
  1436. attr2 = Attribute('My attr2')
  1437. def method():
  1438. "My method, overridden"
  1439. def method2():
  1440. "My method2"
  1441. self.assertEqual(sorted(list(IDerived)),
  1442. ['attr', 'attr2', 'method', 'method2'])
  1443. def test_function_attributes_become_tagged_values(self):
  1444. from zope.interface import Interface
  1445. class ITagMe(Interface):
  1446. def method():
  1447. """docstring"""
  1448. method.optional = 1
  1449. method = ITagMe['method']
  1450. self.assertEqual(method.getTaggedValue('optional'), 1)
  1451. def test___doc___non_element(self):
  1452. from zope.interface import Interface
  1453. class IHaveADocString(Interface):
  1454. "xxx"
  1455. self.assertEqual(IHaveADocString.__doc__, "xxx")
  1456. self.assertEqual(list(IHaveADocString), [])
  1457. def test___doc___as_element(self):
  1458. from zope.interface import Attribute
  1459. from zope.interface import Interface
  1460. class IHaveADocString(Interface):
  1461. "xxx"
  1462. __doc__ = Attribute('the doc')
  1463. self.assertEqual(IHaveADocString.__doc__, "")
  1464. self.assertEqual(list(IHaveADocString), ['__doc__'])
  1465. def _errorsEqual(self, has_invariant, error_len, error_msgs, iface):
  1466. from zope.interface.exceptions import Invalid
  1467. self.assertRaises(Invalid, iface.validateInvariants, has_invariant)
  1468. e = []
  1469. try:
  1470. iface.validateInvariants(has_invariant, e)
  1471. self.fail("validateInvariants should always raise")
  1472. except Invalid as error:
  1473. self.assertEqual(error.args[0], e)
  1474. self.assertEqual(len(e), error_len)
  1475. msgs = [error.args[0] for error in e]
  1476. msgs.sort()
  1477. for msg in msgs:
  1478. self.assertEqual(msg, error_msgs.pop(0))
  1479. def test_invariant_simple(self):
  1480. from zope.interface import Attribute
  1481. from zope.interface import Interface
  1482. from zope.interface import directlyProvides
  1483. from zope.interface import invariant
  1484. class IInvariant(Interface):
  1485. foo = Attribute('foo')
  1486. bar = Attribute('bar; must eval to Boolean True if foo does')
  1487. invariant(_ifFooThenBar)
  1488. class HasInvariant:
  1489. pass
  1490. # set up
  1491. has_invariant = HasInvariant()
  1492. directlyProvides(has_invariant, IInvariant)
  1493. # the tests
  1494. self.assertEqual(IInvariant.getTaggedValue('invariants'),
  1495. [_ifFooThenBar])
  1496. self.assertEqual(IInvariant.validateInvariants(has_invariant), None)
  1497. has_invariant.bar = 27
  1498. self.assertEqual(IInvariant.validateInvariants(has_invariant), None)
  1499. has_invariant.foo = 42
  1500. self.assertEqual(IInvariant.validateInvariants(has_invariant), None)
  1501. del has_invariant.bar
  1502. self._errorsEqual(has_invariant, 1, ['If Foo, then Bar!'],
  1503. IInvariant)
  1504. def test_invariant_nested(self):
  1505. from zope.interface import Attribute
  1506. from zope.interface import Interface
  1507. from zope.interface import directlyProvides
  1508. from zope.interface import invariant
  1509. class IInvariant(Interface):
  1510. foo = Attribute('foo')
  1511. bar = Attribute('bar; must eval to Boolean True if foo does')
  1512. invariant(_ifFooThenBar)
  1513. class ISubInvariant(IInvariant):
  1514. invariant(_barGreaterThanFoo)
  1515. class HasInvariant:
  1516. pass
  1517. # nested interfaces with invariants:
  1518. self.assertEqual(ISubInvariant.getTaggedValue('invariants'),
  1519. [_barGreaterThanFoo])
  1520. has_invariant = HasInvariant()
  1521. directlyProvides(has_invariant, ISubInvariant)
  1522. has_invariant.foo = 42
  1523. # even though the interface has changed, we should still only have one
  1524. # error.
  1525. self._errorsEqual(has_invariant, 1, ['If Foo, then Bar!'],
  1526. ISubInvariant)
  1527. # however, if we set foo to 0 (Boolean False) and bar to a negative
  1528. # number then we'll get the new error
  1529. has_invariant.foo = 2
  1530. has_invariant.bar = 1
  1531. self._errorsEqual(has_invariant, 1,
  1532. ['Please, Boo MUST be greater than Foo!'],
  1533. ISubInvariant)
  1534. # and if we set foo to a positive number and boo to 0, we'll
  1535. # get both errors!
  1536. has_invariant.foo = 1
  1537. has_invariant.bar = 0
  1538. self._errorsEqual(has_invariant, 2,
  1539. ['If Foo, then Bar!',
  1540. 'Please, Boo MUST be greater than Foo!'],
  1541. ISubInvariant)
  1542. # for a happy ending, we'll make the invariants happy
  1543. has_invariant.foo = 1
  1544. has_invariant.bar = 2
  1545. self.assertEqual(IInvariant.validateInvariants(has_invariant), None)
  1546. def test_invariant_mutandis(self):
  1547. from zope.interface import Attribute
  1548. from zope.interface import Interface
  1549. from zope.interface import directlyProvides
  1550. from zope.interface import invariant
  1551. class IInvariant(Interface):
  1552. foo = Attribute('foo')
  1553. bar = Attribute('bar; must eval to Boolean True if foo does')
  1554. invariant(_ifFooThenBar)
  1555. class HasInvariant:
  1556. pass
  1557. # now we'll do two invariants on the same interface,
  1558. # just to make sure that a small
  1559. # multi-invariant interface is at least minimally tested.
  1560. has_invariant = HasInvariant()
  1561. directlyProvides(has_invariant, IInvariant)
  1562. has_invariant.foo = 42
  1563. # if you really need to mutate, then this would be the way to do it.
  1564. # Probably a bad idea, though. :-)
  1565. old_invariants = IInvariant.getTaggedValue('invariants')
  1566. invariants = old_invariants[:]
  1567. invariants.append(_barGreaterThanFoo)
  1568. IInvariant.setTaggedValue('invariants', invariants)
  1569. # even though the interface has changed, we should still only have one
  1570. # error.
  1571. self._errorsEqual(has_invariant, 1, ['If Foo, then Bar!'],
  1572. IInvariant)
  1573. # however, if we set foo to 0 (Boolean False) and bar to a negative
  1574. # number then we'll get the new error
  1575. has_invariant.foo = 2
  1576. has_invariant.bar = 1
  1577. self._errorsEqual(
  1578. has_invariant,
  1579. 1,
  1580. ['Please, Boo MUST be greater than Foo!'],
  1581. IInvariant
  1582. )
  1583. # and if we set foo to a positive number and boo to 0, we'll
  1584. # get both errors!
  1585. has_invariant.foo = 1
  1586. has_invariant.bar = 0
  1587. self._errorsEqual(has_invariant, 2,
  1588. ['If Foo, then Bar!',
  1589. 'Please, Boo MUST be greater than Foo!'],
  1590. IInvariant)
  1591. # for another happy ending, we'll make the invariants happy again
  1592. has_invariant.foo = 1
  1593. has_invariant.bar = 2
  1594. self.assertEqual(IInvariant.validateInvariants(has_invariant), None)
  1595. # clean up
  1596. IInvariant.setTaggedValue('invariants', old_invariants)
  1597. def test___doc___element(self):
  1598. from zope.interface import Attribute
  1599. from zope.interface import Interface
  1600. class IDocstring(Interface):
  1601. "xxx"
  1602. self.assertEqual(IDocstring.__doc__, "xxx")
  1603. self.assertEqual(list(IDocstring), [])
  1604. class IDocstringAndAttribute(Interface):
  1605. "xxx"
  1606. __doc__ = Attribute('the doc')
  1607. self.assertEqual(IDocstringAndAttribute.__doc__, "")
  1608. self.assertEqual(list(IDocstringAndAttribute), ['__doc__'])
  1609. def test_invariant_as_decorator(self):
  1610. from zope.interface import Attribute
  1611. from zope.interface import Interface
  1612. from zope.interface import implementer
  1613. from zope.interface import invariant
  1614. from zope.interface.exceptions import Invalid
  1615. class IRange(Interface):
  1616. min = Attribute("Lower bound")
  1617. max = Attribute("Upper bound")
  1618. @invariant
  1619. def range_invariant(ob):
  1620. if ob.max < ob.min:
  1621. raise Invalid('max < min')
  1622. @implementer(IRange)
  1623. class Range:
  1624. def __init__(self, min, max):
  1625. self.min, self.max = min, max
  1626. IRange.validateInvariants(Range(1, 2))
  1627. IRange.validateInvariants(Range(1, 1))
  1628. try:
  1629. IRange.validateInvariants(Range(2, 1))
  1630. except Invalid as e:
  1631. self.assertEqual(str(e), 'max < min')
  1632. def test_taggedValue(self):
  1633. from zope.interface import Attribute
  1634. from zope.interface import Interface
  1635. from zope.interface import taggedValue
  1636. class ITagged(Interface):
  1637. foo = Attribute('foo')
  1638. bar = Attribute('bar; must eval to Boolean True if foo does')
  1639. taggedValue('qux', 'Spam')
  1640. class IDerived(ITagged):
  1641. taggedValue('qux', 'Spam Spam')
  1642. taggedValue('foo', 'bar')
  1643. class IDerived2(IDerived):
  1644. pass
  1645. self.assertEqual(ITagged.getTaggedValue('qux'), 'Spam')
  1646. self.assertRaises(KeyError, ITagged.getTaggedValue, 'foo')
  1647. self.assertEqual(list(ITagged.getTaggedValueTags()), ['qux'])
  1648. self.assertEqual(IDerived2.getTaggedValue('qux'), 'Spam Spam')
  1649. self.assertEqual(IDerived2.getTaggedValue('foo'), 'bar')
  1650. self.assertEqual(set(IDerived2.getTaggedValueTags()), {'qux', 'foo'})
  1651. def _make_taggedValue_tree(self, base):
  1652. from zope.interface import Attribute
  1653. from zope.interface import taggedValue
  1654. class F(base):
  1655. taggedValue('tag', 'F')
  1656. tag = Attribute('F')
  1657. class E(base):
  1658. taggedValue('tag', 'E')
  1659. tag = Attribute('E')
  1660. class D(base):
  1661. taggedValue('tag', 'D')
  1662. tag = Attribute('D')
  1663. class C(D, F):
  1664. taggedValue('tag', 'C')
  1665. tag = Attribute('C')
  1666. class B(D, E):
  1667. pass
  1668. class A(B, C):
  1669. pass
  1670. return A
  1671. def test_getTaggedValue_follows__iro__(self):
  1672. # And not just looks at __bases__.
  1673. # https://github.com/zopefoundation/zope.interface/issues/190
  1674. from zope.interface import Interface
  1675. # First, confirm that looking at a true class
  1676. # hierarchy follows the __mro__.
  1677. class_A = self._make_taggedValue_tree(object)
  1678. self.assertEqual(class_A.tag.__name__, 'C')
  1679. # Now check that Interface does, both for attributes...
  1680. iface_A = self._make_taggedValue_tree(Interface)
  1681. self.assertEqual(iface_A['tag'].__name__, 'C')
  1682. # ... and for tagged values.
  1683. self.assertEqual(iface_A.getTaggedValue('tag'), 'C')
  1684. self.assertEqual(iface_A.queryTaggedValue('tag'), 'C')
  1685. # Of course setting something lower overrides it.
  1686. assert iface_A.__bases__[0].__name__ == 'B'
  1687. iface_A.__bases__[0].setTaggedValue('tag', 'B')
  1688. self.assertEqual(iface_A.getTaggedValue('tag'), 'B')
  1689. def test_getDirectTaggedValue_ignores__iro__(self):
  1690. # https://github.com/zopefoundation/zope.interface/issues/190
  1691. from zope.interface import Interface
  1692. A = self._make_taggedValue_tree(Interface)
  1693. self.assertIsNone(A.queryDirectTaggedValue('tag'))
  1694. self.assertEqual([], list(A.getDirectTaggedValueTags()))
  1695. with self.assertRaises(KeyError):
  1696. A.getDirectTaggedValue('tag')
  1697. A.setTaggedValue('tag', 'A')
  1698. self.assertEqual(A.queryDirectTaggedValue('tag'), 'A')
  1699. self.assertEqual(A.getDirectTaggedValue('tag'), 'A')
  1700. self.assertEqual(['tag'], list(A.getDirectTaggedValueTags()))
  1701. assert A.__bases__[1].__name__ == 'C'
  1702. C = A.__bases__[1]
  1703. self.assertEqual(C.queryDirectTaggedValue('tag'), 'C')
  1704. self.assertEqual(C.getDirectTaggedValue('tag'), 'C')
  1705. self.assertEqual(['tag'], list(C.getDirectTaggedValueTags()))
  1706. def test_description_cache_management(self):
  1707. # See https://bugs.launchpad.net/zope.interface/+bug/185974
  1708. # There was a bug where the cache used by Specification.get() was not
  1709. # cleared when the bases were changed.
  1710. from zope.interface import Attribute
  1711. from zope.interface import Interface
  1712. class I1(Interface):
  1713. a = Attribute('a')
  1714. class I2(I1):
  1715. pass
  1716. class I3(I2):
  1717. pass
  1718. self.assertIs(I3.get('a'), I1.get('a'))
  1719. I2.__bases__ = (Interface,)
  1720. self.assertIsNone(I3.get('a'))
  1721. def test___call___defers_to___conform___(self):
  1722. from zope.interface import Interface
  1723. from zope.interface import implementer
  1724. class IFoo(Interface):
  1725. pass
  1726. @implementer(IFoo)
  1727. class C:
  1728. def __conform__(self, proto):
  1729. return 0
  1730. self.assertEqual(IFoo(C()), 0)
  1731. def test___call___object_implements(self):
  1732. from zope.interface import Interface
  1733. from zope.interface import implementer
  1734. class IFoo(Interface):
  1735. pass
  1736. @implementer(IFoo)
  1737. class C:
  1738. pass
  1739. c = C()
  1740. self.assertIs(IFoo(c), c)
  1741. def test___call___miss_wo_alternate(self):
  1742. from zope.interface import Interface
  1743. class IFoo(Interface):
  1744. pass
  1745. class C:
  1746. pass
  1747. c = C()
  1748. self.assertRaises(TypeError, IFoo, c)
  1749. def test___call___miss_w_alternate(self):
  1750. from zope.interface import Interface
  1751. class IFoo(Interface):
  1752. pass
  1753. class C:
  1754. pass
  1755. c = C()
  1756. self.assertIs(IFoo(c, self), self)
  1757. def test___call___w_adapter_hook(self):
  1758. from zope.interface import Interface
  1759. from zope.interface.interface import adapter_hooks
  1760. def _miss(iface, obj):
  1761. pass
  1762. def _hit(iface, obj):
  1763. return self
  1764. class IFoo(Interface):
  1765. pass
  1766. class C:
  1767. pass
  1768. c = C()
  1769. old_adapter_hooks = adapter_hooks[:]
  1770. adapter_hooks[:] = [_miss, _hit]
  1771. try:
  1772. self.assertIs(IFoo(c), self)
  1773. finally:
  1774. adapter_hooks[:] = old_adapter_hooks
  1775. def test___call___w_overridden_adapt(self):
  1776. from zope.interface import Interface
  1777. from zope.interface import implementer
  1778. from zope.interface import interfacemethod
  1779. class IFoo(Interface):
  1780. @interfacemethod
  1781. def __adapt__(self, obj):
  1782. return 42
  1783. @implementer(IFoo)
  1784. class Obj:
  1785. pass
  1786. self.assertEqual(42, IFoo(object()))
  1787. # __adapt__ can ignore the fact that the object provides
  1788. # the interface if it chooses.
  1789. self.assertEqual(42, IFoo(Obj()))
  1790. def test___call___w_overridden_adapt_and_conform(self):
  1791. # Conform is first, taking precedence over __adapt__,
  1792. # *if* it returns non-None
  1793. from zope.interface import Interface
  1794. from zope.interface import implementer
  1795. from zope.interface import interfacemethod
  1796. class IAdapt(Interface):
  1797. @interfacemethod
  1798. def __adapt__(self, obj):
  1799. return 42
  1800. class ISimple(Interface):
  1801. """Nothing special."""
  1802. @implementer(IAdapt)
  1803. class Conform24:
  1804. def __conform__(self, iface):
  1805. return 24
  1806. @implementer(IAdapt)
  1807. class ConformNone:
  1808. def __conform__(self, iface):
  1809. return None
  1810. self.assertEqual(42, IAdapt(object()))
  1811. self.assertEqual(24, ISimple(Conform24()))
  1812. self.assertEqual(24, IAdapt(Conform24()))
  1813. with self.assertRaises(TypeError):
  1814. ISimple(ConformNone())
  1815. self.assertEqual(42, IAdapt(ConformNone()))
  1816. def test___call___w_overridden_adapt_call_super(self):
  1817. import sys
  1818. from zope.interface import Interface
  1819. from zope.interface import implementer
  1820. from zope.interface import interfacemethod
  1821. class IFoo(Interface):
  1822. @interfacemethod
  1823. def __adapt__(self, obj):
  1824. if not self.providedBy(obj):
  1825. return 42
  1826. return super().__adapt__(obj)
  1827. @implementer(IFoo)
  1828. class Obj:
  1829. pass
  1830. self.assertEqual(42, IFoo(object()))
  1831. obj = Obj()
  1832. self.assertIs(obj, IFoo(obj))
  1833. def test___adapt___as_method_and_implementation(self):
  1834. from zope.interface import Interface
  1835. from zope.interface import interfacemethod
  1836. class IFoo(Interface):
  1837. @interfacemethod
  1838. def __adapt__(self, obj):
  1839. return 42
  1840. def __adapt__(to_adapt): # noqa F811
  1841. "This is a protocol"
  1842. self.assertEqual(42, IFoo(object()))
  1843. self.assertEqual(IFoo['__adapt__'].getSignatureString(), '(to_adapt)')
  1844. def test___adapt__inheritance_and_type(self):
  1845. from zope.interface import Interface
  1846. from zope.interface import interfacemethod
  1847. class IRoot(Interface):
  1848. """Root"""
  1849. class IWithAdapt(IRoot):
  1850. @interfacemethod
  1851. def __adapt__(self, obj):
  1852. return 42
  1853. class IOther(IRoot):
  1854. """Second branch"""
  1855. class IUnrelated(Interface):
  1856. """Unrelated"""
  1857. class IDerivedAdapt(IUnrelated, IWithAdapt, IOther):
  1858. """Inherits an adapt"""
  1859. # Order of "inheritance" matters here.
  1860. class IDerived2Adapt(IDerivedAdapt):
  1861. """Overrides an inherited custom adapt."""
  1862. @interfacemethod
  1863. def __adapt__(self, obj):
  1864. return 24
  1865. self.assertEqual(42, IDerivedAdapt(object()))
  1866. for iface in IRoot, IWithAdapt, IOther, IUnrelated, IDerivedAdapt:
  1867. self.assertEqual(__name__, iface.__module__)
  1868. for iface in IRoot, IOther, IUnrelated:
  1869. self.assertEqual(type(IRoot), type(Interface))
  1870. # But things that implemented __adapt__ got a new type
  1871. self.assertNotEqual(type(Interface), type(IWithAdapt))
  1872. self.assertEqual(type(IWithAdapt), type(IDerivedAdapt))
  1873. self.assertIsInstance(IWithAdapt, type(Interface))
  1874. self.assertEqual(24, IDerived2Adapt(object()))
  1875. self.assertNotEqual(type(IDerived2Adapt), type(IDerivedAdapt))
  1876. self.assertIsInstance(IDerived2Adapt, type(IDerivedAdapt))
  1877. def test_interfacemethod_is_general(self):
  1878. from zope.interface import Interface
  1879. from zope.interface import interfacemethod
  1880. class IFoo(Interface):
  1881. @interfacemethod
  1882. def __call__(self, obj):
  1883. """Replace an existing method"""
  1884. return 42
  1885. @interfacemethod
  1886. def this_is_new(self):
  1887. return 42
  1888. self.assertEqual(IFoo(self), 42)
  1889. self.assertEqual(IFoo.this_is_new(), 42)
  1890. class AttributeTests(ElementTests):
  1891. DEFAULT_NAME = 'TestAttribute'
  1892. def _getTargetClass(self):
  1893. from zope.interface.interface import Attribute
  1894. return Attribute
  1895. def test__repr__w_interface(self):
  1896. method = self._makeOne()
  1897. method.interface = type(self)
  1898. r = repr(method)
  1899. self.assertTrue(
  1900. r.startswith('<zope.interface.interface.Attribute object at'), r
  1901. )
  1902. self.assertTrue(
  1903. r.endswith(' ' + __name__ + '.AttributeTests.TestAttribute>'), r
  1904. )
  1905. def test__repr__wo_interface(self):
  1906. method = self._makeOne()
  1907. r = repr(method)
  1908. self.assertTrue(
  1909. r.startswith('<zope.interface.interface.Attribute object at'), r
  1910. )
  1911. self.assertTrue(r.endswith(' TestAttribute>'), r)
  1912. def test__str__w_interface(self):
  1913. method = self._makeOne()
  1914. method.interface = type(self)
  1915. r = str(method)
  1916. self.assertEqual(r, __name__ + '.AttributeTests.TestAttribute')
  1917. def test__str__wo_interface(self):
  1918. method = self._makeOne()
  1919. r = str(method)
  1920. self.assertEqual(r, 'TestAttribute')
  1921. class MethodTests(AttributeTests):
  1922. DEFAULT_NAME = 'TestMethod'
  1923. def _getTargetClass(self):
  1924. from zope.interface.interface import Method
  1925. return Method
  1926. def test_optional_as_property(self):
  1927. method = self._makeOne()
  1928. self.assertEqual(method.optional, {})
  1929. method.optional = {'foo': 'bar'}
  1930. self.assertEqual(method.optional, {'foo': 'bar'})
  1931. del method.optional
  1932. self.assertEqual(method.optional, {})
  1933. def test___call___raises_BrokenImplementation(self):
  1934. from zope.interface.exceptions import BrokenImplementation
  1935. method = self._makeOne()
  1936. try:
  1937. method()
  1938. except BrokenImplementation as e:
  1939. self.assertEqual(e.interface, None)
  1940. self.assertEqual(e.name, self.DEFAULT_NAME)
  1941. else:
  1942. self.fail('__call__ should raise BrokenImplementation')
  1943. def test_getSignatureInfo_bare(self):
  1944. method = self._makeOne()
  1945. info = method.getSignatureInfo()
  1946. self.assertEqual(list(info['positional']), [])
  1947. self.assertEqual(list(info['required']), [])
  1948. self.assertEqual(info['optional'], {})
  1949. self.assertEqual(info['varargs'], None)
  1950. self.assertEqual(info['kwargs'], None)
  1951. def test_getSignatureString_bare(self):
  1952. method = self._makeOne()
  1953. self.assertEqual(method.getSignatureString(), '()')
  1954. def test_getSignatureString_w_only_required(self):
  1955. method = self._makeOne()
  1956. method.positional = method.required = ['foo']
  1957. self.assertEqual(method.getSignatureString(), '(foo)')
  1958. def test_getSignatureString_w_optional(self):
  1959. method = self._makeOne()
  1960. method.positional = method.required = ['foo']
  1961. method.optional = {'foo': 'bar'}
  1962. self.assertEqual(method.getSignatureString(), "(foo='bar')")
  1963. def test_getSignatureString_w_varargs(self):
  1964. method = self._makeOne()
  1965. method.varargs = 'args'
  1966. self.assertEqual(method.getSignatureString(), "(*args)")
  1967. def test_getSignatureString_w_kwargs(self):
  1968. method = self._makeOne()
  1969. method.kwargs = 'kw'
  1970. self.assertEqual(method.getSignatureString(), "(**kw)")
  1971. def test__repr__w_interface(self):
  1972. method = self._makeOne()
  1973. method.kwargs = 'kw'
  1974. method.interface = type(self)
  1975. r = repr(method)
  1976. self.assertTrue(
  1977. r.startswith('<zope.interface.interface.Method object at'), r
  1978. )
  1979. self.assertTrue(
  1980. r.endswith(' ' + __name__ + '.MethodTests.TestMethod(**kw)>'), r
  1981. )
  1982. def test__repr__wo_interface(self):
  1983. method = self._makeOne()
  1984. method.kwargs = 'kw'
  1985. r = repr(method)
  1986. self.assertTrue(
  1987. r.startswith('<zope.interface.interface.Method object at'), r
  1988. )
  1989. self.assertTrue(r.endswith(' TestMethod(**kw)>'), r)
  1990. def test__str__w_interface(self):
  1991. method = self._makeOne()
  1992. method.kwargs = 'kw'
  1993. method.interface = type(self)
  1994. r = str(method)
  1995. self.assertEqual(r, __name__ + '.MethodTests.TestMethod(**kw)')
  1996. def test__str__wo_interface(self):
  1997. method = self._makeOne()
  1998. method.kwargs = 'kw'
  1999. r = str(method)
  2000. self.assertEqual(r, 'TestMethod(**kw)')
  2001. class Test_fromFunction(unittest.TestCase):
  2002. def _callFUT(self, *args, **kw):
  2003. from zope.interface.interface import fromFunction
  2004. return fromFunction(*args, **kw)
  2005. def test_bare(self):
  2006. def _func():
  2007. "DOCSTRING"
  2008. method = self._callFUT(_func)
  2009. self.assertEqual(method.getName(), '_func')
  2010. self.assertEqual(method.getDoc(), 'DOCSTRING')
  2011. self.assertEqual(method.interface, None)
  2012. self.assertEqual(list(method.getTaggedValueTags()), [])
  2013. info = method.getSignatureInfo()
  2014. self.assertEqual(list(info['positional']), [])
  2015. self.assertEqual(list(info['required']), [])
  2016. self.assertEqual(info['optional'], {})
  2017. self.assertEqual(info['varargs'], None)
  2018. self.assertEqual(info['kwargs'], None)
  2019. def test_w_interface(self):
  2020. from zope.interface.interface import InterfaceClass
  2021. class IFoo(InterfaceClass):
  2022. pass
  2023. def _func():
  2024. "DOCSTRING"
  2025. method = self._callFUT(_func, interface=IFoo)
  2026. self.assertEqual(method.interface, IFoo)
  2027. def test_w_name(self):
  2028. def _func():
  2029. "DOCSTRING"
  2030. method = self._callFUT(_func, name='anotherName')
  2031. self.assertEqual(method.getName(), 'anotherName')
  2032. def test_w_only_required(self):
  2033. def _func(foo):
  2034. "DOCSTRING"
  2035. method = self._callFUT(_func)
  2036. info = method.getSignatureInfo()
  2037. self.assertEqual(list(info['positional']), ['foo'])
  2038. self.assertEqual(list(info['required']), ['foo'])
  2039. self.assertEqual(info['optional'], {})
  2040. self.assertEqual(info['varargs'], None)
  2041. self.assertEqual(info['kwargs'], None)
  2042. def test_w_optional(self):
  2043. def _func(foo='bar'):
  2044. "DOCSTRING"
  2045. method = self._callFUT(_func)
  2046. info = method.getSignatureInfo()
  2047. self.assertEqual(list(info['positional']), ['foo'])
  2048. self.assertEqual(list(info['required']), [])
  2049. self.assertEqual(info['optional'], {'foo': 'bar'})
  2050. self.assertEqual(info['varargs'], None)
  2051. self.assertEqual(info['kwargs'], None)
  2052. def test_w_optional_self(self):
  2053. # This is a weird case, trying to cover the following code in
  2054. # FUT::
  2055. #
  2056. # nr = na-len(defaults)
  2057. # if nr < 0:
  2058. # defaults=defaults[-nr:]
  2059. # nr = 0
  2060. def _func(self='bar'):
  2061. "DOCSTRING"
  2062. method = self._callFUT(_func, imlevel=1)
  2063. info = method.getSignatureInfo()
  2064. self.assertEqual(list(info['positional']), [])
  2065. self.assertEqual(list(info['required']), [])
  2066. self.assertEqual(info['optional'], {})
  2067. self.assertEqual(info['varargs'], None)
  2068. self.assertEqual(info['kwargs'], None)
  2069. def test_w_varargs(self):
  2070. def _func(*args):
  2071. "DOCSTRING"
  2072. method = self._callFUT(_func)
  2073. info = method.getSignatureInfo()
  2074. self.assertEqual(list(info['positional']), [])
  2075. self.assertEqual(list(info['required']), [])
  2076. self.assertEqual(info['optional'], {})
  2077. self.assertEqual(info['varargs'], 'args')
  2078. self.assertEqual(info['kwargs'], None)
  2079. def test_w_kwargs(self):
  2080. def _func(**kw):
  2081. "DOCSTRING"
  2082. method = self._callFUT(_func)
  2083. info = method.getSignatureInfo()
  2084. self.assertEqual(list(info['positional']), [])
  2085. self.assertEqual(list(info['required']), [])
  2086. self.assertEqual(info['optional'], {})
  2087. self.assertEqual(info['varargs'], None)
  2088. self.assertEqual(info['kwargs'], 'kw')
  2089. def test_full_spectrum(self):
  2090. def _func(
  2091. foo, bar='baz', *args, **kw
  2092. ): # pylint:disable=keyword-arg-before-vararg
  2093. "DOCSTRING"
  2094. method = self._callFUT(_func)
  2095. info = method.getSignatureInfo()
  2096. self.assertEqual(list(info['positional']), ['foo', 'bar'])
  2097. self.assertEqual(list(info['required']), ['foo'])
  2098. self.assertEqual(info['optional'], {'bar': 'baz'})
  2099. self.assertEqual(info['varargs'], 'args')
  2100. self.assertEqual(info['kwargs'], 'kw')
  2101. class Test_fromMethod(unittest.TestCase):
  2102. def _callFUT(self, *args, **kw):
  2103. from zope.interface.interface import fromMethod
  2104. return fromMethod(*args, **kw)
  2105. def test_no_args(self):
  2106. class Foo:
  2107. def bar(self):
  2108. "DOCSTRING"
  2109. method = self._callFUT(Foo.bar)
  2110. self.assertEqual(method.getName(), 'bar')
  2111. self.assertEqual(method.getDoc(), 'DOCSTRING')
  2112. self.assertEqual(method.interface, None)
  2113. self.assertEqual(list(method.getTaggedValueTags()), [])
  2114. info = method.getSignatureInfo()
  2115. self.assertEqual(list(info['positional']), [])
  2116. self.assertEqual(list(info['required']), [])
  2117. self.assertEqual(info['optional'], {})
  2118. self.assertEqual(info['varargs'], None)
  2119. self.assertEqual(info['kwargs'], None)
  2120. def test_full_spectrum(self):
  2121. class Foo:
  2122. def bar(
  2123. self, foo, bar='baz', *args, **kw
  2124. ): # pylint:disable=keyword-arg-before-vararg
  2125. "DOCSTRING"
  2126. method = self._callFUT(Foo.bar)
  2127. info = method.getSignatureInfo()
  2128. self.assertEqual(list(info['positional']), ['foo', 'bar'])
  2129. self.assertEqual(list(info['required']), ['foo'])
  2130. self.assertEqual(info['optional'], {'bar': 'baz'})
  2131. self.assertEqual(info['varargs'], 'args')
  2132. self.assertEqual(info['kwargs'], 'kw')
  2133. def test_w_non_method(self):
  2134. def foo():
  2135. "DOCSTRING"
  2136. method = self._callFUT(foo)
  2137. self.assertEqual(method.getName(), 'foo')
  2138. self.assertEqual(method.getDoc(), 'DOCSTRING')
  2139. self.assertEqual(method.interface, None)
  2140. self.assertEqual(list(method.getTaggedValueTags()), [])
  2141. info = method.getSignatureInfo()
  2142. self.assertEqual(list(info['positional']), [])
  2143. self.assertEqual(list(info['required']), [])
  2144. self.assertEqual(info['optional'], {})
  2145. self.assertEqual(info['varargs'], None)
  2146. self.assertEqual(info['kwargs'], None)
  2147. class DummyDependent:
  2148. def __init__(self):
  2149. self._changed = []
  2150. def changed(self, originally_changed):
  2151. self._changed.append(originally_changed)
  2152. def _barGreaterThanFoo(obj):
  2153. from zope.interface.exceptions import Invalid
  2154. foo = getattr(obj, 'foo', None)
  2155. bar = getattr(obj, 'bar', None)
  2156. if foo is not None and isinstance(foo, type(bar)):
  2157. # type checking should be handled elsewhere (like, say,
  2158. # schema); these invariants should be intra-interface
  2159. # constraints. This is a hacky way to do it, maybe, but you
  2160. # get the idea
  2161. if not bar > foo:
  2162. raise Invalid('Please, Boo MUST be greater than Foo!')
  2163. def _ifFooThenBar(obj):
  2164. from zope.interface.exceptions import Invalid
  2165. if getattr(obj, 'foo', None) and not getattr(obj, 'bar', None):
  2166. raise Invalid('If Foo, then Bar!')
  2167. class _Monkey:
  2168. # context-manager for replacing module names in the scope of a test.
  2169. def __init__(self, module, **kw):
  2170. self.module = module
  2171. self.to_restore = {key: getattr(module, key) for key in kw}
  2172. for key, value in kw.items():
  2173. setattr(module, key, value)
  2174. def __enter__(self):
  2175. return self
  2176. def __exit__(self, exc_type, exc_val, exc_tb):
  2177. for key, value in self.to_restore.items():
  2178. setattr(self.module, key, value)
  2179. class TestTypeAnnotations(unittest.TestCase):
  2180. """Test using Interfaces in type annotations."""
  2181. def test___or__(self):
  2182. from typing import Optional
  2183. from typing import Union
  2184. from zope.interface import Interface
  2185. class I1(Interface):
  2186. pass
  2187. class I2(Interface):
  2188. pass
  2189. class B:
  2190. a: I1 | None
  2191. b: I1 | I2
  2192. self.assertEqual(
  2193. B.__annotations__, {'a': Optional[I1], 'b': Union[I1, I2]})
  2194. def test___ror__(self):
  2195. from typing import Optional
  2196. from typing import Union
  2197. from zope.interface import Interface
  2198. class I1(Interface):
  2199. pass
  2200. class A:
  2201. pass
  2202. class B:
  2203. a: None | I1
  2204. b: A | I1
  2205. self.assertEqual(
  2206. B.__annotations__, {'a': Optional[I1], 'b': Union[A, I1]})