The PEAK Developers' Center   Diff for "MonkeyTyping" UserPreferences
 
HelpContents Search Diffs Info Edit Subscribe XML Print View
Ignore changes in the amount of whitespace

Differences between version dated 2005-01-16 13:05:08 and 2005-01-16 23:51:46 (spanning 2 versions)

Deletions are marked like this.
Additions are marked like this.

prevents users from having to "relearn how to write good code" in order to use
the new features successfully.
 
This PEP directly competes with PEP 245, which proposes a syntax for
Python interfaces. If some form of this proposal is accepted, it
would be unnecessary for a special interface type or syntax to be added to
Python, since normal classes and partially or completely abstract classes will
be routinely usable as interfaces. Some packages or frameworks, of course, may
have additional requirements for interface features, but they can use
metaclasses to implement such enhanced interfaces without impeding their
ability to be used as interfaces by this PEP's system for creating extenders.
 
Of course, given the number of previous failed attempts to create a type
declaration system for Python, this PEP is an act of extreme optimism, and it
will not be altogether surprising if it, too, ultimately fails. However, if

between them because the appliances are independent objects rather than mere
extensions of the power outlet.
 
A key distinction between extenders and independent adapters is the "as a"
relationship versus the "has a" relationship. An iterable "has" iterators
and a model "has" views. But an extender represents an "as a" relationship,
like treating a Person "as an" Employee, or treating a string "as a" filename.
 
For example, Jason Orendorff's ``path`` module offers a string subclass for
representing file or directory paths, supporting operations like ``rename()``
and ``walkfiles()``. Using this class as an extender would allow routines to
declare that they want a ``path`` argument, yet allow the caller to pass in a
string. The routine would then be able to call ``path`` methods on the object
it receives. Yet, if the routine in turn passed that object to another routine
that needs a string, the second routine would receive the original string.
 
In some ways, this approach can actually improve on subclassing. The ``path``
module's string subclass inherits many string methods that have no meaning
for path objects, and it also has a different meaning for __iter__ than a
string does. While iterating over a string yields the characters in the
string, iterating over a path yields the files within the directory specified
by the path. Thus, a path object is not really substitutable for a string, and
today passing a path object to a routine that expects to be able to iterate
over the string's characters would break.
 
However, if it were implemented as an extender, the path type could supply only
methods that make sense for a path, and any given routine can choose to treat
the object "as" either a string or a path, according to its need.
 
PEP 246 was originally proposed for an explicit adaptation model where an
``adapt()`` function is called to retrieve an "adapter", where no distinction
was made between extenders and independent adapters. However, the adapting

return value(s).
 
The problem with this concept is that interface implementations are typically
expected to be complete. In Java, for example, you say that your class
expected to be complete. In Java, for example, you can't say that your class
implements an interface unless you actually add all of the required methods,
even if some of them aren't needed in your program yet.
 

of more rigid type systems like those of Java or Microsoft's COM (Component
Object Model).
 
This PEP directly competes with PEP 245, which proposes a syntax for
Python interfaces. If some form of this proposal is accepted, it
would be unnecessary for a special interface type or syntax to be added to
Python, since normal classes and partially or completely abstract classes will
be routinely usable as interfaces. Some packages or frameworks, of course, may
have additional requirements for interface features, but they can use
metaclasses to implement such enhanced interfaces without impeding their
ability to be used as interfaces by this PEP's system for creating extenders.
 
 
Specification

form the basis for compatible interfacing between packages; if each package
denotes the relationship between its types' operations and the operations
of the ``file`` type, then those packages can accept other packages' objects
as parameters declared as requiring a ``file`` instance.
as ``:file`` parameters.
 
However, the standard library cannot contain base versions of all possible
operations for which multiple implementations might exist, so different

such a type, you must fall back to either storing the additional state in the
object itself, using the object to key some other dictionary to obtain the
state, or declaring that your extender can live with potentially inconsistent
states. XXX have a way to declare that state is kept in the extender for this
states.
 
XXX have a way to declare that state is kept in the extender for this scenario
 
Using Multiple Extenders
------------------------
 
Using Multiple Extender States
------------------------------
 
Different external operations can use different ``using`` types to store
their state. For example, a ``DuckDodgers`` instance might be able to be used

``using`` type that inherits from the conflicting types.
 
 
Miscellaneous
-------------
Non-Method Attributes
---------------------
 
Sometimes, an interface includes not only methods, but also the ability to get
or set an attribute as well. In the case of attributes that are managed by
descriptors in the interface or type, we can use these for ``@like``
declarations by mapping to their ``__get__``, ``__set__``, and ``__delete__``
methods, e.g.::
 
    @like(SomeClass.someAttr.__get__, for_type=OtherClass)
    def get_foo_as_someAttr(self):
        return self.foo
 
    @like(SomeClass.someAttr.__set__, for_type=OtherClass)
    def set_foo_as_someAttr(self, value):
        self.foo = value
 
While creating an extender to map ``OtherClass`` to ``SomeClass``, we will
find the ``someAttr`` descriptor and check for operations defined for its
``__get__``, ``__set__`` and ``__delete__`` methods, using them to assemble
a ``property`` descriptor for the extender. In addition to using functions
as shown, we can also implement a shortcut like this::
 
    like(SomeClass.someAttr, for_type=OtherClass)("foo")
 
To mean that any set/get/delete of ``someAttr`` on the extender should be
mapped to a corresponding action on the ``foo`` attribute of the ``OtherClass``
instance. Or, we can use this::
 
    like(SomeClass.someAttr, for_type=OtherClass, using=FooData)("foo")
 
to mean that the ``foo`` attribute should be gotten, set, or deleted from
the ``FooData`` state instance, whenever the corresponding operation is
performed on the extender's ``someAttr``.
   
 
XXX property get/set/del as three "operations"
Special Methods
---------------
 
XXX binary operators
 

PythonPowered
ShowText of this page
EditText of this page
FindPage by browsing, title search , text search or an index
Or try one of these actions: AttachFile, DeletePage, LikePages, LocalSiteMap, SpellCheck