test_interface.py 72 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114
  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. # pylint:disable=protected-access
  17. import unittest
  18. from zope.interface._compat import _skip_under_py3k
  19. _marker = object()
  20. class Test_invariant(unittest.TestCase):
  21. def test_w_single(self):
  22. from zope.interface.interface import invariant
  23. from zope.interface.interface import TAGGED_DATA
  24. def _check(*args, **kw):
  25. raise NotImplementedError()
  26. class Foo(object):
  27. invariant(_check)
  28. self.assertEqual(getattr(Foo, TAGGED_DATA, None),
  29. {'invariants': [_check]})
  30. def test_w_multiple(self):
  31. from zope.interface.interface import invariant
  32. from zope.interface.interface import TAGGED_DATA
  33. def _check(*args, **kw):
  34. raise NotImplementedError()
  35. def _another_check(*args, **kw):
  36. raise NotImplementedError()
  37. class Foo(object):
  38. invariant(_check)
  39. invariant(_another_check)
  40. self.assertEqual(getattr(Foo, TAGGED_DATA, None),
  41. {'invariants': [_check, _another_check]})
  42. class Test_taggedValue(unittest.TestCase):
  43. def test_w_single(self):
  44. from zope.interface.interface import taggedValue
  45. from zope.interface.interface import TAGGED_DATA
  46. class Foo(object):
  47. taggedValue('bar', ['baz'])
  48. self.assertEqual(getattr(Foo, TAGGED_DATA, None),
  49. {'bar': ['baz']})
  50. def test_w_multiple(self):
  51. from zope.interface.interface import taggedValue
  52. from zope.interface.interface import TAGGED_DATA
  53. class Foo(object):
  54. taggedValue('bar', ['baz'])
  55. taggedValue('qux', 'spam')
  56. self.assertEqual(getattr(Foo, TAGGED_DATA, None),
  57. {'bar': ['baz'], 'qux': 'spam'})
  58. def test_w_multiple_overwriting(self):
  59. from zope.interface.interface import taggedValue
  60. from zope.interface.interface import TAGGED_DATA
  61. class Foo(object):
  62. taggedValue('bar', ['baz'])
  63. taggedValue('qux', 'spam')
  64. taggedValue('bar', 'frob')
  65. self.assertEqual(getattr(Foo, TAGGED_DATA, None),
  66. {'bar': 'frob', 'qux': 'spam'})
  67. class ElementTests(unittest.TestCase):
  68. DEFAULT_NAME = 'AnElement'
  69. def _getTargetClass(self):
  70. from zope.interface.interface import Element
  71. return Element
  72. def _makeOne(self, name=None):
  73. if name is None:
  74. name = self.DEFAULT_NAME
  75. return self._getTargetClass()(name)
  76. def test_ctor_defaults(self):
  77. element = self._makeOne()
  78. self.assertEqual(element.__name__, self.DEFAULT_NAME)
  79. self.assertEqual(element.getName(), self.DEFAULT_NAME)
  80. self.assertEqual(element.__doc__, '')
  81. self.assertEqual(element.getDoc(), '')
  82. self.assertEqual(list(element.getTaggedValueTags()), [])
  83. def test_ctor_no_doc_space_in_name(self):
  84. element = self._makeOne('An Element')
  85. self.assertEqual(element.__name__, None)
  86. self.assertEqual(element.__doc__, 'An Element')
  87. def test_getTaggedValue_miss(self):
  88. element = self._makeOne()
  89. self.assertRaises(KeyError, element.getTaggedValue, 'nonesuch')
  90. def test_queryTaggedValue_miss(self):
  91. element = self._makeOne()
  92. self.assertEqual(element.queryTaggedValue('nonesuch'), None)
  93. def test_queryTaggedValue_miss_w_default(self):
  94. element = self._makeOne()
  95. self.assertEqual(element.queryTaggedValue('nonesuch', 'bar'), 'bar')
  96. def test_setTaggedValue(self):
  97. element = self._makeOne()
  98. element.setTaggedValue('foo', 'bar')
  99. self.assertEqual(list(element.getTaggedValueTags()), ['foo'])
  100. self.assertEqual(element.getTaggedValue('foo'), 'bar')
  101. self.assertEqual(element.queryTaggedValue('foo'), 'bar')
  102. class SpecificationBasePyTests(unittest.TestCase):
  103. def _getTargetClass(self):
  104. from zope.interface.interface import SpecificationBasePy
  105. return SpecificationBasePy
  106. def _makeOne(self):
  107. return self._getTargetClass()()
  108. def test_providedBy_miss(self):
  109. from zope.interface import interface
  110. from zope.interface.declarations import _empty
  111. sb = self._makeOne()
  112. def _providedBy(obj):
  113. return _empty
  114. with _Monkey(interface, providedBy=_providedBy):
  115. self.assertFalse(sb.providedBy(object()))
  116. def test_providedBy_hit(self):
  117. from zope.interface import interface
  118. sb = self._makeOne()
  119. class _Decl(object):
  120. _implied = {sb: {},}
  121. def _providedBy(obj):
  122. return _Decl()
  123. with _Monkey(interface, providedBy=_providedBy):
  124. self.assertTrue(sb.providedBy(object()))
  125. def test_implementedBy_miss(self):
  126. from zope.interface import interface
  127. from zope.interface.declarations import _empty
  128. sb = self._makeOne()
  129. def _implementedBy(obj):
  130. return _empty
  131. with _Monkey(interface, implementedBy=_implementedBy):
  132. self.assertFalse(sb.implementedBy(object()))
  133. def test_implementedBy_hit(self):
  134. from zope.interface import interface
  135. sb = self._makeOne()
  136. class _Decl(object):
  137. _implied = {sb: {},}
  138. def _implementedBy(obj):
  139. return _Decl()
  140. with _Monkey(interface, implementedBy=_implementedBy):
  141. self.assertTrue(sb.implementedBy(object()))
  142. def test_isOrExtends_miss(self):
  143. sb = self._makeOne()
  144. sb._implied = {} # not defined by SpecificationBasePy
  145. self.assertFalse(sb.isOrExtends(object()))
  146. def test_isOrExtends_hit(self):
  147. sb = self._makeOne()
  148. testing = object()
  149. sb._implied = {testing: {}} # not defined by SpecificationBasePy
  150. self.assertTrue(sb(testing))
  151. def test___call___miss(self):
  152. sb = self._makeOne()
  153. sb._implied = {} # not defined by SpecificationBasePy
  154. self.assertFalse(sb.isOrExtends(object()))
  155. def test___call___hit(self):
  156. sb = self._makeOne()
  157. testing = object()
  158. sb._implied = {testing: {}} # not defined by SpecificationBasePy
  159. self.assertTrue(sb(testing))
  160. class SpecificationBaseTests(unittest.TestCase):
  161. def _getTargetClass(self):
  162. from zope.interface.interface import SpecificationBase
  163. return SpecificationBase
  164. def test_optimizations(self):
  165. from zope.interface.interface import SpecificationBasePy
  166. try:
  167. import zope.interface._zope_interface_coptimizations
  168. except ImportError:
  169. self.assertIs(self._getTargetClass(), SpecificationBasePy)
  170. else:
  171. self.assertIsNot(self._getTargetClass(), SpecificationBasePy)
  172. class InterfaceBasePyTests(unittest.TestCase):
  173. def _getTargetClass(self):
  174. from zope.interface.interface import InterfaceBasePy
  175. return InterfaceBasePy
  176. def _makeOne(self, object_should_provide):
  177. class IB(self._getTargetClass()):
  178. def _call_conform(self, conform):
  179. return conform(self)
  180. def providedBy(self, obj):
  181. return object_should_provide
  182. return IB()
  183. def test___call___w___conform___returning_value(self):
  184. ib = self._makeOne(False)
  185. conformed = object()
  186. class _Adapted(object):
  187. def __conform__(self, iface):
  188. return conformed
  189. self.assertTrue(ib(_Adapted()) is conformed)
  190. def test___call___w___conform___miss_ob_provides(self):
  191. ib = self._makeOne(True)
  192. class _Adapted(object):
  193. def __conform__(self, iface):
  194. return None
  195. adapted = _Adapted()
  196. self.assertTrue(ib(adapted) is adapted)
  197. def test___call___wo___conform___ob_no_provides_w_alternate(self):
  198. ib = self._makeOne(False)
  199. adapted = object()
  200. alternate = object()
  201. self.assertTrue(ib(adapted, alternate) is alternate)
  202. def test___call___w___conform___ob_no_provides_wo_alternate(self):
  203. ib = self._makeOne(False)
  204. adapted = object()
  205. self.assertRaises(TypeError, ib, adapted)
  206. def test___adapt___ob_provides(self):
  207. ib = self._makeOne(True)
  208. adapted = object()
  209. self.assertTrue(ib.__adapt__(adapted) is adapted)
  210. def test___adapt___ob_no_provides_uses_hooks(self):
  211. from zope.interface import interface
  212. ib = self._makeOne(False)
  213. adapted = object()
  214. _missed = []
  215. def _hook_miss(iface, obj):
  216. _missed.append((iface, obj))
  217. return None
  218. def _hook_hit(iface, obj):
  219. return obj
  220. with _Monkey(interface, adapter_hooks=[_hook_miss, _hook_hit]):
  221. self.assertTrue(ib.__adapt__(adapted) is adapted)
  222. self.assertEqual(_missed, [(ib, adapted)])
  223. class InterfaceBaseTests(unittest.TestCase):
  224. def _getTargetClass(self):
  225. from zope.interface.interface import InterfaceBase
  226. return InterfaceBase
  227. def test_optimizations(self):
  228. from zope.interface.interface import InterfaceBasePy
  229. try:
  230. import zope.interface._zope_interface_coptimizations
  231. except ImportError:
  232. self.assertIs(self._getTargetClass(), InterfaceBasePy)
  233. else:
  234. self.assertIsNot(self._getTargetClass(), InterfaceBasePy)
  235. class SpecificationTests(unittest.TestCase):
  236. def _getTargetClass(self):
  237. from zope.interface.interface import Specification
  238. return Specification
  239. def _makeOne(self, bases=_marker):
  240. if bases is _marker:
  241. return self._getTargetClass()()
  242. return self._getTargetClass()(bases)
  243. def test_ctor(self):
  244. from zope.interface.interface import Interface
  245. spec = self._makeOne()
  246. self.assertEqual(spec.__bases__, ())
  247. self.assertEqual(len(spec._implied), 2)
  248. self.assertTrue(spec in spec._implied)
  249. self.assertTrue(Interface in spec._implied)
  250. self.assertEqual(len(spec.dependents), 0)
  251. def test_subscribe_first_time(self):
  252. spec = self._makeOne()
  253. dep = DummyDependent()
  254. spec.subscribe(dep)
  255. self.assertEqual(len(spec.dependents), 1)
  256. self.assertEqual(spec.dependents[dep], 1)
  257. def test_subscribe_again(self):
  258. spec = self._makeOne()
  259. dep = DummyDependent()
  260. spec.subscribe(dep)
  261. spec.subscribe(dep)
  262. self.assertEqual(spec.dependents[dep], 2)
  263. def test_unsubscribe_miss(self):
  264. spec = self._makeOne()
  265. dep = DummyDependent()
  266. self.assertRaises(KeyError, spec.unsubscribe, dep)
  267. def test_unsubscribe(self):
  268. spec = self._makeOne()
  269. dep = DummyDependent()
  270. spec.subscribe(dep)
  271. spec.subscribe(dep)
  272. spec.unsubscribe(dep)
  273. self.assertEqual(spec.dependents[dep], 1)
  274. spec.unsubscribe(dep)
  275. self.assertFalse(dep in spec.dependents)
  276. def test___setBases_subscribes_bases_and_notifies_dependents(self):
  277. from zope.interface.interface import Interface
  278. spec = self._makeOne()
  279. dep = DummyDependent()
  280. spec.subscribe(dep)
  281. class I(Interface):
  282. pass
  283. class J(Interface):
  284. pass
  285. spec.__bases__ = (I,)
  286. self.assertEqual(dep._changed, [spec])
  287. self.assertEqual(I.dependents[spec], 1)
  288. spec.__bases__ = (J,)
  289. self.assertEqual(I.dependents.get(spec), None)
  290. self.assertEqual(J.dependents[spec], 1)
  291. def test_changed_clears_volatiles_and_implied(self):
  292. from zope.interface.interface import Interface
  293. class I(Interface):
  294. pass
  295. spec = self._makeOne()
  296. spec._v_attrs = 'Foo'
  297. spec._implied[I] = ()
  298. spec.changed(spec)
  299. self.assertTrue(getattr(spec, '_v_attrs', self) is self)
  300. self.assertFalse(I in spec._implied)
  301. def test_interfaces_skips_already_seen(self):
  302. from zope.interface.interface import Interface
  303. class IFoo(Interface):
  304. pass
  305. spec = self._makeOne([IFoo, IFoo])
  306. self.assertEqual(list(spec.interfaces()), [IFoo])
  307. def test_extends_strict_wo_self(self):
  308. from zope.interface.interface import Interface
  309. class IFoo(Interface):
  310. pass
  311. spec = self._makeOne(IFoo)
  312. self.assertFalse(spec.extends(IFoo, strict=True))
  313. def test_extends_strict_w_self(self):
  314. spec = self._makeOne()
  315. self.assertFalse(spec.extends(spec, strict=True))
  316. def test_extends_non_strict_w_self(self):
  317. spec = self._makeOne()
  318. self.assertTrue(spec.extends(spec, strict=False))
  319. def test_get_hit_w__v_attrs(self):
  320. spec = self._makeOne()
  321. foo = object()
  322. spec._v_attrs = {'foo': foo}
  323. self.assertTrue(spec.get('foo') is foo)
  324. def test_get_hit_from_base_wo__v_attrs(self):
  325. from zope.interface.interface import Attribute
  326. from zope.interface.interface import Interface
  327. class IFoo(Interface):
  328. foo = Attribute('foo')
  329. class IBar(Interface):
  330. bar = Attribute('bar')
  331. spec = self._makeOne([IFoo, IBar])
  332. self.assertTrue(spec.get('foo') is IFoo.get('foo'))
  333. self.assertTrue(spec.get('bar') is IBar.get('bar'))
  334. class InterfaceClassTests(unittest.TestCase):
  335. def _getTargetClass(self):
  336. from zope.interface.interface import InterfaceClass
  337. return InterfaceClass
  338. def _makeOne(self, name='ITest', bases=(), attrs=None, __doc__=None,
  339. __module__=None):
  340. return self._getTargetClass()(name, bases, attrs, __doc__, __module__)
  341. def test_ctor_defaults(self):
  342. klass = self._getTargetClass()
  343. inst = klass('ITesting')
  344. self.assertEqual(inst.__name__, 'ITesting')
  345. self.assertEqual(inst.__doc__, '')
  346. self.assertEqual(inst.__bases__, ())
  347. self.assertEqual(inst.getBases(), ())
  348. def test_ctor_bad_bases(self):
  349. klass = self._getTargetClass()
  350. self.assertRaises(TypeError, klass, 'ITesting', (object(),))
  351. def test_ctor_w_attrs_attrib_methods(self):
  352. from zope.interface.interface import Attribute
  353. from zope.interface.interface import fromFunction
  354. def _bar():
  355. """DOCSTRING"""
  356. ATTRS = {'foo': Attribute('Foo', ''),
  357. 'bar': fromFunction(_bar),
  358. }
  359. klass = self._getTargetClass()
  360. inst = klass('ITesting', attrs=ATTRS)
  361. self.assertEqual(inst.__name__, 'ITesting')
  362. self.assertEqual(inst.__doc__, '')
  363. self.assertEqual(inst.__bases__, ())
  364. self.assertEqual(inst.names(), ATTRS.keys())
  365. def test_ctor_attrs_w___locals__(self):
  366. ATTRS = {'__locals__': {}}
  367. klass = self._getTargetClass()
  368. inst = klass('ITesting', attrs=ATTRS)
  369. self.assertEqual(inst.__name__, 'ITesting')
  370. self.assertEqual(inst.__doc__, '')
  371. self.assertEqual(inst.__bases__, ())
  372. self.assertEqual(inst.names(), ATTRS.keys())
  373. def test_ctor_attrs_w__decorator_non_return(self):
  374. from zope.interface.interface import _decorator_non_return
  375. ATTRS = {'dropme': _decorator_non_return}
  376. klass = self._getTargetClass()
  377. inst = klass('ITesting', attrs=ATTRS)
  378. self.assertEqual(inst.__name__, 'ITesting')
  379. self.assertEqual(inst.__doc__, '')
  380. self.assertEqual(inst.__bases__, ())
  381. self.assertEqual(list(inst.names()), [])
  382. def test_ctor_attrs_w_invalid_attr_type(self):
  383. from zope.interface.exceptions import InvalidInterface
  384. ATTRS = {'invalid': object()}
  385. klass = self._getTargetClass()
  386. self.assertRaises(InvalidInterface, klass, 'ITesting', attrs=ATTRS)
  387. def test_ctor_w_explicit___doc__(self):
  388. ATTRS = {'__doc__': 'ATTR'}
  389. klass = self._getTargetClass()
  390. inst = klass('ITesting', attrs=ATTRS, __doc__='EXPLICIT')
  391. self.assertEqual(inst.__doc__, 'EXPLICIT')
  392. def test_interfaces(self):
  393. iface = self._makeOne()
  394. self.assertEqual(list(iface.interfaces()), [iface])
  395. def test_getBases(self):
  396. iface = self._makeOne()
  397. sub = self._makeOne('ISub', bases=(iface,))
  398. self.assertEqual(sub.getBases(), (iface,))
  399. def test_isEqualOrExtendedBy_identity(self):
  400. iface = self._makeOne()
  401. self.assertTrue(iface.isEqualOrExtendedBy(iface))
  402. def test_isEqualOrExtendedBy_subiface(self):
  403. iface = self._makeOne()
  404. sub = self._makeOne('ISub', bases=(iface,))
  405. self.assertTrue(iface.isEqualOrExtendedBy(sub))
  406. self.assertFalse(sub.isEqualOrExtendedBy(iface))
  407. def test_isEqualOrExtendedBy_unrelated(self):
  408. one = self._makeOne('One')
  409. another = self._makeOne('Another')
  410. self.assertFalse(one.isEqualOrExtendedBy(another))
  411. self.assertFalse(another.isEqualOrExtendedBy(one))
  412. def test_names_w_all_False_ignores_bases(self):
  413. from zope.interface.interface import Attribute
  414. from zope.interface.interface import fromFunction
  415. def _bar():
  416. """DOCSTRING"""
  417. BASE_ATTRS = {'foo': Attribute('Foo', ''),
  418. 'bar': fromFunction(_bar),
  419. }
  420. DERIVED_ATTRS = {'baz': Attribute('Baz', ''),
  421. }
  422. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  423. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  424. self.assertEqual(sorted(derived.names(all=False)), ['baz'])
  425. def test_names_w_all_True_no_bases(self):
  426. from zope.interface.interface import Attribute
  427. from zope.interface.interface import fromFunction
  428. def _bar():
  429. """DOCSTRING"""
  430. ATTRS = {'foo': Attribute('Foo', ''),
  431. 'bar': fromFunction(_bar),
  432. }
  433. one = self._makeOne(attrs=ATTRS)
  434. self.assertEqual(sorted(one.names(all=True)), ['bar', 'foo'])
  435. def test_names_w_all_True_w_bases_simple(self):
  436. from zope.interface.interface import Attribute
  437. from zope.interface.interface import fromFunction
  438. def _bar():
  439. """DOCSTRING"""
  440. BASE_ATTRS = {'foo': Attribute('Foo', ''),
  441. 'bar': fromFunction(_bar),
  442. }
  443. DERIVED_ATTRS = {'baz': Attribute('Baz', ''),
  444. }
  445. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  446. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  447. self.assertEqual(sorted(derived.names(all=True)), ['bar', 'baz', 'foo'])
  448. def test_names_w_all_True_bases_w_same_names(self):
  449. from zope.interface.interface import Attribute
  450. from zope.interface.interface import fromFunction
  451. def _bar():
  452. """DOCSTRING"""
  453. def _foo():
  454. """DOCSTRING"""
  455. BASE_ATTRS = {'foo': Attribute('Foo', ''),
  456. 'bar': fromFunction(_bar),
  457. }
  458. DERIVED_ATTRS = {'foo': fromFunction(_foo),
  459. 'baz': Attribute('Baz', ''),
  460. }
  461. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  462. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  463. self.assertEqual(sorted(derived.names(all=True)), ['bar', 'baz', 'foo'])
  464. def test___iter__(self):
  465. from zope.interface.interface import Attribute
  466. from zope.interface.interface import fromFunction
  467. def _bar():
  468. """DOCSTRING"""
  469. def _foo():
  470. """DOCSTRING"""
  471. BASE_ATTRS = {'foo': Attribute('Foo', ''),
  472. 'bar': fromFunction(_bar),
  473. }
  474. DERIVED_ATTRS = {'foo': fromFunction(_foo),
  475. 'baz': Attribute('Baz', ''),
  476. }
  477. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  478. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  479. self.assertEqual(sorted(derived), ['bar', 'baz', 'foo'])
  480. def test_namesAndDescriptions_w_all_False_ignores_bases(self):
  481. from zope.interface.interface import Attribute
  482. from zope.interface.interface import fromFunction
  483. def _bar():
  484. """DOCSTRING"""
  485. BASE_ATTRS = {'foo': Attribute('Foo', ''),
  486. 'bar': fromFunction(_bar),
  487. }
  488. DERIVED_ATTRS = {'baz': Attribute('Baz', ''),
  489. }
  490. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  491. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  492. self.assertEqual(sorted(derived.namesAndDescriptions(all=False)),
  493. [('baz', DERIVED_ATTRS['baz']),
  494. ])
  495. def test_namesAndDescriptions_w_all_True_no_bases(self):
  496. from zope.interface.interface import Attribute
  497. from zope.interface.interface import fromFunction
  498. def _bar():
  499. """DOCSTRING"""
  500. ATTRS = {'foo': Attribute('Foo', ''),
  501. 'bar': fromFunction(_bar),
  502. }
  503. one = self._makeOne(attrs=ATTRS)
  504. self.assertEqual(sorted(one.namesAndDescriptions(all=False)),
  505. [('bar', ATTRS['bar']),
  506. ('foo', ATTRS['foo']),
  507. ])
  508. def test_namesAndDescriptions_w_all_True_simple(self):
  509. from zope.interface.interface import Attribute
  510. from zope.interface.interface import fromFunction
  511. def _bar():
  512. """DOCSTRING"""
  513. BASE_ATTRS = {'foo': Attribute('Foo', ''),
  514. 'bar': fromFunction(_bar),
  515. }
  516. DERIVED_ATTRS = {'baz': Attribute('Baz', ''),
  517. }
  518. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  519. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  520. self.assertEqual(sorted(derived.namesAndDescriptions(all=True)),
  521. [('bar', BASE_ATTRS['bar']),
  522. ('baz', DERIVED_ATTRS['baz']),
  523. ('foo', BASE_ATTRS['foo']),
  524. ])
  525. def test_namesAndDescriptions_w_all_True_bases_w_same_names(self):
  526. from zope.interface.interface import Attribute
  527. from zope.interface.interface import fromFunction
  528. def _bar():
  529. """DOCSTRING"""
  530. def _foo():
  531. """DOCSTRING"""
  532. BASE_ATTRS = {'foo': Attribute('Foo', ''),
  533. 'bar': fromFunction(_bar),
  534. }
  535. DERIVED_ATTRS = {'foo': fromFunction(_foo),
  536. 'baz': Attribute('Baz', ''),
  537. }
  538. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  539. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  540. self.assertEqual(sorted(derived.namesAndDescriptions(all=True)),
  541. [('bar', BASE_ATTRS['bar']),
  542. ('baz', DERIVED_ATTRS['baz']),
  543. ('foo', DERIVED_ATTRS['foo']),
  544. ])
  545. def test_getDescriptionFor_miss(self):
  546. one = self._makeOne()
  547. self.assertRaises(KeyError, one.getDescriptionFor, 'nonesuch')
  548. def test_getDescriptionFor_hit(self):
  549. from zope.interface.interface import Attribute
  550. from zope.interface.interface import fromFunction
  551. def _bar():
  552. """DOCSTRING"""
  553. ATTRS = {'foo': Attribute('Foo', ''),
  554. 'bar': fromFunction(_bar),
  555. }
  556. one = self._makeOne(attrs=ATTRS)
  557. self.assertEqual(one.getDescriptionFor('foo'), ATTRS['foo'])
  558. self.assertEqual(one.getDescriptionFor('bar'), ATTRS['bar'])
  559. def test___getitem___miss(self):
  560. one = self._makeOne()
  561. def _test():
  562. return one['nonesuch']
  563. self.assertRaises(KeyError, _test)
  564. def test___getitem___hit(self):
  565. from zope.interface.interface import Attribute
  566. from zope.interface.interface import fromFunction
  567. def _bar():
  568. """DOCSTRING"""
  569. ATTRS = {'foo': Attribute('Foo', ''),
  570. 'bar': fromFunction(_bar),
  571. }
  572. one = self._makeOne(attrs=ATTRS)
  573. self.assertEqual(one['foo'], ATTRS['foo'])
  574. self.assertEqual(one['bar'], ATTRS['bar'])
  575. def test___contains___miss(self):
  576. one = self._makeOne()
  577. self.assertFalse('nonesuch' in one)
  578. def test___contains___hit(self):
  579. from zope.interface.interface import Attribute
  580. from zope.interface.interface import fromFunction
  581. def _bar():
  582. """DOCSTRING"""
  583. ATTRS = {'foo': Attribute('Foo', ''),
  584. 'bar': fromFunction(_bar),
  585. }
  586. one = self._makeOne(attrs=ATTRS)
  587. self.assertTrue('foo' in one)
  588. self.assertTrue('bar' in one)
  589. def test_direct_miss(self):
  590. one = self._makeOne()
  591. self.assertEqual(one.direct('nonesuch'), None)
  592. def test_direct_hit_local_miss_bases(self):
  593. from zope.interface.interface import Attribute
  594. from zope.interface.interface import fromFunction
  595. def _bar():
  596. """DOCSTRING"""
  597. def _foo():
  598. """DOCSTRING"""
  599. BASE_ATTRS = {'foo': Attribute('Foo', ''),
  600. 'bar': fromFunction(_bar),
  601. }
  602. DERIVED_ATTRS = {'foo': fromFunction(_foo),
  603. 'baz': Attribute('Baz', ''),
  604. }
  605. base = self._makeOne('IBase', attrs=BASE_ATTRS)
  606. derived = self._makeOne('IDerived', bases=(base,), attrs=DERIVED_ATTRS)
  607. self.assertEqual(derived.direct('foo'), DERIVED_ATTRS['foo'])
  608. self.assertEqual(derived.direct('baz'), DERIVED_ATTRS['baz'])
  609. self.assertEqual(derived.direct('bar'), None)
  610. def test_queryDescriptionFor_miss(self):
  611. iface = self._makeOne()
  612. self.assertEqual(iface.queryDescriptionFor('nonesuch'), None)
  613. def test_queryDescriptionFor_hit(self):
  614. from zope.interface import Attribute
  615. ATTRS = {'attr': Attribute('Title', 'Description')}
  616. iface = self._makeOne(attrs=ATTRS)
  617. self.assertEqual(iface.queryDescriptionFor('attr'), ATTRS['attr'])
  618. def test_validateInvariants_pass(self):
  619. _called_with = []
  620. def _passable(*args, **kw):
  621. _called_with.append((args, kw))
  622. return True
  623. iface = self._makeOne()
  624. obj = object()
  625. iface.setTaggedValue('invariants', [_passable])
  626. self.assertEqual(iface.validateInvariants(obj), None)
  627. self.assertEqual(_called_with, [((obj,), {})])
  628. def test_validateInvariants_fail_wo_errors_passed(self):
  629. from zope.interface.exceptions import Invalid
  630. _passable_called_with = []
  631. def _passable(*args, **kw):
  632. _passable_called_with.append((args, kw))
  633. return True
  634. _fail_called_with = []
  635. def _fail(*args, **kw):
  636. _fail_called_with.append((args, kw))
  637. raise Invalid
  638. iface = self._makeOne()
  639. obj = object()
  640. iface.setTaggedValue('invariants', [_passable, _fail])
  641. self.assertRaises(Invalid, iface.validateInvariants, obj)
  642. self.assertEqual(_passable_called_with, [((obj,), {})])
  643. self.assertEqual(_fail_called_with, [((obj,), {})])
  644. def test_validateInvariants_fail_w_errors_passed(self):
  645. from zope.interface.exceptions import Invalid
  646. _errors = []
  647. _fail_called_with = []
  648. def _fail(*args, **kw):
  649. _fail_called_with.append((args, kw))
  650. raise Invalid
  651. iface = self._makeOne()
  652. obj = object()
  653. iface.setTaggedValue('invariants', [_fail])
  654. self.assertRaises(Invalid, iface.validateInvariants, obj, _errors)
  655. self.assertEqual(_fail_called_with, [((obj,), {})])
  656. self.assertEqual(len(_errors), 1)
  657. self.assertTrue(isinstance(_errors[0], Invalid))
  658. def test_validateInvariants_fail_in_base_wo_errors_passed(self):
  659. from zope.interface.exceptions import Invalid
  660. _passable_called_with = []
  661. def _passable(*args, **kw):
  662. _passable_called_with.append((args, kw))
  663. return True
  664. _fail_called_with = []
  665. def _fail(*args, **kw):
  666. _fail_called_with.append((args, kw))
  667. raise Invalid
  668. base = self._makeOne('IBase')
  669. derived = self._makeOne('IDerived', (base,))
  670. obj = object()
  671. base.setTaggedValue('invariants', [_fail])
  672. derived.setTaggedValue('invariants', [_passable])
  673. self.assertRaises(Invalid, derived.validateInvariants, obj)
  674. self.assertEqual(_passable_called_with, [((obj,), {})])
  675. self.assertEqual(_fail_called_with, [((obj,), {})])
  676. def test_validateInvariants_fail_in_base_w_errors_passed(self):
  677. from zope.interface.exceptions import Invalid
  678. _errors = []
  679. _passable_called_with = []
  680. def _passable(*args, **kw):
  681. _passable_called_with.append((args, kw))
  682. return True
  683. _fail_called_with = []
  684. def _fail(*args, **kw):
  685. _fail_called_with.append((args, kw))
  686. raise Invalid
  687. base = self._makeOne('IBase')
  688. derived = self._makeOne('IDerived', (base,))
  689. obj = object()
  690. base.setTaggedValue('invariants', [_fail])
  691. derived.setTaggedValue('invariants', [_passable])
  692. self.assertRaises(Invalid, derived.validateInvariants, obj, _errors)
  693. self.assertEqual(_passable_called_with, [((obj,), {})])
  694. self.assertEqual(_fail_called_with, [((obj,), {})])
  695. self.assertEqual(len(_errors), 1)
  696. self.assertTrue(isinstance(_errors[0], Invalid))
  697. def test___reduce__(self):
  698. iface = self._makeOne('PickleMe')
  699. self.assertEqual(iface.__reduce__(), 'PickleMe')
  700. def test___hash___normal(self):
  701. iface = self._makeOne('HashMe')
  702. self.assertEqual(hash(iface),
  703. hash((('HashMe',
  704. 'zope.interface.tests.test_interface'))))
  705. def test___hash___missing_required_attrs(self):
  706. import warnings
  707. from warnings import catch_warnings
  708. class Derived(self._getTargetClass()):
  709. def __init__(self):
  710. pass # Don't call base class.
  711. derived = Derived()
  712. with catch_warnings(record=True) as warned:
  713. warnings.simplefilter('always') # see LP #825249
  714. self.assertEqual(hash(derived), 1)
  715. self.assertEqual(len(warned), 1)
  716. self.assertTrue(warned[0].category is UserWarning)
  717. self.assertEqual(str(warned[0].message),
  718. 'Hashing uninitialized InterfaceClass instance')
  719. def test_comparison_with_None(self):
  720. iface = self._makeOne()
  721. self.assertTrue(iface < None)
  722. self.assertTrue(iface <= None)
  723. self.assertFalse(iface == None)
  724. self.assertTrue(iface != None)
  725. self.assertFalse(iface >= None)
  726. self.assertFalse(iface > None)
  727. self.assertFalse(None < iface)
  728. self.assertFalse(None <= iface)
  729. self.assertFalse(None == iface)
  730. self.assertTrue(None != iface)
  731. self.assertTrue(None >= iface)
  732. self.assertTrue(None > iface)
  733. def test_comparison_with_same_instance(self):
  734. iface = self._makeOne()
  735. self.assertFalse(iface < iface)
  736. self.assertTrue(iface <= iface)
  737. self.assertTrue(iface == iface)
  738. self.assertFalse(iface != iface)
  739. self.assertTrue(iface >= iface)
  740. self.assertFalse(iface > iface)
  741. def test_comparison_with_same_named_instance_in_other_module(self):
  742. one = self._makeOne('IName', __module__='zope.interface.tests.one')
  743. other = self._makeOne('IName', __module__='zope.interface.tests.other')
  744. self.assertTrue(one < other)
  745. self.assertFalse(other < one)
  746. self.assertTrue(one <= other)
  747. self.assertFalse(other <= one)
  748. self.assertFalse(one == other)
  749. self.assertFalse(other == one)
  750. self.assertTrue(one != other)
  751. self.assertTrue(other != one)
  752. self.assertFalse(one >= other)
  753. self.assertTrue(other >= one)
  754. self.assertFalse(one > other)
  755. self.assertTrue(other > one)
  756. class InterfaceTests(unittest.TestCase):
  757. def test_attributes_link_to_interface(self):
  758. from zope.interface import Interface
  759. from zope.interface import Attribute
  760. class I1(Interface):
  761. attr = Attribute("My attr")
  762. self.assertTrue(I1['attr'].interface is I1)
  763. def test_methods_link_to_interface(self):
  764. from zope.interface import Interface
  765. class I1(Interface):
  766. def method(foo, bar, bingo):
  767. "A method"
  768. self.assertTrue(I1['method'].interface is I1)
  769. def test_classImplements_simple(self):
  770. from zope.interface import Interface
  771. from zope.interface import implementedBy
  772. from zope.interface import providedBy
  773. class ICurrent(Interface):
  774. def method1(a, b):
  775. pass
  776. def method2(a, b):
  777. pass
  778. class IOther(Interface):
  779. pass
  780. class Current(object):
  781. __implemented__ = ICurrent
  782. def method1(self, a, b):
  783. raise NotImplementedError()
  784. def method2(self, a, b):
  785. raise NotImplementedError()
  786. current = Current()
  787. self.assertTrue(ICurrent.implementedBy(Current))
  788. self.assertFalse(IOther.implementedBy(Current))
  789. self.assertTrue(ICurrent in implementedBy(Current))
  790. self.assertFalse(IOther in implementedBy(Current))
  791. self.assertTrue(ICurrent in providedBy(current))
  792. self.assertFalse(IOther in providedBy(current))
  793. def test_classImplements_base_not_derived(self):
  794. from zope.interface import Interface
  795. from zope.interface import implementedBy
  796. from zope.interface import providedBy
  797. class IBase(Interface):
  798. def method():
  799. pass
  800. class IDerived(IBase):
  801. pass
  802. class Current():
  803. __implemented__ = IBase
  804. def method(self):
  805. raise NotImplementedError()
  806. current = Current()
  807. self.assertTrue(IBase.implementedBy(Current))
  808. self.assertFalse(IDerived.implementedBy(Current))
  809. self.assertTrue(IBase in implementedBy(Current))
  810. self.assertFalse(IDerived in implementedBy(Current))
  811. self.assertTrue(IBase in providedBy(current))
  812. self.assertFalse(IDerived in providedBy(current))
  813. def test_classImplements_base_and_derived(self):
  814. from zope.interface import Interface
  815. from zope.interface import implementedBy
  816. from zope.interface import providedBy
  817. class IBase(Interface):
  818. def method():
  819. pass
  820. class IDerived(IBase):
  821. pass
  822. class Current(object):
  823. __implemented__ = IDerived
  824. def method(self):
  825. raise NotImplementedError()
  826. current = Current()
  827. self.assertTrue(IBase.implementedBy(Current))
  828. self.assertTrue(IDerived.implementedBy(Current))
  829. self.assertFalse(IBase in implementedBy(Current))
  830. self.assertTrue(IBase in implementedBy(Current).flattened())
  831. self.assertTrue(IDerived in implementedBy(Current))
  832. self.assertFalse(IBase in providedBy(current))
  833. self.assertTrue(IBase in providedBy(current).flattened())
  834. self.assertTrue(IDerived in providedBy(current))
  835. def test_classImplements_multiple(self):
  836. from zope.interface import Interface
  837. from zope.interface import implementedBy
  838. from zope.interface import providedBy
  839. class ILeft(Interface):
  840. def method():
  841. pass
  842. class IRight(ILeft):
  843. pass
  844. class Left(object):
  845. __implemented__ = ILeft
  846. def method(self):
  847. raise NotImplementedError()
  848. class Right(object):
  849. __implemented__ = IRight
  850. class Ambi(Left, Right):
  851. pass
  852. ambi = Ambi()
  853. self.assertTrue(ILeft.implementedBy(Ambi))
  854. self.assertTrue(IRight.implementedBy(Ambi))
  855. self.assertTrue(ILeft in implementedBy(Ambi))
  856. self.assertTrue(IRight in implementedBy(Ambi))
  857. self.assertTrue(ILeft in providedBy(ambi))
  858. self.assertTrue(IRight in providedBy(ambi))
  859. def test_classImplements_multiple_w_explict_implements(self):
  860. from zope.interface import Interface
  861. from zope.interface import implementedBy
  862. from zope.interface import providedBy
  863. class ILeft(Interface):
  864. def method():
  865. pass
  866. class IRight(ILeft):
  867. pass
  868. class IOther(Interface):
  869. pass
  870. class Left():
  871. __implemented__ = ILeft
  872. def method(self):
  873. raise NotImplementedError()
  874. class Right(object):
  875. __implemented__ = IRight
  876. class Other(object):
  877. __implemented__ = IOther
  878. class Mixed(Left, Right):
  879. __implemented__ = Left.__implemented__, Other.__implemented__
  880. mixed = Mixed()
  881. self.assertTrue(ILeft.implementedBy(Mixed))
  882. self.assertFalse(IRight.implementedBy(Mixed))
  883. self.assertTrue(IOther.implementedBy(Mixed))
  884. self.assertTrue(ILeft in implementedBy(Mixed))
  885. self.assertFalse(IRight in implementedBy(Mixed))
  886. self.assertTrue(IOther in implementedBy(Mixed))
  887. self.assertTrue(ILeft in providedBy(mixed))
  888. self.assertFalse(IRight in providedBy(mixed))
  889. self.assertTrue(IOther in providedBy(mixed))
  890. def testInterfaceExtendsInterface(self):
  891. from zope.interface import Interface
  892. new = Interface.__class__
  893. FunInterface = new('FunInterface')
  894. BarInterface = new('BarInterface', [FunInterface])
  895. BobInterface = new('BobInterface')
  896. BazInterface = new('BazInterface', [BobInterface, BarInterface])
  897. self.assertTrue(BazInterface.extends(BobInterface))
  898. self.assertTrue(BazInterface.extends(BarInterface))
  899. self.assertTrue(BazInterface.extends(FunInterface))
  900. self.assertFalse(BobInterface.extends(FunInterface))
  901. self.assertFalse(BobInterface.extends(BarInterface))
  902. self.assertTrue(BarInterface.extends(FunInterface))
  903. self.assertFalse(BarInterface.extends(BazInterface))
  904. def test_verifyClass(self):
  905. from zope.interface import Attribute
  906. from zope.interface import Interface
  907. from zope.interface.verify import verifyClass
  908. class ICheckMe(Interface):
  909. attr = Attribute(u'My attr')
  910. def method():
  911. "A method"
  912. class CheckMe(object):
  913. __implemented__ = ICheckMe
  914. attr = 'value'
  915. def method(self):
  916. raise NotImplementedError()
  917. self.assertTrue(verifyClass(ICheckMe, CheckMe))
  918. def test_verifyObject(self):
  919. from zope.interface import Attribute
  920. from zope.interface import Interface
  921. from zope.interface.verify import verifyObject
  922. class ICheckMe(Interface):
  923. attr = Attribute(u'My attr')
  924. def method():
  925. "A method"
  926. class CheckMe(object):
  927. __implemented__ = ICheckMe
  928. attr = 'value'
  929. def method(self):
  930. raise NotImplementedError()
  931. check_me = CheckMe()
  932. self.assertTrue(verifyObject(ICheckMe, check_me))
  933. def test_interface_object_provides_Interface(self):
  934. from zope.interface import Interface
  935. class AnInterface(Interface):
  936. pass
  937. self.assertTrue(Interface.providedBy(AnInterface))
  938. def test_names_simple(self):
  939. from zope.interface import Attribute
  940. from zope.interface import Interface
  941. class ISimple(Interface):
  942. attr = Attribute(u'My attr')
  943. def method():
  944. pass
  945. self.assertEqual(sorted(ISimple.names()), ['attr', 'method'])
  946. def test_names_derived(self):
  947. from zope.interface import Attribute
  948. from zope.interface import Interface
  949. class IBase(Interface):
  950. attr = Attribute(u'My attr')
  951. def method():
  952. pass
  953. class IDerived(IBase):
  954. attr2 = Attribute(u'My attr2')
  955. def method():
  956. pass
  957. def method2():
  958. pass
  959. self.assertEqual(sorted(IDerived.names()),
  960. ['attr2', 'method', 'method2'])
  961. self.assertEqual(sorted(IDerived.names(all=True)),
  962. ['attr', 'attr2', 'method', 'method2'])
  963. def test_namesAndDescriptions_simple(self):
  964. from zope.interface import Attribute
  965. from zope.interface.interface import Method
  966. from zope.interface import Interface
  967. class ISimple(Interface):
  968. attr = Attribute(u'My attr')
  969. def method():
  970. "My method"
  971. name_values = sorted(ISimple.namesAndDescriptions())
  972. self.assertEqual(len(name_values), 2)
  973. self.assertEqual(name_values[0][0], 'attr')
  974. self.assertTrue(isinstance(name_values[0][1], Attribute))
  975. self.assertEqual(name_values[0][1].__name__, 'attr')
  976. self.assertEqual(name_values[0][1].__doc__, 'My attr')
  977. self.assertEqual(name_values[1][0], 'method')
  978. self.assertTrue(isinstance(name_values[1][1], Method))
  979. self.assertEqual(name_values[1][1].__name__, 'method')
  980. self.assertEqual(name_values[1][1].__doc__, 'My method')
  981. def test_namesAndDescriptions_derived(self):
  982. from zope.interface import Attribute
  983. from zope.interface import Interface
  984. from zope.interface.interface import Method
  985. class IBase(Interface):
  986. attr = Attribute(u'My attr')
  987. def method():
  988. "My method"
  989. class IDerived(IBase):
  990. attr2 = Attribute(u'My attr2')
  991. def method():
  992. "My method, overridden"
  993. def method2():
  994. "My method2"
  995. name_values = sorted(IDerived.namesAndDescriptions())
  996. self.assertEqual(len(name_values), 3)
  997. self.assertEqual(name_values[0][0], 'attr2')
  998. self.assertTrue(isinstance(name_values[0][1], Attribute))
  999. self.assertEqual(name_values[0][1].__name__, 'attr2')
  1000. self.assertEqual(name_values[0][1].__doc__, 'My attr2')
  1001. self.assertEqual(name_values[1][0], 'method')
  1002. self.assertTrue(isinstance(name_values[1][1], Method))
  1003. self.assertEqual(name_values[1][1].__name__, 'method')
  1004. self.assertEqual(name_values[1][1].__doc__, 'My method, overridden')
  1005. self.assertEqual(name_values[2][0], 'method2')
  1006. self.assertTrue(isinstance(name_values[2][1], Method))
  1007. self.assertEqual(name_values[2][1].__name__, 'method2')
  1008. self.assertEqual(name_values[2][1].__doc__, 'My method2')
  1009. name_values = sorted(IDerived.namesAndDescriptions(all=True))
  1010. self.assertEqual(len(name_values), 4)
  1011. self.assertEqual(name_values[0][0], 'attr')
  1012. self.assertTrue(isinstance(name_values[0][1], Attribute))
  1013. self.assertEqual(name_values[0][1].__name__, 'attr')
  1014. self.assertEqual(name_values[0][1].__doc__, 'My attr')
  1015. self.assertEqual(name_values[1][0], 'attr2')
  1016. self.assertTrue(isinstance(name_values[1][1], Attribute))
  1017. self.assertEqual(name_values[1][1].__name__, 'attr2')
  1018. self.assertEqual(name_values[1][1].__doc__, 'My attr2')
  1019. self.assertEqual(name_values[2][0], 'method')
  1020. self.assertTrue(isinstance(name_values[2][1], Method))
  1021. self.assertEqual(name_values[2][1].__name__, 'method')
  1022. self.assertEqual(name_values[2][1].__doc__, 'My method, overridden')
  1023. self.assertEqual(name_values[3][0], 'method2')
  1024. self.assertTrue(isinstance(name_values[3][1], Method))
  1025. self.assertEqual(name_values[3][1].__name__, 'method2')
  1026. self.assertEqual(name_values[3][1].__doc__, 'My method2')
  1027. def test_getDescriptionFor_nonesuch_no_default(self):
  1028. from zope.interface import Interface
  1029. class IEmpty(Interface):
  1030. pass
  1031. self.assertRaises(KeyError, IEmpty.getDescriptionFor, 'nonesuch')
  1032. def test_getDescriptionFor_simple(self):
  1033. from zope.interface import Attribute
  1034. from zope.interface.interface import Method
  1035. from zope.interface import Interface
  1036. class ISimple(Interface):
  1037. attr = Attribute(u'My attr')
  1038. def method():
  1039. "My method"
  1040. a_desc = ISimple.getDescriptionFor('attr')
  1041. self.assertTrue(isinstance(a_desc, Attribute))
  1042. self.assertEqual(a_desc.__name__, 'attr')
  1043. self.assertEqual(a_desc.__doc__, 'My attr')
  1044. m_desc = ISimple.getDescriptionFor('method')
  1045. self.assertTrue(isinstance(m_desc, Method))
  1046. self.assertEqual(m_desc.__name__, 'method')
  1047. self.assertEqual(m_desc.__doc__, 'My method')
  1048. def test_getDescriptionFor_derived(self):
  1049. from zope.interface import Attribute
  1050. from zope.interface.interface import Method
  1051. from zope.interface import Interface
  1052. class IBase(Interface):
  1053. attr = Attribute(u'My attr')
  1054. def method():
  1055. "My method"
  1056. class IDerived(IBase):
  1057. attr2 = Attribute(u'My attr2')
  1058. def method():
  1059. "My method, overridden"
  1060. def method2():
  1061. "My method2"
  1062. a_desc = IDerived.getDescriptionFor('attr')
  1063. self.assertTrue(isinstance(a_desc, Attribute))
  1064. self.assertEqual(a_desc.__name__, 'attr')
  1065. self.assertEqual(a_desc.__doc__, 'My attr')
  1066. m_desc = IDerived.getDescriptionFor('method')
  1067. self.assertTrue(isinstance(m_desc, Method))
  1068. self.assertEqual(m_desc.__name__, 'method')
  1069. self.assertEqual(m_desc.__doc__, 'My method, overridden')
  1070. a2_desc = IDerived.getDescriptionFor('attr2')
  1071. self.assertTrue(isinstance(a2_desc, Attribute))
  1072. self.assertEqual(a2_desc.__name__, 'attr2')
  1073. self.assertEqual(a2_desc.__doc__, 'My attr2')
  1074. m2_desc = IDerived.getDescriptionFor('method2')
  1075. self.assertTrue(isinstance(m2_desc, Method))
  1076. self.assertEqual(m2_desc.__name__, 'method2')
  1077. self.assertEqual(m2_desc.__doc__, 'My method2')
  1078. def test___getitem__nonesuch(self):
  1079. from zope.interface import Interface
  1080. class IEmpty(Interface):
  1081. pass
  1082. self.assertRaises(KeyError, IEmpty.__getitem__, 'nonesuch')
  1083. def test___getitem__simple(self):
  1084. from zope.interface import Attribute
  1085. from zope.interface.interface import Method
  1086. from zope.interface import Interface
  1087. class ISimple(Interface):
  1088. attr = Attribute(u'My attr')
  1089. def method():
  1090. "My method"
  1091. a_desc = ISimple['attr']
  1092. self.assertTrue(isinstance(a_desc, Attribute))
  1093. self.assertEqual(a_desc.__name__, 'attr')
  1094. self.assertEqual(a_desc.__doc__, 'My attr')
  1095. m_desc = ISimple['method']
  1096. self.assertTrue(isinstance(m_desc, Method))
  1097. self.assertEqual(m_desc.__name__, 'method')
  1098. self.assertEqual(m_desc.__doc__, 'My method')
  1099. def test___getitem___derived(self):
  1100. from zope.interface import Attribute
  1101. from zope.interface.interface import Method
  1102. from zope.interface import Interface
  1103. class IBase(Interface):
  1104. attr = Attribute(u'My attr')
  1105. def method():
  1106. "My method"
  1107. class IDerived(IBase):
  1108. attr2 = Attribute(u'My attr2')
  1109. def method():
  1110. "My method, overridden"
  1111. def method2():
  1112. "My method2"
  1113. a_desc = IDerived['attr']
  1114. self.assertTrue(isinstance(a_desc, Attribute))
  1115. self.assertEqual(a_desc.__name__, 'attr')
  1116. self.assertEqual(a_desc.__doc__, 'My attr')
  1117. m_desc = IDerived['method']
  1118. self.assertTrue(isinstance(m_desc, Method))
  1119. self.assertEqual(m_desc.__name__, 'method')
  1120. self.assertEqual(m_desc.__doc__, 'My method, overridden')
  1121. a2_desc = IDerived['attr2']
  1122. self.assertTrue(isinstance(a2_desc, Attribute))
  1123. self.assertEqual(a2_desc.__name__, 'attr2')
  1124. self.assertEqual(a2_desc.__doc__, 'My attr2')
  1125. m2_desc = IDerived['method2']
  1126. self.assertTrue(isinstance(m2_desc, Method))
  1127. self.assertEqual(m2_desc.__name__, 'method2')
  1128. self.assertEqual(m2_desc.__doc__, 'My method2')
  1129. def test___contains__nonesuch(self):
  1130. from zope.interface import Interface
  1131. class IEmpty(Interface):
  1132. pass
  1133. self.assertFalse('nonesuch' in IEmpty)
  1134. def test___contains__simple(self):
  1135. from zope.interface import Attribute
  1136. from zope.interface import Interface
  1137. class ISimple(Interface):
  1138. attr = Attribute(u'My attr')
  1139. def method():
  1140. "My method"
  1141. self.assertTrue('attr' in ISimple)
  1142. self.assertTrue('method' in ISimple)
  1143. def test___contains__derived(self):
  1144. from zope.interface import Attribute
  1145. from zope.interface import Interface
  1146. class IBase(Interface):
  1147. attr = Attribute(u'My attr')
  1148. def method():
  1149. "My method"
  1150. class IDerived(IBase):
  1151. attr2 = Attribute(u'My attr2')
  1152. def method():
  1153. "My method, overridden"
  1154. def method2():
  1155. "My method2"
  1156. self.assertTrue('attr' in IDerived)
  1157. self.assertTrue('method' in IDerived)
  1158. self.assertTrue('attr2' in IDerived)
  1159. self.assertTrue('method2' in IDerived)
  1160. def test___iter__empty(self):
  1161. from zope.interface import Interface
  1162. class IEmpty(Interface):
  1163. pass
  1164. self.assertEqual(list(IEmpty), [])
  1165. def test___iter__simple(self):
  1166. from zope.interface import Attribute
  1167. from zope.interface import Interface
  1168. class ISimple(Interface):
  1169. attr = Attribute(u'My attr')
  1170. def method():
  1171. "My method"
  1172. self.assertEqual(sorted(list(ISimple)), ['attr', 'method'])
  1173. def test___iter__derived(self):
  1174. from zope.interface import Attribute
  1175. from zope.interface import Interface
  1176. class IBase(Interface):
  1177. attr = Attribute(u'My attr')
  1178. def method():
  1179. "My method"
  1180. class IDerived(IBase):
  1181. attr2 = Attribute(u'My attr2')
  1182. def method():
  1183. "My method, overridden"
  1184. def method2():
  1185. "My method2"
  1186. self.assertEqual(sorted(list(IDerived)),
  1187. ['attr', 'attr2', 'method', 'method2'])
  1188. def test_function_attributes_become_tagged_values(self):
  1189. from zope.interface import Interface
  1190. class ITagMe(Interface):
  1191. def method():
  1192. pass
  1193. method.optional = 1
  1194. method = ITagMe['method']
  1195. self.assertEqual(method.getTaggedValue('optional'), 1)
  1196. def test___doc___non_element(self):
  1197. from zope.interface import Interface
  1198. class IHaveADocString(Interface):
  1199. "xxx"
  1200. self.assertEqual(IHaveADocString.__doc__, "xxx")
  1201. self.assertEqual(list(IHaveADocString), [])
  1202. def test___doc___as_element(self):
  1203. from zope.interface import Attribute
  1204. from zope.interface import Interface
  1205. class IHaveADocString(Interface):
  1206. "xxx"
  1207. __doc__ = Attribute('the doc')
  1208. self.assertEqual(IHaveADocString.__doc__, "")
  1209. self.assertEqual(list(IHaveADocString), ['__doc__'])
  1210. def _errorsEqual(self, has_invariant, error_len, error_msgs, iface):
  1211. from zope.interface.exceptions import Invalid
  1212. self.assertRaises(Invalid, iface.validateInvariants, has_invariant)
  1213. e = []
  1214. try:
  1215. iface.validateInvariants(has_invariant, e)
  1216. self.fail("validateInvariants should always raise")
  1217. except Invalid as error:
  1218. self.assertEqual(error.args[0], e)
  1219. self.assertEqual(len(e), error_len)
  1220. msgs = [error.args[0] for error in e]
  1221. msgs.sort()
  1222. for msg in msgs:
  1223. self.assertEqual(msg, error_msgs.pop(0))
  1224. def test_invariant_simple(self):
  1225. from zope.interface import Attribute
  1226. from zope.interface import Interface
  1227. from zope.interface import directlyProvides
  1228. from zope.interface import invariant
  1229. class IInvariant(Interface):
  1230. foo = Attribute('foo')
  1231. bar = Attribute('bar; must eval to Boolean True if foo does')
  1232. invariant(_ifFooThenBar)
  1233. class HasInvariant(object):
  1234. pass
  1235. # set up
  1236. has_invariant = HasInvariant()
  1237. directlyProvides(has_invariant, IInvariant)
  1238. # the tests
  1239. self.assertEqual(IInvariant.getTaggedValue('invariants'),
  1240. [_ifFooThenBar])
  1241. self.assertEqual(IInvariant.validateInvariants(has_invariant), None)
  1242. has_invariant.bar = 27
  1243. self.assertEqual(IInvariant.validateInvariants(has_invariant), None)
  1244. has_invariant.foo = 42
  1245. self.assertEqual(IInvariant.validateInvariants(has_invariant), None)
  1246. del has_invariant.bar
  1247. self._errorsEqual(has_invariant, 1, ['If Foo, then Bar!'],
  1248. IInvariant)
  1249. def test_invariant_nested(self):
  1250. from zope.interface import Attribute
  1251. from zope.interface import Interface
  1252. from zope.interface import directlyProvides
  1253. from zope.interface import invariant
  1254. class IInvariant(Interface):
  1255. foo = Attribute('foo')
  1256. bar = Attribute('bar; must eval to Boolean True if foo does')
  1257. invariant(_ifFooThenBar)
  1258. class ISubInvariant(IInvariant):
  1259. invariant(_barGreaterThanFoo)
  1260. class HasInvariant(object):
  1261. pass
  1262. # nested interfaces with invariants:
  1263. self.assertEqual(ISubInvariant.getTaggedValue('invariants'),
  1264. [_barGreaterThanFoo])
  1265. has_invariant = HasInvariant()
  1266. directlyProvides(has_invariant, ISubInvariant)
  1267. has_invariant.foo = 42
  1268. # even though the interface has changed, we should still only have one
  1269. # error.
  1270. self._errorsEqual(has_invariant, 1, ['If Foo, then Bar!'],
  1271. ISubInvariant)
  1272. # however, if we set foo to 0 (Boolean False) and bar to a negative
  1273. # number then we'll get the new error
  1274. has_invariant.foo = 2
  1275. has_invariant.bar = 1
  1276. self._errorsEqual(has_invariant, 1,
  1277. ['Please, Boo MUST be greater than Foo!'],
  1278. ISubInvariant)
  1279. # and if we set foo to a positive number and boo to 0, we'll
  1280. # get both errors!
  1281. has_invariant.foo = 1
  1282. has_invariant.bar = 0
  1283. self._errorsEqual(has_invariant, 2,
  1284. ['If Foo, then Bar!',
  1285. 'Please, Boo MUST be greater than Foo!'],
  1286. ISubInvariant)
  1287. # for a happy ending, we'll make the invariants happy
  1288. has_invariant.foo = 1
  1289. has_invariant.bar = 2
  1290. self.assertEqual(IInvariant.validateInvariants(has_invariant), None)
  1291. def test_invariant_mutandis(self):
  1292. from zope.interface import Attribute
  1293. from zope.interface import Interface
  1294. from zope.interface import directlyProvides
  1295. from zope.interface import invariant
  1296. class IInvariant(Interface):
  1297. foo = Attribute('foo')
  1298. bar = Attribute('bar; must eval to Boolean True if foo does')
  1299. invariant(_ifFooThenBar)
  1300. class HasInvariant(object):
  1301. pass
  1302. # now we'll do two invariants on the same interface,
  1303. # just to make sure that a small
  1304. # multi-invariant interface is at least minimally tested.
  1305. has_invariant = HasInvariant()
  1306. directlyProvides(has_invariant, IInvariant)
  1307. has_invariant.foo = 42
  1308. # if you really need to mutate, then this would be the way to do it.
  1309. # Probably a bad idea, though. :-)
  1310. old_invariants = IInvariant.getTaggedValue('invariants')
  1311. invariants = old_invariants[:]
  1312. invariants.append(_barGreaterThanFoo)
  1313. IInvariant.setTaggedValue('invariants', invariants)
  1314. # even though the interface has changed, we should still only have one
  1315. # error.
  1316. self._errorsEqual(has_invariant, 1, ['If Foo, then Bar!'],
  1317. IInvariant)
  1318. # however, if we set foo to 0 (Boolean False) and bar to a negative
  1319. # number then we'll get the new error
  1320. has_invariant.foo = 2
  1321. has_invariant.bar = 1
  1322. self._errorsEqual(has_invariant, 1,
  1323. ['Please, Boo MUST be greater than Foo!'], IInvariant)
  1324. # and if we set foo to a positive number and boo to 0, we'll
  1325. # get both errors!
  1326. has_invariant.foo = 1
  1327. has_invariant.bar = 0
  1328. self._errorsEqual(has_invariant, 2,
  1329. ['If Foo, then Bar!',
  1330. 'Please, Boo MUST be greater than Foo!'],
  1331. IInvariant)
  1332. # for another happy ending, we'll make the invariants happy again
  1333. has_invariant.foo = 1
  1334. has_invariant.bar = 2
  1335. self.assertEqual(IInvariant.validateInvariants(has_invariant), None)
  1336. # clean up
  1337. IInvariant.setTaggedValue('invariants', old_invariants)
  1338. def test___doc___element(self):
  1339. from zope.interface import Interface
  1340. from zope.interface import Attribute
  1341. class I(Interface):
  1342. "xxx"
  1343. self.assertEqual(I.__doc__, "xxx")
  1344. self.assertEqual(list(I), [])
  1345. class I(Interface):
  1346. "xxx"
  1347. __doc__ = Attribute('the doc')
  1348. self.assertEqual(I.__doc__, "")
  1349. self.assertEqual(list(I), ['__doc__'])
  1350. @_skip_under_py3k
  1351. def testIssue228(self):
  1352. # Test for http://collector.zope.org/Zope3-dev/228
  1353. # Old style classes don't have a '__class__' attribute
  1354. # No old style classes in Python 3, so the test becomes moot.
  1355. import sys
  1356. from zope.interface import Interface
  1357. class I(Interface):
  1358. "xxx"
  1359. class OldStyle:
  1360. __providedBy__ = None
  1361. self.assertRaises(AttributeError, I.providedBy, OldStyle)
  1362. def test_invariant_as_decorator(self):
  1363. from zope.interface import Interface
  1364. from zope.interface import Attribute
  1365. from zope.interface import implementer
  1366. from zope.interface import invariant
  1367. from zope.interface.exceptions import Invalid
  1368. class IRange(Interface):
  1369. min = Attribute("Lower bound")
  1370. max = Attribute("Upper bound")
  1371. @invariant
  1372. def range_invariant(ob):
  1373. if ob.max < ob.min:
  1374. raise Invalid('max < min')
  1375. @implementer(IRange)
  1376. class Range(object):
  1377. def __init__(self, min, max):
  1378. self.min, self.max = min, max
  1379. IRange.validateInvariants(Range(1,2))
  1380. IRange.validateInvariants(Range(1,1))
  1381. try:
  1382. IRange.validateInvariants(Range(2,1))
  1383. except Invalid as e:
  1384. self.assertEqual(str(e), 'max < min')
  1385. def test_taggedValue(self):
  1386. from zope.interface import Attribute
  1387. from zope.interface import Interface
  1388. from zope.interface import taggedValue
  1389. class ITagged(Interface):
  1390. foo = Attribute('foo')
  1391. bar = Attribute('bar; must eval to Boolean True if foo does')
  1392. taggedValue('qux', 'Spam')
  1393. class HasInvariant(object):
  1394. pass
  1395. self.assertEqual(ITagged.getTaggedValue('qux'), 'Spam')
  1396. self.assertTrue('qux' in ITagged.getTaggedValueTags())
  1397. def test_description_cache_management(self):
  1398. # See https://bugs.launchpad.net/zope.interface/+bug/185974
  1399. # There was a bug where the cache used by Specification.get() was not
  1400. # cleared when the bases were changed.
  1401. from zope.interface import Interface
  1402. from zope.interface import Attribute
  1403. class I1(Interface):
  1404. a = Attribute('a')
  1405. class I2(I1):
  1406. pass
  1407. class I3(I2):
  1408. pass
  1409. self.assertTrue(I3.get('a') is I1.get('a'))
  1410. I2.__bases__ = (Interface,)
  1411. self.assertTrue(I3.get('a') is None)
  1412. def test___call___defers_to___conform___(self):
  1413. from zope.interface import Interface
  1414. from zope.interface import implementer
  1415. class I(Interface):
  1416. pass
  1417. @implementer(I)
  1418. class C(object):
  1419. def __conform__(self, proto):
  1420. return 0
  1421. self.assertEqual(I(C()), 0)
  1422. def test___call___object_implements(self):
  1423. from zope.interface import Interface
  1424. from zope.interface import implementer
  1425. class I(Interface):
  1426. pass
  1427. @implementer(I)
  1428. class C(object):
  1429. pass
  1430. c = C()
  1431. self.assertTrue(I(c) is c)
  1432. def test___call___miss_wo_alternate(self):
  1433. from zope.interface import Interface
  1434. class I(Interface):
  1435. pass
  1436. class C(object):
  1437. pass
  1438. c = C()
  1439. self.assertRaises(TypeError, I, c)
  1440. def test___call___miss_w_alternate(self):
  1441. from zope.interface import Interface
  1442. class I(Interface):
  1443. pass
  1444. class C(object):
  1445. pass
  1446. c = C()
  1447. self.assertTrue(I(c, self) is self)
  1448. def test___call___w_adapter_hook(self):
  1449. from zope.interface import Interface
  1450. from zope.interface.interface import adapter_hooks
  1451. old_hooks = adapter_hooks[:]
  1452. def _miss(iface, obj):
  1453. pass
  1454. def _hit(iface, obj):
  1455. return self
  1456. class I(Interface):
  1457. pass
  1458. class C(object):
  1459. pass
  1460. c = C()
  1461. old_adapter_hooks = adapter_hooks[:]
  1462. adapter_hooks[:] = [_miss, _hit]
  1463. try:
  1464. self.assertTrue(I(c) is self)
  1465. finally:
  1466. adapter_hooks[:] = old_adapter_hooks
  1467. class AttributeTests(ElementTests):
  1468. DEFAULT_NAME = 'TestAttribute'
  1469. def _getTargetClass(self):
  1470. from zope.interface.interface import Attribute
  1471. return Attribute
  1472. class MethodTests(AttributeTests):
  1473. DEFAULT_NAME = 'TestMethod'
  1474. def _getTargetClass(self):
  1475. from zope.interface.interface import Method
  1476. return Method
  1477. def test_optional_as_property(self):
  1478. method = self._makeOne()
  1479. self.assertEqual(method.optional, {})
  1480. method.optional = {'foo': 'bar'}
  1481. self.assertEqual(method.optional, {'foo': 'bar'})
  1482. del method.optional
  1483. self.assertEqual(method.optional, {})
  1484. def test___call___raises_BrokenImplementation(self):
  1485. from zope.interface.exceptions import BrokenImplementation
  1486. method = self._makeOne()
  1487. try:
  1488. method()
  1489. except BrokenImplementation as e:
  1490. self.assertEqual(e.interface, None)
  1491. self.assertEqual(e.name, self.DEFAULT_NAME)
  1492. else:
  1493. self.fail('__call__ should raise BrokenImplementation')
  1494. def test_getSignatureInfo_bare(self):
  1495. method = self._makeOne()
  1496. info = method.getSignatureInfo()
  1497. self.assertEqual(list(info['positional']), [])
  1498. self.assertEqual(list(info['required']), [])
  1499. self.assertEqual(info['optional'], {})
  1500. self.assertEqual(info['varargs'], None)
  1501. self.assertEqual(info['kwargs'], None)
  1502. def test_getSignatureString_bare(self):
  1503. method = self._makeOne()
  1504. self.assertEqual(method.getSignatureString(), '()')
  1505. def test_getSignatureString_w_only_required(self):
  1506. method = self._makeOne()
  1507. method.positional = method.required = ['foo']
  1508. self.assertEqual(method.getSignatureString(), '(foo)')
  1509. def test_getSignatureString_w_optional(self):
  1510. method = self._makeOne()
  1511. method.positional = method.required = ['foo']
  1512. method.optional = {'foo': 'bar'}
  1513. self.assertEqual(method.getSignatureString(), "(foo='bar')")
  1514. def test_getSignatureString_w_varargs(self):
  1515. method = self._makeOne()
  1516. method.varargs = 'args'
  1517. self.assertEqual(method.getSignatureString(), "(*args)")
  1518. def test_getSignatureString_w_kwargs(self):
  1519. method = self._makeOne()
  1520. method.kwargs = 'kw'
  1521. self.assertEqual(method.getSignatureString(), "(**kw)")
  1522. class Test_fromFunction(unittest.TestCase):
  1523. def _callFUT(self, *args, **kw):
  1524. from zope.interface.interface import fromFunction
  1525. return fromFunction(*args, **kw)
  1526. def test_bare(self):
  1527. def _func():
  1528. "DOCSTRING"
  1529. method = self._callFUT(_func)
  1530. self.assertEqual(method.getName(), '_func')
  1531. self.assertEqual(method.getDoc(), 'DOCSTRING')
  1532. self.assertEqual(method.interface, None)
  1533. self.assertEqual(list(method.getTaggedValueTags()), [])
  1534. info = method.getSignatureInfo()
  1535. self.assertEqual(list(info['positional']), [])
  1536. self.assertEqual(list(info['required']), [])
  1537. self.assertEqual(info['optional'], {})
  1538. self.assertEqual(info['varargs'], None)
  1539. self.assertEqual(info['kwargs'], None)
  1540. def test_w_interface(self):
  1541. from zope.interface.interface import InterfaceClass
  1542. class IFoo(InterfaceClass):
  1543. pass
  1544. def _func():
  1545. "DOCSTRING"
  1546. method = self._callFUT(_func, interface=IFoo)
  1547. self.assertEqual(method.interface, IFoo)
  1548. def test_w_name(self):
  1549. def _func():
  1550. "DOCSTRING"
  1551. method = self._callFUT(_func, name='anotherName')
  1552. self.assertEqual(method.getName(), 'anotherName')
  1553. def test_w_only_required(self):
  1554. def _func(foo):
  1555. "DOCSTRING"
  1556. method = self._callFUT(_func)
  1557. info = method.getSignatureInfo()
  1558. self.assertEqual(list(info['positional']), ['foo'])
  1559. self.assertEqual(list(info['required']), ['foo'])
  1560. self.assertEqual(info['optional'], {})
  1561. self.assertEqual(info['varargs'], None)
  1562. self.assertEqual(info['kwargs'], None)
  1563. def test_w_optional(self):
  1564. def _func(foo='bar'):
  1565. "DOCSTRING"
  1566. method = self._callFUT(_func)
  1567. info = method.getSignatureInfo()
  1568. self.assertEqual(list(info['positional']), ['foo'])
  1569. self.assertEqual(list(info['required']), [])
  1570. self.assertEqual(info['optional'], {'foo': 'bar'})
  1571. self.assertEqual(info['varargs'], None)
  1572. self.assertEqual(info['kwargs'], None)
  1573. def test_w_optional_self(self):
  1574. # XXX This is a weird case, trying to cover the following code in
  1575. # FUT::
  1576. #
  1577. # nr = na-len(defaults)
  1578. # if nr < 0:
  1579. # defaults=defaults[-nr:]
  1580. # nr = 0
  1581. def _func(self='bar'):
  1582. "DOCSTRING"
  1583. method = self._callFUT(_func, imlevel=1)
  1584. info = method.getSignatureInfo()
  1585. self.assertEqual(list(info['positional']), [])
  1586. self.assertEqual(list(info['required']), [])
  1587. self.assertEqual(info['optional'], {})
  1588. self.assertEqual(info['varargs'], None)
  1589. self.assertEqual(info['kwargs'], None)
  1590. def test_w_varargs(self):
  1591. def _func(*args):
  1592. "DOCSTRING"
  1593. method = self._callFUT(_func)
  1594. info = method.getSignatureInfo()
  1595. self.assertEqual(list(info['positional']), [])
  1596. self.assertEqual(list(info['required']), [])
  1597. self.assertEqual(info['optional'], {})
  1598. self.assertEqual(info['varargs'], 'args')
  1599. self.assertEqual(info['kwargs'], None)
  1600. def test_w_kwargs(self):
  1601. def _func(**kw):
  1602. "DOCSTRING"
  1603. method = self._callFUT(_func)
  1604. info = method.getSignatureInfo()
  1605. self.assertEqual(list(info['positional']), [])
  1606. self.assertEqual(list(info['required']), [])
  1607. self.assertEqual(info['optional'], {})
  1608. self.assertEqual(info['varargs'], None)
  1609. self.assertEqual(info['kwargs'], 'kw')
  1610. def test_full_spectrum(self):
  1611. def _func(foo, bar='baz', *args, **kw):
  1612. "DOCSTRING"
  1613. method = self._callFUT(_func)
  1614. info = method.getSignatureInfo()
  1615. self.assertEqual(list(info['positional']), ['foo', 'bar'])
  1616. self.assertEqual(list(info['required']), ['foo'])
  1617. self.assertEqual(info['optional'], {'bar': 'baz'})
  1618. self.assertEqual(info['varargs'], 'args')
  1619. self.assertEqual(info['kwargs'], 'kw')
  1620. class Test_fromMethod(unittest.TestCase):
  1621. def _callFUT(self, *args, **kw):
  1622. from zope.interface.interface import fromMethod
  1623. return fromMethod(*args, **kw)
  1624. def test_no_args(self):
  1625. class Foo(object):
  1626. def bar(self):
  1627. "DOCSTRING"
  1628. method = self._callFUT(Foo.bar)
  1629. self.assertEqual(method.getName(), 'bar')
  1630. self.assertEqual(method.getDoc(), 'DOCSTRING')
  1631. self.assertEqual(method.interface, None)
  1632. self.assertEqual(list(method.getTaggedValueTags()), [])
  1633. info = method.getSignatureInfo()
  1634. self.assertEqual(list(info['positional']), [])
  1635. self.assertEqual(list(info['required']), [])
  1636. self.assertEqual(info['optional'], {})
  1637. self.assertEqual(info['varargs'], None)
  1638. self.assertEqual(info['kwargs'], None)
  1639. def test_full_spectrum(self):
  1640. class Foo(object):
  1641. def bar(self, foo, bar='baz', *args, **kw):
  1642. "DOCSTRING"
  1643. method = self._callFUT(Foo.bar)
  1644. info = method.getSignatureInfo()
  1645. self.assertEqual(list(info['positional']), ['foo', 'bar'])
  1646. self.assertEqual(list(info['required']), ['foo'])
  1647. self.assertEqual(info['optional'], {'bar': 'baz'})
  1648. self.assertEqual(info['varargs'], 'args')
  1649. self.assertEqual(info['kwargs'], 'kw')
  1650. def test_w_non_method(self):
  1651. def foo():
  1652. "DOCSTRING"
  1653. method = self._callFUT(foo)
  1654. self.assertEqual(method.getName(), 'foo')
  1655. self.assertEqual(method.getDoc(), 'DOCSTRING')
  1656. self.assertEqual(method.interface, None)
  1657. self.assertEqual(list(method.getTaggedValueTags()), [])
  1658. info = method.getSignatureInfo()
  1659. self.assertEqual(list(info['positional']), [])
  1660. self.assertEqual(list(info['required']), [])
  1661. self.assertEqual(info['optional'], {})
  1662. self.assertEqual(info['varargs'], None)
  1663. self.assertEqual(info['kwargs'], None)
  1664. class DummyDependent(object):
  1665. def __init__(self):
  1666. self._changed = []
  1667. def changed(self, originally_changed):
  1668. self._changed.append(originally_changed)
  1669. def _barGreaterThanFoo(obj):
  1670. from zope.interface.exceptions import Invalid
  1671. foo = getattr(obj, 'foo', None)
  1672. bar = getattr(obj, 'bar', None)
  1673. if foo is not None and isinstance(foo, type(bar)):
  1674. # type checking should be handled elsewhere (like, say,
  1675. # schema); these invariants should be intra-interface
  1676. # constraints. This is a hacky way to do it, maybe, but you
  1677. # get the idea
  1678. if not bar > foo:
  1679. raise Invalid('Please, Boo MUST be greater than Foo!')
  1680. def _ifFooThenBar(obj):
  1681. from zope.interface.exceptions import Invalid
  1682. if getattr(obj, 'foo', None) and not getattr(obj, 'bar', None):
  1683. raise Invalid('If Foo, then Bar!')
  1684. class _Monkey(object):
  1685. # context-manager for replacing module names in the scope of a test.
  1686. def __init__(self, module, **kw):
  1687. self.module = module
  1688. self.to_restore = dict([(key, getattr(module, key)) for key in kw])
  1689. for key, value in kw.items():
  1690. setattr(module, key, value)
  1691. def __enter__(self):
  1692. return self
  1693. def __exit__(self, exc_type, exc_val, exc_tb):
  1694. for key, value in self.to_restore.items():
  1695. setattr(self.module, key, value)