From me at jarradhope.com Sun May 3 06:08:42 2015 From: me at jarradhope.com (Jarrad Hope) Date: Sun, 3 May 2015 11:08:42 +0700 Subject: [code-quality] Parsing Docstrings? Message-ID: Hey again Any ideas how can I get the docstring from a module or function? I was hoping to do something like ast.get_docstring(node.pytype()) Thanks, Jarrad From ben+python at benfinney.id.au Sun May 3 07:15:13 2015 From: ben+python at benfinney.id.au (Ben Finney) Date: Sun, 03 May 2015 15:15:13 +1000 Subject: [code-quality] Parsing Docstrings? References: Message-ID: <85twvudyxq.fsf@benfinney.id.au> Jarrad Hope writes: > Any ideas how can I get the docstring from a module or function? Once the code object is defined, its ?__doc__? attribute contains the docstring . What happens when you use that? -- \ ?The way to build large Python applications is to componentize | `\ and loosely-couple the hell out of everything.? ?Aahz | _o__) | Ben Finney From me at jarradhope.com Sun May 3 07:30:52 2015 From: me at jarradhope.com (Jarrad Hope) Date: Sun, 3 May 2015 12:30:52 +0700 Subject: [code-quality] Parsing Docstrings? In-Reply-To: <85twvudyxq.fsf@benfinney.id.au> References: <85twvudyxq.fsf@benfinney.id.au> Message-ID: hurr .. theres a .doc attribute of the node which has it all. sorry :) On Sun, May 3, 2015 at 12:15 PM, Ben Finney wrote: > Jarrad Hope writes: > >> Any ideas how can I get the docstring from a module or function? > > Once the code object is defined, its ?__doc__? attribute contains the > docstring . > > What happens when you use that? > > -- > \ ?The way to build large Python applications is to componentize | > `\ and loosely-couple the hell out of everything.? ?Aahz | > _o__) | > Ben Finney > > _______________________________________________ > code-quality mailing list > code-quality at python.org > https://mail.python.org/mailman/listinfo/code-quality From kay.hayen at gmail.com Sun May 3 11:40:20 2015 From: kay.hayen at gmail.com (Kay Hayen) Date: Sun, 3 May 2015 11:40:20 +0200 Subject: [code-quality] Jedi 0.9.0 is now a static analysis library In-Reply-To: References: Message-ID: Hello Dave, in my Python compiler Nuitka, I am using the "ast" module, and it's working fine for many things, but it lends itself badly to other things. I am condemned to do my own static analysis, as it's intended for optimization. My interest is in the reporting and also auto-format of source code. I would love to be able to report about source code easily for "profile guided optimization", or make annotations about Nuitka's finding in HTML reports from generated output. And I want a coherent code base for my private and work projects, and would like to be able to apply formatting, even function call style changes automatically, but on a programmatic base. I think the two tools are very similar. The biggest difference is > probably static analysis, which you definitely need for certain > refactorings. > Static analysis is great for auto-format indeed. Being e.g. able to tell that a method is only there for overload because it raises a "must be overloaded" exception, that kind of thing would otherwise be too hard. However Jedi definitely has fewer AST functions. The node/leaf objects > of Jedi are at the moment quite simple. I'm willing to add > functionality there, but only if it's used. Currently there's only the > functions there that Jedi needs internally. To support the well known > refactorings (e.g. inline/extract name/function), we might need to add > a few methods there. > With RedBaron, I can do this (bare with me on code quality, and by no means assume it's competent RedBaron usage): def updateString(string_node): # Skip doc strings for now. if string_node.parent.type in ("class", "def", None): return value = string_node.value def isQuotedWith(quote): return value.startswith(quote) and value.endswith(quote) for quote in "'''", '"""', "'", '"': if isQuotedWith(quote): break else: assert False, value real_value = value[len(quote):-len(quote)] assert quote + real_value + quote == value if "\n" not in real_value: # Single characters, should be quoted with "'" if len(eval(value)) == 1: if real_value != "'": string_node.value = "'" + real_value + "'" else: if '"' not in real_value: string_node.value = '"' + real_value + '"' And then call this: for node in red.find_all("StringNode"): try: updateString(node) except Exception: print("Problem with", node) node.help(deep = True, with_formatting = True) raise It allows me do enforce some rules according to strings that are not multi-line. My rules there are, do not use triple quites without a new-line, strings of resulting length 1, become 'a' or '\n' and others, use "" or "ab", except of course "'" is valid and 'some "quote" would be too' as well. I do a bunch of these, and like to have these things, to e.g. make sure that my multi-line calling convention lines up the "=" signs nicely, etc, inserting and removing white space from tuples, comma separated stuff, etc. To me, it's not about, if I should do this, but if it can be done. > > Does it provide a bounding box for code constructs? > > I'm not really sure what you mean. Jedi knows the exact positions of > objects. At the moment there's no method like RedBaron's > `bounding_box`. Relative positions could be easily calculated with the > current parser. However, I don't know what such a BoundingBox would be > doing. > That is the caret, typically used in stack traces, and fits the concept of a cursor. If I go to a report, then I will want to have the bounding box. When e.g. highlighting a function or a call expression, or argument expression, I am not only interested in where it starts, but where it ends. For an XHTML report of Nuitka performance compared to CPython performance on the same code (which is my plan for this autumn, at about the time it starts to make actual sense), with the "ast" module and apparently "jedi", all I get is this: f( arg1(), arg2(), c ** d) + g() And I would like to mouse over or highlight and know where the call to f() ends, where the third argument ends, what the operation "+" entails. Without a bounding box, that falls down. In fact, I would also want some position, like the "+" or "(" to indicate which bounding box I mean. My problem there with the "ast" module boils down to this: >>> ast.parse("a+b").body[0].value.col_offset 0 >>> ast.dump(ast.parse("a+b").body[0]) "Expr(value=BinOp(left=Name(id='a', ctx=Load()), op=Add(), right=Name(id='b', ctx=Load())))" With RedBaron, I get to have a "bounding_box". I must admit to not yet have used it. But I aspire to. And even for Nuitka, I would love to have the position of the "+" for use tracebacks in at least improved mode, as opposed to the first argument. But performance and bugs are keeping me away from considering any alternatives to "ast" there. So sure, I am asking of Jedi, if it has that bounding box, precisely to address this. With RedBaron, I can do this: >>> from redbaron import RedBaron >>> red = RedBaron("a+b") >>> red[0] a+b >>> red[0].second_formatting = " " >>> red 0 a+ b That of course also means, it knows the "+" location, or I can infer it: >>> red[0].second.bounding_box BoundingBox (Position (1, 1), Position (1, 1)) >>> red[0].first.bounding_box BoundingBox (Position (1, 1), Position (1, 1)) >>> red[0].bounding_box BoundingBox (Position (1, 1), Position (1, 5)) Seems bounding boxes are relative, but it also has "get_absolute_bounding_box_of_attribute". So, eventually I am faced with the issue of producing run time information from expressions, and then to find the same expression again in two different "ast" forms. But for rendering and editing, both RedBaron seems like it might work with heavy fighting. I would love for you to provide a code example how to use Jedi for editing like I did above, and if you think that creating such reports could be based on Jedi parsing. My plan for Nuitka now entails to probably identify an expression in Nuitka uniquely by path. That "uid" for code in a module is probably a new idea. The "uid" could be a run time number, hash code, which is then resolvable looking at the original code again in a new parse with even another tool that provides more detail. Finding it then in RedBaron or Jedi again may involve some normalization. The "ast" module hides some things from me, e.g. try/except/finally is nested statements in at least Python2. Yours, Kay -------------- next part -------------- An HTML attachment was scrubbed... URL: From davidhalter88 at gmail.com Mon May 4 17:57:37 2015 From: davidhalter88 at gmail.com (Dave Halter) Date: Mon, 4 May 2015 17:57:37 +0200 Subject: [code-quality] Jedi 0.9.0 is now a static analysis library In-Reply-To: References: Message-ID: Hi Kay I will not write a very lengthy email here, but just guide you in a general direction of how Jedi handles things. First I want you to know that Jedi doesn't have a public API for its parser, YET. This is intentional. As long as there are no real users of it, why make it public? So if you're interested in a parser only (not static analysis), RedBaron might be the better choice for now, because Jedi's parser API is not offical yet. Pretty sure this will change, though. 2015-05-03 11:40 GMT+02:00 Kay Hayen : > With RedBaron, I can do this (bare with me on code quality, and by no means > assume it's competent RedBaron usage): > > def updateString(string_node): > # Skip doc strings for now. > if string_node.parent.type in ("class", "def", None): > return > > value = string_node.value > > def isQuotedWith(quote): > return value.startswith(quote) and value.endswith(quote) > > for quote in "'''", '"""', "'", '"': > if isQuotedWith(quote): > break > else: > assert False, value > > real_value = value[len(quote):-len(quote)] > assert quote + real_value + quote == value > > if "\n" not in real_value: > # Single characters, should be quoted with "'" > if len(eval(value)) == 1: > if real_value != "'": > string_node.value = "'" + real_value + "'" > else: > if '"' not in real_value: > string_node.value = '"' + real_value + '"' > > And then call this: > > for node in red.find_all("StringNode"): > try: > updateString(node) > except Exception: > print("Problem with", node) > node.help(deep = True, with_formatting = True) > raise > > It allows me do enforce some rules according to strings that are not > multi-line. My rules there are, do not use triple quites without a new-line, > strings of resulting length 1, become 'a' or '\n' and others, use "" or > "ab", except of course "'" is valid and 'some "quote" would be too' as well. > > I do a bunch of these, and like to have these things, to e.g. make sure that > my multi-line calling convention lines up the "=" signs nicely, etc, > inserting and removing white space from tuples, comma separated stuff, etc. > > To me, it's not about, if I should do this, but if it can be done. I think you could do that in a very similar way in Jedi. E.g. with this you can get all docstrings: >>> for scope in p.module.walk(): ... print(repr(scope.raw_doc)) ... '' With this you get all string leafs: >>> from jedi.parser import tree >>> def nested(node): ... for child in node.children: ... if isinstance(node, tree.Node): ... nested(node) ... elif node.type == 'string': ... print(node) # You can change everything here. ... nested(jedi.parser.Parser(load_grammar(), SOURCE)) You can of course modify them. Look at the example below... > So sure, I am asking of Jedi, if it has that bounding box, precisely to > address this. > > With RedBaron, I can do this: > >>>> from redbaron import RedBaron >>>> red = RedBaron("a+b") >>>> red[0] > a+b > >>>> red[0].second_formatting = " " >>>> red > 0 a+ b > > That of course also means, it knows the "+" location, or I can infer it: > >>>> red[0].second.bounding_box > BoundingBox (Position (1, 1), Position (1, 1)) >>>> red[0].first.bounding_box > BoundingBox (Position (1, 1), Position (1, 1)) >>>> red[0].bounding_box > BoundingBox (Position (1, 1), Position (1, 5)) >>> from jedi.parser import Parser, load_grammar >>> Parser(load_grammar(), 'a + b') > >>> p = Parser(load_grammar(), 'a + b') >>> p.module.children [Node(simple_stmt, [Node(arith_expr, [, , ]), ]), ] >>> expression = p.module.children[0].children[0] >>> expression Node(arith_expr, [, , ]) >>> b = p.module.children[0].children[0].children[2] >>> b >>> b.prefix ' ' >>> b.start_pos (1, 4) >>> b.end_pos (1, 5) >>> expression.children[1] >>> expression.children[1].start_pos (1, 2) >>> b.prefix = '' >>> b.value = '3' # Make the expression to '+3' instead of '+ b' >>> p.module.get_code() 'a +3' So as you can see, Jedi is all about positions. Jedi knows the positions of all leafs as well as the prefixes (whitespace + comments) of that stuff. > I would love for you to provide a code example how to use Jedi for editing > like I did above, and if you think that creating such reports could be based > on Jedi parsing. I hope my example above is good enough. It shows how easy it is to play with code. Jedi nodes are really simple, but still powerful. Let me know if something is still unclear. ~ Dave From me at jarradhope.com Thu May 7 17:02:58 2015 From: me at jarradhope.com (Jarrad Hope) Date: Thu, 7 May 2015 22:02:58 +0700 Subject: [code-quality] assigning node type with function annotations? In-Reply-To: References: Message-ID: This is how far I got with this, https://gist.github.com/jarradh/02dd8f5ad07527c9fd10 In the example go through Arguments(i imagine I'll have to apply transform on functiondef later) and apply an explicit transformation, and I manage to apply a Const type to all of them but I got stuck at how to switch based on node._annotype.name since Const instantiates with the name as a value and therefore it's a string type. How can I switch the Const type based on node._annotype.name ? Or is there a better way of going about this? On Tue, Apr 28, 2015 at 1:55 PM, Claudiu Popa wrote: > On Tue, Apr 28, 2015 at 9:03 AM, Jarrad Hope wrote: >> Hello >> >> Been using astroid extensively this past week, really enjoying it! Great work! > > Thank you. > >> >> What's the best way I can deliberately set the type of an argument, >> based on the function annotations? > > Currently we don't have any mechanism for this (but it is something > that we want). One way to do it would be to add a Transform in > astroid.brain for Function nodes, which checks that it has > annotations, infers them and replaces the default inference with that > one. From pcmanticore at gmail.com Thu May 7 17:39:59 2015 From: pcmanticore at gmail.com (Claudiu Popa) Date: Thu, 7 May 2015 18:39:59 +0300 Subject: [code-quality] assigning node type with function annotations? In-Reply-To: References: Message-ID: On Thu, May 7, 2015 at 6:02 PM, Jarrad Hope wrote: > This is how far I got with this, > https://gist.github.com/jarradh/02dd8f5ad07527c9fd10 > > In the example go through Arguments(i imagine I'll have to apply > transform on functiondef later) and apply an explicit transformation, > and I manage to apply a Const type to all of them but I got stuck at > how to switch based on node._annotype.name > since Const instantiates with the name as a value and therefore it's a > string type. > > How can I switch the Const type based on node._annotype.name ? > Or is there a better way of going about this? > > You'll have to infer node._annontype.name (which can be a Class) and get its name. Then retrieving the name from builtins and try to go from there. Something along these lines: import builtins type = next(node._annotype.infer()) const = Const(vars(builtins)[type.name]()) From me at jarradhope.com Thu May 7 18:37:03 2015 From: me at jarradhope.com (Jarrad Hope) Date: Thu, 7 May 2015 23:37:03 +0700 Subject: [code-quality] assigning node type with function annotations? In-Reply-To: References: Message-ID: Ahh thank-you so much! I ended up with this so I can define list, seq, dict, etc def argument_annotation_inference(node, context=None): _type = next(node._annotype.infer()) klass = vars(builtins)[_type.name] return iter([CONST_CLS[klass](klass())]) On Thu, May 7, 2015 at 10:39 PM, Claudiu Popa wrote: > On Thu, May 7, 2015 at 6:02 PM, Jarrad Hope wrote: >> This is how far I got with this, >> https://gist.github.com/jarradh/02dd8f5ad07527c9fd10 >> >> In the example go through Arguments(i imagine I'll have to apply >> transform on functiondef later) and apply an explicit transformation, >> and I manage to apply a Const type to all of them but I got stuck at >> how to switch based on node._annotype.name >> since Const instantiates with the name as a value and therefore it's a >> string type. >> >> How can I switch the Const type based on node._annotype.name ? >> Or is there a better way of going about this? >> >> > > > You'll have to infer node._annontype.name (which can be a Class) and > get its name. Then retrieving the name from builtins and try to go from there. > Something along these lines: > > import builtins > > type = next(node._annotype.infer()) > const = Const(vars(builtins)[type.name]()) From fajwilson at gmail.com Mon May 18 11:45:44 2015 From: fajwilson at gmail.com (Frank Wilson) Date: Mon, 18 May 2015 10:45:44 +0100 Subject: [code-quality] Site issues: Pylint Messages Wikidot Message-ID: Does anyone on this list administrate pylint-messages.wikidot.com ? I just wanted to point out there is some pretty nasty ad code on there. I am getting click jerked to some random spammy website every time I hit my back button. I'm confident my computer is clean. I probably haven't noticed until now because I usually run uBlock in my browser (but was not on this occasion). Thought I should reach out to the warn the community as it comes up pretty high in google search ranks. Regards, Frank From pcmanticore at gmail.com Mon May 18 17:08:58 2015 From: pcmanticore at gmail.com (Claudiu Popa) Date: Mon, 18 May 2015 18:08:58 +0300 Subject: [code-quality] Site issues: Pylint Messages Wikidot In-Reply-To: References: Message-ID: Hi, On Mon, May 18, 2015 at 12:45 PM, Frank Wilson wrote: > Does anyone on this list administrate pylint-messages.wikidot.com ? Ah, I always saw that when I started contributing to Pylint. It is actually something that we are sanctioning as an official message list? If so, maybe we should move away from it, we have documentation for documenting messages and all that. Could open a new issue on the bugtracker, please? https://bitbucket.org/logilab/pylint > > I just wanted to point out there is some pretty nasty ad code on > there. I am getting click jerked to some random spammy website every > time I hit my back button. > > I'm confident my computer is clean. I probably haven't noticed until > now because I usually run uBlock in my browser (but was not on this > occasion). > > Thought I should reach out to the warn the community as it comes up > pretty high in google search ranks. > > Regards, > > Frank > _______________________________________________ > code-quality mailing list > code-quality at python.org > https://mail.python.org/mailman/listinfo/code-quality From froilan0709 at gmail.com Fri May 22 12:13:08 2015 From: froilan0709 at gmail.com (=?UTF-8?B?5bKz5pif5YWG?=) Date: Fri, 22 May 2015 18:13:08 +0800 Subject: [code-quality] Custom exit value of check-items Message-ID: Hi, I?m using pylint in buildbot, and I want to customize failure items. Now I think buildbot give failure result since pylint returns(exit) contains 1 or 2. So, I wonder how can I customize an error/warning to trigger failure. e.g, when pylint found an C0101, it exit 1 or 2. Thanks Froilan -------------- next part -------------- An HTML attachment was scrubbed... URL: From me at the-compiler.org Fri May 22 16:41:20 2015 From: me at the-compiler.org (Florian Bruhin) Date: Fri, 22 May 2015 16:41:20 +0200 Subject: [code-quality] Custom exit value of check-items In-Reply-To: References: Message-ID: <20150522144120.GC448@tonks> * ??? [2015-05-22 18:13:08 +0800]: > I?m using pylint in buildbot, and I want to customize failure items. Note buildbot comes with a PyLint buildstep which parses the results: http://docs.buildbot.net/current/manual/cfg-buildsteps.html#step-PyLint > Now I think buildbot give failure result since pylint returns(exit) > contains 1 or 2. I think it exists with 0 when no errors are found, and != 0 if there are errors. That worked fine in buildbot for me (until I discovered the thing above). Florian -- http://www.the-compiler.org | me at the-compiler.org (Mail/XMPP) GPG: 916E B0C8 FD55 A072 | http://the-compiler.org/pubkey.asc I love long mails! | http://email.is-not-s.ms/ -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 819 bytes Desc: not available URL: From radu at devrandom.ro Fri May 22 16:48:57 2015 From: radu at devrandom.ro (Radu Ciorba) Date: Fri, 22 May 2015 17:48:57 +0300 Subject: [code-quality] Custom exit value of check-items In-Reply-To: References: Message-ID: <1432306137.3280494.275761977.54134528@webmail.messagingengine.com> Apologies, i'm not 100% sure I understood what you need. You can always disable any checks you don't care for: --disable=C0101,C0102 Do you still want to see the warnings about stuff like C0101, just don't want the build to be marked as failed? In the latest versions of pylint the exit code is a bitwise or of the following: MSG_TYPES_STATUS = { 'I' : 0, # info 'C' : 16, # conventions 'R' : 8, # refactor 'W' : 4, # warning 'E' : 2, # error 'F' : 1 # fatal } You could always write some custom logic in your buildbot config, or wrap your pylint invocation in a bash script that looks at the return value and marks the build appropriately. Regards, R. On Fri, May 22, 2015, at 01:13 PM, ??? wrote: > Hi, > > I?m using pylint in buildbot, and I want to customize failure items. > > Now I think buildbot give failure result since pylint returns(exit) > contains 1 or 2. > > So, I wonder how can I customize an error/warning to trigger failure. > e.g, when pylint found an C0101, it exit 1 or 2. > > Thanks Froilan > _________________________________________________ > code-quality mailing list code-quality at python.org > https://mail.python.org/mailman/listinfo/code-quality -------------- next part -------------- An HTML attachment was scrubbed... URL: From indigo at bitglue.com Sun May 31 21:10:17 2015 From: indigo at bitglue.com (Phil Frost) Date: Sun, 31 May 2015 15:10:17 -0400 Subject: [code-quality] Pyflakes 0.9.0 released Message-ID: I'm happy to announce the release of Pyflakes 0.9.0. The release is available on PyPI: https://pypi.python.org/pypi/pyflakes and the code is available on GitHub: https://github.com/pyflakes/pyflakes/releases/tag/0.9.0 Bugfixes: - Exit gracefully, not with a traceback, on SIGINT and SIGPIPE. - Fix incorrect report of undefined name when using lambda expressions in generator expressions - Don't crash on DOS line endings on Windows and Python 2.6 - Don't report an undefined name if the 'del' which caused a name to become undefined is only conditionally executed - Properly handle differences in list comprehension scope in Python 3 - Improve handling of edge cases around 'global' defined variables New Features: - Report an error for 'return' outside a function I'd like to thank all the people who contributed to this release: - Aaron Meurer - Adi Roiban - Charles-Francois Natali - Florent Xicluna - Ian Cordasco - Jan St?rtz - ryneeverett - Steven Myint From graffatcolmingov at gmail.com Sun May 31 22:41:11 2015 From: graffatcolmingov at gmail.com (Ian Cordasco) Date: Sun, 31 May 2015 15:41:11 -0500 Subject: [code-quality] Pyflakes 0.9.0 released In-Reply-To: References: Message-ID: On May 31, 2015 2:24 PM, "Phil Frost" wrote: > > I'm happy to announce the release of Pyflakes 0.9.0. The release is > available on PyPI: > > https://pypi.python.org/pypi/pyflakes > > and the code is available on GitHub: > > https://github.com/pyflakes/pyflakes/releases/tag/0.9.0 > > Bugfixes: > > - Exit gracefully, not with a traceback, on SIGINT and SIGPIPE. > - Fix incorrect report of undefined name when using lambda expressions > in generator expressions > - Don't crash on DOS line endings on Windows and Python 2.6 > - Don't report an undefined name if the 'del' which caused a name to > become undefined is only conditionally executed > - Properly handle differences in list comprehension scope in Python 3 > - Improve handling of edge cases around 'global' defined variables > > New Features: > > - Report an error for 'return' outside a function > > I'd like to thank all the people who contributed to this release: > > - Aaron Meurer > - Adi Roiban > - Charles-Francois Natali > - Florent Xicluna > - Ian Cordasco > - Jan St?rtz > - ryneeverett > - Steven Myint > _______________________________________________ > code-quality mailing list > code-quality at python.org > https://mail.python.org/mailman/listinfo/code-quality Thanks for another awesome release Phil! -------------- next part -------------- An HTML attachment was scrubbed... URL: