[Python-Dev] constant/enum type in stdlib (original) (raw)
Michael Foord fuzzyman at voidspace.org.uk
Wed Nov 24 13:30:15 CET 2010
- Previous message: [Python-Dev] constant/enum type in stdlib
- Next message: [Python-Dev] constant/enum type in stdlib
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 23/11/2010 14:16, Nick Coghlan wrote:
On Tue, Nov 23, 2010 at 11:50 PM, Michael Foord <fuzzyman at voidspace.org.uk> wrote:
PEP 354 was rejected for two primary reasons - lack of interest and nowhere obvious to put it. Would it be so bad if an enum type lived in its own module? There is certainly more interest now, and if we are to use something like this in the standard library it has to be in the standard library (unless every module implements their own private Constant class).
Time to revisit the PEP? If you (or anyone else) wanted to revisit the PEP, then I would advise trawling through the standard library looking for constants that could be sensibly converted to enum values.
Based on a non-exhaustive search, Python standard library modules currently using integers for constants:
re - has flags (OR'able constants) defined in sre_constants, each flag has two names (e.g. re.IGNORECASE and re.I)
os has SEEK_SET, SEEK_CUR, SEEK_END - plus those implemented in posix / nt
doctest has its own flag system, but is really just using integer flags / constants (quite a few of them)
token has a tonne of constants (autogenerated)
socket exports a bunch of constants defined in _socket
gzip has flags: FTEXT, FHCRC, FEXTRA, FNAME, FCOMMENT
errno (builtin module)
EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, EINVAL, ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EBADF, ECONNABORTED
- opcode has HAVE_ARGUMENT, EXTENDED_ARG. In fact pretty much the whole of opcode is about defining and exposing named constants
- msilib uses flag constants
- multiprocessing.pool - RUN, CLOSE, TERMINATE
- multiprocessing.util - NOTSET, SUBDEBUG, DEBUG, INFO, SUBWARNING
- xml.dom and xml.dom.Node (in init.py) have a bunch of constants
- xml.dom.NodeFilter.NodeFilter holds a bunch of constants (some of them flags)
- xmlrpc.client has a bunch of error constants
- calendar uses constants to represent weekdays, plus one for the EPOCH that is best left alone
- http.client has a tonne of constants - recognisable as ports / error codes though
- dis has flags in COMPILER_FLAG_NAMES, which are then set as locals in inspect
- io defines SEEK_SET, SEEK_CUR, SEEK_END (same as os)
Where constants are implemented in C but exported via a Python module (the constants exported by os and socket for example) they could be wrapped. Where they are exported directly by a C extension or builtin module (e.g. errno) they are probably best left.
Raymond feels that having an enum / constant type would be Javaesque and unused. If we used it in the standard library the unused fear at least would be unwarranted. The change would be largely transparent to developers, except they get better debugging info. Twisted is also looking for an enum / constant type:
http://twistedmatrix.com/trac/ticket/4671
Because we would need to subclass from int for backwards compatibility we can't (unless the base class is set dynamically which I don't propose) it couldn't replace float / string constants. Hopefully it would still be sufficient to allow Twisted to use it. (Although they do so love reimplementing parts of the standard library - usually better than the standard library it has to be said.)
All the best,
Michael
There are a tonne of constants that are used as numbers (MAX_LINE_LENGTH appears in a few places) and aren't just arbitrary constants. There are also some other interesting ones:
- pty has STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, CHILD
- poplib has POP3_PORT, POP3_SSL_PORT - recognisable as port numbers, should be left as ints
- datetime.py has MINYEAR and MAXYEAR
- colorsys has float constants
- tty uses constants for termios list indexes (used as numbers I guess)
- curses.ascii has a whole bunch of integer constants referring to ascii characters
- Several modules - decimal, concurrent.futures, uuid (and now inspect) already use strings
A decision would also need to be made as to whether or not to subclass int, or just provide index (the former has the advantage of being able to drop cleanly into OS level APIs that expect a numerical constant).
Whether enums should provide arbitrary name-value mappings (ala C enums) or were restricted to sequential indices starting from zero would be another question best addressed by a code survey of at least the stdlib. And getgeneratorstate() doesn't count as a use case, since the ordering isn't needed and using string literals instead of integers will cover the debugging aspect :) Cheers, Nick.
--
READ CAREFULLY. By accepting and reading this email you agree, on behalf of your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies (”BOGUS AGREEMENTS”) that I have entered into with your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.
- Previous message: [Python-Dev] constant/enum type in stdlib
- Next message: [Python-Dev] constant/enum type in stdlib
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]