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

Differences between version dated 2010-08-17 19:59:04 and 2011-08-31 21:11:53

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

conform with ``isinstance()`` here::
 
    >>> class X: pass
 
    >>> implies(X, object)
    True
    >>> implies(X, type(X())) # InstanceType
 
    >>> from types import InstanceType
    >>> implies(X, InstanceType)
    True
 
 
``istype()`` objects
--------------------
 
Type or class objects are used to represent "this class or a subclass", but
``istype()`` objects are used to represent either "this exact type" (using
``istype(aType, True)``), or "anything but this exact type" (``istype(aType,
False)``). So their implication rules are different.
 
Internally, PEAK-Rules uses ``istype`` objects to represent a call signature
being matched, because the argument being tested is of some exact type. Then,
any rule signatures that are implied by the calling signature are considered
"applicable".
 
So, ``istype(aType, True)`` (the default) must always imply the same type or
class, or any parent class thereof::
 
    >>> from peak.rules import istype
 
    >>> implies(istype(int), int)
    True
    >>> implies(istype(int), object)
    True
    >>> implies(istype(X), InstanceType)
    True
    >>> implies(istype(X), object)
    True
 
But not the other way around::
 
    >>> implies(int, istype(int))
    False
    >>> implies(object, istype(int))
    False
    >>> implies(InstanceType, istype(X))
    False
    >>> implies(object, istype(X))
    False
 
An exact type will also imply any exclusion of a *different* exact type::
 
    >>> implies(istype(int), istype(str, False))
    True
 
In other words, if ``type(x) is int``, that implies ``type(x) is not str``.
But of course, that doesn't work they other way around::
 
    >>> implies(istype(str, False), istype(int))
    False
 
These implication rules are sufficient to bootstrap the basic types-only
rules engine; additional rules for ``istype`` behavior are explained in
Criteria.txt to show intersection of criteria such as ``istype``, and other
more-advanced criteria manipulation used in the full predicate rules engine.
 
 
Action Types

arguments.)
 
 
Defining Method Precedence
--------------------------
 
You can define one method type's precedence relative to another using the
``>>`` operator (which always returns its right-side operand)::
 
    >>> NoisyMethod >> Method
    <class 'peak.rules.core.Method'>
 
You can also chain ``>>`` operators to define overall method precedence between
multiple types, e.g.::
 
    >>> Around >> NoisyMethod >> Method
    <class 'peak.rules.core.Method'>
 
As long as you don't try to introduce a precedence cycle::
 
    >>> NoisyMethod >> MyMethod2 >> Around
    Traceback (most recent call last):
      ...
    TypeError: <class 'peak.rules.core.Around'> already overrides <class 'MyMethod2'>
 
 
 
Decorators
==========
 

    yo!
    after
 
Decorators can accept an entry point string in place of an actual function,
provided that the PEAK "Importing" package (``peak.util.imports``) is
available. In that case, the registration is deferred until the named module
is imported::
 
    >>> before('some.module:somefunc')(lambda: p("before"))
    <function <lambda> at ...>
 
If the named module is already imported, the registration takes place
immediately, otherwise it is deferred until the named module is actually
imported.
 
This allows you to provide optional integration with modules that might or
might not be used by a given application, without creating a dependency between
your code and that package.
 
Note, however, that if the named function doesn't exist when the module is
imported, then an attribute error will occur at import time. The syntax of
the target name is lightly checked at call time, however::
 
    >>> before('foo.bar')(lambda: p("before"))
    Traceback (most recent call last):
      ...
    TypeError: Function specifier 'foo.bar' is not in
               'module.name:attrib.name' format
 
    >>> before('foo: bar')(lambda: p("before"))
    Traceback (most recent call last):
      ...
    TypeError: Function specifier 'foo: bar' is not in
               'module.name:attrib.name' format
 
(This is just a sanity check, though, just to make sure you didn't accidentally
put some other string first (like the criteria). It won't detect a string
that points to a non-existent module, or various other possible errors, so you
should still verify that your code gets run when the target module is imported
and the relevant conditions apply.)
 
 
Creating Custom Combinations

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