Preventing execution of a method

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Thu Dec 11 14:28:52 EST 2008


Emanuele D'Arrigo a écrit :
> Sorry if I'm a bit thick here...
> 
> can any of the esteemed participant in this noble newsgroup

Ain't that a bit over the border ?-)

> confirm
> that is not possible to prevent a python module's code from executing
> the methods of another module?
> 
> I.e. if I have a class with two methods, doSomethingSafe() and
> doSomethingDangerous(), is there a way to prevent another module from
> executing doSomethingDangerous() but allow the execution of
> doSomethingSafe()?
> 
> My understanding is that in python this is not possible. Can you
> confirm?

Well... If you really want a totally secure, absolute protection of 
doSomethingDangerors, the only way is to run client code on a distinct 
machine (implied : you have a client/server protocol).

Now the question is : do you _really_ need this level of security ?

If you want to "protect" your implementation methods (and other 
attributes FWIW) from python developpers - IOW, to warn them they 
_should_ not use them -, just prepend the name with a single leading 
underscore. Yes, this is just a convention, but it's a very strong one.

If you want to protect some critical attributes (methods or whatever) 
from _accidental_ redefinitions, prepend the name with two underscores. 
This will invoke a name mangling mechanism such that what's internally 
known as __my_attribute or __my_method is only externally (child classes 
or any other code) as _MyClass__my_attribute (resp. _MyClass__my_method).

The next step would require using a lexical closure - IOW, define 
do_something_dangerous *and* all the methods needing access to  it in a 
same function, and make this function return only "safe" functions, ie:

class MyClass(object):
     def private_stuff_inside():
         def do_something_dangerous(self, whatever):
             # code here
         def do_something_safe(self, yadda):
             # code here
             # NB : note the explicit passing of self here
             foo = do_something_dangerous(self, yadda)
             # more code here
         def do_another_safe_thing(self, yadda):
             # code here
             bar = do_something_dangerous(self, yadda)
             # more code here
         return do_something_safe, do_another_safe_thing

     do_something_safe, do_another_safe_thing = private_stuff_inside()
     del private_stuff_inside()


This is not 100% safe, but accessing do_something_dangerous requires 
some work, pretty good Python knowledge (and either access to the source 
code or 'luck' or being very nasty, since there's no simple way to even 
know do_something_dangerous exists). As far as I'm concerned, I'd say 
that it's as safe as a Java so-called "private" method (which can always 
be accessed thru reflexion FWIW...).

If that's still not enough, then *no* existing language will have 
sufficiant protection (hint : how hard is it to get a crack for 
Photoshop ?), and you're back to not even distributing the critical part 
of your code - IOW, have the critical part only live on your own server.

A last word: unless do_something_dangerous *really* do something 
"dangerous"[1] or business-critical[2] - in which cases you just don't 
want to let _anyone_ access your code, not even in byte-compiled form -, 
the two first solutions are good enough. FWIW and as far as I'm 
concerned, I wouldn't even bother using the second one (name mangling) 
unless I really have a pretty good reason to do so.


[1] like controlling a nuclear powerplant, posting all your porns to all 
your addressbook, or such...

[2] IOW : it's your very secret killing algorithm that none of your 
concurrents must learn or your out of business



More information about the Python-list mailing list