How can I tell the file (or tty) that is attached to my stdios?
Something like:
>>> import sys
>>> print sys.stdin.__path__
'/dev/tty1'
>>>
I could look in proc:
import os, sys
os.readlink('/proc/self/fd/%s' % sys.stdin.fileno())
But seems like there should be a builtin way?
The sys.std* objects are standard Python file objects, so they have a name attribute and a isatty method:
>>> import sys
>>> sys.stdout.name
'<stdout>'
>>> sys.stdout.isatty()
True
>>> anotherfile = open('/etc/hosts', 'r')
>>> anotherfile.name
'/etc/hosts'
>>> anotherfile.isatty()
False
Short of telling you exactly what TTY device you got, that's the extend of the API offered by Python.
Got it!
>>> import os
>>> import sys
>>> print os.ttyname(sys.stdin.fileno())
'/dev/pts/0'
>>>
It raises OSError: [Errno 22] Invalid argument if stdin isn't a TTY; but thats easy enough to test for with isatty()
Related
I want to pickle and unpickle a GdkPixbuf.Pixbuf in Python3. To be more specific the multiprocessing package of Python3 need to do it because I share such objects between process via a Queue.
The problem is that the object changes from
<GdkPixbuf.Pixbuf object at 0x7f8b9e9cfb88 (GdkPixbuf at 0x563b61725c60)>
to
<GdkPixbuf.Pixbuf object at 0x7f8b9e9eaea0 (uninitialized at 0x(nil))>
That is the minimal working example.
>>> import gi
>>> from gi.repository import GdkPixbuf
__main__:1: PyGIWarning: GdkPixbuf was imported without specifying a version first. Use gi.require_version('GdkPixbuf', '2.0') before import to ensure that the right version gets loaded.
>>> pf = GdkPixbuf.Pixbuf.new_from_file('_icon.png')
>>> pf
<GdkPixbuf.Pixbuf object at 0x7f8b9e9cfb88 (GdkPixbuf at 0x563b61725c60)>
>>> import pickle
>>> pickle.dump(pf, open('p', 'wb'))
>>> pb2 = pickle.load(open('p', 'rb'))
>>> pb2
<GdkPixbuf.Pixbuf object at 0x7f8b9e9eaea0 (uninitialized at 0x(nil))>
I see no other way to pickle. The icon need to be loaded in a separate process (on a different CPU core then the applications main/first process) and then should be transfered to the main process. This is done via a Queue which pickles all data.
My solution is holding the "icon" not as a Pixbuf object in memory but as raw bytes I read from the file.
After unpickling this bytes I convert them to a Pixbuf.
>>> import gi
>>> from gi.repository import GdkPixbuf, Gio, GLib
__main__:1: PyGIWarning: GdkPixbuf was imported without specifying a version first. Use gi.require_version('GdkPixbuf', '2.0') before import to ensure that the right version gets loaded.
>>> with open('_icon.png', 'rb') as f:
... icon_bytes = f.read()
...
>>>
>>> import pickle
>>> pickle.dump(icon_bytes, open('p', 'wb'))
>>>
>>> pb = pickle.load(open('p', 'rb'))
>>> pb = GLib.Bytes(pb)
>>> pb = GdkPixbuf.Pixbuf.new_from_stream(Gio.MemoryInputStream.new_from_bytes(pb))
>>> pb
<GdkPixbuf.Pixbuf object at 0x7fc0858ac5e8 (GdkPixbuf at 0x55e0d8d08b60)>
I would like to capture error messages which are generated from a python module A. A is written in C++ and SWIG, and so I cannot capture Python's sys.stderr.
>>> import A
>>> A.func() # this prints an error message by C++ std::cerr.
this is an error message from module A
What I want to do are to suppress the error message and to change my script behavior according to the error type. But A.func() does not return error numbers.
Assuming that my use of contextlib below is correct, it did not help.
>>> import io
>>> f = io.StringIO()
>>> import contextlib
>>> with contextlib.redirect_stderr(f):
... no_return = A.func()
ERROR MESSAGE HERE
>>> f.getvalue()
>>>
Thank you #PM2Ring
https://eli.thegreenplace.net/2015/redirecting-all-kinds-of-stdout-in-python/#id1
With minor modifications: replacing all the stdout with stderr and supporting macOS as shown below, it worked perfectly as expected.
if sys.platform == 'darwin':
c_stderr = ctypes.c_void_p.in_dll(libc, '__stderrp')
else:
c_stderr = ctypes.c_void_p.in_dll(libc, 'stderr')
I am learning selenium and intend to check methods available.
browser = webdriver.Chrome()
browser.get(start_url)
help(browser)
The help document is too long so I'd like to copy them to a file.
In [19]: with open("webdriver.md", "w") as file:
...: file.write(help(browser))
...:
TypeError: write() argument must be str, not None
Either pydoc is not helpful
In [23]: pydoc.writedoc("browser")
No Python documentation found for 'browser'.
Use help() to get the interactive help utility.
Use help(str) for help on the str class.
How could I write help(browser) to a plain text file.
bulit-in help() is a wrapper around pydoc.Helper, it writes to stdout by default, you could temporarily redirecting sys.stdout to a file:
>>> import contextlib
>>> with contextlib.redirect_stdout(open('browser_help.txt', 'w')):
... help(browser)
or you could call pydoc.Helper directly, :
>>> import pydoc
>>> with open('browser_help.txt', 'w') as f:
... h = pydoc.Helper(output=f)
... h(browser)
You can try to change the current stdout:
import sys
sys.stdout = open('webdriver.md', 'w')
help(browser)
Starting from Python 3.4, you can also use contextlib.redirect_stdout:
from contextlib import redirect_stdout
with redirect_stdout(open('webdriver.md', 'w')):
help(browser)
File ex.py:
print('hello,word')
Trial run:
>>> d:\learning\python\ex.py
SyntaxError: invalid syntax
On the command line, outside the Python console, type:
python D:\learning\python\ex.py
You need to import the module:
>>> import ex
See the documentation about modules
The module has to be on your path or in the current working directory. You can change directories using chdir:
>>> import os
>>> os.chdir(r'd:\learning\python')
>>> import ex
hello,word
Or, in the command prompt, you can set PYTHONPATH=d:\learning\python, for example, before you start python, and d:\learning\python will get added to sys.path.
Instead, you could add it programatically:
>>> import sys
>>> sys.path.insert(0, r'd:\learning\python')
>>> import ex
hello,word
I am using the ctypes module to do some ptrace system calls on Linux, which actually works
pretty well. But if I get an error I wanna provide some useful information. Therefore I
do an get_errno() function call which returns the value of errno, but I didn't found
any function or something else which interprets the errno value and gives me an associated
error message.
Am I missing something?
Is there a ctypes based solution?
Here is my setup:
import logging
from ctypes import get_errno, cdll
from ctypes.util import find_library, errno
# load the c lib
libc = cdll.LoadLibrary(find_library("c"), use_errno=True)
...
Example:
return_code = libc.ptrace(PTRACE_ATTACH, pid, None, None)
if return_code == -1:
errno = get_errno()
error_msg = # here i wanna provide some information about the error
logger.error(error_msg)
This prints ENODEV: No such device.
import errno, os
def error_text(errnumber):
return '%s: %s' % (errno.errorcode[errnumber], os.strerror(errnumber))
print error_text(errno.ENODEV)
>>> import errno
>>> import os
>>> os.strerror(errno.ENODEV)
'No such device'