This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: pydoc: move __future__ imports out of the DATA block
Type: enhancement Stage: resolved
Components: Documentation, Library (Lib) Versions: Python 3.11
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: docs@python, iritkatriel, serhiy.storchaka, veky
Priority: normal Keywords: patch

Created on 2016-01-15 06:31 by Antony.Lee, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 30888 merged iritkatriel, 2022-01-25 15:46
PR 32180 merged iritkatriel, 2022-03-29 17:56
Messages (15)
msg258272 - (view) Author: Antony Lee (Antony.Lee) * Date: 2016-01-15 06:31
Currently, for a module that uses __future__ imports, the DATA section of `pydoc foo` contains these imports interspersed with the "real" data from the module.

Even though it is fully-featured _Feature objects that are imported, it probably makes sense to move them out of this section.
msg407922 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2021-12-07 11:48
Reproduced on 3.11.
msg407939 - (view) Author: Vedran Čačić (veky) * Date: 2021-12-07 15:15
I thought that _Feature starts with an underscore precisely to evade such listings. Do other "private" module data also get listed?
msg411604 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-01-25 14:48
It's like this:

>>> import foo
>>> dir(foo)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'annotations', 'x']
>>> foo.annotations
_Feature((3, 7, 0, 'beta', 1), (3, 11, 0, 'alpha', 0), 16777216)


So the attribute in foo is called annotations, i.e. it's not private.
msg416086 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2022-03-26 19:59
I am positive about this idea, but we must also think about the possible negative consequences. For example, the future annotations will be included in the star-import by default and can override some global names. The fact that some names not visible in the module help can override global names can be confusing.

I think it should be discussed with a wider auditory.
msg416155 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-03-28 09:51
That's a good point. I see that the __future__ imports appear in the dir() of the module, and indeed they are imported with 'from m import *'. 

But I wonder if that is actually a bug. If you try this:


% cat x.py    

from __future__ import annotations

% cat y.py    
from x import *

print(dir())

class D:
    def f(self, a: D):
        return 42

% ./python.exe y.py    
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'annotations']
Traceback (most recent call last):
  File "/Users/iritkatriel/src/cpython-654/y.py", line 5, in <module>
    class D:
    ^^^^^^^^
  File "/Users/iritkatriel/src/cpython-654/y.py", line 6, in D
    def f(self, a: D):
                   ^
NameError: name 'D' is not defined
--------------------------------------------------


but if you add "from __future__ import annotations" at the top of y.py, then it does run.

So perhaps the future imports should be excluded by "from m import *"?
msg416160 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2022-03-28 11:54
I once proposed to exclude modules from the star import by default, but this proposition was rejected. You can try, maybe your proposition will be more acceptable.
msg416192 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2022-03-28 16:49
Module objects are not shown in the help unless they are submodules of the specified module, even if they are imported with the star import. With this precedence I think it is okay to exclude the __future__ annotations as well.
msg416212 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-03-28 21:03
New changeset 15ba8167d78f9e66bd5b07c4e5cbb0463460310a by Irit Katriel in branch 'main':
bpo-26120: make pydoc exclude __future__ imports from the data block of the module (GH-30888)
https://github.com/python/cpython/commit/15ba8167d78f9e66bd5b07c4e5cbb0463460310a
msg416213 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-03-28 21:04
Thank you, Serhiy!
msg416263 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2022-03-29 14:49
I am sorry that I did not test the changes manually, but it seems that __future__ annotations are now disappeared from the pydoc output for the __future__ module help.

    $ ./python -m pydoc __future__

It is now difficult to get a list of available features from the help.

They should be kept in the DATA section for the __future__ module.
msg416264 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2022-03-29 14:54
Yet one bug: PR 30888 only changed the text output. But there is also the html output generator.
msg416276 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-03-29 17:31
> Yet one bug: PR 30888 only changed the text output. But there is also the html output generator.

I'm not sure - if I revert the change like this:

         if isinstance(getattr(obj, name, None), __future__._Feature):
-            return False
+            pass # return False


then test_html_doc fails:


======================================================================
FAIL: test_html_doc (test.test_pydoc.PydocDocTest.test_html_doc)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/iritkatriel/src/cpython/Lib/test/test_pydoc.py", line 414, in test_html_doc
    self.assertEqual(text_lines, expected_lines)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: Lists differ: ['tes[1392 chars]t]', "print_function = _Feature((2, 6, 0, 'alp[156 chars]ody'] != ['tes[1392 chars]t]', 'type_union1 = typing.Union[int, str]', '[72 chars]ody']

First differing element 55:
"print_function = _Feature((2, 6, 0, 'alp[36 chars]576)"
'type_union1 = typing.Union[int, str]'

First list contains 1 additional elements.
First extra element 61:
'Nobody'

  ['test.pydoc_mod (version 1.2.3.4)',
   'This is a test module for test_pydoc',
   'Modules',
   'types',
   'typing',
   'Classes',
   'builtins.object',
   'A',
   'B',
   'C',
   'class A(builtins.object)',
   'Hello and goodbye',
   'Methods defined here:',
   '__init__()',
   'Wow, I have no function!',
   'Data descriptors defined here:',
   '__dict__',
   'dictionary for instance variables (if defined)',
   '__weakref__',
   'list of weak references to the object (if defined)',
   'class B(builtins.object)',
   'Data descriptors defined here:',
   '__dict__',
   'dictionary for instance variables (if defined)',
   '__weakref__',
   'list of weak references to the object (if defined)',
   'Data and other attributes defined here:',
   "NO_MEANING = 'eggs'",
   "__annotations__ = {'NO_MEANING': <class 'str'>}",
   'class C(builtins.object)',
   'Methods defined here:',
   'get_answer(self)',
   'Return say_no()',
   'is_it_true(self)',
   'Return self.get_answer()',
   'say_no(self)',
   'Class methods defined here:',
   '__class_getitem__(item) from builtins.type',
   'Data descriptors defined here:',
   '__dict__',
   'dictionary for instance variables (if defined)',
   '__weakref__',
   'list of weak references to the object (if defined)',
   'Functions',
   'doc_func()',
   "This function solves all of the world's problems:",
   'hunger',
   'lack of Python',
   'war',
   'nodoc_func()',
   'Data',
   "__xyz__ = 'X, Y and Z'",
   'c_alias = test.pydoc_mod.C[int]',
   'list_alias1 = typing.List[int]',
   'list_alias2 = list[int]',
-  "print_function = _Feature((2, 6, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), "
-  '1048576)',
   'type_union1 = typing.Union[int, str]',
   'type_union2 = int | str',
   'Author',
   'Benjamin Peterson',
   'Credits',
   'Nobody']
msg416284 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2022-03-29 18:59
> Yet one bug: PR 30888 only changed the text output. But there is also the html output generator.

Sorry, I was wrong. The changed code is common for all generators. Perhaps I tested with wrong version.
msg416301 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-03-29 22:07
New changeset 63f32fae79e16e6dc71777bd3fcb623b2c3ff742 by Irit Katriel in branch 'main':
bpo-26120: do not exclude __future__ import in pydoc of the __future__ module itself (GH-32180)
https://github.com/python/cpython/commit/63f32fae79e16e6dc71777bd3fcb623b2c3ff742
History
Date User Action Args
2022-04-11 14:58:26adminsetgithub: 70308
2022-03-29 22:07:47iritkatrielsetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2022-03-29 22:07:23iritkatrielsetmessages: + msg416301
2022-03-29 18:59:53serhiy.storchakasetmessages: + msg416284
2022-03-29 17:56:07iritkatrielsetstage: needs patch -> patch review
pull_requests: + pull_request30258
2022-03-29 17:31:38iritkatrielsetmessages: + msg416276
2022-03-29 14:54:03serhiy.storchakasetmessages: + msg416264
2022-03-29 14:49:04serhiy.storchakasetstatus: closed -> open
resolution: fixed -> (no value)
messages: + msg416263

stage: resolved -> needs patch
2022-03-28 21:04:12iritkatrielsetstatus: open -> closed
resolution: fixed
messages: + msg416213

stage: patch review -> resolved
2022-03-28 21:03:12iritkatrielsetmessages: + msg416212
2022-03-28 16:49:49serhiy.storchakasetmessages: + msg416192
2022-03-28 11:54:59serhiy.storchakasetmessages: + msg416160
2022-03-28 09:51:33iritkatrielsetmessages: + msg416155
2022-03-26 19:59:17serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg416086
2022-01-25 15:48:40iritkatrielsetcomponents: + Library (Lib)
2022-01-25 15:46:28iritkatrielsetkeywords: + patch
stage: patch review
pull_requests: + pull_request29070
2022-01-25 14:48:27iritkatrielsetmessages: + msg411604
2021-12-07 15:15:32vekysetnosy: + veky
messages: + msg407939
2021-12-07 13:28:12Antony.Leesetnosy: - Antony.Lee
2021-12-07 11:48:48iritkatrielsetversions: + Python 3.11, - Python 3.5, Python 3.6
nosy: + iritkatriel

messages: + msg407922

type: enhancement
2016-01-15 06:31:40Antony.Leecreate