(RenPy) Python2.x What is the difference of str() and unicode() ? [solved]

Mattock

Newbie
May 27, 2018
91
79
hello,
I'm a modder not a dev, I hope that's OK too?
(well I started modding to learn RenPy coz I still want to make a game some time in the future;)

from what I understand python3 has "only" str()
(2to3fixer renames all unicode() to str() )

When I started using RenPy I thought it a good idea to always use unicode(),
later on I realized unicode16(be or le doesn't matter to me) was meant...(of course I had hoped utf8 was meant...)

I want to use code that works on RenPy7 and 8 and if possible without too much: if PY2 or similiar


so what's the difference in PY2 ?
-English: NONE! (at least I think so(?))
-German ?
-French ?
-Japanese ?
-whatever ?

thanks
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,192
When I started using RenPy I thought it a good idea to always use unicode(),
Why ? Even the use of str() is just exceptionally needed. As long as you put your code in a RPY file, it will be automatically turned into Unicode by Ren'Py.
It's less true if it's in a PY file, but if you stick to English there's no problems.


so what's the difference in PY2 ?
The charset. But it's more complex, and in the same time way more simple, than you believe ; it's the whole string processing that change between Python 2.x and Python 3.x.
In Python 2.x, strings are ASCII by default. Unless stated otherwise (u"string" and unicode( "string" )) strings will limits to the charset. Therefore you can write English, or bad [whatever language using the Latin alphabet] since you can't access to accentuated letters.
In Python 3.x, all strings will be Unicode by default, what let you directly use any strings you want.

Therefore, the difference do not happen at the language level, in the way that you'll not have a different french sentence in Python 2.x and in Python 3.x. You can't have proper french sentence in Python 2.x by using the default strings. As for Japanese, you can't use it at all.


All this being said, why do you care ?
Unless you're crazy enough to build a toolbox and/or an generic configuration menu, you'll never have to face a case where your code should works on both Python 2.x and Python 3.x. Just marks the line each time you've code that would be incompatible with Python 3.x, and if the game author decide mid game to switch to the 8.x branch you'll know what lines you've to change.

There's the case of generic tools intended to works with any games. But for them there's more works trying to make them compatible with older version of Ren'Py than making them compatible with Python 2.x and Python 3.x. Over the near to 100 use of PY2 tests for my variable viewer (including the toolbox and configuration menu), only 9 are not due to the basestring if renpy.PY2 else str needed for the type validation. This while it have probably more than 100 fixes/downgrade needed for the compatibility with older versions of Ren'Py.
 
  • Like
Reactions: Mattock

Mattock

Newbie
May 27, 2018
91
79
well sometimes I need to convert between different "variable-types" and e.g. want to keep french and german "strings"...but oh well it seems I need to resort back to mighty ASCII (mäh)
and yes I would consider myself crazy and want to use some things in "both worlds" (in fact atm. my range is 6.99.14 to 7.5.x)

I tested a little with 8.0.1 and found the
type( someListVar ) had in PY2 given something like: type list
and now with 8(PY3) it's: class list

but you frighten me massively...you mean to say
if isinstance( someVar, basestring ):
must now be
if isinstance( someVar, str ):
?
oh no! I did that, like, hundreds of times...
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,957
16,192
well sometimes I need to convert between different "variable-types" [...]
Then let do it for you.


I tested a little with 8.0.1 and found the
type( someListVar ) had in PY2 given something like: type list
and now with 8(PY3) it's: class list
What is just a change in the terminology.


but you frighten me massively...you mean to say
if isinstance( someVar, basestring ):
must now be
if isinstance( someVar, str ):
?
Yes, it must. And since basestring is not known by Python 3.x


oh no! I did that, like, hundreds of times...
Yeah, me too...
 

shark_inna_hat

Active Member
Game Developer
Dec 25, 2018
705
2,765
but you frighten me massively...you mean to say
if isinstance( someVar, basestring ):
must now be
if isinstance( someVar, str ):
?
oh no! I did that, like, hundreds of times...
Put this little bit of code at the top of all your scripts:
Python:
try:
  basestring
except NameError:
  basestring = str
You can now use basestring in both py2 and py3, but you still need to watch out for cases where the API requires bytes (usually file-like objects or string/bytes/io buffers).
 
  • Like
Reactions: Mattock

Mattock

Newbie
May 27, 2018
91
79
shark_inna_hat: good idea
anne O'nymous: thanks for your patient explanations!
I think I'll mainly resort back to ASCII and the rest may need some special handling
edit: now I did a "python early"-function that checks py2 or py3 and upon the result I use unicode() or str()
____BAD, but if ever in the future UTF8 may be used, I'm ready.../edit
Thank you
 
Last edited:
  • Like
Reactions: anne O'nymous