[Python-Dev] Type checks of instance variables

Michael McLay mclay@nist.gov
Thu, 11 Oct 2001 13:15:09 -0400


On Wednesday 10 October 2001 05:58 pm, Andy Robinson wrote:

> Let me throw in a few more ideas:
>
> (1) __slots__ could hold optional attribute doc strings
> (2) 'one of a list' is a mightily useful type,
> and we have GUIs that can infer enough from this
> to build smart editing interfaces.
> (3) frequently you want the __slots__ for a class
> to 'inherit' from a parent, which we do by allowing
> one to pass in the parent's class; it then looks
> for the __slots__ in that as a starting point.
> (4) you may also sometimes want to delete things
> from the __slots__ in a derived class, and to reduce
> visibility.

I hope we can use the TypedSlots proposal as a starting point and refine it 
until it also meets the requirements for ReportLab and Grouch.

The following example attempts to add the features you suggested.  It extends 
the original TypedSlots definition to include actions that would be applied 
to slots. Adding type checking actions would simplify writing a number of 
applications, such as validation software for XML Schema. The XML Schema type 
system inspired the Restrict action in the example.  The XML Schema type 
system could be used to identify candidate actions to be added to TypedSlots. 
class Widget(object):
    __slots__ = TypedSlots({ "name": CheckType(str,
                          doc="The name by which a widget can be 
referenced")})

class Color(Widget):
    __slots__ = TypedSlots({ "r": CheckType(unsignedByte, 
                                            default = unsignedByte(0)),
                             "g": CheckType(unsignedByte, 
                                            default = unsignedByte(0)),
                             "b": CheckType(unsignedByte, 
                                            default = unsignedByte(0)),})

class Shape(Widget):
    __slots__ = TypedSlots({ "colorRef": CheckType(Color)})

class Circle(Shape):
    __slots__ = TypedSlots({ "diameter": CheckType(Number,default=1)})
                             

class RedCircle(Circle):
    """Define a type for red Circles.  The Restrict declaration allows
       the "colorRef" name to be restricted to a subset of the allowed
       values of the colorRef name.  In this case a ReadOnly
       flag is set to keep the Circle color from being changed and the
       value is set.
    """
    __slots__ = TypedSlots({"colorRef": Restrict( ReadOnly( Color(r=255)))})

class Drawable(Widget):
    """The OneOf action allows one of several types to be assigned to the
       name.  Most likely all the types share a common interface.
    """
    __slots__ = TypedSlots({"shapeRef":OneOf(Circle, RedCircle,Rectangle)})

    
> (5) things can get slow. I'm also wondering if support
> for type-checking classes could be enhanced by a C
> extension, so that if one stuck to a basic bunch of types,
> the penalty of checking every attribute assignment
> would not be too great.  It would still need to
> call out to Python if the 'checking function' was
> written in Python.

Performance will benefit from making C enhancements. Creating a type 
verification system that can't be hacked (from Python) will require writing 
some of the implementation in C.   The danger in extending the actions of the 
TypedSlots to more than a simple type check on __set__ is that it will become 
to complected to implement in a timely manner.  What is the bare minimum 
required?  Specification languages tend to grow to be ugly monsters. Can we 
start small and add other actions as needed? Could some of the actions be 
defined in a Python module?

>
> Here's one of our classes:
>
> class Marker(Widget):
>     '''A polymorphic class of markers'''
>     _attrMap = AttrMap(BASE=Widget,
>                     kind = AttrMapValue(
>                             OneOf(None, 'Square', 'Diamond',
>                     'Circle', 'Cross', 'Triangle', 'StarSix',
> ...

My project involves capturing the product information for printed circuit 
boards and printed circuit assemblies.  You r example looks like it came 
right out of the definition of the graphics required to by tools that draw 
the layers of a printed circuit board.