Skip to content

Py313 REPL crash on malformed os.environ #128636

Closed

Description

@khk-globus

Bug description

While researching a personal project bug, I made a typo in the REPL. Obviously, one shouldn't do like the following distilled MRE, but a crash is a crash so reporting it:

$ python3.13
Python 3.13.1 (main, Dec 12 2024, 16:35:44) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ = []
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File ".../.local/Python3.13.1/lib/python3.13/_pyrepl/__main__.py", line 6, in <module>
    __pyrepl_interactive_console()
  File ".../.local/Python3.13.1/lib/python3.13/_pyrepl/main.py", line 59, in interactive_console
    run_multiline_interactive_console(console)
  File ".../local/Python3.13.1/lib/python3.13/_pyrepl/simple_interact.py", line 151, in run_multiline_interactive_console
    statement = multiline_input(more_lines, ps1, ps2)
  File ".../local/Python3.13.1/lib/python3.13/_pyrepl/readline.py", line 389, in multiline_input
    return reader.readline()
  File ".../local/Python3.13.1/lib/python3.13/_pyrepl/reader.py", line 795, in readline
    self.prepare()
  File ".../local/Python3.13.1/lib/python3.13/_pyrepl/historical_reader.py", line 302, in prepare
    super().prepare()
  File ".../local/Python3.13.1/lib/python3.13/_pyrepl/reader.py", line 635, in prepare
    self.console.prepare()
  File ".../local/Python3.13.1/lib/python3.13/_pyrepl/unix_console.py", line 349, in prepare
    self.height, self.width = self.getheightwidth()
  File ".../local/Python3.13.1/lib/python3.13/_pyrepl/unix_console.py", line 451, in getheightwidth
    return int(os.environ["LINES"]), int(os.environ["COLUMNS"])
TypeError: list indices must be integers or slices, not str

$ echo $?
1

This is clearly a PEBCAK interaction; the proper way to have cleared the environment would have been .clear() (and as an education point and/or reminder for search engine retrieval or others reading this later, os.environ and os.environb are "special" in that they're assumed to exist and are linked — a change to one affects the other).

But, my late-night typo did produce an interpreter crash, so reporting here.

Note that this does not appear to fail in Python up to v3.12. Python 3.13 is the first to crash this way.

Background

I initially thought it was an IPython bug, and so reported it there. @Carreau rightly course-corrected me, with a suggestion for a possible upstream fix in CPython.

CPython versions tested on:

3.13

Operating systems tested on:

Linux

Linked PRs

Activity

  1. hugovk commented on Jan 8, 2025

    @hugovk
    Member

    Thanks for the report.

    Note that this does not appear to fail in Python up to v3.12. Python 3.13 is the first to crash this way.

    It's a problem in the new PyREPL added in 3.13, the old one is okay:

    ❯ PYTHON_BASIC_REPL=1 python
    Python 3.13.1 (v3.13.1:06714517797, Dec  3 2024, 14:00:22) [Clang 15.0.0 (clang-1500.3.9.4)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import os
    >>> os.environ = []
    >>> 

    https://docs.python.org/3/whatsnew/3.13.html#a-better-interactive-interpreter

  2. tomasr8 commented on Jan 8, 2025

    @tomasr8
    Member

    Similar thing happens when you do e.g.:

    >>> import os
    >>> os.environ['LINES'] = ''
  3. khk-globus commented on Jan 8, 2025

    @khk-globus
    Author

    So, that specific bug is within the new PyREPL. I see that. But Carreau hinted that a number of projects assume os.environ is just there and has a dict-like structure; would there be value in considering some protection around os.environ? Something like (hypothetical):

    >>> import os
    >>> os.environ = {}
    Traceback (most recent call last):
       ...
    Exception: environ and environb are protected variables; consider `.clear()`
    >>> 

    That's more controversial of course, but perhaps not without some merit. A thought.

    With that, I'll watch from the sidelines unless otherwise poked. Thanks!

  4. tomasr8 commented on Jan 8, 2025

    @tomasr8
    Member

    I don't think we need to make os.environ protected (that would be a pretty large breaking change), but the new REPL probably shouldn't crash because of it. Perhaps just catching the extra TypeError and ValueError might be sufficient?

  5. MarcRene71 commented on Jan 22, 2025

    @MarcRene71

    This kills wfastcgi.py, too. When you configue a Flaskhandler in an Microsoft IIS, pointing to "E:\Python313\python.exe|D:\www_test\wfastcgi.py" it immediately crashes with the self.getheightwidth() Error.

    Using 3.12, the same thing works fine.

  6. added a commit that references this issue on Jan 22, 2025
  7. added a commit that references this issue on Jan 22, 2025
  8. added a commit that references this issue on Jan 22, 2025
  9. reopened this on Jul 18, 2025
  10. ambv commented on Jul 18, 2025

    @ambv
    Contributor

    This is still not solved on macOS where the same PEBKAC causes a loop of:

    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/readline.py", line 395, in multiline_input
        return reader.readline()
               ~~~~~~~~~~~~~~~^^
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/reader.py", line 742, in readline
        self.prepare()
        ~~~~~~~~~~~~^^
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/historical_reader.py", line 306, in prepare
        super().prepare()
        ~~~~~~~~~~~~~~~^^
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/reader.py", line 594, in prepare
        self.restore()
        ~~~~~~~~~~~~^^
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/reader.py", line 608, in restore
        self.console.restore()
        ~~~~~~~~~~~~~~~~~~~~^^
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/unix_console.py", line 373, in restore
        if platform.system() == "Darwin" and os.getenv("TERM_PROGRAM") == "Apple_Terminal":
                                             ~~~~~~~~~^^^^^^^^^^^^^^^^
      File "/Volumes/RAMDisk/cpython/Lib/os.py", line 821, in getenv
        return environ.get(key, default)
               ^^^^^^^^^^^
    AttributeError: 'list' object has no attribute 'get'
    Traceback (most recent call last):
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/reader.py", line 585, in prepare
        self.console.prepare()
        ~~~~~~~~~~~~~~~~~~~~^^
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/unix_console.py", line 342, in prepare
        if platform.system() == "Darwin" and os.getenv("TERM_PROGRAM") == "Apple_Terminal":
                                             ~~~~~~~~~^^^^^^^^^^^^^^^^
      File "/Volumes/RAMDisk/cpython/Lib/os.py", line 821, in getenv
        return environ.get(key, default)
               ^^^^^^^^^^^
    AttributeError: 'list' object has no attribute 'get'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/readline.py", line 395, in multiline_input
        return reader.readline()
               ~~~~~~~~~~~~~~~^^
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/reader.py", line 742, in readline
        self.prepare()
        ~~~~~~~~~~~~^^
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/historical_reader.py", line 306, in prepare
        super().prepare()
        ~~~~~~~~~~~~~~~^^
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/reader.py", line 594, in prepare
        self.restore()
        ~~~~~~~~~~~~^^
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/reader.py", line 608, in restore
        self.console.restore()
        ~~~~~~~~~~~~~~~~~~~~^^
      File "/Volumes/RAMDisk/cpython/Lib/_pyrepl/unix_console.py", line 373, in restore
        if platform.system() == "Darwin" and os.getenv("TERM_PROGRAM") == "Apple_Terminal":
                                             ~~~~~~~~~^^^^^^^^^^^^^^^^
      File "/Volumes/RAMDisk/cpython/Lib/os.py", line 821, in getenv
        return environ.get(key, default)
               ^^^^^^^^^^^
    AttributeError: 'list' object has no attribute 'get'
  11. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Jul 18, 2025
  12. added a commit that references this issue on Sep 15, 2025
  13. added a commit that references this issue on Sep 15, 2025
  14. added 3 commits that reference this issue on Sep 15, 2025
  15. added a commit that references this issue on Sep 16, 2025
  16. yihong0618 commented on Sep 17, 2025

    @yihong0618
    Contributor

    This issue can close I think

  17. hugovk commented on Feb 13, 2026

    @hugovk
    Member

    Reported @standaell1234-maker to GH (also for #138942 (comment))

  18. locked and limited conversation to collaborators on Feb 13, 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

    OS-macstdlibStandard Library Python modules in the Lib/ directorytopic-replRelated to the interactive shelltype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions