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

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:

3 Likes

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

2 Likes