Sebastien Roy wrote:
> Max and Cecilia,
>
> This case looks good overall; I'd like a few clarifications and have a
> few questions/comments and nit-picks in-line:
>
> On Tue, 2008-08-12 at 15:40 +0800, Cecilia Hu wrote:
>   
>> 4.2. Python 'dlpi' module
>>
>>      Classification of interfaces provided in this module is 'Committed'.
>>      The on-line help clearly shows all interfaces and their counterparts
>>      of dlpi functions in this module as below:
>>     
>
> In documenting all of the functions, the definition of error semantics
> isn't brought up at all.  For a Committed interface, I would expect that
> to be made explicit.  I've asked some specific questions regarding
> return values in-line, but this is more of a general comment that I
> think needs to be addressed.
>   
In general, error handling in Python code is done by catching the
exception raised by the function it calls. It is required to do so when
writing C extension for Python.
So, in this dlpi module for Python, I followed the requirement by
calling PyErr_SetString(PyExc_OSError, err_code_from_libdlpi_interface)
to raise the exception whenever dlpi interface returns an error.

So, in C, we check return value for error, but, in Python, we raise
exceptions, instead. And PyErr_setString() is the standard way to raise
an exception in C code for other Python code to catch and handle.
>   
>> CLASSES
>>      __builtin__.object
>>          link
>>
>>      class link(__builtin__.object)
>>       |  link(linkname, modes) -> link object
>>       |
>>       |  Open linkname in specified mode.
>>       |  Three modes are supported: PASSIVE, RAW, NATIVE.
>>       |  See dlpi_open(3DLPI).
>>     
>
> in dlpi_open(3DLPI), the "modes" are actually "flags" that can be
> bitwise-OR'ed together to achieve a combination of behaviors
> (DLPI_PASSIVE, DLPI_RAW, and DLPI_NATIVE).  I assume that this is also
> what's intended with "modes", although it isn't made explicit.
>   
Yes, you can OR them. I'll make it more clear in the on-line help text.
> On a related note, I'm no python expert, but aren't symbol names like
> "PASSIVE", "RAW", and "NATIVE" likely to clash with symbols defined by
> other classes potentially imported by an application?
>   
As pointed out by Danek, these symbols is only visible in dlpi class.
>   
>>       |
>>       |  bind(...)
>>       |      bind(sap) -> unsigned int
>>       |
>>       |      Attempts to bind the link to specified sap, or ANY_SAP.
>>       |      Returns the real sap gets bound.
>>       |      See dlpi_bind(3DLPI).
>>     
>
> Suggested rewording: "It returns the SAP that the function actually
> bound to, which could be different from the SAP requested." 
OK.
> Also what
> happens on error?  How does the application differentiate between errors
> and SAP values?
>   
An exception will be raised if there is an error.
>   
>>       |
>>       |  disabmulti(...)
>>       |      disabmulti(address) -> None
>>       |
>>       |      Disable a specified multicast address on this link.
>>       |      See dlpi_disabmulti(3DLPI).
>>     
>
> dlpi_disabmulti() can fail...
>   
An exception will be raised if dlpi_disabmulti() fails.
>   
>>       |
>>       |  enabmulti(...)
>>       |      enabmulti(address) -> None
>>       |
>>       |      Enable a specified multicast address on this link.
>>       |      See dlpi_enabmulti(3DLPI).
>>     
>
> dlpi_enabmulti() can fail, and I think any sane application would want
> to know whether or not enabling multicast reception worked.  Similar
> comment for other functions that don't have error semantics.
>   
An exception will be raised if there is an error. So, application
written in Python can catch the exception and handle the error.
>   
>>       |
>>       |  enabnotify(...)
>>       |      enabnotify(events, function[, arg]) -> unsigned long
>>       |
>>       |      Enables a notification callback for the set of specified 
>> events,
>>       |      which must be one or more (by a logical OR) events listed 
>> as below:
>>       |      NOTE_LINK_DOWN         Notify when link has gone down
>>       |      NOTE_LINK_UP           Notify when link has come up
>>       |      NOTE_PHYS_ADDR         Notify when address changes
>>       |      NOTE_SDU_SIZE          Notify when MTU changes
>>       |      NOTE_SPEED             Notify when speed changes
>>       |      NOTE_PROMISC_ON_PHYS   Notify when DL_PROMISC_PHYS is set
>>       |      NOTE_PROMISC_OFF_PHYS  Notify when DL_PROMISC_PHYS is cleared
>>       |      Returns a handle for this registration.
>>       |      See dlpi_enabnotify(3DLPI).
>>     
>
> What happens if this fails?
>   
An exception will be raised if there is an error, just like others.
>   
>>       |
>>       |  get_bcastaddr(...)
>>       |      get_bcastaddr() -> string
>>       |
>>       |      Returns the broadcast address of the link.
>>       |      See dlpi_info(3DLPI).
>>     
>
> What is the link has no broadcast address?
>   
If dlpi_info() fails (I get broadcast address by calling dlpi_info()),
an exception will be raised accordingly. If dlpi_info() returns no
error, but there is no broadcast address, a string Python object, whose
length is zero, will be returned.
>   
>>       |  recv(...)
>>       |      recv(trunksize[, timeout]) -> (string, string)
>>       |
>>       |      Attempts to receive message over this link.
>>       |      You need to specify the trunk size for the received message.
>>       |      And you can specify timeout value in seconds.
>>       |      Returns (source address, message data).
>>       |      See dlpi_recv(3DLPI).
>>     
>
> If timeout is not specified, does recv() behave as dlpi_recv() would if
> "msec" were 0 or -1 (i.e., does it not block, or does it block forever
> or until a message is received?).
>   
Ah...I did not make it clear. The default value is -1, which means it'll
block forever.
I'll fix the on-line help here.
>   
>>       |
>>       |  send(...)
>>       |      send(destaddr, message[, sap, minpri, maxpri]) -> None
>>       |
>>       |      Attempts to send message over this link to destaddr.
>>       |      You can specify new sap, and priority range (minpri, maxpri).
>>       |      See dlpi_send(3DLPI).
>>     
>
> IMO, "you can specify new sap" is ambiguous.  The idea is that a message
> is sent to the specified destination address and SAP.  If the SAP isn't
> specified as the "sap" argument, then the bound SAP is used instead.  At
> least that's what dlpi_send() does, and I think you want the same
> semantics.
>   
Yes, I'll change the on-line help text to make it clear.
>   
>> DATA
>>      ANY_SAP = 4294967295
>>      CURR_PHYS_ADDR = 2
>>      DEF_TIMEOUT = 5
>>      FACT_PHYS_ADDR = 1
>>      IDLE = 3
>>      NATIVE = 32
>>      NOTE_LINK_DOWN = 8
>>      NOTE_LINK_UP = 16
>>      NOTE_PHYS_ADDR = 1
>>      NOTE_PROMISC_OFF_PHYS = 4
>>      NOTE_PROMISC_ON_PHYS = 2
>>      NOTE_SDU_SIZE = 128
>>      NOTE_SPEED = 256
>>      PASSIVE = 2
>>      PROMISC_MULTI = 3
>>      PROMISC_PHYS = 1
>>      PROMISC_SAP = 2
>>      RAW = 4
>>      UNBOUND = 0
>>      UNKNOWN = -1
>>     
>
> Are the values part of the committed interface?  If not, then I would
> either remove the values from the case materials or explicitly state
> that only the symbol names are committed, and that their values are not
> an interface.
>   
Only the symbol names are committed.
Yes, I need to make it more clear here. Thanks, Seb!

Max
> -Seb
>
>
>   

Reply via email to