Pep 3105: the end of print?

E

Edward K Ream

Why won't it be possible to make 'print' in Python 3 that supports all
the functionality of the current print statement, and then translate to
that ?
I saw an assertion to the effect that it wasn't possible - but no proof.

As discussed in the original post, the problem is the reverse: the Python
2.x print statement does not support the keyword args required by the pep,
so that print(foo) **in Python 2.x** can not simulate the effect of the
print statement with a trailing comma. Here is the theorum carefully stated
and proved.

Theorem: is not possible to define a function called print in Python 3.x
such that

A) print (whatever) is syntaxtically valid in Python 2.x and

B) print(whatever) outputs what 'print whatever' outputs in Python 2.x for
all values of 'whatever'.

Proof:

It is impossible for the print function to simulate the effect of the print
statement with a trailing comma. Indeed, print ('line'), and print
('line',) (note the position of the commas) are valid in Python 2.x, but
neither does what is wanted. And print('line',end='') is invalid in Python
2.x. Let's look at some examples:

1. The following works (prints 'line after\n') in Python 2.x, but will not
suppress the newline in Python 3.x:

print('line'),
print('after')

2. The following doesn't work in Python 2.x. (It prints
"('line',)\nafter").

print ('line',)
print ('after')

3. print ('line',end='') produces a syntax error in Python 2.x:

print ('line',end='')
^
SyntaxError: invalid syntax

That's the proof. Can you find a flaw in it?

Edward
 
R

Roel Schroeven

Edward K Ream schreef:
Pep 3105 breaks a *lot* of code, despite the bland assertion that most
production programs don't use print.

Presumably, Guido wanted to improve print in such a way that *more* people
would use it. But the effect of the pep is that *less* people will be able
to use print, *regardless* of how backward compatible Python 3.x is
'allowed' to be.

AFAIK the intention is not primarily to get more people to use print.
Instead Guido has felt for some time that the print statement is a wart
in the language (see the references in PEP 3105 for his arguments), and
Python 3000 seems like a good opportunity to fix it once and for all.
Precisely because AFAIK the point of Python 3000 is to fix a number of
long-standing shortcomings, even if that means giving up a degree of
backward compatibility.
 
R

Roel Schroeven

Edward K Ream schreef:
The point of my original post was that if I want to maintain a common code
base the tool must translate 'print foo' to 'print2(foo)'.

At first sight it seems to me that it's pretty straightforward to
translate print(foo) to print2(foo) once "2to3" has done its job.

It looks your main issue is that you're complaining that Python 3000 is
going to break things in a non-backward compatible way. If you want to
change that, you're going to be fighting an uphill battle, as this quote
from PEP 3000 illustrates:

"We need a meta-PEP to describe the compatibility requirements. Python
3000 will break backwards compatibility. There is no requirement that
Python 2.9 code will run unmodified on Python 3.0.

I'm not sure whether it is reasonable to require that Python 2.x code
can be mechanically translated to equivalent Python 3.0 code; Python's
dynamic typing combined with the plans to change the semantics of
certain methods of dictionaries, for example, would make this task
really hard. However, it would be great if there was some tool that did
at least an 80% job of translation, pointing out areas where it wasn't
sure using comments or warnings. Perhaps such a tool could be based on
something like Pychecker."
 
S

Steven D'Aprano

Pep 3105 breaks a *lot* of code, despite the bland assertion that most
production programs don't use print.

Presumably, Guido wanted to improve print in such a way that *more* people
would use it.

I don't think Guido cares about _how many_ people use print. I think he
cares about making print better. If that leads to more people using it,
that's a bonus. But your and my guesses about what Guido cares about
aren't terribly important.

But the effect of the pep is that *less* people will be able
to use print, *regardless* of how backward compatible Python 3.x is
'allowed' to be.

I don't think that follows at all. print is only a problem if you expect
your code to work under both Python 2.x and 3.x. I wouldn't imagine
that many people are going to expect that: I know I don't. There are
likely to be a whole lot of things which change, sometimes radically, from
one to the other. They'll support one or the other, or fork the code, or
in extreme cases take over maintenance of Python 2.x (it is open source,
you can do that).

If you want to "future-proof" your Python code, well, you can't fully
because nobody yet knows all the things which will change. But you can
start by not calling print directly. There are a number of alternatives,
depending on what you're doing. Here's a simple function that does very
close to what print currently does:

def print_(*args, where=None, newline=True):
if where is None:
where = sys.stdout
args = [str(arg) for arg in args]
where.write(' '.join(args))
if newline:
where.write('\n')
 
S

Stefan Rank

The point of my original post was that if I want to maintain a common code
base the tool must translate 'print foo' to 'print2(foo)'.

I think you are misunderstanding the purpose of the 2to3 tool.
It is supposed to create a new version of the code that runs on py3,
while you can still run your *"old"* code on py2.x

There won't be a common code base for all python versions.
You will have to decide at what point you want to switch from developing
the 2.x code (and using the 2to3 tool to support py3) to developing the
py3 code.

(You might then develop a 3to2 tool, but I think this discussion is
getting way ahead of its time. ;-)
 
F

Fuzzyman

As discussed in the original post, the problem is the reverse: the Python
2.x print statement does not support the keyword args required by the pep,
so that print(foo) **in Python 2.x** can not simulate the effect of the
print statement with a trailing comma. Here is the theorum carefully stated
and proved.

Theorem: is not possible to define a function called print in Python 3.x
such that

A) print (whatever) is syntaxtically valid in Python 2.x and

B) print(whatever) outputs what 'print whatever' outputs in Python 2.x for
all values of 'whatever'.

Proof:

It is impossible for the print function to simulate the effect of the print
statement with a trailing comma. Indeed, print ('line'), and print
('line',) (note the position of the commas) are valid in Python 2.x, but
neither does what is wanted. And print('line',end='') is invalid in Python
2.x. Let's look at some examples:

1. The following works (prints 'line after\n') in Python 2.x, but will not
suppress the newline in Python 3.x:

print('line'),
print('after')

2. The following doesn't work in Python 2.x. (It prints
"('line',)\nafter").

print ('line',)
print ('after')

3. print ('line',end='') produces a syntax error in Python 2.x:

print ('line',end='')
^
SyntaxError: invalid syntax

That's the proof. Can you find a flaw in it?

I mentioned the 2to3 translator- the goal of which is *precisely* to
allow you to write code that will run on Python 2.X and when
translated run under Python 3.0.

You then repeated the problem with the 'print' statement.

It may be true that you won't be able to write code that runs
untranslated on 2 and 3. That doesn't stop you writing code for Python
2.X, then translating a version for Python 3. (Uhm... indeed that's
the point of 2to3.)

So you only have one codebase to maintain and you can still use
print...

Fuzzyman
http://www.voidspace.org.uk/python/articles.shtml
 
E

Edward K Ream

It looks your main issue is that you're complaining that Python 3000 is
going to break things in a non-backward compatible way.

No. My complaint is *only* that changing the meaning of 'print' is needless
pain.

Edward
 
S

Steven D'Aprano

Why won't it be possible to make 'print' in Python 3 that supports all
the functionality of the current print statement, and then translate to
that ?
I saw an assertion to the effect that it wasn't possible - but no proof.

As discussed in the original post, the problem is the reverse: the Python
2.x print statement does not support the keyword args required by the pep,
so that print(foo) **in Python 2.x** can not simulate the effect of the
print statement with a trailing comma. Here is the theorum carefully stated
and proved.

Theorem: is not possible to define a function called print in Python 3.x
such that

A) print (whatever) is syntaxtically valid in Python 2.x and

B) print(whatever) outputs what 'print whatever' outputs in Python 2.x for
all values of 'whatever'.
[snip]

That's the proof. Can you find a flaw in it?

No, but it doesn't matter. There's no particular reason why you have to
write "print (whatever)" in your code. What you need is *some function*
that is capable of duplicating the functionality of print, which can be
used under Python 2.x and 3. It isn't hard to write a function that will
duplicate print's functionality, so long as you give up the requirement
that it is called just like print.

The problem you describe with the print syntax only is a problem if you
insist on supporting Python 2.x and 3 from the same codebase. I don't
expect many people will try to do that. For those who do, don't use the
print syntax. As for the rest of us, we'll just continue to use print
using whichever syntax is appropriate.
 
S

Steven D'Aprano

I mentioned the 2to3 translator- the goal of which is *precisely* to
allow you to write code that will run on Python 2.X and when
translated run under Python 3.0.

Unfortunately, that is not a realistic goal for the 2to3 translator. The
goal is to accurately translate 80% of Python code that needs changing,
and issue warnings for the other 20%.

You then repeated the problem with the 'print' statement.

It may be true that you won't be able to write code that runs
untranslated on 2 and 3. That doesn't stop you writing code for Python
2.X, then translating a version for Python 3. (Uhm... indeed that's
the point of 2to3.)

So you only have one codebase to maintain and you can still use
print...

No, you have TWO sets of code. You have the code you write, and the code
you have run through 2to3. Even if 2to3 gives you 100% coverage, which it
won't, you still have two codebases.
 
E

Edward K Ream

So you only have one codebase to maintain and you can still use print...

Not if the theorum is correct.
It may be true that you won't be able to write code that runs
untranslated on 2 and 3.

That's my definition of a common code base. That is the content of the
theorum.
That doesn't stop you writing code for Python
2.X, then translating a version for Python 3. (Uhm... indeed that's the
point of 2to3.)

That is not what I would call a common code base. The developer would have
to run the translater every time the code changed. And if the Python 3.0
code were considered the 'master' code, the developer would need a 3to2
translater.

Either disprove the theorum or give up the notion of having a common code
base that uses print.

Edward
 
E

Edward K Ream

That's the proof. Can you find a flaw in it?
No, but it doesn't matter. There's no particular reason why you have to
write "print (whatever)" in your code. What you need is *some function*
that is capable of duplicating the functionality of print,

Precisely wrong. The title of this thread is 'the end of print', and the
whole point of my comments is that spelling matters.

I would have absolutely no objection to the pep if it specified some other
name for an 'official' print function. Pick any name, preferably longer
than two characters, that does not conflict with either an existing global
function or module.

Edward
 
F

Fuzzyman

Unfortunately, that is not a realistic goal for the 2to3 translator. The
goal is to accurately translate 80% of Python code that needs changing,
and issue warnings for the other 20%.

Right, but it *was* a stated aim of the translator when discussed on
Python-dev recently.
No, you have TWO sets of code. You have the code you write, and the code
you have run through 2to3. Even if 2to3 gives you 100% coverage, which it
won't, you still have two codebases.

Only one of which you maintain - if the translator works 100% (which I
accept may be unrealistic).

Fuzzyman
http://www.voidspace.org.uk/python/articles.shtml
 
F

Fuzzyman

Not if the theorum is correct.


That's my definition of a common code base. That is the content of the
theorum.

Ok - in which case it is very limited.

That is not what I would call a common code base.

But it is what I call a common code base. We are at an impasse. :)
The developer would have
to run the translater every time the code changed. And if the Python 3.0
code were considered the 'master' code, the developer would need a 3to2
translater.

Either disprove the theorum or give up the notion of having a common code
base that uses print.

Yes the use of print is changing in a backwards incompatible way, no
one is disputing that.

Personally I wish it wasn't, print 'feels like a statement' to me. But
it's not the end of the world and it is *definitely* going to be able
to be handled by 2to3.

It's also not about to change.

Fuzzyman
http://www.voidpsace.org.uk/python/articles.shtml
 
S

Steven D'Aprano

Precisely wrong.

Are you trying to say that the name "print" is more important to you
than the functionality?

If not, then I have no idea why you say I'm wrong.

The title of this thread is 'the end of print', and the
whole point of my comments is that spelling matters.

That might be the point you are trying to make, but you haven't succeeded.

I would have absolutely no objection to the pep if it specified some other
name for an 'official' print function. Pick any name, preferably longer
than two characters, that does not conflict with either an existing global
function or module.

Huh? Now you're just not making sense. If Python 3 dropped the print
statement and replaced it with official_print_function(), how would that
help you in your goal to have a single code base that will run on both
Python 2.3 and Python 3, while still using print?

In software development there is a common saying: "Good, Fast, Cheap --
Pick any two". The same holds here:

Keep the print name;
Keep the print functionality;
Keep a single code base.

Pick any two.
 
E

Edward K Ream

Keep the print name;
Keep the print functionality;
Keep a single code base.

Retain the print statement and its functionality, and define an
official_print_function to be used in the common code base. I would be
satisfied with this (it's what I do now), and it would cause no needless
problems for anyone. Having an official print function is a *good* idea,
provided it isn't called print :)

Edward
 
S

Steve Holden

Jean-Paul Calderone said:
[snip]

I don't think that follows at all. print is only a problem if you expect
your code to work under both Python 2.x and 3.x. I wouldn't imagine
that many people are going to expect that: I know I don't.

I think some people are confused that the language "Python 3.x" has "Python"
in its name, since there is already a language with "Python" in its name,
with which it is not compatible.
Right. Let's call Python 3.0 something different but related. How about
"snake oil"? ;-)

regards
Steve
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
Blog of Note: http://holdenweb.blogspot.com
See you at PyCon? http://us.pycon.org/TX2007
 
T

Tobias Brox

[Edward K Ream]
Not at all. Backwards compatibility means that one can still run old code
provided the code eschews new features. Python releases have generally
been backwards compatible with previous releases, with a few minor
exceptions. For example, my app runs fine on Python 2.2.2 through Python
2.5, and little work was required to make this happen.

2.2 -> 2.5 is a minor step, the 2.2-code should in general work out on
2.5 without problems.

2.6 -> 3.0 will be a major step, and code written for 2.6 or earlier
will in general not run on python 3.0. Hopefully this issue can be
partially solved by automatic code converting.
 
K

Klaas

That's the proof. Can you find a flaw in it?

Casting this in terms of theorem proving only obfuscates the
discussion.

Here is how to maintain a single codebase for this feature:

1. Convert all your print statements to 3.0 print functions, named
something else (say, print2())
2. define a module called compat26 containing:

def print2(*args, **kwargs):
# code to convert the above to print statements (better still,
sys.stdout.write())

3. in your code:
try:
from compat26 import print2
except (ImportError, SyntaxError):
# python 3.0
print2 = print

-Mike
 
S

Sam

3. in your code:
try:
from compat26 import print2
except (ImportError, SyntaxError):
# python 3.0
print2 = print

Python 2.5c1 (r25c1:51305, Aug 17 2006, 10:41:11) [MSC v.1310 32 bit
(Intel)] on win32
Type "copyright", "credits" or "license()" for more information. from compat26 import print2
except (ImportError, SyntaxError):
# python 3.0
print2 = print
SyntaxError: invalid syntax pass
except (ImportError, SyntaxError):
# python 3.0
print2 = print
SyntaxError: invalid syntax

Any and all aliasing must happen in compat26.py. My suggested solution is this:

#_compat30.py
print2 = print

#compat.py
try:
from _compat30 import print2
except SyntaxErorr, ImportError):
def print2():
....

--Sam
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,772
Messages
2,569,589
Members
45,100
Latest member
MelodeeFaj
Top