Using `print()` to write to file opened in binary mode - python

I often use print() instead of file.write() when writing to files in Python. Recently, I had to write out some binary data, and tried a similar pattern:
f = open('test.txt', 'w')
f.write('abcd')
print('efgh', file=f)
f.close()
f = open('test.bin', 'wb')
f.write(b'abcd') # works as expected
print(b'efgh', file=f)
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# TypeError: a bytes-like object is required, not 'str'
f.close()
My first thought was the default newline-appending behaivor of print() might be at fault:
print(b'efgh', file=f, end='')
# same error
print(b'efgh', file=f, end=None)
# same error
print(b'efgh', file=f, end=b'')
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# TypeError: end must be None or a string, not bytes
print(b'efgh', file=f, end=b'\n')
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# TypeError: end must be None or a string, not bytes
Unfortunately, none of the permutations of changing the end worked.
Why is this happening? I suspect that this use of print() might not be supported, but in that case the error message is quite confusing.

From python3 documentation: https://docs.python.org/3/library/functions.html#print
All non-keyword arguments are converted to strings like str() does and written to the stream, separated by sep and followed by end. Both sep and end must be strings; they can also be None, which means to use the default values. If no objects are given, print() will just write end.
As I understand, you can't write bytes with print() because the object you want to write is passed only as positional argument and positional arguments are converted to strings(hence the error).

Related

Python how insert a variable in codecs.decode?

I have a list.txt where every line has a different hex string. So I want to choose a line and convert the specific line in ascii. So I have written this code:
import codecs
f=open('list.txt')
lines=f.readlines()
var=lines[25]
print(var)
print( codecs.decode("{var}", "hex") )
The specific var = 2d560d4b0618203249312a310d5f541f295c3f0f25235c2b20037d1600f3
when I execute this command:
print( codecs.decode("2d560d4b0618203249312a310d5f541f295c3f0f25235c2b20037d1600f3", "hex") ) I get the result.
But when I try to put the var variable I get this error:
Traceback (most recent call last): File "/usr/local/lib/python3.7/encodings/hex_codec.py", line 19, in ee4'hex_decode return (binascii.a2b_hex(input), len(input))binascii.Error: Odd-length string
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "main.py", line 8, in <module>
print( codecs.decode("{var}", "hex") )
binascii.Error: decoding with 'hex' codec failed (Error: Odd-length string) `
The new lines were being included in the string. Here is a working version that strips the white-space characters.
import codecs
f=open('list.txt')
lines=f.readlines()
var=lines[25].strip()
print(codecs.decode(var, "hex"))
Example code:https://onlinegdb.com/S1ZVk4jiH

Removing certain strings from base64 output python

Here is my code.
import base64
encoded = base64.b64encode(b"data to be encoded")
print(encoded)
print(encoded.replace("b", ""))
Here is my output
b'ZGF0YSB0byBiZSBlbmNvZGVk'
Traceback (most recent call last):
File "C:\Users\user\Desktop\base64_obfuscation.py", line 8, in <module>
print(decoded.replace("b", ""))
TypeError: a bytes-like object is required, not 'str'
My overall task is to remove the single quotes and the "b" chracter from the string but I'm unsure on how to do so?
print(str(encoded).replace("b", ""))

TypeError: not all arguments converted during string formatting error python

I have customized tempest code for our REST API's, but when i run the scripts, using nosetests at the beginning it gives some weird type error as mentioned below, though test cases in the script passes
Traceback (most recent call last):
File "/usr/lib64/python2.6/logging/__init__.py",line 776, in emit msg = self.format(record)
File "/usr/lib64/python2.6/logging/__init__.py", line 654, in format return fmt.format(record)
File "/home/rmcbuild/repository/rmc-test/tempest/openstack/common/log.py", line 516, in format return logging.Formatter.format(self, record)
File "/usr/lib64/python2.6/logging/__init__.py", line 436, in format record.message = record.getMessage()
File "/usr/lib64/python2.6/logging/__init__.py", line 306, in getMessage msg = msg % self.args
TypeError: not all arguments converted during string formatting
has anyone come across this type of error, would appreciate if someone helps me out of it.
Thanks,
This happens when using %s to print a string:
>>> x = 'aj8uppal'
>>> print 'Hello, %s %s' %(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
>>> print 'Hello, ' %(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting
>>>
If you put one too many %ss, it gives a TypeError: not enough arguments for format string, but if you put one to few, it gives TypeError: not all arguments converted during string formatting.
What is likely is that you have put a variable(s) in parentheses at the end, but the number of percent signs does not match. Please post your code if you want us to help you further :)
I received this error when I typed a '&s' by mistake rather than a '%s'

Open files in "rock&roll" mode

I'm wondering what is going on with the file open() mode validation (Python2.7):
>>> with open('input.txt', 'illegal') as f:
... for line in f:
... print line
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: mode string must begin with one of 'r', 'w', 'a' or 'U', not 'illegal'
>>> with open('input.txt', 'rock&roll') as f:
... for line in f:
... print line
...
1
2
3
So, I cannot open the file in illegal mode, but I can open it in rock&roll mode. What mode is actually used for opening the file in this case?
Note that on python3 I cannot use both illegal and rock&roll:
>>> with open('input.txt', 'rock&roll') as f:
... for line in f:
... print(line)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid mode: 'rock&roll'
>>> with open('input.txt', 'illegal') as f:
... for line in f:
... print(line)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid mode: 'illegal'
And, this is confusing, why the behavior is different for python3.x?
The Python 2.x open function essentially delegates its work to the C library fopen function. On my system, the documentation for fopen contains:
The argument mode points to a string beginning with one of the following sequences (Additional characters may follow these sequences.):
Your ock&roll is considered "additional characters".
In Python 3, the allowed open modes are more restricted (essentially, only valid strings are permitted).
The previous traceback explains it nicely:
"ValueError: mode string must begin with one of 'r', 'w', 'a' or 'U'"
"rock&roll" begins with "r", so it's apparently legal.

where is the call to encode the string or force the string to need to be encoded in this file?

I know this may seem rude or mean or unpolite, but I need some help to try to figure out why I cant call window.loadPvmFile("f:\games#DD.ATC3.Root\common\models\a300\amu\dummy.pvm") exactly like that as a string. Instead of doing that, it gives me a traceback error:
Traceback (most recent call last):
File "F:\Python Apps\pvmViewer_v1_1.py", line 415, in <module>
window.loadPvmFile("f:\games\#DD.ATC3.Root\common\models\a300\amu\dummy.pvm")
File "F:\Python Apps\pvmViewer_v1_1.py", line 392, in loadPvmFile
file1 = open(path, "rb")
IOError: [Errno 22] invalid mode ('rb') or filename:
'f:\\games\\#DD.ATC3.Root\\common\\models\x07300\x07mu\\dummy.pvm'
Also notice, that in the traceback error, the file path is different. When I try a path that has no letters in it except for the drive letter and filename, it throws this error:
Traceback (most recent call last):
File "F:\Python Apps\pvmViewer_v1_1.py", line 416, in <module>
loadPvmFile('f:\0\0\dummy.pvm')
File "F:\Python Apps\pvmViewer_v1_1.py", line 393, in loadPvmFile
file1 = open(path, "r")
TypeError: file() argument 1 must be encoded string without NULL bytes, not str
I have searched for the place that the encode function is called or where the argument is encoded and cant find it. Flat out, I am out of ideas, frustrated and I have nowhere else to go. The source code can be found here: PVM VIEWER
Also note that you will not be able to run this code and load a pvm file and that I am using portable python 2.7.3! Thanks for everyone's time and effort!
\a and \0 are escape sequences. Use r'' (or R'') around the string to mark it as a raw string.
window.loadPvmFile(r"f:\games#DD.ATC3.Root\common\models\a300\amu\dummy.pvm")

Categories

Resources