Re: [Zope-dev] ZPatterns AttributeProvider question

2001-04-22 Thread Steve Alexander

Christian Scholz wrote:


 So what I do now as workaround is 
 
 dtml method 1:
 
 - creates new object via newItem()
 - redirects to dtml method 2
 
 dtml method 2:
 - retrieves the newly created object with getItem()
 - calls manage_changeProperties on that object
 
 This is working. Putting the manage_changeProperties directly after the
 newItem() is not working. I've also tried retrieving the new object
 directly after newItem() and calling manage_changeProperties on that
 but this also did not work.
 (so it is named correctly as otherwise it wouldn't be called either in dtml method 
2).
 
 So the main problem is: SetAttributeFor() is not called (and also _objectChanging()
 is not called) in the same request cycle after creating a new object.
 They're called however in the "next" request after retrieving it with getItem().


   As a simpler workaround, you can use 
your_object.commitSubtransaction() instead of redirecting to a new page. 
A few Zope versions ago, that could conceivably cause problems with 
certain database adapters. With some of the recent fixes to Zope, you 
should be ok using subtransactions even with DAs that don't support 
them. Check this out before you use it for important stuff though :-)

   You really should be able to create a new object and set its 
attributes in the same transaction. The status of the object (_v_status 
in DataSkin.py) will be ChangedStatus, if you're adding and changing in 
the same transaction. That's a good place to look for where the problem is.

--
Steve Alexander
Software Engineer
Cat-Box limited


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPatterns AttributeProvider question

2001-04-22 Thread Phillip J. Eby

At 03:07 PM 4/22/01 +0100, Steve Alexander wrote:

   As a simpler workaround, you can use 
your_object.commitSubtransaction() instead of redirecting to a new page. 

Um, this shouldn't be the issue here.  _SetAttributeFor() should be called
when the attribute is set; it's not transaction-driven.  Something weird is
happening with Christian's situation that I haven't investigated yet.


   You really should be able to create a new object and set its 
attributes in the same transaction. The status of the object (_v_status 
in DataSkin.py) will be ChangedStatus, if you're adding and changing in 
the same transaction. That's a good place to look for where the problem is.

Actually, the status should be AddedStatus, and it should stay that way
throughout the transaction, unless the object gets deleted in the same
transaction.


___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPatterns AttributeProvider question

2001-04-22 Thread Steve Alexander

Phillip J. Eby wrote:

 Steve Alexander wrote:
 
  As a simpler workaround, you can use 
your_object.commitSubtransaction() instead of redirecting to a new page. 

 Um, this shouldn't be the issue here.  _SetAttributeFor() should be called
 when the attribute is set; it's not transaction-driven.  Something weird is
 happening with Christian's situation that I haven't investigated yet.


I agree. However, if Christian's problem can be worked-around by 
redirecting before setting attributes, then it should also be 
workaroundable by calling commitSubtransaction.


 Actually, the status should be AddedStatus, and it should stay that way
 throughout the transaction, unless the object gets deleted in the same
 transaction.


That's what I'd originally thought. Then I (mis-?)read the code again...

The __set_attr__ method of DataSkins.py says:

self._objectChanging(name)

The _objectChanging method says:

 if self._v_status_ is not ChangedStatus:
 d[_v_dm_]._objectChanging(self)
 d[_v_status_] = ChangedStatus

I don't see an exception for if _v_status is already AddedStatus.

--
Steve Alexander
Software Engineer
Cat-Box limited



___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPatterns AttributeProvider question

2001-04-22 Thread Christian Scholz

Hi!

A little update..

Actually I was mistaken and SetAttributeFor() is called. Just _objectChanged()
is not called in that case.. and thus my attributes are not stored to the database.
Also commit() is not called at all in this case. It get's called once when the
subtranscation is committed but not after some data has changed (which happens
after that).

Printing _v_status_ in SetAttributeFor() also gives me "Changed", thus this seems
right.

Maybe some more code will help (just the important pieces):

def _objectAdded(self,client):
""" store cached data in database """

... here we do an sql query to insert things in database ...

def _objectChanged(self,client):
""" store cached data in database """

... here we do an sql query to update things in database ...

def _objectAdding(self,client,
_tmap={ None:AddedStatus,
DeletedStatus:ChangedStatus,
ChangedStatus:AddedStatus
}
):
t = client._getTokenFor(self)
s = t.status
t.status = _tmap.get(s,s)

# we need to do a commit here in order to store the record into the database!
# and we need to have it stored as an AttributeFor() of the primary key will
# return None otherwise (as this also just makes a query).
client.commitSubtransaction()

def _SetAttributeFor(self,client,name,value):
"""Set the attribute and return true if successful"""
# attribs stores the attributes we care about
if name in self._attribs.keys():
client._getCache()[name]=value
client.__dict__[name]=value; 
client._p_changed = 1
return 1
return None


So _objectChanging() is not overridden, the rest I have ommitted..

So as you also can see I already do a subtransaction commit but it does
not seem to help for this problem.. 

regards,
  Christian

PS: It might also be that I am simply blind ;-) But somehow ZPatterns always confuses 
me,
especially the inner workings ;-)

-- 
COM.lounge  http://comlounge.net/
communication  design [EMAIL PROTECTED]

___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



[Zope-dev] pydoc for Zope - another great documentation finding tool

2001-04-22 Thread Dieter Maurer

I installed Python 2.1 and checked what great new things are there:
they are numerous!


As you know, I am a fan of documentation - reliable documentation,
if possible directly extracted from the source.
Therefore, the new Python documenter "pydoc" was very attractive for me.


I had to tweak "Zope" and "pydoc" a bit such that they work nicely
together:

  *  "pydoc" imports the modules to find out about its content.
 Zope does not like to be imported, when another Zope
 process is running.

 Solved by calling "FileStorage.FileStorage" with the
 "read_only" parameter in "Zope.__init__", if instructed
 by an environment variable

  *  "pydoc" is slightly confused by some of Zope's extension
 classes: it wants any class to have a "__module__"
 attribute. Zope's extension classes do not have it.

 Solved by wrapping pydoc's "__module__" access in an
 "try  except".

  *  "inspect" does not understand "Python Methods" (and
 other Zope methods). Correspondingly, Zope class documentation
 was almost empty.

 Solved by defining "implementsMethodInterface" and
 replacing "inspect.ismethod" by this function (at runtime).


After these tweaks, "pydoc" can document Zope code.
It is a bit overwhelming:

   The "pydoc" authors decided to document inherited methods with the
   class itself. As a consequence, for each Zope class, hundreds of
   mostly irrelevant methods are documented.

   But it should be easy to change this to get something
   similar to "javadoc": summary information for inherited methods.

Already in the current state, I think, it is a great help
for Zope developpers.


If there is interest, I can post my changes.



Dieter

___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] pydoc for Zope - another great documentation finding tool

2001-04-22 Thread Dieter Maurer

Zopista writes:
  Yes please, I want to integrate pydoc in to the SourceCodeBrowser which is
  at zopezen.org and I'm just to about to release as a product.
The (minor) modification to let "pydoc" work with Zope can
be found via

  URL:http://www.dieter.handshake.de/pyprojects/zope/pydoc.html

"pydoc" requires installation and use of Python2.1.
It seems that Zope need not be run with Python2.1 just "pydoc".
But I made no thourough tests for this.


Dieter



___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] ZPatterns AttributeProvider question

2001-04-22 Thread Phillip J. Eby

At 08:29 PM 4/22/01 +0200, Christian Scholz wrote:
Hi!

A little update..

Actually I was mistaken and SetAttributeFor() is called. Just
_objectChanged()
is not called in that case.. and thus my attributes are not stored to the
database.

When an object is newly added, only _objectAdded() is called.
_objectAdded(), _objectChanged(), and _objectDeleted() are mutually
exclusive within a given transaction.  That is, only one of them occurs in
a given transaction.  See more below.


Maybe some more code will help (just the important pieces):

def _objectAdded(self,client):
""" store cached data in database """

   ... here we do an sql query to insert things in database ...

def _objectChanged(self,client):
""" store cached data in database """

   ... here we do an sql query to update things in database ...

def _objectAdding(self,client,
_tmap={ None:AddedStatus,
DeletedStatus:ChangedStatus,
ChangedStatus:AddedStatus
}
):
t = client._getTokenFor(self)
s = t.status
t.status = _tmap.get(s,s)

# we need to do a commit here in order to store the record into
the database!
   # and we need to have it stored as an AttributeFor() of the primary key will
   # return None otherwise (as this also just makes a query).
client.commitSubtransaction()

This is broken.  Don't do this!  commitSubtransaction() is an
application-level operation.  Only.  If you have to use it inside of
provider-level code or code called from SkinScript, chances are that you
are doing something horribly wrong.  You run the risk of causing a
recursive commit operation in the Zope transaction machinery.  Don't do this!



def _SetAttributeFor(self,client,name,value):
"""Set the attribute and return true if successful"""
   # attribs stores the attributes we care about
if name in self._attribs.keys():
client._getCache()[name]=value
client.__dict__[name]=value; 
   client._p_changed = 1
return 1
return None

This also looks broken to me.  Why are you changing both the cache and the
persistent state?  There's no reason to do both.



So _objectChanging() is not overridden, the rest I have ommitted..

So as you also can see I already do a subtransaction commit but it does
not seem to help for this problem.. 


I think you're seriously over-engineering this.  I don't see anything that
you're doing here that couldn't be done more easily with SkinScript
statements.  If all you want to do is store the data in an SQL database, a
few SkinScript triggers would suffice.

Now, if you're trying to get a row to be inserted in an SQL database at the
actual time of the newItem() call, there is a trick you can use to do that
from SkinScript also.  Do this:

INITIALIZE OBJECT WITH someAttr1=default1,
someAttr2=default2,...,dummyAttributeName=myInsertQuery(primaryKey=self.id)

Where myInsertQuery() is an SQL insert query that takes primaryKey as a
parameter, and dummyAttributeName is some attribute name you don't care
about.  You should also set any default values for fields that will be
inserted.  Your insert query will be called, initializing the row in the
database, and then use something like this:

WHEN OBJECT ADDED,CHANGED STORE foo,bar,baz USING
UpdateMethod(widget_id=self.id, foo_field=self.foo, wbar=self.bar)


To update the data at transaction commit time.  Voila.  No need to make any
custom attribute providers just to do this.

Just to clarify the event sequence that should take place:

1. newItem() is called, which fires an _objectCreating() event

1.1. The SkinScript INITIALIZE OBJECT statement is triggered by the
_objectCreating() event, and calls myInsertQuery() to insert a row in the
database, with default values for everything but the primary key.

1.2. newItem() fires an _objectAdding() event, which does nothing except
flag the object as "AddedStatus" and pass the event back to the DataManager
(Rack).

1.3. The Rack passes the _objectAdding() event to all appropriately
registered providers.  The WHEN OBJECT ADDED,CHANGED statement is such a
provider, so it receives the message and notes that the DataSkin was added,
but does not act on it yet.  Instead, it registers a proxy for itself with
the Zope transaction object so that it will be notified of transaction commit.

2. newItem() returns a new DataSkin to your application, bearing the
contents set up by the INITIALIZE OBJECT WITH statement.

3. Your application calls manage_changeProperties, to change an attribute.

3.1. The DataSkin fires an _objectChanging() event, which flags the object
as "ChangedStatus", and the event is propagated to all registered providers
in the Rack.  (Such as the WHEN OBJECT statement)

3.2. The WHEN OBJECT statement ignores the _objectChanging() event, because
from its point of view the object is in AddedStatus.

3.3. The DataSkin calls 

Re: [Zope-dev] ZPatterns AttributeProvider question

2001-04-22 Thread Phillip J. Eby

At 08:29 PM 4/22/01 +0200, Christian Scholz wrote:
Hi!

A little update..

Actually I was mistaken and SetAttributeFor() is called. Just
_objectChanged()
is not called in that case.. and thus my attributes are not stored to the
database.

When an object is newly added, only _objectAdded() is called.
_objectAdded(), _objectChanged(), and _objectDeleted() are mutually
exclusive within a given transaction.  That is, only one of them occurs in
a given transaction.  See more below.


Maybe some more code will help (just the important pieces):

def _objectAdded(self,client):
""" store cached data in database """

   ... here we do an sql query to insert things in database ...

def _objectChanged(self,client):
""" store cached data in database """

   ... here we do an sql query to update things in database ...

def _objectAdding(self,client,
_tmap={ None:AddedStatus,
DeletedStatus:ChangedStatus,
ChangedStatus:AddedStatus
}
):
t = client._getTokenFor(self)
s = t.status
t.status = _tmap.get(s,s)

# we need to do a commit here in order to store the record into
the database!
   # and we need to have it stored as an AttributeFor() of the primary key will
   # return None otherwise (as this also just makes a query).
client.commitSubtransaction()

This is broken.  Don't do this!  commitSubtransaction() is an
application-level operation.  Only.  If you have to use it inside of
provider-level code or code called from SkinScript, chances are that you
are doing something horribly wrong.  You run the risk of causing a
recursive commit operation in the Zope transaction machinery.  Don't do this!



def _SetAttributeFor(self,client,name,value):
"""Set the attribute and return true if successful"""
   # attribs stores the attributes we care about
if name in self._attribs.keys():
client._getCache()[name]=value
client.__dict__[name]=value; 
   client._p_changed = 1
return 1
return None

This also looks broken to me.  Why are you changing both the cache and the
persistent state?  There's no reason to do both.



So _objectChanging() is not overridden, the rest I have ommitted..

So as you also can see I already do a subtransaction commit but it does
not seem to help for this problem.. 


I think you're seriously over-engineering this.  I don't see anything that
you're doing here that couldn't be done more easily with SkinScript
statements.  If all you want to do is store the data in an SQL database, a
few SkinScript triggers would suffice.

Now, if you're trying to get a row to be inserted in an SQL database at the
actual time of the newItem() call, there is a trick you can use to do that
from SkinScript also.  Do this:

INITIALIZE OBJECT WITH someAttr1=default1,
someAttr2=default2,...,dummyAttributeName=myInsertQuery(primaryKey=self.id)

Where myInsertQuery() is an SQL insert query that takes primaryKey as a
parameter, and dummyAttributeName is some attribute name you don't care
about.  You should also set any default values for fields that will be
inserted.  Your insert query will be called, initializing the row in the
database, and then use something like this:

WHEN OBJECT ADDED,CHANGED STORE foo,bar,baz USING
UpdateMethod(widget_id=self.id, foo_field=self.foo, wbar=self.bar)


To update the data at transaction commit time.  Voila.  No need to make any
custom attribute providers just to do this.

Just to clarify the event sequence that should take place:

1. newItem() is called, which fires an _objectCreating() event

1.1. The SkinScript INITIALIZE OBJECT statement is triggered by the
_objectCreating() event, and calls myInsertQuery() to insert a row in the
database, with default values for everything but the primary key.

1.2. newItem() fires an _objectAdding() event, which does nothing except
flag the object as "AddedStatus" and pass the event back to the DataManager
(Rack).

1.3. The Rack passes the _objectAdding() event to all appropriately
registered providers.  The WHEN OBJECT ADDED,CHANGED statement is such a
provider, so it receives the message and notes that the DataSkin was added,
but does not act on it yet.  Instead, it registers a proxy for itself with
the Zope transaction object so that it will be notified of transaction commit.

2. newItem() returns a new DataSkin to your application, bearing the
contents set up by the INITIALIZE OBJECT WITH statement.

3. Your application calls manage_changeProperties, to change an attribute.

3.1. The DataSkin fires an _objectChanging() event, which flags the object
as "ChangedStatus", and the event is propagated to all registered providers
in the Rack.  (Such as the WHEN OBJECT statement)

3.2. The WHEN OBJECT statement ignores the _objectChanging() event, because
from its point of view the object is in AddedStatus.

3.3. The DataSkin calls 

Re: [Zope-dev] ZPatterns AttributeProvider question

2001-04-22 Thread Christian Scholz

Hi!

Just a quick note as it's quite late already (more tomorrow):

 In the early days of ZPatterns, I assumed that I would create SQL
 providers, LDAP providers, and suchlike gizmos.  Later, it became clear
 that it was more useful to have a simple "glue" language to allow
 harnessing the full power of Zope in the context of events happening to
 objects.  I still toy with the idea of making an "SQL attribute provider",
 however, that would be based on the ZSQLMethod object and add some
 ZPatterns hooks to it, but it's not a big priority.  Its main value would
 be to cut down on some repetitive typing between one's SQL statements and
 SkinScript statements.

Well, exactly this was the intention of programming this as I was a bit
bored by all this typing, exactly when the attribute lists are getting 
longer. So right now I define it once in the ZClass, press the "Read
ZCLass propsheet" button and the my attribute provider sets everything
up itself..
(it also saves me from typing errors..)

Actually I did it with SkinScript before but thought some simple plugin
would be nicer..

But thanks for explaining the inner workings in some more detail (maybe
I should put this into some howto or so? or it might be put into the
ZPatterns wiki..), as this really should help (not only me I guess :)

I will comment more on this tomorrow.. 
(at least I got some idea how I might solve my problem... though I thought this
some times before already.. ;-)

And the other possible option would be (as Steve suggested once on IRC) to create
some wizard which sets up all the SkinScript methods and ZSQL methods in one
go.. 

Anyway, more about it tomorrow.

good nite..
  Christian

-- 
COM.lounge  http://comlounge.net/
communication  design [EMAIL PROTECTED]

___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



[Zope-dev] .zexp's

2001-04-22 Thread Zopista

Just ran into a problem with a newbie where they couldnt figure out where to
import the zexp, if its a product it should go in /Control_Panel/Products,
if not it should go in the ZODB. I couldn't think of an obvious way to tell,
so I just had a look in the zexp and came up with this:

file = open(infile, 'r')
if string.find(file.readline(), 'App.Product') = 0:
print "%s is a product zexp, go to Control_Panel" % infile

Can anyone think of a better way? It would be figure out where to stick this
in ExportImport.py so it would give nicer error messages...

Cheers
--
  Andy McKay



___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



[Zope-dev] [] vs () in dtml-in: is this a bug ?

2001-04-22 Thread Stefane Fermigier

Hi,

please try this as a DTML Method:

dtml-let l=[[1, 2], [3, 4]]
dtml-in l
  dtml-var _['sequence-item']br
/dtml-in
/dtml-let
 
dtml-let l=[(1, 2), (3, 4)]
dtml-in l
  dtml-var _['sequence-item']br
/dtml-in
/dtml-let

Why should the two results differ ?

S.

-- 
Stéfane Fermigier, Tel: 06 63 04 12 77 (mobile).
http://nuxeo.com/  http://portalux.com/  http://aful.org/
Amazon: we patent the dot in .com

___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists -
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] [] vs () in dtml-in: is this a bug ?

2001-04-22 Thread Steve Alexander

Stefane Fermigier wrote:

 Hi,
 
 please try this as a DTML Method:
 
 dtml-let l=[[1, 2], [3, 4]]
 dtml-in l
   dtml-var _['sequence-item']br
 /dtml-in
 /dtml-let

 dtml-let l=[(1, 2), (3, 4)]
 dtml-in l
   dtml-var _['sequence-item']br
 /dtml-in
 /dtml-let
 
 Why should the two results differ ?


This is a designed-in feature of dtml-in.

When you call an items() method on a dictionary-like object, you get 
back a list of two-tuples: [(key1,value1), (key2,value2, ...]

It is often nice to iterate through such a list in dtml, so, dtml-in 
detects that the next item in the iteration is a two-tuple, and puts the 
elements of the tuple in sequence-key and sequence-item.

  If you look throughthe zope-dev list archives, you'll find a number of 
arguments on each side as to whether this is a bug or a feature.

--
Steve Alexander
Software Engineer
Cat-Box limited



___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )



Re: [Zope-dev] [] vs () in dtml-in: is this a bug ?

2001-04-22 Thread Stefane Fermigier

On Sun, Apr 22, 2001 at 01:16:57PM +0100, Steve Alexander wrote:
 
   If you look throughthe zope-dev list archives, you'll find a number of 
 arguments on each side as to whether this is a bug or a feature.

Thanks. I definitely call that a bug.

S.

-- 
Stéfane Fermigier, Tel: +33 (0)6 63 04 12 77 (mobile).
http://nuxeo.com/  http://portalux.com/  http://aful.org/
Amazon: we patent the dot in .com

___
Zope-Dev maillist  -  [EMAIL PROTECTED]
http://lists.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists -
 http://lists.zope.org/mailman/listinfo/zope-announce
 http://lists.zope.org/mailman/listinfo/zope )