Repository navigation
Decide the fate of enum.bin #136763
Description
Activity
- addedstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorydocsDocumentation in the Doc dirDocumentation in the Doc dir
on Jul 18, 2025 Please do not throw multiple things into one issue. The comment can just be a PR if you have a suggestion. For the function, I use this issue.
CC @ethanfurman
- changed the title
[-]A few things to correct in the enum module[/-][+]Undocumented bin() in enum[/+]on Jul 18, 2025 Indeed, it would feel weird for a user to use from enum import * and have the standard bin() function overriden
This wouldn't happen as the module defines an
__all__which, in this case, doesn't re-exportbin. So users importing the module wouldn't be annoyed (or they must access it explicitly). Now, I don't know if it's was an oversight that we didn't documentbinor not. Ethan, hasbinever been considered part of the public API?The nonsense in this code, present in the class EnumCheck, is the comment about powers of 1.
This is indeed a typo, probably because it was copy-pasted from above.
Broadlier speaking, I do not see a valid reason for the import of builtins in the enum module, because it is bad practice: the only use case is builtin functions having been redefined inside the code, which is a source of confusions and errors and therefore not good practice.
Sometimes practility beats purity. If the function was meant to be public,
enum.binis clearer than anything else (it's really the same asbinwith a few tweaks; callingenum_binwould be overly verbose IMO).I understand, but it doesn't feel to me like it's meant to be public in this case. Because this function is not the kind of things one would expect to find in a module about enumerations.
As a utility function that is meant only for enums, this is the place where one would expect. It can be a helper for people who want to subclass the enum type itself. However, if it was meant to be private, we need to first deprecate it (it's publicly named and we could break stuff) and the make it private. If it was meant to be part of the public API, then we should document it. I don't really know whether it was meant to be private or not though.
Concerning the import to builtins, I think it's really because of
enum.property, which is however documented: https://docs.python.org/3/library/enum.html#enum.property, so this is why we need to importbuiltinsto be able to use it internally (here, we can't change the name of this exposed function without going through a deprecation period and probably a Discourse post and lots of discussions).- changed the title
[-]Undocumented `enum.bin`[/-][+]Decide the fate of `enum.bin`[/+]on Jul 18, 2025 If we document enum.bin, I think we can use the docstring. It looks explaining enough to me:
`"""
Like built-in bin(), except negative values are represented in
twos-compliment, and the leading bit always indicates sign
(0=positive, 1=negative).>>> bin(10) '0b0 1010' >>> bin(~10) # ~10 is -11 '0b1 0101' """`We would just need to correct the spelling mistake: it's two's complement and not compliment
Yes, but I first want to know if it was meant to be public (which is why I changed the issue's title).
We could maybe ask @ethanfurman , who made the initial commit. His last commit to enum.py is from July, 10. And it look's on his contribution activity that he's still active
Though he may not remember what he thought back in 2021, date of the initial commit
Looking at previous discussion, I do not see a mention of enum.bin in the initial commit nor in the pull request that came along ( #24215)
For information: I splitted this issue in 2. one fro enum.bin (this one) and another one for the comment
When a module has an
__all__, that is the public API. Any functions not in__all__do not need a leading underscore. I do intend forenum.bin()to become public at some point -- I suppose 3.15 will do.Reacted by Serhiy Storchaka and Brian SchubertActually, I just saw that
propertyis exposed in__all__. May I suggest that we don't exposebinlike that as it can shadows built-ins? I don't think it has ever been an issue in practice but this should probably avoided (the OP did mention the possibility forbinto shadow the built-inbin).Unfortunately, I don't think we can change
propertybeing in__all__in a backwards compatible manner as we can't really know whether someone is havingfrom enum import *and@propertysomewhere, without knowing that this@propertyis actually@enum.property(maybe their tests don't cover it).But if we could avoid making the same thing with
bin, I think it would be preferrable (enumcan definitely be imported in anutil.pyfile that usesbinfor some reasons as well).Using
from some_module import *on a module not designed for that usage is bad practice, and theenummodule was not designed with that usage in mind.Reacted by Serhiy StorchakaBut the fact that it has an
__all__means that it should be supported right? or at least that's what I always thought. Maybe we should document that it is not recommended to do it (I don't know if it's not already documented)__all__has more than one function. It specifies the names for star-import, and it also specifies the public interface shown inpydoc. So names can be added to__all__for the sake ofpydoc. It does not mean that using star-import with that module is recommended.On the other hand, sometimes (in rare cases) public names are intentionally not added to
__all__if using star-import with a module is common.I actually thought that
from enum import *was a quite well-used pattern as it's common forenumto be imported with two members (the type and auto), no members (and useenum.*) or more than two members (in which case we have a very long list of members and maybe usingenum.*would make the line length overflows).However, https://grep.app/search?q=from%20enum%20import%20* shows that the pattern is quite rare actually! so maybe we don't even need to document it and we can leave the warning to linters instead (as their warnings are usually read more often that the online docs I think).
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsNo status
- StatusShow more project fieldsTodo
First, this module defines a bin function that is not present in the documentation. Such a method should be documented or made private. Indeed, it would feel weird for a user to use
from enum import *and have the standard bin() function overriden.The commit that introcuced this function is #7aaeb2a
This function only appears to have be used by the commit for Flag.missing, where it's present two or three times
Thus, i guess this function was created for internal code refactorisation.
This is a normal use for a function. However, a function used for this should not be available to an importer of enum. It should especially not be able to cause problems in the code of the importer.
I suggest renaming the function _bin and replacing existing occurences of call to this function by a call to its new name.
Broadlier speaking, I do not see a valid reason for the import of builtins in the enum module, because it is bad practice: the only use case is builtin functions having been redefined inside the code, which is a source of confusions and errors and therefore not good practice.
This probably means they're other problems like this in the enum module. One I found is the decorator
@property. I did not investigated this one further.