Python 3 upgrade, a bytes-like object is required, not 'str' - python-3.x

I've been trying to get this work but getting the error TypeError: a bytes-like object is required, not 'str'' after upgrading to python 3.
What am I doing wrong here? I tried r, wb+ and w learned from here, Confused by python file mode "w+"
my code:
with open(output_filename, 'wb') as f:
# write column names
f.write("stack,overflow,super,user\n")
writer = csv.writer(f)
Can anyone help with this? Thanks.

The difference between 'wb' and 'w' filemodes is that 'wb' directly reads the binary and 'w' reads it as string. Your issue is that you're using 'wb' instead of 'w'. csv.writer is expecting a string, not binary.
If you use with open(output_filename, 'w') as f: instead, it should work.

Related

pynag with python3.6 TypeError

I'm trying to read my nagios config data as follows:
pynag.Model.cfg_file = "path_to_nagios.cfg"
all_hosts = pynag.Model.Host.objects.all"
This returns an error
TypeError: endswith first arg must be bytes or a tuple of bytes
From what I've read so far, it seems that it's related to how files are opened in python3
Do you know how to correct this?
Thanks.
The fix was in the library code. The def parse_file() is opening files as 'rb'. The reason this is an error in Python 3 and not Python 2 is that Python 2 treats bytes as an alias or synonym for str. It doesn't make a distinction between byte strings and unicode strings as is done in Python 3.
In pynag/Parsers/init.py changed
lines = open(self.filename, 'rb').readlines()
to
lines = open(self.filename, 'r').readlines()

Getting the "bytes-like object is required" error, but the fix causes a "write() arguments must be str" error

This is a piece of a script that is giving me fits. If I use 'wb', I get the "bytes like" error. If I change it to 'w', I get the "write() arguments" error.
with open(output_path+filename, 'wb') as f:
f.write('<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n')
f.write(ET.tostring(elem, pretty_print = True))
If I have 'wb', it gives me this error:
f.write("<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n")
TypeError: a bytes-like object is required, not 'str'
If I have 'w', it gives me:
f.write(ET.tostring(elem, pretty_print = True))
TypeError: write() argument must be str, not bytes
The reason I'm doing it like this, is because I'm using lxml to take one HUGE XML sheet with several files'-worth of metadata and split it up into several XML files. So the like with the UTF-8 encoding is so that each individual file, has that written at the top. Without posting a ton of code, ET = lxml.etree.

Python 3 - correct way to write to .html without TypeError

# save-webpage.py (To write first 100 characters of html source into 'simple.html')
import urllib.request, io, sys
f = urllib.request.urlopen('https://news.google.com')
webContent = f.read(100)
#g = io.open('simple.html', 'w', encoding='UTF-8')
g = io.open('simple.html', 'w')
#g.write(webContent)
g.write(webContent.decode("UTF-8"))
g.close()
2019-01-11: See above for corrected working code after answers were received. Thanks guys.
Original question:
Upon execution, the file, simple.html, is created with 0 bytes.
Along with an error:
TypeError: must be str, not bytes.
Please help. I've gone about this several ways but to no avail. Thank you in advance!
g.write(webContent.decode("utf-8"))
File objects opened in text mode require you to write Unicode Text.
In this line you encoded to UTF-8 bytes
g = io.open('simple.html', 'w', encoding='UTF-8')
You could either not encode or try decoding it after.

Python3 open text file

I am trying to open a simple text file using
dir_path = os.path.dirname(os.path.realpath(__file__))
F = open(dir_path+"\\sankey2.txt","r")
The path to the file is :C:\Users\David\Google Drive\Jobs\1.Efe\Transporte\0.MODEL
Inside the text file is the following text :
sankey2.txt
$SETGLOBAL REFERENCIA
Now if I run python it gives me the error :
TypeError: decoding to str: need a bytes-like object, _io.TextIOWrapper found
So I tried the following 2 solutions :
Trying this
F = bytes(open(dir_path+"\\sankey2.txt","r"))
I get
TypeError: 'str' object cannot be interpreted as an integer
Trying this
F = open(dir_path+"\\sankey2.txt","rb")
I get
TypeError: decoding to str: need a bytes-like object, _io.BufferedReader found
It is not entirely clear to me how to solve this problem. Encoding to UTF-8 doesn't help either.
Thanks for your help.

a bytes-like object is required, not 'str': typeerror in compressed file

I am finding substring in compressed file using following python script. I am getting "TypeError: a bytes-like object is required, not 'str'". Please any one help me in fixing this.
from re import *
import re
import gzip
import sys
import io
import os
seq={}
with open(sys.argv[1],'r') as fh:
for line1 in fh:
a=line1.split("\t")
seq[a[0]]=a[1]
abcd="AGATCGGAAGAGCTCGTATGCCGTCTTCTGCTTG"
print(a[0],"\t",seq[a[0]])
count={}
with gzip.open(sys.argv[2]) as gz_file:
with io.BufferedReader(gz_file) as f:
for line in f:
for b in seq:
if abcd in line:
count[b] +=1
for c in count:
print(c,"\t",count[c])
fh.close()
gz_file.close()
f.close()
and input files are
TruSeq2_SE AGATCGGAAGAGCTCGTATGCCGTCTTCTGCTTG
the second file is compressed text file. The line "if abcd in line:" shows the error.
The "BufferedReader" class gives you bytestrings, not text strings - you can directly compare both objects in Python3 -
Since these strings just use a few ASCII characters and are not actually text, you can work all the way along with byte strings for your code.
So, whenever you "open" a file (not gzip.open), open it in binary mode (i.e.
open(sys.argv[1],'rb') instead of 'r' to open the file)
And also prefix your hardcoded string with a b so that Python uses a binary string inernally: abcd=b"AGATCGGAAGAGCTCGTATGCCGTCTTCTGCTTG" - this will avoid a similar error on your if abcd in line - though the error message should be different than the one you presented.
Alternativally, use everything as text - this can give you more methods to work with the strings (Python3's byte strigns are somewhat crippled) presentation of data when printing, and should not be much slower - in that case, instead of the changes suggested above, include an extra line to decode the line fetched from your data-file:
with io.BufferedReader(gz_file) as f:
for line in f:
line = line.decode("latin1")
for b in seq:
(Besides the error, your progam logic seens to be a bit faulty, as you don't actually use a variable string in your innermost comparison - just the fixed bcd value - but I suppose you can fix taht once you get rid of the errors)

Resources