On Tue, Aug 31, 2021 at 12:09 AM Stephen J. Turnbull <stephenjturnbull@gmail.com> wrote:
*sigh* __members__ is just the mechanism.  As a consequence, Enums are
iterable, and they automatically DTRT with dir() and help() even if
there are no docstrings.

but you didn't say dir(), you said __members__ ;-)

But my bad, yes, dir() is easy and obvious, and works.

As for help() -- for some reason, I never use it -- not sure why. I do use iPython's ?, which gives me:

In [15]: NaNflag?

Init signature:

NaNflag(

    value,

    names=None,

    *,

    module=None,

    qualname=None,

    type=None,

    start=1,

)

Docstring:      An enumeration.

File:           /Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/enum.py

Type:           EnumMeta
Subclasses: 

which is not that useful, because the docstring is pretty worthless.

help() on the other hand, is useful:

class NaNflag(enum.Enum)
 |  NaNflag(value, names=None, *, module=None, qualname=None, type=None, start=1
)
 |  
 |  An enumeration.
 |  
 |  Method resolution order:
 |      NaNflag
 |      enum.Enum
 |      builtins.object
 |  
 |  Data and other attributes defined here:
 |  
 |  Propogate = <NaNflag.Propogate: 3>
 |  
 |  Raise = <NaNflag.Raise: 1>
 |  
 |  Skip = <NaNflag.Skip: 2>
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from enum.Enum:
 
 |  name
 |      The name of the Enum member.
 |  
 |  value
 |      The value of the Enum member.
 |  
 |  ----------------------------------------------------------------------
 |  Readonly properties inherited from enum.EnumMeta:
 |  
 |  __members__
 |      Returns a mapping of member name->value.
 |      
 |      This mapping lists all enum members, including aliases. Note that this
 |      is a read-only view of the internal mapping.

 
Hmm - maybe that's why I don't use help() much -- If an object has a decent docstring, I'd rather not see all that other cruft :-)

So if you want a well documented Enum, you need to write a docstring, which is, or course, the case with everything in Python, so no problem there.

(though a nice auto-generated docstring would be good -- maybe a feature request for the future)

I've been convinced, Enums do provide a nice way to document flag options. But unfortunately, it doesn't put that documentation where I'd want it -- in the docstring of the functions that use it.
 
DRY is hard with documentation -- this reminds me of when there's a big class hierarchy, and you have go read the docs way up the tree to know how to use a class.

Now show me how to do any of those with str
codes.

In that case, the documentation needs to go in the docstring of the function where they are used, which is where I want it anyway.

That's a documentation style matter, though.  Since just about every
function in the statistics package will take the 'nans' argument, not
only the writer, but most readers of the documentation will favor
DRYing it once, IMHO YMMV.

I don't think readers will have a preference for having something documented in one place that is not the place you actually use it. They WILL appreciate that all functions in the statistics package work the same way though, that's for sure.

Anyway, I was expressing a preference, and I still have that preference, but Enums are a fine option as well.  And the proposed idea of using the string value for the Enum, so that users can use either has its appeal.

For me, it's like Lays potato chips; I can't call just one.  Almost
all my use cases call for mean, standard deviation, and median.

hmm, another topic, but computing mean and standard deviation at the same time would make sense.

Bringing back to the decision Steven needs to make:

I still prefer string flags, but there are certainly good arguments to be made for an Enum. If you do go with an Enum, I suggest:

- The flag names are put in the statistics module namespace.
- The Enum gets a good docstring.
- The functions that use the Enum also document the flags and what they mean.
    - to keep that dry, you could automatically insert the Enum docstring into each function's docstring, so that it would be there where users need it.

That's my $ 0.2

-CHB



--
Christopher Barker, PhD (Chris)

Python Language Consulting
  - Teaching
  - Scientific Software Development
  - Desktop GUI and Web Development
  - wxPython, numpy, scipy, Cython