Skip to content

Misleading __version__ attribute of modules in standard library #76007

Closed

Description

@abukaj
mannequin
BPO 31826
Nosy @warsaw, @rhettinger, @ncoghlan, @pitrou, @merwok, @encukou, @serhiy-storchaka, @abukaj, @cryvate
PRs
  • bpo-31826: remove unused __version__ from mock.py #17977
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2017-10-20.13:21:04.010>
    labels = ['3.7', 'type-bug', 'library']
    title = 'Misleading __version__ attribute of modules in standard library'
    updated_at = <Date 2020-02-04.10:54:36.743>
    user = 'https://github.com/abukaj'

    bugs.python.org fields:

    activity = <Date 2020-02-04.10:54:36.743>
    actor = 'cryvate'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Library (Lib)']
    creation = <Date 2017-10-20.13:21:04.010>
    creator = 'abukaj'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 31826
    keywords = ['patch']
    message_count = 7.0
    messages = ['304654', '304763', '304765', '304779', '304780', '304823', '361340']
    nosy_count = 9.0
    nosy_names = ['barry', 'rhettinger', 'ncoghlan', 'pitrou', 'eric.araujo', 'petr.viktorin', 'serhiy.storchaka', 'abukaj', 'cryvate']
    pr_nums = ['17977']
    priority = 'normal'
    resolution = None
    stage = 'needs patch'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue31826'
    versions = ['Python 3.7']

    Linked PRs

    Activity

    1. hugovk commented on Sep 8, 2025

      @hugovk
      Member

      Please see #138675 to take care of the straightforward Python modules.

      To follow up: there's some Python ones which use __version__ internally, but some of these can also be deprecated. And there's some C modules to also check.

    2. warsaw commented on Sep 8, 2025

      @warsaw
      Member

      __version__ is used in smtpd.py as the response banner. That should probably just be platform.python_version().

    3. picnixz commented on Sep 8, 2025

      @picnixz
      Member

      Ah yes, I'd like the version in imaplib to be gone. I actually bumped the version in main but there were differences between main and 3.14 (or 3.13 I don't remember) but a bugfix actually was needed for both so they were out of sync (in one branch we had version x.y.z, while in the other we had x.y.(z-1), but the bugfix bumped them both...)

    4. hugovk commented on Sep 9, 2025

      @hugovk
      Member

      Other non-test __version__s in Lib/:

      Lib/_pydecimal.py
      55:__version__ = '1.70'    # Highest version of the spec this complies with

      -> Commented, and needs to stay.

      -> Edit: done in python/cpython#140302 ✅


      Lib/ctypes/__init__.py
      6:__version__ = "1.1.0"
      11:from _ctypes import __version__ as _ctypes_version
      19:if __version__ != _ctypes_version:
      20:    raise Exception("Version number mismatch", __version__, _ctypes_version)

      -> Ensures the version matches that in _ctypes.c. I think both can be deprecated this version check removed in 3.15?

      -> Edit: PR at python/cpython#142679


      Lib/http/server.py
      64:__version__ = "0.6"
      283:    server_version = "BaseHTTP/" + __version__
      686:    server_version = "SimpleHTTP/" + __version__

      -> Only used in this function:

          def version_string(self):
              """Return the server software version string."""
              return self.server_version + ' ' + self.sys_version

      Which is set in the response header:

          def send_response(self, code, message=None):
              ...
              self.send_header('Server', self.version_string())

      Perhaps these can also be deprecated?

      -> Edit: done in python/cpython#142658 ✅


      Lib/imaplib.py
      24:__version__ = "2.60"
      250:                self._mesg('imaplib version %s' % __version__)

      -> Only used in debugging, I think __version__ is fine for deprecation. And we could remove this debug already in 3.15?

              if __debug__:
                  ...
                  if self.debug >= 1:
                      self._mesg('imaplib version %s' % __version__)

      -> Edit: done in python/cpython#140299 ✅


      Lib/urllib/request.py
      133: # used in User-Agent header sent
      134:__version__ = '%d.%d' % sys.version_info[:2]
      396:        client_version = "Python-urllib/%s" % __version__

      -> Edit: Can stay.


      Lib/wsgiref/simple_server.py
      19:__version__ = "0.2"
      23:server_version = "WSGIServer/" + __version__
      73:    server_version = "WSGIServer/" + __version__

      -> Set here:

      server_version = "WSGIServer/" + __version__
      sys_version = python_implementation() + "/" + sys.version.split()[0]
      software_version = server_version + ' ' + sys_version
      
      class ServerHandler(SimpleHandler):
      
          server_software = software_version

      OK to deprecate __version__ and change server_version to f"WSGIServer/{sys_version}" in 3.15?

      -> Edit: PR at python/cpython#142675


      Lib/xmlrpc/client.py
      154:# used in User-Agent header sent
      155:__version__ = '%d.%d' % sys.version_info[:2]
      1108:    user_agent = "Python-xmlrpc/%s" % __version__

      -> Edit: Can stay.

    5. picnixz commented on Sep 9, 2025

      @picnixz
      Member

      Well... actually for urllib, we have the following docs:

      while urllib’s default user agent string is "Python-urllib/2.6" (on Python 2.6). All header keys are sent in camel case.

      So we need to keep it (or document that has now a different form?) I don't think there is a difference between using sys.version_info and platform.python_version here.

      For XMLRPC, I think it's fine to change it as we can override it. We should change the default value use sys.version_info probably. For WSI, since it's a simple server, let's do the same as well. Same for http.server, we should just match the server version with the Python version. Maybe for parsing purposes, I would suggest that we keep BaseHTTP/version:Python/version as it's documented in https://docs.python.org/3/library/http.server.html#http.server.BaseHTTPRequestHandler.server_version.

      For imaplib, I can just deprecate it in 3.14 and remove in 3.15. I don't think anyone has ever relied on it. Also the version depends on the underlying Python version so having the Python version is much more useful.

    6. hugovk commented on Sep 9, 2025

      @hugovk
      Member

      For imaplib, I can just deprecate it in 3.14 and remove in 3.15.

      It's too late to deprecate in 3.14, do you mean deprecate in 3.15? And we're in no rush to remove these, we can stick to the usual two-release policy for removing (so in 3.17).

    7. picnixz commented on Sep 9, 2025

      @picnixz
      Member

      Oh sorry I misunderstood the "And we could remove this debug already in 3.15?" by assuming you wanted to remove the version as well. I'm fine with deprecating them in 3.15 and removing it in 3.17.

    8. smontanaro commented on Sep 9, 2025

      @smontanaro
      Contributor

      @hugovk wrote:

      Lib/_pydecimal.py
      55:version = '1.70' # Highest version of the spec this complies with

      -> Commented, and needs to stay.

      This seems like a poor name to me. Can it change to, say, __spec_version__ so people who come along later don't think it's the module version.

    9. merwok commented on Sep 9, 2025

      @merwok
      Member

      Yes, let’s avoid dunders for things that are not actually defined by the Python documentation.

    10. smontanaro commented on Sep 9, 2025

      @smontanaro
      Contributor

      Yes, let’s avoid dunders for things that are not actually defined by the Python documentation.

      Thanks, even better, SPEC_VERSION?

    11. added a commit that references this issue on Sep 29, 2025
    12. StanFromIreland commented on Oct 12, 2025

      @StanFromIreland
      Member

      @hugovk , the deprecation causes warnings to be raised by pydoc:

      >>> import json
      >>> help(json)
      /usr/local/lib/python3.15/pydoc.py:1385: DeprecationWarning: '__version__' is deprecated and slated for removal in Python 3.20
        if hasattr(object, '__version__'):
      /usr/local/lib/python3.15/pydoc.py:1386: DeprecationWarning: '__version__' is deprecated and slated for removal in Python 3.20
        version = str(object.__version__)
      
      

      Should we just remove the handling of __version__ since it is scheduled for removal anyway, or catch the warnings for now? (I propose the first).

    13. pitrou commented on Oct 12, 2025

      @pitrou
      Member

      Should we just remove the handling of __version__ since it is scheduled for removal anyway

      Eh? pydoc is meant to work with all kinds of modules, not just stdlib modules.

    14. StanFromIreland commented on Oct 12, 2025

      @StanFromIreland
      Member

      Just for stdlib modules, we similarly gate the docs.python.org link generation.

    15. picnixz commented on Oct 12, 2025

      @picnixz
      Member

      Do you mean to catch the warning only for stdlib modules? if so, why not (because we special case the stdlib for the link), otherwise I agree that pydoc is a general tool.

    16. StanFromIreland commented on Oct 12, 2025

      @StanFromIreland
      Member

      Do you mean to catch the warning only for stdlib modules? if so, why not (because we special case the stdlib for the link)

      Yes. I wrote #139997 for this, reusing the logic from getdoclink.

    17. StanFromIreland commented on Oct 14, 2025

      @StanFromIreland
      Member

      I see zlib.__version__ was not deprecated, and I see no mention in this issue as to why, so I assume it was missed. I will open a pr.

    18. added a commit that references this issue on Oct 15, 2025
    19. added a commit that references this issue on Oct 20, 2025
    20. onerandomusername commented on Oct 26, 2025

      @onerandomusername
      Contributor

      Noticed another __version__: http.server.__version__ doesn't seem to have been deprecated.

      Looking into it, it seems to be used by the http.server.SimpleHTTPRequestHandler.server_version attribute.

      __version__ = "0.6"

      I would be willing to make this pull request, following the deprecation guidelines and module level getattr.

      My question is as follows: should the server_version default be changed to be the first two of sys.version_info?
      Should this adjustment happen with 3.15? Or wait until 3.20?

    21. picnixz commented on Oct 26, 2025

      @picnixz
    22. onerandomusername commented on Oct 26, 2025

      @onerandomusername
    23. picnixz commented on Oct 26, 2025

      @picnixz
      Member

      [Oh my bad, I was on mobile and thought you were talking about the class' version]. I don't really know which would be the best but if it hadn't been changed for years, it's better to get rid of it. However, whatever we choose here should be done for XMLRPC and other modules that provide simple servers or handlers as they essentially do the same. This would require a bit more work as we would need to change the docs as well.

    24. added a commit that references this issue on Oct 26, 2025
    25. vstinner commented on Oct 26, 2025

      @vstinner
      Member

      IMO it's a good idea to use the Python version as the HTTP server version.

    26. added a commit that references this issue on Nov 5, 2025
    27. added 2 commits that reference this issue on Nov 5, 2025
    28. added 2 commits that reference this issue on Nov 5, 2025
    29. added 4 commits that reference this issue on Dec 6, 2025
    30. added 2 commits that reference this issue on Dec 13, 2025
    31. hugovk commented on Dec 14, 2025

      @hugovk
      Member

      I think we're done with __version__ once #142675 and #142679 are merged, or are there any more to do?

      There's also a VERSION and a couple of versions we could deprecate:

      VERSION = "1.3.0"

      version = "0.20"

      version = '2.0beta'

      Thoughts?

    32. added a commit that references this issue on Dec 15, 2025
    33. added 2 commits that reference this issue on Dec 16, 2025
    34. added a commit that references this issue on Dec 16, 2025
    35. hugovk commented on Dec 17, 2025

      @hugovk
      Member

      There's also a VERSION and a couple of versions we could deprecate:

      PR #142898 for that, to close this issue.

    36. added a commit that references this issue on Dec 18, 2025
    37. added a commit that references this issue on Dec 18, 2025
    38. added a commit that references this issue on Feb 27, 2026
    39. added a commit that references this issue on Feb 28, 2026
    40. added a commit that references this issue on Apr 25, 2026
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions