RE: [Zope] Modifying __bases__
Out of curiosity, I've noticed the word "evil" attached to patching of various and monkey kinds. Not "bad", or "unwise", but "evil", implying a morality associated with the act. What is morally wrong with modifying live objects in a dynamic language to achieve desired functionality? The idea is "I want to modify the zope core in a way that survives version to version, yet does not impose a specific use case on all zope users". -----Original Message----- From: Tino Wildenhain [mailto:tino@wildenhain.de] Sent: Friday, May 20, 2005 2:38 PM To: Dan Pozmanter Cc: Andreas Jung; zope@zope.org Subject: RE: [Zope] Modifying __bases__ Am Freitag, den 20.05.2005, 13:48 -0400 schrieb Dan Pozmanter:
Well, when I run it, I am able to do the following:
------------------------------------ class A: pass
class B(A): pass
b = B()
B.__bases__ = ()
print B.__bases__ ------------------------------------
Not so on the version that comes with zope. (B.__bases__ will remain unchanged.)
What I aim to do is have the User Object inherit from a custom class (AlienUser).
Well, you can just inherit with a class from zopes extension classes. You cannot modify the class bases like this with extension classes. You can work around that like I did with the history (monkey) patch: http://www.zope.org/Members/tino/PatchHistory/view Otherwise it sounds evil and you failed to show the true motivation with your example above. Tino. PS: Votes for a true implementation in current zope instead of the monkey patch? If so, tell me.
On Fri, May 20, 2005 at 05:10:30PM -0400, Dan Pozmanter wrote:
What is morally wrong with modifying live objects in a dynamic language to achieve desired functionality? The idea is "I want to modify the zope core in a way that survives version to version, yet does not impose a specific use case on all zope users".
I don't want to overgeneralize, but the "moral" issue I have with monkey-patching is illustrated by an anecdote. Once I was attempting to debug a problem with a core Zope product. It was behaving in a baffling fashion that contradicted what the source code was telling me. It was only during a tedious pdb session that I discovered that a third-party product had monkey-patched the method in question. (This turned out not to be the cause of the problem we were having - but the mystery wasted an hour of my time when I was facing a deadline.) The lesson is: python code may be eminently readable, and on this list we are fond of telling users to "use the source" - but a monkeypatch in some obscure corner of an add-on package can turn the source code into a big fat lie. That's evil :-) Of course, sometimes it is a necessary (or at least expedient) evil... sometimes you need a hook where there just isn't one and you have no choice but to bash your way in there like a 500-pound gorilla. So, I monkeypatch, and I feel guilty :-) -PW -- Paul Winkler http://www.slinkp.com
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Dan Pozmanter wrote:
Out of curiosity, I've noticed the word "evil" attached to patching of various and monkey kinds. Not "bad", or "unwise", but "evil", implying a morality associated with the act.
The phrase encodes a bunch of folklore and geek sentiments in a humourous ("half in fun but full earnest") meme: - Monkey patching can invalidate documented APIs and behavior; in this sense, a monkey patch is "taking out a loan" which will be repaid later, either by the original perpetrator or by some other poor schmuck ("Vinny's crowbar *hurts*.") - A monkey patch is often a pure expedience: "Rather than redo *my* software to correct a problem *I* injected, I'll just bash the base software to work around it." In this mode, it is a sign of poor design or quality in the perpetrator's code. - Sometimes, a monkey patch is the only way to address a particular issue without updating the underlying software (most "hotfixes" for security issues involve monkey patching). In this mode, the patch is a sign that the underlying software has a bug, hard-wired some policy that it shouldn't have, or is otherwise defective.
What is morally wrong with modifying live objects in a dynamic language to achieve desired functionality? The idea is "I want to modify the zope core in a way that survives version to version, yet does not impose a specific use case on all zope users".
In general, the use case is fine; we would prefer to address it by making the core software more flexible / configurable, such that it is not necessary to monkey patch. Tres. - -- =================================================================== Tres Seaver tseaver@palladion.com Palladion Software "Excellence by Design" http://palladion.com -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.5 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFCj1B9+gerLs4ltQ4RAmWjAJ97Qvr2xnv5qsCRYC7it4UtHdxvewCg2Zu9 ADCK48Ly7ZMUWbV8E6wS6Q0= =3SS5 -----END PGP SIGNATURE-----
I am creating a CMF product. It is simple and will only have an id, title, description and the ability to upload its content. I am wanting to restrict the files uploaded to a certain mime type, specifically .txt files (plain text). I see many products like this: 'filter_content_types' : 0, 'allowed_content_types': (), but can't seem to find an example where it is creating this kind of restriction Can I use filter_content_type and allowed_content_types in this context to help restrict the type (or should I do my check on the file type somewhere else (or in addition to something else like discovering the mimetype from a method in the mimetypes registry product))? Regards, David
David Pratt wrote at 2005-5-21 12:36 -0300:
I am creating a CMF product. It is simple and will only have an id, title, description and the ability to upload its content. I am wanting to restrict the files uploaded to a certain mime type, specifically .txt files (plain text).
I see many products like this:
'filter_content_types' : 0, 'allowed_content_types': (),
but can't seem to find an example where it is creating this kind of restriction
These are used as defaults for "Filter content types" and "Allowed contents types", respectively, for the type factories (look in "portal_types --> <sometype>"). They have nothing to do with MIME types and uploading. Instead, they control what other types can be contained in a folder like type. -- Dieter
Thanks Dieter for clarifying this. I was not sure and could not find anything on these so thought I would ask. I think I got the idea they might restrict mime types from Archetypes which has a similarly named method. Regards, David On Saturday, May 21, 2005, at 03:10 PM, Dieter Maurer wrote:
David Pratt wrote at 2005-5-21 12:36 -0300:
I am creating a CMF product. It is simple and will only have an id, title, description and the ability to upload its content. I am wanting to restrict the files uploaded to a certain mime type, specifically .txt files (plain text).
I see many products like this:
'filter_content_types' : 0, 'allowed_content_types': (),
but can't seem to find an example where it is creating this kind of restriction
These are used as defaults for "Filter content types" and "Allowed contents types", respectively, for the type factories (look in "portal_types --> <sometype>").
They have nothing to do with MIME types and uploading.
Instead, they control what other types can be contained in a folder like type.
-- Dieter
On Fri, May 20, 2005 at 05:10:30PM -0400, Dan Pozmanter wrote: | Out of curiosity, I've noticed the word "evil" attached to patching | of various and monkey kinds. Not "bad", or "unwise", but "evil", | implying a morality associated with the act. I think it is used mainly to give added emphasis to lessons learned from painful experience. As Paul reported, hours can be wasted tracing the wrong code trying to understand what is happening. | What is morally wrong with modifying live objects in a dynamic language | to achieve desired functionality? The problem is maintainability. When you dynamically rewrite the code, the code is then very difficult to follow, verify, and modify. It is even harder for someone else to maintain the code because they don't have the historical background to rememeber where , what and why the code is dynamically changed. | The idea is "I want to modify the zope core in a way that survives | version to version, yet does not | impose a specific use case on all zope users". The good pattern for handling this is to create a new class that extends the core classes that provide almost the functionality you want. Then, in your part of the database, create an instance of your class instead of the built-in core class. Specifically for your case, extend the basic UserFolder class to create instances of your custom User class instead of the built-in one. It would be good if the UserFolder allowed you to parameterize it so you could simply say "use this User class", but in the absence of that foresight, you can extend the UserFolder clas. HTH, -D -- Whoever loves discipline loves knowledge, but he who hates correction is stupid. Proverbs 12:1 www: http://dman13.dyndns.org/~dman/ jabber: dman@dman13.dyndns.org
participants (6)
-
Dan Pozmanter -
David Pratt -
Derrick Hudson -
Dieter Maurer -
Paul Winkler -
Tres Seaver