[SciPy-User] How to create Interface classes at runtime?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[SciPy-User] How to create Interface classes at runtime?

Stephen Waterbury-2
I am creating an application that has a strong "meta" aspect and
uses mappings among models of various types (including both
"semantic models" -- schemas that are intended to be mappable to
real things, e.g. OWL -- and "data models" -- models that are
useful for something but may or may not map directly to "real"
things, e.g. SQL, UML, etc.) to define "domain [classes,
interfaces, schemas]".  My app creates schemas (in the sense of
zope.schema) and interfaces (in the sense of zope.interface or
PyProtocols) at runtime from some combination of models and
mappings.  (Those who are familiar with this type of application
will probably observe that I'm studiously avoiding the term
"model-driven" -- this is because of its baggage and also because
I am not a fan of UML, XMI, or the UML model-driven orthodoxy,
even though my app will have to deal with UML/XMI ... ugh.)

I have been using zope.interface but now I want to move into the
traits-based universe -- as much because of its strong support for
numpy datatypes as anything because my app's domain is mainly
engineering, but all the other traits features will be useful
as well.

So now to my request for hints:

I've been reading the traits modules has_traits.py and protocols.py
and trying to figure out what I'd use to create Interface classes
at runtime, but my brain is beginning to melt so thought I'd ask for
some advice.  I have code that creates zope.interface-style Interface
classes at runtime by instantiating InterfaceClass, but PyProtocols,
which is used by traits, has a significantly different set of api's,
with perhaps no public/supported api's to do this, and the code is
somewhat more difficult to read than zope.interface code, so it's
not obvious how to create traits-style Interface classes at
runtime ... any hints would be appreciated!

Thanks,
Steve

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: [SciPy-User] How to create Interface classes at runtime?

Stephen Waterbury-2
Oops!  Apologies for not removing the "[SciPy-User]" tag from
the subject -- my original post was to that list.  :(

Steve
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: [SciPy-User] How to create Interface classes at runtime?

Robert Kern
In reply to this post by Stephen Waterbury-2
On Tue, Apr 19, 2011 at 12:32 PM, Stephen Waterbury
<[hidden email]> wrote:

> I am creating an application that has a strong "meta" aspect and
> uses mappings among models of various types (including both
> "semantic models" -- schemas that are intended to be mappable to
> real things, e.g. OWL -- and "data models" -- models that are
> useful for something but may or may not map directly to "real"
> things, e.g. SQL, UML, etc.) to define "domain [classes,
> interfaces, schemas]".  My app creates schemas (in the sense of
> zope.schema) and interfaces (in the sense of zope.interface or
> PyProtocols) at runtime from some combination of models and
> mappings.  (Those who are familiar with this type of application
> will probably observe that I'm studiously avoiding the term
> "model-driven" -- this is because of its baggage and also because
> I am not a fan of UML, XMI, or the UML model-driven orthodoxy,
> even though my app will have to deal with UML/XMI ... ugh.)
>
> I have been using zope.interface but now I want to move into the
> traits-based universe -- as much because of its strong support for
> numpy datatypes as anything because my app's domain is mainly
> engineering, but all the other traits features will be useful
> as well.
>
> So now to my request for hints:
>
> I've been reading the traits modules has_traits.py and protocols.py
> and trying to figure out what I'd use to create Interface classes
> at runtime, but my brain is beginning to melt so thought I'd ask for
> some advice.  I have code that creates zope.interface-style Interface
> classes at runtime by instantiating InterfaceClass, but PyProtocols,
> which is used by traits, has a significantly different set of api's,
> with perhaps no public/supported api's to do this, and the code is
> somewhat more difficult to read than zope.interface code, so it's
> not obvious how to create traits-style Interface classes at
> runtime ... any hints would be appreciated!

Well, do you really need Interfaces? We don't actually use any of the
information about the attributes and methods for anything. They are
just documentation. The Interface classes are essentially just opaque
enums that are used as markers as an adjunct to isinstance() testing
and for adaptation in our Instance() trait. It *sounds* like you just
want to make HasTraits classes instead, with the traits on them
reflecting the atributes in the schema. For this use case, Traits
itself shares more in common with zope.interfaces than PyProtocols.

But really, the answer is similar for both: use type().

[~]
|3> type?
Type: type
Base Class: <type 'type'>
String Form: <type 'type'>
Namespace: Python builtin
Docstring:
    type(object) -> the object's type
    type(name, bases, dict) -> a new type

[~]
|4> MyClass = type('MyClass', (HasTraits,), dict(x=Float(), y=Int()))

[~]
|5> mc = MyClass()

[~]
|6> mc.x
0.0

[~]
|7> mc.y
0

[~]
|9> IMyInterface = type('IMyInterface', (Interface,), {})


If you really think you need to dynamically make interfaces and
classes that implement those interfaces, you will need to explicitly
declare their relationship using
enthought.traits.protocols.api.declareImplementation(). Sorry for the
long "address"; it's not something that is typically used, so we never
lifted it up to a more prominent place.

--
Robert Kern
Enthought
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: [SciPy-User] How to create Interface classes at runtime?

Stephen Waterbury
On 04/19/2011 03:02 PM, Robert Kern wrote:

> On Tue, Apr 19, 2011 at 12:32 PM, Stephen Waterbury
> <[hidden email]>  wrote:
>> I am creating an application that has a strong "meta" aspect and
>> uses mappings among models of various types (including both
>> "semantic models" -- schemas that are intended to be mappable to
>> real things, e.g. OWL -- and "data models" -- models that are
>> useful for something but may or may not map directly to "real"
>> things, e.g. SQL, UML, etc.) to define "domain [classes,
>> interfaces, schemas]".  My app creates schemas (in the sense of
>> zope.schema) and interfaces (in the sense of zope.interface or
>> PyProtocols) at runtime from some combination of models and
>> mappings.  (Those who are familiar with this type of application
>> will probably observe that I'm studiously avoiding the term
>> "model-driven" -- this is because of its baggage and also because
>> I am not a fan of UML, XMI, or the UML model-driven orthodoxy,
>> even though my app will have to deal with UML/XMI ... ugh.)
>>
>> I have been using zope.interface but now I want to move into the
>> traits-based universe -- as much because of its strong support for
>> numpy datatypes as anything because my app's domain is mainly
>> engineering, but all the other traits features will be useful
>> as well.
>>
>> So now to my request for hints:
>>
>> I've been reading the traits modules has_traits.py and protocols.py
>> and trying to figure out what I'd use to create Interface classes
>> at runtime, but my brain is beginning to melt so thought I'd ask for
>> some advice.  I have code that creates zope.interface-style Interface
>> classes at runtime by instantiating InterfaceClass, but PyProtocols,
>> which is used by traits, has a significantly different set of api's,
>> with perhaps no public/supported api's to do this, and the code is
>> somewhat more difficult to read than zope.interface code, so it's
>> not obvious how to create traits-style Interface classes at
>> runtime ... any hints would be appreciated!
>
> Well, do you really need Interfaces? We don't actually use any of the
> information about the attributes and methods for anything. They are
> just documentation.

A reasonable question.  I'll definitely go with what you suggest
here because it will be much simpler and will work.  In the final
analysis, the classes are the bottom line and traits itself
already does or can be made to do much of what I had in mind for
the interfaces and schemas:  automagically provide api's,
schemas, and possibly multiple alternate ui's ... all in the
interest of DRY, efficiency, flexibility, and ease of code
maintenance (all the usual motivations for meta-driven frameworks
like traits).

I liked the separation of interfaces and schemas explicitly
because I like to think of them as orthogonal and complementary
(behavior/state) in sort of a quantum sense ... in my app's
zope.interfaces version, I was using the interfaces and schemas
as active companions of the application classes, which knew what
their interfaces and schemas were and referred to them for
introspective things -- now I understand that traits just
encapsulates all that in the HasTraits classes -- a different
concept.  I'll take that as far as I can and see if it does
what I need without the interfaces/schemas.

If I really need the schema/interface level of explicitness (e.g.
to support getting schemas and interfaces from different sources
and changing them dynamically or something like that), I'll cross
that bridge when I come to it.

> The Interface classes are essentially just opaque
> enums that are used as markers as an adjunct to isinstance() testing
> and for adaptation in our Instance() trait.

Interesting -- I *was* curious what traits was using adaptation
for.  I didn't plan to use adaptation in my app (well, maybe it
would evolve).

> It *sounds* like you just
> want to make HasTraits classes instead, with the traits on them
> reflecting the atributes in the schema. For this use case, Traits
> itself shares more in common with zope.interfaces than PyProtocols.

Great, I might have guessed that but it's better to hear it from
one of the developers.  And it will save me a lot by not needing
a cryogenic cooling system for my brain ... hopefully. :)

> But really, the answer is similar for both: use type().
>
> [~]
> |3>  type?
> Type: type
> Base Class: <type 'type'>
> String Form: <type 'type'>
> Namespace: Python builtin
> Docstring:
>      type(object) ->  the object's type
>      type(name, bases, dict) ->  a new type
>
> [~]
> |4>  MyClass = type('MyClass', (HasTraits,), dict(x=Float(), y=Int()))
>
> [~]
> |5>  mc = MyClass()
>
> [~]
> |6>  mc.x
> 0.0
>
> [~]
> |7>  mc.y
> 0

Elegant!  I'm reminded again why I love Python ... with due
credit to traits -- excellent stuff!

> [~]
> |9>  IMyInterface = type('IMyInterface', (Interface,), {})
>
>
> If you really think you need to dynamically make interfaces and
> classes that implement those interfaces, you will need to explicitly
> declare their relationship using
> enthought.traits.protocols.api.declareImplementation(). Sorry for the
> long "address"; it's not something that is typically used, so we never
> lifted it up to a more prominent place.

No problem -- that's a good thing to keep in my back pocket in
case I want it later.

Many thanks!
Steve

_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: [SciPy-User] How to create Interface classes at runtime?

Stephen Waterbury
On 04/19/2011 04:44 PM, Stephen Waterbury wrote:
> On 04/19/2011 03:02 PM, Robert Kern wrote:
>> But really, the answer is similar for both: use type().
>> ...
>> |4>   MyClass = type('MyClass', (HasTraits,), dict(x=Float(), y=Int()))
>>  ...
>
> Elegant!  I'm reminded again why I love Python ... with due
> credit to traits -- excellent stuff!

... but just so I don't give the impression that I'm completely
ignorant of the use of type(), I already use it to create Storm
classes from the schemas I mentioned -- see the function
'_update_classes_from_schemas' beginning at line 451:

https://pangalactic.us/repo/pgef/file/4c5456c796cf/pangalactic/meta/registry.py

Steve
_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev