Closed gerasimovich-a closed 1 year ago
Thanks for the report.
I've been able to reproduce your problem; for others, the critical piece is that briefcase dev
and briefcase run
won't trigger the problem. You need to start the app from the icon - either by installing, or activating the app from the file manager.
The thing is - I'm not 100% clear if this is a bug in Briefcase, or a bug in Catboost.
The problem is caused by this line in the Briefcase bootstrap app. This code exists because GUI apps can generate console output; but on Windows, that console output is lost when the app is run from the icon. This can make it exceedingly difficult to debug errors, because an app will just "not start", and the logs telling you what went wrong will be lost. The dialog that you've seen on the crash is part of this handling - we capture exception crashes and display the stack trace; we also write all stdout/stderr output to a log file in the user's AppData folder (keeping the last 9 runs, and deleting old log files as they age out).
This code is only executed when the app doesn't have a console attached. So, if you use briefcase run
, the console is attached, and you get both stdout and stderr. However, when you run from the icon, there's no console, stderr is set to None, and as a result, stderr output redirects to stdout. We have to do this because we can only open a single pipe to write a log file, and IIRC stderr can't be dup'd on Windows to point to the same file handle as stdout. And - if you print("hello", file=sys.stderr)
, it works fine - the output is directed to stdout, which is logged to the output file.
However, catboost is doing something different - it's assuming that stderr exists, and is looking specifically for a write
method on sys.stderr
. That then raises the error you're seeing. I think this is a bug in catboost, because it's assuming that stderr must exist - which I think is a false assumption. However, I can't find any canonical documentation that confirms this. It's certainly true that processes usually have both stdout and stderr - but I don't know if they're required, or if Python guarantees that they're open pipes. Regardless, patching catboost to return stdout when stderr is None would fix the problem; whether you can convince catboost this is a required fix in their library is left as an exercise to the reader :-)
I can think of 2 immediate workarounds:
Firstly - based on the code you've referenced, catboost appears to have the ability to set a custom logger; if you install a custom logger that directs stderr output to stdout, that should work.
Secondly - you can do the same thing, but at the base Python level: if you put
import sys
sys.stderr = sys.stdout
into your code before catboost is initialised, you should get the same effect.
I'm going to transfer this issue to the briefcase visual studio template, since the problem isn't with Briefcase itself, but with the stub app used on Windows.
Mild defense for catboost implementing a change.
Note Under some conditions stdin, stdout and stderr as well as the original values stdin, stdout and stderr can be None. It is usually the case for Windows GUI apps that aren’t connected to a console and Python apps started with pythonw.
🤦 I was looking for a Unix stdout/err reference, and forgot that Python's docs might have something to say on the matter.
I'd call that a little more than "mild"... that's pretty much canonical defence of what the stub app is doing, IMHO :-)
On the basis that Briefcase has a documented defence of it's implementation, and workarounds exist, I'm going to close this issue and call it a bug in catboost.
Describe the bug
I'm trying to deploy my ML model with briefcase. It works with
briefcase run
but i have an error when launch an .exeCatBoostError: Expected callable object or stream-like object
\windows\app\src\app_packages\catboost\core.py", line 120, in _get_stream_like_object
https://github.com/catboost/catboost/blob/master/catboost/python-package/catboost/core.py
i found out that
sys.stderr
isNone
in case of running exe fileHow can i fix it? I really appreciate any help you can provide
Expected behavior
sys.stderr is not None
Environment