How to print to stderr (Swift 6.1)

Hi! I have just upgraded from 5.9 to 6.1 on Windows 10. In 5.9 I was using this technique to 'print' to stderr (and also can be used to 'print' to any text file):

extension FileHandle: TextOutputStream {
    public func write(_ string: String) {
        // convert String to Data (a byte buffer in memory)
        // utf8 is a property that is a collection of UTF8 code units
        let data = Data(string.utf8)
        self.write(data)
    }
}

var stderr = FileHandle.standardError
print("error: file has no file extension, file ignored: \(fileName)", to: &stderr)

Now in 6.1 I am getting this warning:

warning: extension declares a conformance of imported type 'FileHandle' to imported protocol 'TextOutputStream'; this will not behave correctly if the owners of 'Foundation' introduce this conformance in the future

I understand the warning. My question is: Is there a better way to 'print' to stderr or other text file that will not receive warnings and will not be at risk of future Foundation changes?

thanks!
Kim

1 Like

While it's usually more verbose to write a wrapper type that you do own to conform to a protocol like this, in this case, it's not much more code to write something like

import Foundation

struct StandardError: TextOutputStream, Sendable {
    private static let handle = FileHandle.standardError

    public func write(_ string: String) {
        Self.handle.write(Data(string.utf8))
    }
}

var stderr = StandardError()
print("Hello", to: &stderr)

I'm not aware of a more succinct way of getting access to stderr for use with print.

5 Likes

Thanks very much! That will work just fine. :slightly_smiling_face:

1 Like

You should add locking if you don't want prints from multiple threads to mix. Here is how printing to stdout is done:

4 Likes

Who wants to write up a PR for struct _Stderr? :smiley:

5 Likes