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