Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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"""Interface object implementation 

15""" 

16# pylint:disable=protected-access 

17import sys 

18from types import MethodType 

19from types import FunctionType 

20import weakref 

21 

22from zope.interface._compat import _use_c_impl 

23from zope.interface._compat import PYTHON2 as PY2 

24from zope.interface.exceptions import Invalid 

25from zope.interface.ro import ro as calculate_ro 

26from zope.interface import ro 

27 

28__all__ = [ 

29 # Most of the public API from this module is directly exported 

30 # from zope.interface. The only remaining public API intended to 

31 # be imported from here should be those few things documented as 

32 # such. 

33 'InterfaceClass', 

34 'Specification', 

35 'adapter_hooks', 

36] 

37 

38CO_VARARGS = 4 

39CO_VARKEYWORDS = 8 

40# Put in the attrs dict of an interface by ``taggedValue`` and ``invariants`` 

41TAGGED_DATA = '__interface_tagged_values__' 

42# Put in the attrs dict of an interface by ``interfacemethod`` 

43INTERFACE_METHODS = '__interface_methods__' 

44 

45_decorator_non_return = object() 

46_marker = object() 

47 

48 

49 

50def invariant(call): 

51 f_locals = sys._getframe(1).f_locals 

52 tags = f_locals.setdefault(TAGGED_DATA, {}) 

53 invariants = tags.setdefault('invariants', []) 

54 invariants.append(call) 

55 return _decorator_non_return 

56 

57 

58def taggedValue(key, value): 

59 """Attaches a tagged value to an interface at definition time.""" 

60 f_locals = sys._getframe(1).f_locals 

61 tagged_values = f_locals.setdefault(TAGGED_DATA, {}) 

62 tagged_values[key] = value 

63 return _decorator_non_return 

64 

65 

66class Element(object): 

67 """ 

68 Default implementation of `zope.interface.interfaces.IElement`. 

69 """ 

70 

71 # We can't say this yet because we don't have enough 

72 # infrastructure in place. 

73 # 

74 #implements(IElement) 

75 

76 def __init__(self, __name__, __doc__=''): # pylint:disable=redefined-builtin 

77 if not __doc__ and __name__.find(' ') >= 0: 

78 __doc__ = __name__ 

79 __name__ = None 

80 

81 self.__name__ = __name__ 

82 self.__doc__ = __doc__ 

83 # Tagged values are rare, especially on methods or attributes. 

84 # Deferring the allocation can save substantial memory. 

85 self.__tagged_values = None 

86 

87 def getName(self): 

88 """ Returns the name of the object. """ 

89 return self.__name__ 

90 

91 def getDoc(self): 

92 """ Returns the documentation for the object. """ 

93 return self.__doc__ 

94 

95 ### 

96 # Tagged values. 

97 # 

98 # Direct tagged values are set only in this instance. Others 

99 # may be inherited (for those subclasses that have that concept). 

100 ### 

101 

102 def getTaggedValue(self, tag): 

103 """ Returns the value associated with 'tag'. """ 

104 if not self.__tagged_values: 

105 raise KeyError(tag) 

106 return self.__tagged_values[tag] 

107 

108 def queryTaggedValue(self, tag, default=None): 

109 """ Returns the value associated with 'tag'. """ 

110 return self.__tagged_values.get(tag, default) if self.__tagged_values else default 

111 

112 def getTaggedValueTags(self): 

113 """ Returns a collection of all tags. """ 

114 return self.__tagged_values.keys() if self.__tagged_values else () 

115 

116 def setTaggedValue(self, tag, value): 

117 """ Associates 'value' with 'key'. """ 

118 if self.__tagged_values is None: 

119 self.__tagged_values = {} 

120 self.__tagged_values[tag] = value 

121 

122 queryDirectTaggedValue = queryTaggedValue 

123 getDirectTaggedValue = getTaggedValue 

124 getDirectTaggedValueTags = getTaggedValueTags 

125 

126 

127SpecificationBasePy = object # filled by _use_c_impl. 

128 

129 

130@_use_c_impl 

131class SpecificationBase(object): 

132 # This object is the base of the inheritance hierarchy for ClassProvides: 

133 # 

134 # ClassProvides < ClassProvidesBase, Declaration 

135 # Declaration < Specification < SpecificationBase 

136 # ClassProvidesBase < SpecificationBase 

137 # 

138 # In order to have compatible instance layouts, we need to declare 

139 # the storage used by Specification and Declaration here (and 

140 # those classes must have ``__slots__ = ()``); fortunately this is 

141 # not a waste of space because those are the only two inheritance 

142 # trees. These all translate into tp_members in C. 

143 __slots__ = ( 

144 # Things used here. 

145 '_implied', 

146 # Things used in Specification. 

147 '_dependents', 

148 '_bases', 

149 '_v_attrs', 

150 '__iro__', 

151 '__sro__', 

152 '__weakref__', 

153 ) 

154 

155 def providedBy(self, ob): 

156 """Is the interface implemented by an object 

157 """ 

158 spec = providedBy(ob) 

159 return self in spec._implied 

160 

161 def implementedBy(self, cls): 

162 """Test whether the specification is implemented by a class or factory. 

163 

164 Raise TypeError if argument is neither a class nor a callable. 

165 """ 

166 spec = implementedBy(cls) 

167 return self in spec._implied 

168 

169 def isOrExtends(self, interface): 

170 """Is the interface the same as or extend the given interface 

171 """ 

172 return interface in self._implied # pylint:disable=no-member 

173 

174 __call__ = isOrExtends 

175 

176 

177class NameAndModuleComparisonMixin(object): 

178 # Internal use. Implement the basic sorting operators (but not (in)equality 

179 # or hashing). Subclasses must provide ``__name__`` and ``__module__`` 

180 # attributes. Subclasses will be mutually comparable; but because equality 

181 # and hashing semantics are missing from this class, take care in how 

182 # you define those two attributes: If you stick with the default equality 

183 # and hashing (identity based) you should make sure that all possible ``__name__`` 

184 # and ``__module__`` pairs are unique ACROSS ALL SUBCLASSES. (Actually, pretty 

185 # much the same thing goes if you define equality and hashing to be based on 

186 # those two attributes: they must still be consistent ACROSS ALL SUBCLASSES.) 

187 

188 # pylint:disable=assigning-non-slot 

189 __slots__ = () 

190 

191 def _compare(self, other): 

192 """ 

193 Compare *self* to *other* based on ``__name__`` and ``__module__``. 

194 

195 Return 0 if they are equal, return 1 if *self* is 

196 greater than *other*, and return -1 if *self* is less than 

197 *other*. 

198 

199 If *other* does not have ``__name__`` or ``__module__``, then 

200 return ``NotImplemented``. 

201 

202 .. caution:: 

203 This allows comparison to things well outside the type hierarchy, 

204 perhaps not symmetrically. 

205 

206 For example, ``class Foo(object)`` and ``class Foo(Interface)`` 

207 in the same file would compare equal, depending on the order of 

208 operands. Writing code like this by hand would be unusual, but it could 

209 happen with dynamic creation of types and interfaces. 

210 

211 None is treated as a pseudo interface that implies the loosest 

212 contact possible, no contract. For that reason, all interfaces 

213 sort before None. 

214 """ 

215 if other is self: 

216 return 0 

217 

218 if other is None: 

219 return -1 

220 

221 n1 = (self.__name__, self.__module__) 

222 try: 

223 n2 = (other.__name__, other.__module__) 

224 except AttributeError: 

225 return NotImplemented 

226 

227 # This spelling works under Python3, which doesn't have cmp(). 

228 return (n1 > n2) - (n1 < n2) 

229 

230 def __lt__(self, other): 

231 c = self._compare(other) 

232 if c is NotImplemented: 

233 return c 

234 return c < 0 

235 

236 def __le__(self, other): 

237 c = self._compare(other) 

238 if c is NotImplemented: 

239 return c 

240 return c <= 0 

241 

242 def __gt__(self, other): 

243 c = self._compare(other) 

244 if c is NotImplemented: 

245 return c 

246 return c > 0 

247 

248 def __ge__(self, other): 

249 c = self._compare(other) 

250 if c is NotImplemented: 

251 return c 

252 return c >= 0 

253 

254 

255@_use_c_impl 

256class InterfaceBase(NameAndModuleComparisonMixin, SpecificationBasePy): 

257 """Base class that wants to be replaced with a C base :) 

258 """ 

259 

260 __slots__ = ( 

261 '__name__', 

262 '__ibmodule__', 

263 '_v_cached_hash', 

264 ) 

265 

266 def __init__(self, name=None, module=None): 

267 self.__name__ = name 

268 self.__ibmodule__ = module 

269 

270 def _call_conform(self, conform): 

271 raise NotImplementedError 

272 

273 @property 

274 def __module_property__(self): 

275 # This is for _InterfaceMetaClass 

276 return self.__ibmodule__ 

277 

278 def __call__(self, obj, alternate=_marker): 

279 """Adapt an object to the interface 

280 """ 

281 try: 

282 conform = obj.__conform__ 

283 except AttributeError: 

284 conform = None 

285 

286 if conform is not None: 

287 adapter = self._call_conform(conform) 

288 if adapter is not None: 

289 return adapter 

290 

291 adapter = self.__adapt__(obj) 

292 

293 if adapter is not None: 

294 return adapter 

295 if alternate is not _marker: 

296 return alternate 

297 raise TypeError("Could not adapt", obj, self) 

298 

299 def __adapt__(self, obj): 

300 """Adapt an object to the receiver 

301 """ 

302 if self.providedBy(obj): 

303 return obj 

304 

305 for hook in adapter_hooks: 

306 adapter = hook(self, obj) 

307 if adapter is not None: 

308 return adapter 

309 

310 return None 

311 

312 def __hash__(self): 

313 # pylint:disable=assigning-non-slot,attribute-defined-outside-init 

314 try: 

315 return self._v_cached_hash 

316 except AttributeError: 

317 self._v_cached_hash = hash((self.__name__, self.__module__)) 

318 return self._v_cached_hash 

319 

320 def __eq__(self, other): 

321 c = self._compare(other) 

322 if c is NotImplemented: 

323 return c 

324 return c == 0 

325 

326 def __ne__(self, other): 

327 if other is self: 

328 return False 

329 

330 c = self._compare(other) 

331 if c is NotImplemented: 

332 return c 

333 return c != 0 

334 

335adapter_hooks = _use_c_impl([], 'adapter_hooks') 

336 

337 

338class Specification(SpecificationBase): 

339 """Specifications 

340 

341 An interface specification is used to track interface declarations 

342 and component registrations. 

343 

344 This class is a base class for both interfaces themselves and for 

345 interface specifications (declarations). 

346 

347 Specifications are mutable. If you reassign their bases, their 

348 relations with other specifications are adjusted accordingly. 

349 """ 

350 __slots__ = () 

351 

352 # The root of all Specifications. This will be assigned `Interface`, 

353 # once it is defined. 

354 _ROOT = None 

355 

356 # Copy some base class methods for speed 

357 isOrExtends = SpecificationBase.isOrExtends 

358 providedBy = SpecificationBase.providedBy 

359 

360 def __init__(self, bases=()): 

361 # There are many leaf interfaces with no dependents, 

362 # and a few with very many. It's a heavily left-skewed 

363 # distribution. In a survey of Plone and Zope related packages 

364 # that loaded 2245 InterfaceClass objects and 2235 ClassProvides 

365 # instances, there were a total of 7000 Specification objects created. 

366 # 4700 had 0 dependents, 1400 had 1, 382 had 2 and so on. Only one 

367 # for <type> had 1664. So there's savings to be had deferring 

368 # the creation of dependents. 

369 self._dependents = None # type: weakref.WeakKeyDictionary 

370 self._bases = () 

371 self._implied = {} 

372 self._v_attrs = None 

373 self.__iro__ = () 

374 self.__sro__ = () 

375 

376 self.__bases__ = tuple(bases) 

377 

378 @property 

379 def dependents(self): 

380 if self._dependents is None: 

381 self._dependents = weakref.WeakKeyDictionary() 

382 return self._dependents 

383 

384 def subscribe(self, dependent): 

385 self._dependents[dependent] = self.dependents.get(dependent, 0) + 1 

386 

387 def unsubscribe(self, dependent): 

388 try: 

389 n = self._dependents[dependent] 

390 except TypeError: 

391 raise KeyError(dependent) 

392 n -= 1 

393 if not n: 

394 del self.dependents[dependent] 

395 else: 

396 assert n > 0 

397 self.dependents[dependent] = n 

398 

399 def __setBases(self, bases): 

400 # Remove ourselves as a dependent of our old bases 

401 for b in self.__bases__: 

402 b.unsubscribe(self) 

403 

404 # Register ourselves as a dependent of our new bases 

405 self._bases = bases 

406 for b in bases: 

407 b.subscribe(self) 

408 

409 self.changed(self) 

410 

411 __bases__ = property( 

412 lambda self: self._bases, 

413 __setBases, 

414 ) 

415 

416 # This method exists for tests to override the way we call 

417 # ro.calculate_ro(), usually by adding extra kwargs. We don't 

418 # want to have a mutable dictionary as a class member that we pass 

419 # ourself because mutability is bad, and passing **kw is slower than 

420 # calling the bound function. 

421 _do_calculate_ro = calculate_ro 

422 

423 def _calculate_sro(self): 

424 """ 

425 Calculate and return the resolution order for this object, using its ``__bases__``. 

426 

427 Ensures that ``Interface`` is always the last (lowest priority) element. 

428 """ 

429 # We'd like to make Interface the lowest priority as a 

430 # property of the resolution order algorithm. That almost 

431 # works out naturally, but it fails when class inheritance has 

432 # some bases that DO implement an interface, and some that DO 

433 # NOT. In such a mixed scenario, you wind up with a set of 

434 # bases to consider that look like this: [[..., Interface], 

435 # [..., object], ...]. Depending on the order of inheritance, 

436 # Interface can wind up before or after object, and that can 

437 # happen at any point in the tree, meaning Interface can wind 

438 # up somewhere in the middle of the order. Since Interface is 

439 # treated as something that everything winds up implementing 

440 # anyway (a catch-all for things like adapters), having it high up 

441 # the order is bad. It's also bad to have it at the end, just before 

442 # some concrete class: concrete classes should be HIGHER priority than 

443 # interfaces (because there's only one class, but many implementations). 

444 # 

445 # One technically nice way to fix this would be to have 

446 # ``implementedBy(object).__bases__ = (Interface,)`` 

447 # 

448 # But: (1) That fails for old-style classes and (2) that causes 

449 # everything to appear to *explicitly* implement Interface, when up 

450 # to this point it's been an implicit virtual sort of relationship. 

451 # 

452 # So we force the issue by mutating the resolution order. 

453 

454 # Note that we let C3 use pre-computed __sro__ for our bases. 

455 # This requires that by the time this method is invoked, our bases 

456 # have settled their SROs. Thus, ``changed()`` must first 

457 # update itself before telling its descendents of changes. 

458 sro = self._do_calculate_ro(base_mros={ 

459 b: b.__sro__ 

460 for b in self.__bases__ 

461 }) 

462 root = self._ROOT 

463 if root is not None and sro and sro[-1] is not root: 

464 # In one dataset of 1823 Interface objects, 1117 ClassProvides objects, 

465 # sro[-1] was root 4496 times, and only not root 118 times. So it's 

466 # probably worth checking. 

467 

468 # Once we don't have to deal with old-style classes, 

469 # we can add a check and only do this if base_count > 1, 

470 # if we tweak the bootstrapping for ``<implementedBy object>`` 

471 sro = [ 

472 x 

473 for x in sro 

474 if x is not root 

475 ] 

476 sro.append(root) 

477 

478 return sro 

479 

480 def changed(self, originally_changed): 

481 """ 

482 We, or something we depend on, have changed. 

483 

484 By the time this is called, the things we depend on, 

485 such as our bases, should themselves be stable. 

486 """ 

487 self._v_attrs = None 

488 

489 implied = self._implied 

490 implied.clear() 

491 

492 ancestors = self._calculate_sro() 

493 self.__sro__ = tuple(ancestors) 

494 self.__iro__ = tuple([ancestor for ancestor in ancestors 

495 if isinstance(ancestor, InterfaceClass) 

496 ]) 

497 

498 for ancestor in ancestors: 

499 # We directly imply our ancestors: 

500 implied[ancestor] = () 

501 

502 # Now, advise our dependents of change 

503 # (being careful not to create the WeakKeyDictionary if not needed): 

504 for dependent in tuple(self._dependents.keys() if self._dependents else ()): 

505 dependent.changed(originally_changed) 

506 

507 # Just in case something called get() at some point 

508 # during that process and we have a cycle of some sort 

509 # make sure we didn't cache incomplete results. 

510 self._v_attrs = None 

511 

512 def interfaces(self): 

513 """Return an iterator for the interfaces in the specification. 

514 """ 

515 seen = {} 

516 for base in self.__bases__: 

517 for interface in base.interfaces(): 

518 if interface not in seen: 

519 seen[interface] = 1 

520 yield interface 

521 

522 def extends(self, interface, strict=True): 

523 """Does the specification extend the given interface? 

524 

525 Test whether an interface in the specification extends the 

526 given interface 

527 """ 

528 return ((interface in self._implied) 

529 and 

530 ((not strict) or (self != interface)) 

531 ) 

532 

533 def weakref(self, callback=None): 

534 return weakref.ref(self, callback) 

535 

536 def get(self, name, default=None): 

537 """Query for an attribute description 

538 """ 

539 attrs = self._v_attrs 

540 if attrs is None: 

541 attrs = self._v_attrs = {} 

542 attr = attrs.get(name) 

543 if attr is None: 

544 for iface in self.__iro__: 

545 attr = iface.direct(name) 

546 if attr is not None: 

547 attrs[name] = attr 

548 break 

549 

550 return default if attr is None else attr 

551 

552 

553class _InterfaceMetaClass(type): 

554 # Handling ``__module__`` on ``InterfaceClass`` is tricky. We need 

555 # to be able to read it on a type and get the expected string. We 

556 # also need to be able to set it on an instance and get the value 

557 # we set. So far so good. But what gets tricky is that we'd like 

558 # to store the value in the C structure (``InterfaceBase.__ibmodule__``) for 

559 # direct access during equality, sorting, and hashing. "No 

560 # problem, you think, I'll just use a property" (well, the C 

561 # equivalents, ``PyMemberDef`` or ``PyGetSetDef``). 

562 # 

563 # Except there is a problem. When a subclass is created, the 

564 # metaclass (``type``) always automatically puts the expected 

565 # string in the class's dictionary under ``__module__``, thus 

566 # overriding the property inherited from the superclass. Writing 

567 # ``Subclass.__module__`` still works, but 

568 # ``Subclass().__module__`` fails. 

569 # 

570 # There are multiple ways to work around this: 

571 # 

572 # (1) Define ``InterfaceBase.__getattribute__`` to watch for 

573 # ``__module__`` and return the C storage. 

574 # 

575 # This works, but slows down *all* attribute access (except, 

576 # ironically, to ``__module__``) by about 25% (40ns becomes 50ns) 

577 # (when implemented in C). Since that includes methods like 

578 # ``providedBy``, that's probably not acceptable. 

579 # 

580 # All the other methods involve modifying subclasses. This can be 

581 # done either on the fly in some cases, as instances are 

582 # constructed, or by using a metaclass. These next few can be done on the fly. 

583 # 

584 # (2) Make ``__module__`` a descriptor in each subclass dictionary. 

585 # It can't be a straight up ``@property`` descriptor, though, because accessing 

586 # it on the class returns a ``property`` object, not the desired string. 

587 # 

588 # (3) Implement a data descriptor (``__get__`` and ``__set__``) 

589 # that is both a subclass of string, and also does the redirect of 

590 # ``__module__`` to ``__ibmodule__`` and does the correct thing 

591 # with the ``instance`` argument to ``__get__`` is None (returns 

592 # the class's value.) (Why must it be a subclass of string? Because 

593 # when it' s in the class's dict, it's defined on an *instance* of the 

594 # metaclass; descriptors in an instance's dict aren't honored --- their 

595 # ``__get__`` is never invoked --- so it must also *be* the value we want 

596 # returned.) 

597 # 

598 # This works, preserves the ability to read and write 

599 # ``__module__``, and eliminates any penalty accessing other 

600 # attributes. But it slows down accessing ``__module__`` of 

601 # instances by 200% (40ns to 124ns), requires editing class dicts on the fly 

602 # (in InterfaceClass.__init__), thus slightly slowing down all interface creation, 

603 # and is ugly. 

604 # 

605 # (4) As in the last step, but make it a non-data descriptor (no ``__set__``). 

606 # 

607 # If you then *also* store a copy of ``__ibmodule__`` in 

608 # ``__module__`` in the instance's dict, reading works for both 

609 # class and instance and is full speed for instances. But the cost 

610 # is storage space, and you can't write to it anymore, not without 

611 # things getting out of sync. 

612 # 

613 # (Actually, ``__module__`` was never meant to be writable. Doing 

614 # so would break BTrees and normal dictionaries, as well as the 

615 # repr, maybe more.) 

616 # 

617 # That leaves us with a metaclass. (Recall that a class is an 

618 # instance of its metaclass, so properties/descriptors defined in 

619 # the metaclass are used when accessing attributes on the 

620 # instance/class. We'll use that to define ``__module__``.) Here 

621 # we can have our cake and eat it too: no extra storage, and 

622 # C-speed access to the underlying storage. The only substantial 

623 # cost is that metaclasses tend to make people's heads hurt. (But 

624 # still less than the descriptor-is-string, hopefully.) 

625 

626 __slots__ = () 

627 

628 def __new__(cls, name, bases, attrs): 

629 # Figure out what module defined the interface. 

630 # This is copied from ``InterfaceClass.__init__``; 

631 # reviewers aren't sure how AttributeError or KeyError 

632 # could be raised. 

633 __module__ = sys._getframe(1).f_globals['__name__'] 

634 # Get the C optimized __module__ accessor and give it 

635 # to the new class. 

636 moduledescr = InterfaceBase.__dict__['__module__'] 

637 if isinstance(moduledescr, str): 

638 # We're working with the Python implementation, 

639 # not the C version 

640 moduledescr = InterfaceBase.__dict__['__module_property__'] 

641 attrs['__module__'] = moduledescr 

642 kind = type.__new__(cls, name, bases, attrs) 

643 kind.__module = __module__ 

644 return kind 

645 

646 @property 

647 def __module__(cls): 

648 return cls.__module 

649 

650 def __repr__(cls): 

651 return "<class '%s.%s'>" % ( 

652 cls.__module, 

653 cls.__name__, 

654 ) 

655 

656 

657_InterfaceClassBase = _InterfaceMetaClass( 

658 'InterfaceClass', 

659 # From least specific to most specific. 

660 (InterfaceBase, Specification, Element), 

661 {'__slots__': ()} 

662) 

663 

664 

665def interfacemethod(func): 

666 """ 

667 Convert a method specification to an actual method of the interface. 

668 

669 This is a decorator that functions like `staticmethod` et al. 

670 

671 The primary use of this decorator is to allow interface definitions to 

672 define the ``__adapt__`` method, but other interface methods can be 

673 overridden this way too. 

674 

675 .. seealso:: `zope.interface.interfaces.IInterfaceDeclaration.interfacemethod` 

676 """ 

677 f_locals = sys._getframe(1).f_locals 

678 methods = f_locals.setdefault(INTERFACE_METHODS, {}) 

679 methods[func.__name__] = func 

680 return _decorator_non_return 

681 

682 

683class InterfaceClass(_InterfaceClassBase): 

684 """ 

685 Prototype (scarecrow) Interfaces Implementation. 

686 

687 Note that it is not possible to change the ``__name__`` or ``__module__`` 

688 after an instance of this object has been constructed. 

689 """ 

690 

691 # We can't say this yet because we don't have enough 

692 # infrastructure in place. 

693 # 

694 #implements(IInterface) 

695 

696 def __new__(cls, name=None, bases=(), attrs=None, __doc__=None, # pylint:disable=redefined-builtin 

697 __module__=None): 

698 assert isinstance(bases, tuple) 

699 attrs = attrs or {} 

700 needs_custom_class = attrs.pop(INTERFACE_METHODS, None) 

701 if needs_custom_class: 

702 needs_custom_class.update( 

703 {'__classcell__': attrs.pop('__classcell__')} 

704 if '__classcell__' in attrs 

705 else {} 

706 ) 

707 if '__adapt__' in needs_custom_class: 

708 # We need to tell the C code to call this. 

709 needs_custom_class['_CALL_CUSTOM_ADAPT'] = 1 

710 

711 if issubclass(cls, _InterfaceClassWithCustomMethods): 

712 cls_bases = (cls,) 

713 elif cls is InterfaceClass: 

714 cls_bases = (_InterfaceClassWithCustomMethods,) 

715 else: 

716 cls_bases = (cls, _InterfaceClassWithCustomMethods) 

717 

718 cls = type(cls)( # pylint:disable=self-cls-assignment 

719 name + "<WithCustomMethods>", 

720 cls_bases, 

721 needs_custom_class 

722 ) 

723 elif PY2 and bases and len(bases) > 1: 

724 bases_with_custom_methods = tuple( 

725 type(b) 

726 for b in bases 

727 if issubclass(type(b), _InterfaceClassWithCustomMethods) 

728 ) 

729 

730 # If we have a subclass of InterfaceClass in *bases*, 

731 # Python 3 is smart enough to pass that as *cls*, but Python 

732 # 2 just passes whatever the first base in *bases* is. This means that if 

733 # we have multiple inheritance, and one of our bases has already defined 

734 # a custom method like ``__adapt__``, we do the right thing automatically 

735 # and extend it on Python 3, but not necessarily on Python 2. To fix this, we need 

736 # to run the MRO algorithm and get the most derived base manually. 

737 # Note that this only works for consistent resolution orders 

738 if bases_with_custom_methods: 

739 cls = type( # pylint:disable=self-cls-assignment 

740 name + "<WithCustomMethods>", 

741 bases_with_custom_methods, 

742 {} 

743 ).__mro__[1] # Not the class we created, the most derived. 

744 

745 return _InterfaceClassBase.__new__(cls) 

746 

747 def __init__(self, name, bases=(), attrs=None, __doc__=None, # pylint:disable=redefined-builtin 

748 __module__=None): 

749 # We don't call our metaclass parent directly 

750 # pylint:disable=non-parent-init-called 

751 # pylint:disable=super-init-not-called 

752 if not all(isinstance(base, InterfaceClass) for base in bases): 

753 raise TypeError('Expected base interfaces') 

754 

755 if attrs is None: 

756 attrs = {} 

757 

758 if __module__ is None: 

759 __module__ = attrs.get('__module__') 

760 if isinstance(__module__, str): 

761 del attrs['__module__'] 

762 else: 

763 try: 

764 # Figure out what module defined the interface. 

765 # This is how cPython figures out the module of 

766 # a class, but of course it does it in C. :-/ 

767 __module__ = sys._getframe(1).f_globals['__name__'] 

768 except (AttributeError, KeyError): # pragma: no cover 

769 pass 

770 

771 InterfaceBase.__init__(self, name, __module__) 

772 # These asserts assisted debugging the metaclass 

773 # assert '__module__' not in self.__dict__ 

774 # assert self.__ibmodule__ is self.__module__ is __module__ 

775 

776 d = attrs.get('__doc__') 

777 if d is not None: 

778 if not isinstance(d, Attribute): 

779 if __doc__ is None: 

780 __doc__ = d 

781 del attrs['__doc__'] 

782 

783 if __doc__ is None: 

784 __doc__ = '' 

785 

786 Element.__init__(self, name, __doc__) 

787 

788 tagged_data = attrs.pop(TAGGED_DATA, None) 

789 if tagged_data is not None: 

790 for key, val in tagged_data.items(): 

791 self.setTaggedValue(key, val) 

792 

793 Specification.__init__(self, bases) 

794 self.__attrs = self.__compute_attrs(attrs) 

795 

796 self.__identifier__ = "%s.%s" % (__module__, name) 

797 

798 def __compute_attrs(self, attrs): 

799 # Make sure that all recorded attributes (and methods) are of type 

800 # `Attribute` and `Method` 

801 def update_value(aname, aval): 

802 if isinstance(aval, Attribute): 

803 aval.interface = self 

804 if not aval.__name__: 

805 aval.__name__ = aname 

806 elif isinstance(aval, FunctionType): 

807 aval = fromFunction(aval, self, name=aname) 

808 else: 

809 raise InvalidInterface("Concrete attribute, " + aname) 

810 return aval 

811 

812 return { 

813 aname: update_value(aname, aval) 

814 for aname, aval in attrs.items() 

815 if aname not in ( 

816 # __locals__: Python 3 sometimes adds this. 

817 '__locals__', 

818 # __qualname__: PEP 3155 (Python 3.3+) 

819 '__qualname__', 

820 # __annotations__: PEP 3107 (Python 3.0+) 

821 '__annotations__', 

822 ) 

823 and aval is not _decorator_non_return 

824 } 

825 

826 def interfaces(self): 

827 """Return an iterator for the interfaces in the specification. 

828 """ 

829 yield self 

830 

831 def getBases(self): 

832 return self.__bases__ 

833 

834 def isEqualOrExtendedBy(self, other): 

835 """Same interface or extends?""" 

836 return self == other or other.extends(self) 

837 

838 def names(self, all=False): # pylint:disable=redefined-builtin 

839 """Return the attribute names defined by the interface.""" 

840 if not all: 

841 return self.__attrs.keys() 

842 

843 r = self.__attrs.copy() 

844 

845 for base in self.__bases__: 

846 r.update(dict.fromkeys(base.names(all))) 

847 

848 return r.keys() 

849 

850 def __iter__(self): 

851 return iter(self.names(all=True)) 

852 

853 def namesAndDescriptions(self, all=False): # pylint:disable=redefined-builtin 

854 """Return attribute names and descriptions defined by interface.""" 

855 if not all: 

856 return self.__attrs.items() 

857 

858 r = {} 

859 for base in self.__bases__[::-1]: 

860 r.update(dict(base.namesAndDescriptions(all))) 

861 

862 r.update(self.__attrs) 

863 

864 return r.items() 

865 

866 def getDescriptionFor(self, name): 

867 """Return the attribute description for the given name.""" 

868 r = self.get(name) 

869 if r is not None: 

870 return r 

871 

872 raise KeyError(name) 

873 

874 __getitem__ = getDescriptionFor 

875 

876 def __contains__(self, name): 

877 return self.get(name) is not None 

878 

879 def direct(self, name): 

880 return self.__attrs.get(name) 

881 

882 def queryDescriptionFor(self, name, default=None): 

883 return self.get(name, default) 

884 

885 def validateInvariants(self, obj, errors=None): 

886 """validate object to defined invariants.""" 

887 

888 for iface in self.__iro__: 

889 for invariant in iface.queryDirectTaggedValue('invariants', ()): 

890 try: 

891 invariant(obj) 

892 except Invalid as error: 

893 if errors is not None: 

894 errors.append(error) 

895 else: 

896 raise 

897 

898 if errors: 

899 raise Invalid(errors) 

900 

901 def queryTaggedValue(self, tag, default=None): 

902 """ 

903 Queries for the value associated with *tag*, returning it from the nearest 

904 interface in the ``__iro__``. 

905 

906 If not found, returns *default*. 

907 """ 

908 for iface in self.__iro__: 

909 value = iface.queryDirectTaggedValue(tag, _marker) 

910 if value is not _marker: 

911 return value 

912 return default 

913 

914 def getTaggedValue(self, tag): 

915 """ Returns the value associated with 'tag'. """ 

916 value = self.queryTaggedValue(tag, default=_marker) 

917 if value is _marker: 

918 raise KeyError(tag) 

919 return value 

920 

921 def getTaggedValueTags(self): 

922 """ Returns a list of all tags. """ 

923 keys = set() 

924 for base in self.__iro__: 

925 keys.update(base.getDirectTaggedValueTags()) 

926 return keys 

927 

928 def __repr__(self): 

929 try: 

930 return self._v_repr 

931 except AttributeError: 

932 name = str(self) 

933 r = "<%s %s>" % (self.__class__.__name__, name) 

934 self._v_repr = r # pylint:disable=attribute-defined-outside-init 

935 return r 

936 

937 def __str__(self): 

938 name = self.__name__ 

939 m = self.__ibmodule__ 

940 if m: 

941 name = '%s.%s' % (m, name) 

942 return name 

943 

944 def _call_conform(self, conform): 

945 try: 

946 return conform(self) 

947 except TypeError: # pragma: no cover 

948 # We got a TypeError. It might be an error raised by 

949 # the __conform__ implementation, or *we* may have 

950 # made the TypeError by calling an unbound method 

951 # (object is a class). In the later case, we behave 

952 # as though there is no __conform__ method. We can 

953 # detect this case by checking whether there is more 

954 # than one traceback object in the traceback chain: 

955 if sys.exc_info()[2].tb_next is not None: 

956 # There is more than one entry in the chain, so 

957 # reraise the error: 

958 raise 

959 # This clever trick is from Phillip Eby 

960 

961 return None # pragma: no cover 

962 

963 def __reduce__(self): 

964 return self.__name__ 

965 

966Interface = InterfaceClass("Interface", __module__='zope.interface') 

967# Interface is the only member of its own SRO. 

968Interface._calculate_sro = lambda: (Interface,) 

969Interface.changed(Interface) 

970assert Interface.__sro__ == (Interface,) 

971Specification._ROOT = Interface 

972ro._ROOT = Interface 

973 

974class _InterfaceClassWithCustomMethods(InterfaceClass): 

975 """ 

976 Marker class for interfaces with custom methods that override InterfaceClass methods. 

977 """ 

978 

979 

980class Attribute(Element): 

981 """Attribute descriptions 

982 """ 

983 

984 # We can't say this yet because we don't have enough 

985 # infrastructure in place. 

986 # 

987 # implements(IAttribute) 

988 

989 interface = None 

990 

991 def _get_str_info(self): 

992 """Return extra data to put at the end of __str__.""" 

993 return "" 

994 

995 def __str__(self): 

996 of = '' 

997 if self.interface is not None: 

998 of = self.interface.__module__ + '.' + self.interface.__name__ + '.' 

999 # self.__name__ may be None during construction (e.g., debugging) 

1000 return of + (self.__name__ or '<unknown>') + self._get_str_info() 

1001 

1002 def __repr__(self): 

1003 return "<%s.%s object at 0x%x %s>" % ( 

1004 type(self).__module__, 

1005 type(self).__name__, 

1006 id(self), 

1007 self 

1008 ) 

1009 

1010 

1011class Method(Attribute): 

1012 """Method interfaces 

1013 

1014 The idea here is that you have objects that describe methods. 

1015 This provides an opportunity for rich meta-data. 

1016 """ 

1017 

1018 # We can't say this yet because we don't have enough 

1019 # infrastructure in place. 

1020 # 

1021 # implements(IMethod) 

1022 

1023 positional = required = () 

1024 _optional = varargs = kwargs = None 

1025 def _get_optional(self): 

1026 if self._optional is None: 

1027 return {} 

1028 return self._optional 

1029 def _set_optional(self, opt): 

1030 self._optional = opt 

1031 def _del_optional(self): 

1032 self._optional = None 

1033 optional = property(_get_optional, _set_optional, _del_optional) 

1034 

1035 def __call__(self, *args, **kw): 

1036 raise BrokenImplementation(self.interface, self.__name__) 

1037 

1038 def getSignatureInfo(self): 

1039 return {'positional': self.positional, 

1040 'required': self.required, 

1041 'optional': self.optional, 

1042 'varargs': self.varargs, 

1043 'kwargs': self.kwargs, 

1044 } 

1045 

1046 def getSignatureString(self): 

1047 sig = [] 

1048 for v in self.positional: 

1049 sig.append(v) 

1050 if v in self.optional.keys(): 

1051 sig[-1] += "=" + repr(self.optional[v]) 

1052 if self.varargs: 

1053 sig.append("*" + self.varargs) 

1054 if self.kwargs: 

1055 sig.append("**" + self.kwargs) 

1056 

1057 return "(%s)" % ", ".join(sig) 

1058 

1059 _get_str_info = getSignatureString 

1060 

1061 

1062def fromFunction(func, interface=None, imlevel=0, name=None): 

1063 name = name or func.__name__ 

1064 method = Method(name, func.__doc__) 

1065 defaults = getattr(func, '__defaults__', None) or () 

1066 code = func.__code__ 

1067 # Number of positional arguments 

1068 na = code.co_argcount - imlevel 

1069 names = code.co_varnames[imlevel:] 

1070 opt = {} 

1071 # Number of required arguments 

1072 defaults_count = len(defaults) 

1073 if not defaults_count: 

1074 # PyPy3 uses ``__defaults_count__`` for builtin methods 

1075 # like ``dict.pop``. Surprisingly, these don't have recorded 

1076 # ``__defaults__`` 

1077 defaults_count = getattr(func, '__defaults_count__', 0) 

1078 

1079 nr = na - defaults_count 

1080 if nr < 0: 

1081 defaults = defaults[-nr:] 

1082 nr = 0 

1083 

1084 # Determine the optional arguments. 

1085 opt.update(dict(zip(names[nr:], defaults))) 

1086 

1087 method.positional = names[:na] 

1088 method.required = names[:nr] 

1089 method.optional = opt 

1090 

1091 argno = na 

1092 

1093 # Determine the function's variable argument's name (i.e. *args) 

1094 if code.co_flags & CO_VARARGS: 

1095 method.varargs = names[argno] 

1096 argno = argno + 1 

1097 else: 

1098 method.varargs = None 

1099 

1100 # Determine the function's keyword argument's name (i.e. **kw) 

1101 if code.co_flags & CO_VARKEYWORDS: 

1102 method.kwargs = names[argno] 

1103 else: 

1104 method.kwargs = None 

1105 

1106 method.interface = interface 

1107 

1108 for key, value in func.__dict__.items(): 

1109 method.setTaggedValue(key, value) 

1110 

1111 return method 

1112 

1113 

1114def fromMethod(meth, interface=None, name=None): 

1115 if isinstance(meth, MethodType): 

1116 func = meth.__func__ 

1117 else: 

1118 func = meth 

1119 return fromFunction(func, interface, imlevel=1, name=name) 

1120 

1121 

1122# Now we can create the interesting interfaces and wire them up: 

1123def _wire(): 

1124 from zope.interface.declarations import classImplements 

1125 # From lest specific to most specific. 

1126 from zope.interface.interfaces import IElement 

1127 classImplements(Element, IElement) 

1128 

1129 from zope.interface.interfaces import IAttribute 

1130 classImplements(Attribute, IAttribute) 

1131 

1132 from zope.interface.interfaces import IMethod 

1133 classImplements(Method, IMethod) 

1134 

1135 from zope.interface.interfaces import ISpecification 

1136 classImplements(Specification, ISpecification) 

1137 

1138 from zope.interface.interfaces import IInterface 

1139 classImplements(InterfaceClass, IInterface) 

1140 

1141 

1142# We import this here to deal with module dependencies. 

1143# pylint:disable=wrong-import-position 

1144from zope.interface.declarations import implementedBy 

1145from zope.interface.declarations import providedBy 

1146from zope.interface.exceptions import InvalidInterface 

1147from zope.interface.exceptions import BrokenImplementation 

1148 

1149# This ensures that ``Interface`` winds up in the flattened() 

1150# list of the immutable declaration. It correctly overrides changed() 

1151# as a no-op, so we bypass that. 

1152from zope.interface.declarations import _empty 

1153Specification.changed(_empty, _empty)