Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Restrictive APIs for Python

Reply
Thread Tools

Restrictive APIs for Python

 
 
Will Ware
Guest
Posts: n/a
 
      12-15-2006
Python has no inherent provision for a restrictive API that blocks
accesses to methods and variables outside an allowed set.
Inexperienced Python programmers may fail to adhere to an agreed-upon
API, directly accessing the private internals of a class. Adherence to
defined APIs is a good thing. This function allows a class to specify
its API, and raise AttributeErrors for disallowed accesses.

def restrictiveApi(klas):
class newklas:
def __init__(self, *args):
self.__inst = apply(klas, args)
def __getattr__(self, attr):
# If the attribute is in the permitted API, then return
# the correct thing, no matter who asks for it.
#
if attr in self.__inst._PUBLIC:
return getattr(self.__inst, attr)
# If the attribute is outside the permitted API, then
# return it only if the calling class is in the list of
# friends. Otherwise raise an AttributeError.
#
elif hasattr(self.__inst, '_FRIENDS'):
# find the class of the method that called us
try:
raise Exception
except:
import sys
tb = sys.exc_info()[2]
callerClass = tb.tb_frame.f_back.\
f_locals['self'].__class__
# if it's a friend class, return the requested thing
if callerClass.__name__ in self.__inst._FRIENDS:
return getattr(self.__inst, attr)
# if not a friend, raise an AttributeError
raise AttributeError, attr
return newklas

To use this, a class needs to define two class variables, _PUBLIC and
_FRIENDS, both being lists (or tuples) of strings. The _PUBLIC list
gives the names of all methods and variables that should be considered
public, i.e. any other class may use them. The _FRIENDS list gives the
names of classes that are allowed free access to all methods and
variables in the protected class. The _FRIENDS list is optional.

Having defined _PUBLIC and optionally _FRIENDS, use something like the
following to protect your class. Restricting the API will incur a
performance overhead, so it's best to do it under the control of some
sort of debug flag.

if debug_flag:
from restrictive import restrictiveApi
MyClass = restrictiveApi(MyClass)

======== Examples ==========

class ClassUnderTest:
# This class has a private variable called privateX. It can be
# set using the setX() method or gotten using the x() method.
# If another class appears in the _FRIENDS list, that class
# can access privateX directly.
#
_PUBLIC = ('x', 'setX')
_FRIENDS = ('FriendClass',)
def __init__(self, x): # __init__ is always callable by anybody
self.setX(x)
def x(self): # callable by anybody
return self.privateX
def setX(self, x): # callable by anybody
self.privateX = x

ClassUnderTest = restrictiveApi(ClassUnderTest)

class FriendClass:
def getX(self, cut):
return cut.privateX # this works fine

class StrangerClass:
def getX(self, cut):
return cut.privateX # this raises an AttributeError

 
Reply With Quote
 
 
 
 
Gabriel Genellina
Guest
Posts: n/a
 
      12-15-2006
On 15 dic, 11:31, "Will Ware" <(E-Mail Removed)> wrote:
> Python has no inherent provision for a restrictive API that blocks
> accesses to methods and variables outside an allowed set.
> Inexperienced Python programmers may fail to adhere to an agreed-upon
> API, directly accessing the private internals of a class.


In Python, the usual way of saying "don't play with me" is prepending
an underscore: _private
BTW, have you *ever* tested your code?

--
Gabriel Genellina

 
Reply With Quote
 
 
 
 
Roberto Bonvallet
Guest
Posts: n/a
 
      12-15-2006
Will Ware wrote:
> Python has no inherent provision for a restrictive API that blocks
> accesses to methods and variables outside an allowed set.
> Inexperienced Python programmers may fail to adhere to an agreed-upon
> API, directly accessing the private internals of a class.


Just don't document those private internals.
Or document that they must not be accessed directly.

--
Roberto Bonvallet
 
Reply With Quote
 
Will Ware
Guest
Posts: n/a
 
      12-15-2006
Gabriel Genellina wrote:
> In Python, the usual way of saying "don't play with me" is prepending
> an underscore: _private


Thanks, I am familiar with that.

> BTW, have you *ever* tested your code?


Yes, we have a QA process. The problem is not that the code doesn't
work, it does. It was developed by a mix of more and less experienced
programmers, and early in the code's history, some hadn't been trained
on the benefits of complying to an API, or Pythonic idioms like the
leading underscore. So the code varies in its clarity, and some
maintenance chores aren't as pleasant as they might be.

I have found that the work of more experienced programmers often
includes improving the quality of code written by less experienced
programmers. Is this inconsistent with your own experience?

 
Reply With Quote
 
Gabriel Genellina
Guest
Posts: n/a
 
      12-15-2006
On 15 dic, 13:46, "Will Ware" <(E-Mail Removed)> wrote:
> Gabriel Genellina wrote:
> > In Python, the usual way of saying "don't play with me" is prepending
> > an underscore: _private

> Thanks, I am familiar with that.

So enforce it instead of going against the nature of the language.

> > BTW, have you *ever* tested your code?

> Yes, we have a QA process.
> The problem is not that the code doesn't
> work, it does.


Does it?

>>> c = ClassUnderTest(1)
>>> print c

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 22, in __getattr__
KeyError: 'self'
>>>


Even if you try to correct this, c is no more an instance of the
intended class, it's a "newklas" now, so isinstance() wont work
anymore. It has lost his docstring so you don't know its purpose and
intended usage anymore; you cannot inspect its methods using dir() so
editors and other tools can't help you writting and documenting code.
And a lot of other things upon which a lot of Python programs relies
on.
Don't go *against* the language, learn to use it the right way on your
own advantage.

> It was developed by a mix of more and less experienced
> programmers, and early in the code's history, some hadn't been trained
> on the benefits of complying to an API, or Pythonic idioms like the
> leading underscore. So the code varies in its clarity, and some
> maintenance chores aren't as pleasant as they might be.

You can use tools like pylint or pychecker to try to detect and fix
those issues.

> I have found that the work of more experienced programmers often
> includes improving the quality of code written by less experienced
> programmers. Is this inconsistent with your own experience?

If the less experienced guys get the feedback, I feel that's Ok.
Just cut them a finger phalanx each time someone breaks the rules and
see how well your programmers behave

--
Gabriel Genellina

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re:Least Restrictive Censorship Laws In The World? Heidy Computer Support 10 04-04-2007 08:45 PM
New to Subclipse Behind Restrictive Firewall & RA layer request failed DRS.Usenet@sengsational.com Java 1 12-06-2006 01:34 AM
RE: x64 license - Why is it so restrictive ? =?Utf-8?B?TURLXzE4Nw==?= Windows 64bit 2 05-10-2005 07:26 PM
Most restrictive type Vijay Kumar R Zanvar C Programming 6 06-02-2004 02:13 PM
restrictive software Lou Computer Support 4 06-24-2003 05:12 PM



Advertisments