Hi, Von: Markus Schaber > Von: Dino Viehland [mailto:di...@microsoft.com] > > So you want to warn if the file contains a print statement w/o from > > __future__ import print_function? What if it's a call to print such > > as > > print('foo') which is valid in both 2.x and 3.x? > > Considering our user base, I could ignore this corner case, as the user can > simply get rid of the warning by adding the import statement. > > > Either way you should be able to just update ParsePrintStmt in Parser.cs. > > But dealing w/ the case of the parens would be a little more difficult > > - but I think you can just peek at the next token after print and see > > if it's a parenthesis right after we eat the print keyword. > > Ok, I'll see whether I can do that.
The patch below emits a warning during Compilation for print statements whose argument list does not start with a '(' if Py3k warnings are enabled. Best regards Markus Schaber 944eab0d7da3660001f1dabf473f48d5ddd4ee25 Languages/IronPython/IronPython/Compiler/Parser.cs | 18 ++++++++++++++++-- .../IronPython/IronPython/Resources.Designer.cs | 9 +++++++++ Languages/IronPython/IronPython/Resources.resx | 3 +++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Languages/IronPython/IronPython/Compiler/Parser.cs b/Languages/IronPython/IronPython/Compiler/Parser.cs index bdef897..d756593 100644 --- a/Languages/IronPython/IronPython/Compiler/Parser.cs +++ b/Languages/IronPython/IronPython/Compiler/Parser.cs @@ -38,6 +38,7 @@ namespace IronPython.Compiler { public class Parser : IDisposable { // TODO: remove IDisposable // immutable properties: private readonly Tokenizer _tokenizer; + private readonly bool _warnPython30; // mutable properties: private ErrorSink _errors; @@ -70,7 +71,7 @@ namespace IronPython.Compiler { #region Construction - private Parser(CompilerContext context, Tokenizer tokenizer, ErrorSink errorSink, ParserSink parserSink, ModuleOptions languageFeatures) { + private Parser(CompilerContext context, Tokenizer tokenizer, ErrorSink errorSink, ParserSink parserSink, ModuleOptions languageFeatures, bool warnPython30) { ContractUtils.RequiresNotNull(tokenizer, "tokenizer"); ContractUtils.RequiresNotNull(errorSink, "errorSink"); ContractUtils.RequiresNotNull(parserSink, "parserSink"); @@ -79,6 +80,7 @@ namespace IronPython.Compiler { _tokenizer = tokenizer; _errors = errorSink; + _warnPython30 = warnPython30; if (parserSink != ParserSink.Null) { _sink = parserSink; } @@ -123,7 +125,7 @@ namespace IronPython.Compiler { tokenizer.Initialize(null, reader, context.SourceUnit, SourceLocation.MinValue); tokenizer.IndentationInconsistencySeverity = options.IndentationInconsistencySeverity; - Parser result = new Parser(context, tokenizer, context.Errors, context.ParserSink, compilerOptions.Module); + Parser result = new Parser(context, tokenizer, context.Errors, context.ParserSink, compilerOptions.Module, options.WarnPython30); result._sourceReader = reader; return result; } @@ -379,6 +381,13 @@ namespace IronPython.Compiler { Severity.FatalError); } + private void ReportWarning(string message) + { + SourceLocation start = _tokenizer.IndexToLocation(_lookahead.Span.Start); + SourceLocation end = _tokenizer.IndexToLocation(_lookahead.Span.End); + _errors.Add(_sourceUnit, message, new SourceSpan(start, end), 0, Severity.Warning); + } + #endregion #region LL(1) Parsing @@ -1017,6 +1026,11 @@ namespace IronPython.Compiler { //print_stmt: 'print' ( [ expression (',' expression)* [','] ] | '>>' expression [ (',' expression)+ [','] ] ) private PrintStatement ParsePrintStmt() { Eat(TokenKind.KeywordPrint); + + if (_warnPython30 && PeekToken().Kind != TokenKind.LeftParenthesis) { + ReportWarning(Resources.UsingPrintStatementWarning); + } + var start = GetStart(); Expression dest = null; PrintStatement ret; diff --git a/Languages/IronPython/IronPython/Resources.Designer.cs b/Languages/IronPython/IronPython/Resources.Designer.cs index b564a8e..4a5d5fe 100644 --- a/Languages/IronPython/IronPython/Resources.Designer.cs +++ b/Languages/IronPython/IronPython/Resources.Designer.cs @@ -419,5 +419,14 @@ namespace IronPython { return ResourceManager.GetString("UnknownFutureFeature", resourceCulture); } } + + /// <summary> + /// Looks up a localized string similar to Python 2 print statement found. For Python 3 compatibility, use "from __future__ import print_function" and the print() function instead.. + /// </summary> + internal static string UsingPrintStatementWarning { + get { + return ResourceManager.GetString("UsingPrintStatementWarning", resourceCulture); + } + } } } diff --git a/Languages/IronPython/IronPython/Resources.resx b/Languages/IronPython/IronPython/Resources.resx index 3d89b3d..f666b1f 100644 --- a/Languages/IronPython/IronPython/Resources.resx +++ b/Languages/IronPython/IronPython/Resources.resx @@ -238,4 +238,7 @@ <data name="UnknownFutureFeature" xml:space="preserve"> <value>future feature is not defined:</value> </data> + <data name="UsingPrintStatementWarning" xml:space="preserve"> + <value>Python 2 print statement found. For Python 3 compatibility, use "from __future__ import print_function" and the print() function instead.</value> + </data> </root> \ No newline at end of file _______________________________________________ Ironpython-users mailing list Ironpython-users@python.org http://mail.python.org/mailman/listinfo/ironpython-users