Skip to content

[Bug]: Savefig with invalid filename #27748

Closed

Description

@hantangantan

Bug summary

savefig returns no error when using invalid filename

Code for reproduction

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 10, 100)
y = np.sin(x)


plt.figure(figsize=(8, 6))
plt.plot(x, y, '-r', label='Sinewave')
plt.title('Example')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.legend(loc='best')

# creates empty file named test - no error thrown
plt.savefig('test : diagramm')

Actual outcome

no error message - only empty file which is a little bit confusing as there is no error message created

Expected outcome

Thrown Exception: Invalid Filename

Additional information

No response

Operating system

Windows 10 Professional

Matplotlib Version

3.8.2

Matplotlib Backend

No response

Python version

3.11.6

Jupyter version

No response

Installation

pip

Activity

  1. rcomer commented on Feb 5, 2024

    @rcomer
    Member

    For me on Ubuntu with TkAgg this code saves out an image with filename test : diagramm.png. The image itself is as you would expect from the code.

  2. timhoffm commented on Feb 5, 2024

    @timhoffm
    Member

    Might be a windows topic since : is not allowed there.

  3. tacaswell commented on Feb 5, 2024

    @tacaswell
    Member

    what does

    with open("test : broken", 'w') as fout:
       fout.write('test')

    do?

  4. QuLogic commented on Feb 5, 2024

    @QuLogic
    Member

    : is not technically barred on Windows, since maybe NT? The above test code works fine.

    However, the file is not usable in Explorer. It appears as test , so if you try to open or delete it, it doesn't work. It's also not accessible from PowerShell or the Command Prompt. That's not actually because of the colon, but because the filename ends with a space, which is not allowed. While os.unlink('test ') did seem to work, it seems to be stuck in the system somewhere and still shows up in dir or Explorer but can't be opened any more.

    What the colon actually does is open an NTFS Alternate Data Stream, and that is intentional. If you remove the space before the colon, then everything works a bit more reasonably:

    PS > python
    >>> with open('test:broken', 'w') as f:
    ...     f.write('test')
    >>> exit()
    PS > Get-Item test
    
        Directory: ...\matplotlib
    
    Mode                 LastWriteTime         Length Name
    ----                 -------------         ------ ----
    -a----        2024-02-05   6:23 PM              0 test
    PS > Get-Item test | Get-Content  # Main stream is empty.
    PS > Get-Item test | Get-Content -Stream broken  # But this alternate stream contains the data we wrote.
    test
    PS > del test  # Works fine here.
    
  5. QuLogic commented on Feb 5, 2024

    @QuLogic
    Member

    While os.unlink('test ') did seem to work, it seems to be stuck in the system somewhere and still shows up in dir or Explorer but can't be opened any more.

    Weirdly, if you have just this invalid filename-ending-in-space, then you can't see it correctly with dir /R (you only see test itself), but if you create a valid one as test:broken, then you can see both correctly:

    > dir /R "test*"
     Directory of ...\matplotlib
    
    2024-02-05  06:38 PM                 0 test
                                         4 test:broken:$DATA
    2024-02-05  06:38 PM                 0 test
                                         4 test :broken:$DATA
                   2 File(s)              0 bytes
    

    That is, you can see both of them and their Alternate Data Streams.

    And it seems del "test*" is able to delete them both.

  6. timhoffm commented on Feb 6, 2024

    @timhoffm
    Member

    because the filename ends with a space, which is not allowed.

    Seems not exactly true. It's allowed but not fully supported 🙄 : https://stackoverflow.com/a/67886889

    Edit: Official win32 docs say:

    Do not end a file or directory name with a space or a period. Although the underlying file system may support such names, the Windows shell and user interface does not.

    Handling this is beyond our responsibility. This should be reported upstream and cpython itself should decide whether they act on it.

  7. timhoffm commented on Feb 8, 2024

    @timhoffm
    Member

    I'm closing this as we're not going to do any special casing on the Matplotlib side. This is up to cpython: python/cpython#115104.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions