Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
zope.interface / docs / _build / doctrees / human.doctree
Size: Mime:
€cdocutils.nodes
document
q)q}q(UtagnameqUdocumentqUreporterqNU
attributesq}q(Udupnamesq	]Ubackrefsq
]UsourceX</home/tseaver/projects/Zope/Z3/zope.interface/docs/human.rstqUidsq]Uclassesq
]Unamesq]uUparse_messagesq]qU
decorationqNU	citationsq]qU	rawsourceqUU	nametypesq}qXusing the adapter registryqNsUsettingsq(cdocutils.frontend
Values
qoq}q(Upep_referencesqNUoutput_encoding_error_handlerqUstrictqU
halt_levelqKU
source_urlq NU
dump_settingsq!NUdoctitle_xformq"‰Udump_pseudo_xmlq#NU	tab_widthq$KU	id_prefixq%UUtitleq&NUembed_stylesheetq'‰U
docinfo_xformq(KUfootnote_backlinksq)KUerror_encodingq*UUTF-8q+Uauto_id_prefixq,Uidq-U
language_codeq.Uenq/U	datestampq0NUdump_transformsq1NUoutput_encodingq2Uutf-8q3Uexit_status_levelq4KUstrict_visitorq5NU_disable_configq6NUfile_insertion_enabledq7ˆU	tracebackq8ˆUrecord_dependenciesq9NUstrip_commentsq:NUdebugq;NU	generatorq<NUgettext_compactq=ˆUenvq>NU
strip_classesq?NUpep_file_url_templateq@Upep-%04dqAUinput_encoding_error_handlerqBhUexpose_internalsqCNUrfc_referencesqDNU
toc_backlinksqEUentryqFUtrim_footnote_reference_spaceqG‰U_sourceqHhUwarning_streamqINUinput_encodingqJU	utf-8-sigqKUsectsubtitle_xformqL‰Usource_linkqMNUconfigqNNU
sectnum_xformqOKUerror_encoding_error_handlerqPUbackslashreplaceqQU
_config_filesqR]Udump_internalsqSNUsmart_quotesqT‰Ucloak_email_addressesqUˆUraw_enabledqVKUstrip_elements_with_classesqWNUpep_base_urlqXU https://www.python.org/dev/peps/qYUreport_levelqZKUrfc_base_urlq[Uhttps://tools.ietf.org/html/q\U_destinationq]NUsyntax_highlightq^Ulongq_ubUautofootnote_refsq`]qaU
footnote_refsqb}qcUid_startqdKU
citation_refsqe}qfUsymbol_footnote_refsqg]qhUtransform_messagesqi]qjU	footnotesqk]qlUnameidsqm}qnhUusing-the-adapter-registryqosUrefnamesqp}qqUtransformerqrNUidsqs}qthocdocutils.nodes
section
qu)qv}qw(hhhUsectionqxh}qy(h
]h	]h]qzhah]q{hoah
]uUlineq|KUsourceq}hhUUparentq~hUchildrenq]q€(cdocutils.nodes
title
q)q‚}qƒ(hhhh&h}q„(h
]h	]h]h]h
]uh|Kh}hhXUsing the Adapter Registryq…h~hvh]q†cdocutils.nodes
Text
q‡XUsing the Adapter Registryqˆ…q‰}qŠ(hh…h~h‚ubaubcdocutils.nodes
paragraph
q‹)qŒ}q(hhhU	paragraphqŽh}q(h
]h	]h]h]h
]uh|Kh}hhXÐThis is a small demonstration of the ``zope.interface`` package including its
adapter registry. It is intended to provide a concrete but narrow example on
how to use interfaces and adapters outside of Zope 3.h~hvh]q(h‡X%This is a small demonstration of the q‘…q’}q“(hX%This is a small demonstration of the h~hŒubcdocutils.nodes
literal
q”)q•}q–(hX``zope.interface``hUliteralq—h}q˜(h
]h	]h]h]h
]uh~hŒh]q™h‡Xzope.interfaceqš…q›}qœ(hUh~h•ubaubh‡X™ package including its
adapter registry. It is intended to provide a concrete but narrow example on
how to use interfaces and adapters outside of Zope 3.q…qž}qŸ(hX™ package including its
adapter registry. It is intended to provide a concrete but narrow example on
how to use interfaces and adapters outside of Zope 3.h~hŒubeubh‹)q }q¡(hhhhŽh}q¢(h
]h	]h]h]h
]uh|K	h}hhX.First we have to import the interface package:q£h~hvh]q¤h‡X.First we have to import the interface package:q¥…q¦}q§(hh£h~h ubaubcdocutils.nodes
literal_block
q¨)q©}qª(hhhU
literal_blockq«h}q¬(h	]U	xml:spaceq­Upreserveq®h
]UtestnodetypeXdoctesth
]Ugroups]q¯Udefaultq°ah]Uoptionsq±}h]uh|Kh}hhX>>> import zope.interfaceh~hvh]q²h‡X>>> import zope.interfaceq³…q´}qµ(hUh~h©ubaubh‹)q¶}q·(hhhhŽh}q¸(h
]h	]h]h]h
]uh|Kh}hhX¬We now develop an interface for our object, which is a simple file in this
case. For now we simply support one attribute, the body, which contains the
actual file contents:q¹h~hvh]qºh‡X¬We now develop an interface for our object, which is a simple file in this
case. For now we simply support one attribute, the body, which contains the
actual file contents:q»…q¼}q½(hh¹h~h¶ubaubh¨)q¾}q¿(hhhh«h}qÀ(h	]h­h®h
]UtestnodetypeXdoctesth
]Ugroups]qÁh°ah]h±}h]uh|Kh}hhXs>>> class IFile(zope.interface.Interface):
...
...     body = zope.interface.Attribute('Contents of the file.')
...h~hvh]qÂh‡Xs>>> class IFile(zope.interface.Interface):
...
...     body = zope.interface.Attribute('Contents of the file.')
...qŁqÄ}qÅ(hUh~h¾ubaubh‹)qÆ}qÇ(hhhhŽh}qÈ(h
]h	]h]h]h
]uh|Kh}hhXFor statistical reasons we often want to know the size of a file. However, it
would be clumsy to implement the size directly in the file object, since the
size really represents meta-data. Thus we create another interface that
provides the size of something:qÉh~hvh]qÊh‡XFor statistical reasons we often want to know the size of a file. However, it
would be clumsy to implement the size directly in the file object, since the
size really represents meta-data. Thus we create another interface that
provides the size of something:q˅qÌ}qÍ(hhÉh~hÆubaubh¨)qÎ}qÏ(hhhh«h}qÐ(h	]h­h®h
]UtestnodetypeXdoctesth
]Ugroups]qÑh°ah]h±}h]uh|Kh}hhXu>>> class ISize(zope.interface.Interface):
...
...     def getSize():
...         'Return the size of an object.'
...h~hvh]qÒh‡Xu>>> class ISize(zope.interface.Interface):
...
...     def getSize():
...         'Return the size of an object.'
...qӅqÔ}qÕ(hUh~hÎubaubh‹)qÖ}q×(hhhhŽh}qØ(h
]h	]h]h]h
]uh|K'h}hhXÈNow we need to implement the file. It is essential that the object states
that it implements the `IFile` interface. We also provide a default body
value (just to make things simpler for this example):h~hvh]qÙ(h‡XaNow we need to implement the file. It is essential that the object states
that it implements the qڅqÛ}qÜ(hXaNow we need to implement the file. It is essential that the object states
that it implements the h~hÖubcdocutils.nodes
title_reference
qÝ)qÞ}qß(hX`IFile`hUtitle_referenceqàh}qá(h
]h	]h]h]h
]uh~hÖh]qâh‡XIFileqㅁqä}qå(hUh~hÞubaubh‡X` interface. We also provide a default body
value (just to make things simpler for this example):q慁qç}qè(hX` interface. We also provide a default body
value (just to make things simpler for this example):h~hÖubeubh¨)qé}qê(hhhh«h}që(h	]h­h®h
]UtestnodetypeXdoctesth
]Ugroups]qìh°ah]h±}h]uh|K+h}hhXc>>> class File(object):
...
...      zope.interface.implements(IFile)
...      body = 'foo bar'
...h~hvh]qíh‡Xc>>> class File(object):
...
...      zope.interface.implements(IFile)
...      body = 'foo bar'
...qqï}qð(hUh~héubaubh‹)qñ}qò(hhhhŽh}qó(h
]h	]h]h]h
]uh|K3h}hhX€Next we implement an adapter that can provide the `ISize` interface given any
object providing `IFile`. By convention we use `__used_for__` to specify the
interface that we expect the adapted object to provide, in our case
`IFile`. However, this attribute is not used for anything. If you have
multiple interfaces for which an adapter is used, just specify the interfaces
via a tuple.h~hvh]qô(h‡X2Next we implement an adapter that can provide the qõ…qö}q÷(hX2Next we implement an adapter that can provide the h~hñubhÝ)qø}qù(hX`ISize`hhàh}qú(h
]h	]h]h]h
]uh~hñh]qûh‡XISizeqü…qý}qþ(hUh~høubaubh‡X& interface given any
object providing qÿ…r}r(hX& interface given any
object providing h~hñubhÝ)r}r(hX`IFile`hhàh}r(h
]h	]h]h]h
]uh~hñh]rh‡XIFiler…r}r(hUh~jubaubh‡X. By convention we use r	…r
}r(hX. By convention we use h~hñubhÝ)r}r
(hX`__used_for__`hhàh}r(h
]h	]h]h]h
]uh~hñh]rh‡X__used_for__r…r}r(hUh~jubaubh‡XT to specify the
interface that we expect the adapted object to provide, in our case
r…r}r(hXT to specify the
interface that we expect the adapted object to provide, in our case
h~hñubhÝ)r}r(hX`IFile`hhàh}r(h
]h	]h]h]h
]uh~hñh]rh‡XIFiler…r}r(hUh~jubaubh‡Xš. However, this attribute is not used for anything. If you have
multiple interfaces for which an adapter is used, just specify the interfaces
via a tuple.r…r}r(hXš. However, this attribute is not used for anything. If you have
multiple interfaces for which an adapter is used, just specify the interfaces
via a tuple.h~hñubeubh‹)r }r!(hhhhŽh}r"(h
]h	]h]h]h
]uh|K:h}hhX«Again by convention, the constructor of an adapter takes one argument, the
context. The context in this case is an instance of `File` (providing `IFile`)
that is used to extract the size from. Also by convention the context is
stored in an attribute named `context` on the adapter. The twisted community
refers to the context as the `original` object. However, you may feel free to
use a specific argument name, such as `file`:h~hvh]r#(h‡XAgain by convention, the constructor of an adapter takes one argument, the
context. The context in this case is an instance of r$…r%}r&(hXAgain by convention, the constructor of an adapter takes one argument, the
context. The context in this case is an instance of h~j ubhÝ)r'}r((hX`File`hhàh}r)(h
]h	]h]h]h
]uh~j h]r*h‡XFiler+…r,}r-(hUh~j'ubaubh‡X (providing r.…r/}r0(hX (providing h~j ubhÝ)r1}r2(hX`IFile`hhàh}r3(h
]h	]h]h]h
]uh~j h]r4h‡XIFiler5…r6}r7(hUh~j1ubaubh‡Xh)
that is used to extract the size from. Also by convention the context is
stored in an attribute named r8…r9}r:(hXh)
that is used to extract the size from. Also by convention the context is
stored in an attribute named h~j ubhÝ)r;}r<(hX	`context`hhàh}r=(h
]h	]h]h]h
]uh~j h]r>h‡Xcontextr?…r@}rA(hUh~j;ubaubh‡XD on the adapter. The twisted community
refers to the context as the rB…rC}rD(hXD on the adapter. The twisted community
refers to the context as the h~j ubhÝ)rE}rF(hX
`original`hhàh}rG(h
]h	]h]h]h
]uh~j h]rHh‡XoriginalrI…rJ}rK(hUh~jEubaubh‡XM object. However, you may feel free to
use a specific argument name, such as rL…rM}rN(hXM object. However, you may feel free to
use a specific argument name, such as h~j ubhÝ)rO}rP(hX`file`hhàh}rQ(h
]h	]h]h]h
]uh~j h]rRh‡XfilerS…rT}rU(hUh~jOubaubh‡X:…rV}rW(hX:h~j ubeubh¨)rX}rY(hhhh«h}rZ(h	]h­h®h
]UtestnodetypeXdoctesth
]Ugroups]r[h°ah]h±}h]uh|KAh}hhX>>> class FileSize(object):
...
...      zope.interface.implements(ISize)
...      __used_for__ = IFile
...
...      def __init__(self, context):
...          self.context = context
...
...      def getSize(self):
...          return len(self.context.body)
...h~hvh]r\h‡X>>> class FileSize(object):
...
...      zope.interface.implements(ISize)
...      __used_for__ = IFile
...
...      def __init__(self, context):
...          self.context = context
...
...      def getSize(self):
...          return len(self.context.body)
...r]…r^}r_(hUh~jXubaubh‹)r`}ra(hhhhŽh}rb(h
]h	]h]h]h
]uh|KOh}hhXæNow that we have written our adapter, we have to register it with an adapter
registry, so that it can be looked up when needed. There is no such thing as a
global registry; thus we have to instantiate one for our example manually:rch~hvh]rdh‡XæNow that we have written our adapter, we have to register it with an adapter
registry, so that it can be looked up when needed. There is no such thing as a
global registry; thus we have to instantiate one for our example manually:re…rf}rg(hjch~j`ubaubh¨)rh}ri(hhhh«h}rj(h	]h­h®h
]UtestnodetypeXdoctesth
]Ugroups]rkh°ah]h±}h]uh|KSh}hhXW>>> from zope.interface.adapter import AdapterRegistry
>>> registry = AdapterRegistry()h~hvh]rlh‡XW>>> from zope.interface.adapter import AdapterRegistry
>>> registry = AdapterRegistry()rm…rn}ro(hUh~jhubaubh‹)rp}rq(hhhhŽh}rr(h
]h	]h]h]h
]uh|KYh}hhX[The registry keeps a map of what adapters implement based on another
interface, the object already provides. Therefore, we next have to register an
adapter that adapts from `IFile` to `ISize`. The first argument to
the registry's `register()` method is a list of original interfaces.In our
cause we have only one original interface, `IFile`. A list makes sense, since
the interface package has the concept of multi-adapters, which are adapters
that require multiple objects to adapt to a new interface. In these
situations, your adapter constructor will require an argument for each
specified interface.h~hvh]rs(h‡X­The registry keeps a map of what adapters implement based on another
interface, the object already provides. Therefore, we next have to register an
adapter that adapts from rt…ru}rv(hX­The registry keeps a map of what adapters implement based on another
interface, the object already provides. Therefore, we next have to register an
adapter that adapts from h~jpubhÝ)rw}rx(hX`IFile`hhàh}ry(h
]h	]h]h]h
]uh~jph]rzh‡XIFiler{…r|}r}(hUh~jwubaubh‡X to r~…r}r€(hX to h~jpubhÝ)r}r‚(hX`ISize`hhàh}rƒ(h
]h	]h]h]h
]uh~jph]r„h‡XISizer……r†}r‡(hUh~jubaubh‡X'. The first argument to
the registry's rˆ…r‰}rŠ(hX'. The first argument to
the registry's h~jpubhÝ)r‹}rŒ(hX`register()`hhàh}r(h
]h	]h]h]h
]uh~jph]rŽh‡X
register()r…r}r‘(hUh~j‹ubaubh‡X[ method is a list of original interfaces.In our
cause we have only one original interface, r’…r“}r”(hX[ method is a list of original interfaces.In our
cause we have only one original interface, h~jpubhÝ)r•}r–(hX`IFile`hhàh}r—(h
]h	]h]h]h
]uh~jph]r˜h‡XIFiler™…rš}r›(hUh~j•ubaubh‡X. A list makes sense, since
the interface package has the concept of multi-adapters, which are adapters
that require multiple objects to adapt to a new interface. In these
situations, your adapter constructor will require an argument for each
specified interface.rœ…r}rž(hX. A list makes sense, since
the interface package has the concept of multi-adapters, which are adapters
that require multiple objects to adapt to a new interface. In these
situations, your adapter constructor will require an argument for each
specified interface.h~jpubeubh‹)rŸ}r (hhhhŽh}r¡(h
]h	]h]h]h
]uh|Kch}hhXsThe second argument is the interface the adapter provides, in our case
`ISize`. The third argument is the name of the adapter. Since we do not care
about names, we simply leave it as an empty string. Names are commonly useful,
if you have adapters for the same set of interfaces, but they are useful in
different situations. The last argument is simply the adapter class:h~hvh]r¢(h‡XGThe second argument is the interface the adapter provides, in our case
r£…r¤}r¥(hXGThe second argument is the interface the adapter provides, in our case
h~jŸubhÝ)r¦}r§(hX`ISize`hhàh}r¨(h
]h	]h]h]h
]uh~jŸh]r©h‡XISizerª…r«}r¬(hUh~j¦ubaubh‡X%. The third argument is the name of the adapter. Since we do not care
about names, we simply leave it as an empty string. Names are commonly useful,
if you have adapters for the same set of interfaces, but they are useful in
different situations. The last argument is simply the adapter class:r­…r®}r¯(hX%. The third argument is the name of the adapter. Since we do not care
about names, we simply leave it as an empty string. Names are commonly useful,
if you have adapters for the same set of interfaces, but they are useful in
different situations. The last argument is simply the adapter class:h~jŸubeubh¨)r°}r±(hhhh«h}r²(h	]h­h®h
]UtestnodetypeXdoctesth
]Ugroups]r³h°ah]h±}h]uh|Kih}hhX3>>> registry.register([IFile], ISize, '', FileSize)h~hvh]r´h‡X3>>> registry.register([IFile], ISize, '', FileSize)rµ…r¶}r·(hUh~j°ubaubh‹)r¸}r¹(hhhhŽh}rº(h
]h	]h]h]h
]uh|Kmh}hhX7You can now use the the registry to lookup the adapter:r»h~hvh]r¼h‡X7You can now use the the registry to lookup the adapter:r½…r¾}r¿(hj»h~j¸ubaubh¨)rÀ}rÁ(hhhh«h}rÂ(h	]h­h®h
]UtestnodetypeXdoctesth
]Ugroups]rÃh°ah]h±}h]uh|Koh}hhX9>>> registry.lookup1(IFile, ISize, '')
<class 'FileSize'>h~hvh]rÄh‡X9>>> registry.lookup1(IFile, ISize, '')
<class 'FileSize'>rÅ…rÆ}rÇ(hUh~jÀubaubh‹)rÈ}rÉ(hhhhŽh}rÊ(h
]h	]h]h]h
]uh|Kth}hhXÆLet's get a little bit more practical. Let's create a `File` instance and
create the adapter using a registry lookup. Then we see whether the adapter
returns the correct size by calling `getSize()`:h~hvh]rË(h‡X6Let's get a little bit more practical. Let's create a rÌ…rÍ}rÎ(hX6Let's get a little bit more practical. Let's create a h~jÈubhÝ)rÏ}rÐ(hX`File`hhàh}rÑ(h
]h	]h]h]h
]uh~jÈh]rÒh‡XFilerÓ…rÔ}rÕ(hUh~jÏubaubh‡X~ instance and
create the adapter using a registry lookup. Then we see whether the adapter
returns the correct size by calling rÖ…r×}rØ(hX~ instance and
create the adapter using a registry lookup. Then we see whether the adapter
returns the correct size by calling h~jÈubhÝ)rÙ}rÚ(hX`getSize()`hhàh}rÛ(h
]h	]h]h]h
]uh~jÈh]rÜh‡X	getSize()rÝ…rÞ}rß(hUh~jÙubaubh‡X:…rà}rá(hX:h~jÈubeubh¨)râ}rã(hhhh«h}rä(h	]h­h®h
]UtestnodetypeXdoctesth
]Ugroups]råh°ah]h±}h]uh|Kxh}hhXZ>>> file = File()
>>> size = registry.lookup1(IFile, ISize, '')(file)
>>> size.getSize()
7h~hvh]ræh‡XZ>>> file = File()
>>> size = registry.lookup1(IFile, ISize, '')(file)
>>> size.getSize()
7r煁rè}ré(hUh~jâubaubh‹)rê}rë(hhhhŽh}rì(h
]h	]h]h]h
]uh|Kh}hhXHowever, this is not very practical, since I have to manually pass in the
arguments to the lookup method. There is some syntactic candy that will allow
us to get an adapter instance by simply calling `ISize(file)`. To make use of
this functionality, we need to add our registry to the adapter_hooks list,
which is a member of the adapters module. This list stores a collection of
callables that are automatically invoked when IFoo(obj) is called; their
purpose is to locate adapters that implement an interface for a certain
context instance.h~hvh]rí(h‡XÈHowever, this is not very practical, since I have to manually pass in the
arguments to the lookup method. There is some syntactic candy that will allow
us to get an adapter instance by simply calling rrï}rð(hXÈHowever, this is not very practical, since I have to manually pass in the
arguments to the lookup method. There is some syntactic candy that will allow
us to get an adapter instance by simply calling h~jêubhÝ)rñ}rò(hX
`ISize(file)`hhàh}ró(h
]h	]h]h]h
]uh~jêh]rôh‡XISize(file)rõ…rö}r÷(hUh~jñubaubh‡XI. To make use of
this functionality, we need to add our registry to the adapter_hooks list,
which is a member of the adapters module. This list stores a collection of
callables that are automatically invoked when IFoo(obj) is called; their
purpose is to locate adapters that implement an interface for a certain
context instance.rø…rù}rú(hXI. To make use of
this functionality, we need to add our registry to the adapter_hooks list,
which is a member of the adapters module. This list stores a collection of
callables that are automatically invoked when IFoo(obj) is called; their
purpose is to locate adapters that implement an interface for a certain
context instance.h~jêubeubh‹)rû}rü(hhhhŽh}rý(h
]h	]h]h]h
]uh|Kˆh}hhX¾You are required to implement your own adapter hook; this example covers one
of the simplest hooks that use the registry, but you could implement one that
used an adapter cache or persistent adapters, for instance. The helper hook is
required to expect as first argument the desired output interface (for us
`ISize`) and as the second argument the context of the adapter (here
`file`). The function returns an adapter, i.e. a `FileSize` instance:h~hvh]rþ(h‡X4You are required to implement your own adapter hook; this example covers one
of the simplest hooks that use the registry, but you could implement one that
used an adapter cache or persistent adapters, for instance. The helper hook is
required to expect as first argument the desired output interface (for us
rÿ…r}r(hX4You are required to implement your own adapter hook; this example covers one
of the simplest hooks that use the registry, but you could implement one that
used an adapter cache or persistent adapters, for instance. The helper hook is
required to expect as first argument the desired output interface (for us
h~jûubhÝ)r}r(hX`ISize`hhàh}r(h
]h	]h]h]h
]uh~jûh]rh‡XISizer…r}r(hUh~jubaubh‡X>) and as the second argument the context of the adapter (here
r	…r
}r(hX>) and as the second argument the context of the adapter (here
h~jûubhÝ)r}r
(hX`file`hhàh}r(h
]h	]h]h]h
]uh~jûh]rh‡Xfiler…r}r(hUh~jubaubh‡X+). The function returns an adapter, i.e. a r…r}r(hX+). The function returns an adapter, i.e. a h~jûubhÝ)r}r(hX
`FileSize`hhàh}r(h
]h	]h]h]h
]uh~jûh]rh‡XFileSizer…r}r(hUh~jubaubh‡X
 instance:r…r}r(hX
 instance:h~jûubeubh¨)r }r!(hhhh«h}r"(h	]h­h®h
]UtestnodetypeXdoctesth
]Ugroups]r#h°ah]h±}h]uh|Kh}hhX¹>>> def hook(provided, object):
...     adapter = registry.lookup1(zope.interface.providedBy(object),
...                                provided, '')
...     return adapter(object)
...h~hvh]r$h‡X¹>>> def hook(provided, object):
...     adapter = registry.lookup1(zope.interface.providedBy(object),
...                                provided, '')
...     return adapter(object)
...r%…r&}r'(hUh~j ubaubh‹)r(}r)(hhhhŽh}r*(h
]h	]h]h]h
]uh|K—h}hhX4We now just add the hook to an `adapter_hooks` list:r+h~hvh]r,(h‡XWe now just add the hook to an r-…r.}r/(hXWe now just add the hook to an h~j(ubhÝ)r0}r1(hX`adapter_hooks`hhàh}r2(h
]h	]h]h]h
]uh~j(h]r3h‡X
adapter_hooksr4…r5}r6(hUh~j0ubaubh‡X list:r7…r8}r9(hX list:h~j(ubeubh¨)r:}r;(hhhh«h}r<(h	]h­h®h
]UtestnodetypeXdoctesth
]Ugroups]r=h°ah]h±}h]uh|K™h}hhXU>>> from zope.interface.interface import adapter_hooks
>>> adapter_hooks.append(hook)h~hvh]r>h‡XU>>> from zope.interface.interface import adapter_hooks
>>> adapter_hooks.append(hook)r?…r@}rA(hUh~j:ubaubh‹)rB}rC(hhhhŽh}rD(h
]h	]h]h]h
]uh|Kžh}hhX<Once the hook is registered, you can use the desired syntax:rEh~hvh]rFh‡X<Once the hook is registered, you can use the desired syntax:rG…rH}rI(hjEh~jBubaubh¨)rJ}rK(hhhh«h}rL(h	]h­h®h
]UtestnodetypeXdoctesth
]Ugroups]rMh°ah]h±}h]uh|K h}hhX+>>> size = ISize(file)
>>> size.getSize()
7h~hvh]rNh‡X+>>> size = ISize(file)
>>> size.getSize()
7rO…rP}rQ(hUh~jJubaubh‹)rR}rS(hhhhŽh}rT(h
]h	]h]h]h
]uh|K¦h}hhXbNow we have to cleanup after ourselves, so that others after us have a clean
`adapter_hooks` list:h~hvh]rU(h‡XMNow we have to cleanup after ourselves, so that others after us have a clean
rV…rW}rX(hXMNow we have to cleanup after ourselves, so that others after us have a clean
h~jRubhÝ)rY}rZ(hX`adapter_hooks`hhàh}r[(h
]h	]h]h]h
]uh~jRh]r\h‡X
adapter_hooksr]…r^}r_(hUh~jYubaubh‡X list:r`…ra}rb(hX list:h~jRubeubh¨)rc}rd(hhhh«h}re(h	]h­h®h
]UtestnodetypeXdoctesth
]Ugroups]rfh°ah]h±}h]uh|K©h}hhX>>> adapter_hooks.remove(hook)h~hvh]rgh‡X>>> adapter_hooks.remove(hook)rh…ri}rj(hUh~jcubaubh‹)rk}rl(hhhhŽh}rm(h
]h	]h]h]h
]uh|K­h}hhXžThat's it. I have intentionally left out a discussion of named adapters and
multi-adapters, since this text is intended as a practical and simple
introduction to Zope 3 interfaces and adapters. You might want to read the
`adapter.txt` in the `zope.interface` package for a more formal, referencial
and complete treatment of the package. Warning: People have reported that
`adapter.txt` makes their brain feel soft!h~hvh]rn(h‡XÝThat's it. I have intentionally left out a discussion of named adapters and
multi-adapters, since this text is intended as a practical and simple
introduction to Zope 3 interfaces and adapters. You might want to read the
ro…rp}rq(hXÝThat's it. I have intentionally left out a discussion of named adapters and
multi-adapters, since this text is intended as a practical and simple
introduction to Zope 3 interfaces and adapters. You might want to read the
h~jkubhÝ)rr}rs(hX
`adapter.txt`hhàh}rt(h
]h	]h]h]h
]uh~jkh]ruh‡Xadapter.txtrv…rw}rx(hUh~jrubaubh‡X in the ry…rz}r{(hX in the h~jkubhÝ)r|}r}(hX`zope.interface`hhàh}r~(h
]h	]h]h]h
]uh~jkh]rh‡Xzope.interfacer€…r}r‚(hUh~j|ubaubh‡Xr package for a more formal, referencial
and complete treatment of the package. Warning: People have reported that
rƒ…r„}r…(hXr package for a more formal, referencial
and complete treatment of the package. Warning: People have reported that
h~jkubhÝ)r†}r‡(hX
`adapter.txt`hhàh}rˆ(h
]h	]h]h]h
]uh~jkh]r‰h‡Xadapter.txtrŠ…r‹}rŒ(hUh~j†ubaubh‡X makes their brain feel soft!r…rŽ}r(hX makes their brain feel soft!h~jkubeubeubsUsymbol_footnotesr]r‘hhUindirect_targetsr’]r“Usubstitution_namesr”}r•Ucurrent_liner–NUsubstitution_defsr—}r˜Usymbol_footnote_startr™KUautofootnote_startršKU
autofootnotesr›]rœh]rhvaUcurrent_sourceržNUrefidsrŸ}r ub.