Repository: ipython/ipython

Issue:
typings: publicly export `IPython.display.*` symbols
The `IPython.display.*` constructors (e.g., `IPython.display.HTML`, `IPython.display.Javascript`, etc.) are supposed to be public exports (considering that they are [officially documented as part of the API](https://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html#IPython.display.HTML).

However, according to the way [the `IPython.display` module is currently written](https://github.com/ipython/ipython/blob/7ad98de56d38e1ec951de4708c32d10ed51b997b/IPython/display.py), most of its members are currently considered private (i.e., not re-exported), under the current Python library typing guidelines (https://typing.readthedocs.io/en/latest/source/libraries.html#library-interface-public-and-private-symbols):

> Each module exposes a set of symbols. Some of these symbols are considered “private” — implementation details that are not part of the library’s interface. Type checkers can use the following rules to determine which symbols are visible outside of the package.
> - Symbols whose names begin with an underscore (but are not dunder names) are considered private.
> - Imported symbols are considered private by default. If they use the `import A as A` (a redundant module alias), `from X import A as A` (a redundant symbol alias), or `from . import A` forms, symbol `A` is not private unless the name begins with an underscore. If a file `__init__.py` uses form `from .A import X`, symbol `A` is treated likewise. If a wildcard import (of the form `from X import *`) is used, all symbols referenced by the wildcard are not private.
> - A module can expose an `__all__` symbol at the module level that provides a list of names that are considered part of the interface. This overrides all other rules above, allowing imported symbols or symbols whose names begin with an underscore to be included in the interface.
> - Local variables within a function (including nested functions) are always considered private.

https://github.com/ipython/ipython/blob/7ad98de56d38e1ec951de4708c32d10ed51b997b/IPython/display.py#L16-L43

This leads to IDE typecheckers complaining that classes such as `IPython.display.HTML` aren't publicly accessible, which is incorrect according to the IPython documentation, and annoying:
![image](https://github.com/ipython/ipython/assets/3887189/0b4cd114-6b8f-47e8-b69b-519d07448bc7)

## Suggestion

Could we revise this to make the `IPython.display.*` members publicly exported? This entails either:
- Rewriting the imports to use redundant alias forms:
  ```python
  from IPython.core.display import (
      display_pretty as display_pretty,
      display_html as display_html,
      display_markdown as display_markdown,
      display_svg as display_svg,
      display_png as display_png,
      display_jpeg as display_jpeg,
      display_latex as display_latex,
      display_json as display_json,
      display_javascript as display_javascript,
      display_pdf as display_pdf,
      DisplayObject as DisplayObject,
      TextDisplayObject as TextDisplayObject,
      Pretty as Pretty,
      HTML as HTML,
      Markdown as Markdown,
      Math as Math,
      Latex as Latex,
      SVG as SVG,
      ProgressBar as ProgressBar,
      JSON as JSON,
      GeoJSON as GeoJSON,
      Javascript as Javascript,
      Image as Image,
      set_matplotlib_formats as set_matplotlib_formats,
      set_matplotlib_close as set_matplotlib_close,
      Video as Video,
  )
  ```
- Using the `import *` form (although this means potentially importing/exporting too many things from `IPython.core.display`):
  ```python
  from IPython.core.display import *
  ```
- Explicitly listing all re-exported members in `__all__`.

## See also

- https://github.com/microsoft/pyright/issues/5902
- https://microsoft.github.io/pyright/#/typed-libraries?id=library-interface


Discussion:
I'm happy with any approach. Would you like to submit a PR ? 

Resolving patch:
diff --git a/IPython/display.py b/IPython/display.py
--- a/IPython/display.py
+++ b/IPython/display.py
@@ -14,31 +14,31 @@
 
 from IPython.core.display_functions import *
 from IPython.core.display import (
-    display_pretty,
-    display_html,
-    display_markdown,
-    display_svg,
-    display_png,
-    display_jpeg,
-    display_latex,
-    display_json,
-    display_javascript,
-    display_pdf,
-    DisplayObject,
-    TextDisplayObject,
-    Pretty,
-    HTML,
-    Markdown,
-    Math,
-    Latex,
-    SVG,
-    ProgressBar,
-    JSON,
-    GeoJSON,
-    Javascript,
-    Image,
-    set_matplotlib_formats,
-    set_matplotlib_close,
-    Video,
+    display_pretty as display_pretty,
+    display_html as display_html,
+    display_markdown as display_markdown,
+    display_svg as display_svg,
+    display_png as display_png,
+    display_jpeg as display_jpeg,
+    display_latex as display_latex,
+    display_json as display_json,
+    display_javascript as display_javascript,
+    display_pdf as display_pdf,
+    DisplayObject as DisplayObject,
+    TextDisplayObject as TextDisplayObject,
+    Pretty as Pretty,
+    HTML as HTML,
+    Markdown as Markdown,
+    Math as Math,
+    Latex as Latex,
+    SVG as SVG,
+    ProgressBar as ProgressBar,
+    JSON as JSON,
+    GeoJSON as GeoJSON,
+    Javascript as Javascript,
+    Image as Image,
+    set_matplotlib_formats as set_matplotlib_formats,
+    set_matplotlib_close as set_matplotlib_close,
+    Video as Video,
 )
 from IPython.lib.display import *


Test patch: