From patrik.mrx at gmail.com Sat Aug 13 04:31:29 2016 From: patrik.mrx at gmail.com (mrx) Date: Sat, 13 Aug 2016 10:31:29 +0200 Subject: [code-quality] Minimal example Message-ID: Hi, Where can i find a bare minimum pylint checker that will successfully be registered and called? I've tried to write a checker like so: $ cat mychecker.py from pylint import checkers import pdb class Foo(checkers.BaseChecker): name = "FooBar" def visit_module(self, node): self.add_message('blaha-name', node=node) pdb.set_trace() def visit_importfrom(self, node): self.add_message('foo-name', node=node) pdb.set_trace() def visit_import(self, node): self.add_message('bar-name', node=node) pdb.set_trace() def register(linter): linter.register_checker(Foo(linter)) print "Mychecker registered successfully it seems" I get the print from register but neither of my visit_* methods seems to get called, i cannot see why. I run it like so: PYTHONPATH=. pylint --load-plugins=mychecker -rn main.py testmodule What am i missing? Regards, Patrik Iselind -------------- next part -------------- An HTML attachment was scrubbed... URL: From pcmanticore at gmail.com Sun Aug 14 09:32:16 2016 From: pcmanticore at gmail.com (Claudiu Popa) Date: Sun, 14 Aug 2016 16:32:16 +0300 Subject: [code-quality] Minimal example In-Reply-To: References: Message-ID: On Sat, Aug 13, 2016 at 11:31 AM, mrx wrote: > Hi, > > Where can i find a bare minimum pylint checker that will successfully be > registered and called? > > I've tried to write a checker like so: > $ cat mychecker.py > from pylint import checkers > import pdb > > class Foo(checkers.BaseChecker): > > name = "FooBar" > > def visit_module(self, node): > self.add_message('blaha-name', node=node) > pdb.set_trace() > > def visit_importfrom(self, node): > self.add_message('foo-name', node=node) > pdb.set_trace() > > def visit_import(self, node): > self.add_message('bar-name', node=node) > pdb.set_trace() > > def register(linter): > linter.register_checker(Foo(linter)) > print "Mychecker registered successfully it seems" > > I get the print from register but neither of my visit_* methods seems to > get called, i cannot see why. > > I run it like so: > PYTHONPATH=. pylint --load-plugins=mychecker -rn main.py testmodule > > What am i missing? > > > Hi, You will have to provide as well the message dictionary that you checker is going to emit. I just documented this here: https://docs.pylint.org/en/latest/custom_checkers.html#writing-your-own-checker This part needs more documentation work though, so if you notice any other inconsistency, let me know. Claudiu -------------- next part -------------- An HTML attachment was scrubbed... URL: From patrik.mrx at gmail.com Wed Aug 17 15:37:10 2016 From: patrik.mrx at gmail.com (Patrik Iselind) Date: Wed, 17 Aug 2016 21:37:10 +0200 Subject: [code-quality] Minimal example In-Reply-To: References: Message-ID: Thanks, i got it to work now. I have some feedback on the page you referred to. I was missing the implements line as well. This was not highlighted at all. Bullet two concerning priority. How checkers are ordered (internally?) doesn't help me to decide if i should set a negative priority close to zero or very far from zero in order for the checker to be first or at least among the first. I interpret this page as a resource you'd give programmers new to pylint checkers to get them started, awesome start! I think it would be really helpful if the page gave a overview of how the AST is buid and how i'm meant to access for example function variables in a function or the identifiers defined in a module. Where can i find a list of all the visit_* methods that i can use? I cannot find any class defining them all, are they dynamically called somehow? In examples directory referred to, looking at custom_raw.py. It implements process_module() instead of visit_*. What is the difference? When should i choose one over the other? Thanks a lot for your assistance in getting my first checker running. // Patrik Den 2016-08-14 kl. 15:32, skrev Claudiu Popa: > > > On Sat, Aug 13, 2016 at 11:31 AM, mrx > wrote: > > Hi, > > Where can i find a bare minimum pylint checker that will > successfully be registered and called? > > I've tried to write a checker like so: > $ cat mychecker.py > from pylint import checkers > import pdb > > class Foo(checkers.BaseChecker): > > name = "FooBar" > > def visit_module(self, node): > self.add_message('blaha-name', node=node) > pdb.set_trace() > > def visit_importfrom(self, node): > self.add_message('foo-name', node=node) > pdb.set_trace() > > def visit_import(self, node): > self.add_message('bar-name', node=node) > pdb.set_trace() > > def register(linter): > linter.register_checker(Foo(linter)) > print "Mychecker registered successfully it seems" > > I get the print from register but neither of my visit_* methods > seems to get called, i cannot see why. > > I run it like so: > PYTHONPATH=. pylint --load-plugins=mychecker -rn main.py testmodule > > What am i missing? > > > > > Hi, > > You will have to provide as well the message dictionary that you checker > is going to emit. I just documented this here: > https://docs.pylint.org/en/latest/custom_checkers.html#writing-your-own-checker > > > This part needs more documentation work though, so if you notice > any other inconsistency, let me know. > > > Claudiu -------------- next part -------------- An HTML attachment was scrubbed... URL: From pcmanticore at gmail.com Wed Aug 17 17:05:50 2016 From: pcmanticore at gmail.com (Claudiu Popa) Date: Thu, 18 Aug 2016 00:05:50 +0300 Subject: [code-quality] Minimal example In-Reply-To: References: Message-ID: On Wed, Aug 17, 2016 at 10:37 PM, Patrik Iselind wrote: > Thanks, i got it to work now. > > I have some feedback on the page you referred to. > > I was missing the implements line as well. This was not highlighted at > all. > > Bullet two concerning priority. How checkers are ordered (internally?) > doesn't help me to decide if i should set a negative priority close to zero > or very far from zero in order for the checker to be first or at least > among the first. > > I interpret this page as a resource you'd give programmers new to pylint > checkers to get them started, awesome start! I think it would be really > helpful if the page gave a overview of how the AST is buid and how i'm > meant to access for example function variables in a function or the > identifiers defined in a module. Where can i find a list of all the visit_* > methods that i can use? I cannot find any class defining them all, are they > dynamically called somehow? > > In examples directory referred to, looking at custom_raw.py. It implements > process_module() instead of visit_*. What is the difference? When should i > choose one over the other? > > Thanks a lot for your assistance in getting my first checker running. > > // Patrik > > Hi Patrik, These are all really good questions! Would you mind adding your feedback over this issue (https://github.com/PyCQA/pylint/issues/1071), where I am tracking the documentation effort for writing a new checker? In the mean time, some answers for your questions: - probably you shouldn't care that much about the priority, I don't know what its initial purpose was, so I presume it could be removed at some point. For what I care, each checker should not care about its order of execution, especially when considering calling them in a parallel environment. - sure, we need to document these as well. Basically, any node from the builtin ast module should be available in pylint as well, under a visit_ method. - the process_module method is called whenever the checker is also a raw checker. The checkers can be AST checkers, operating on trees, token checkers, operating on tokens and raw checkers, operating on the file content itself. A checker can be all of these at the same time, if you declare the right __implements__. process_module is usually used when you need the entire content of the file for some reason. Of course, this can also be implemented with a visit_module() and getting the string representation of the module node, although we have some problems now with that, since we can't respect the invariant that ast.to_string() == file content. -------------- next part -------------- An HTML attachment was scrubbed... URL: From patrik.mrx at gmail.com Thu Aug 18 08:15:33 2016 From: patrik.mrx at gmail.com (mrx) Date: Thu, 18 Aug 2016 14:15:33 +0200 Subject: [code-quality] Minimal example In-Reply-To: References: Message-ID: Done, thanks again! Patrik Iselind On Wed, Aug 17, 2016 at 11:05 PM, Claudiu Popa wrote: > > > On Wed, Aug 17, 2016 at 10:37 PM, Patrik Iselind > wrote: > >> Thanks, i got it to work now. >> >> I have some feedback on the page you referred to. >> >> I was missing the implements line as well. This was not highlighted at >> all. >> >> Bullet two concerning priority. How checkers are ordered (internally?) >> doesn't help me to decide if i should set a negative priority close to zero >> or very far from zero in order for the checker to be first or at least >> among the first. >> >> I interpret this page as a resource you'd give programmers new to pylint >> checkers to get them started, awesome start! I think it would be really >> helpful if the page gave a overview of how the AST is buid and how i'm >> meant to access for example function variables in a function or the >> identifiers defined in a module. Where can i find a list of all the visit_* >> methods that i can use? I cannot find any class defining them all, are they >> dynamically called somehow? >> >> In examples directory referred to, looking at custom_raw.py. It >> implements process_module() instead of visit_*. What is the difference? >> When should i choose one over the other? >> >> Thanks a lot for your assistance in getting my first checker running. >> >> // Patrik >> >> > Hi Patrik, > > These are all really good questions! > > Would you mind adding your feedback over this issue > (https://github.com/PyCQA/pylint/issues/1071), > where I am tracking the documentation effort for writing a new checker? > > In the mean time, some answers for your questions: > > - probably you shouldn't care that much about the priority, > I don't know what its initial purpose was, so I presume it could > be removed at some point. For what I care, each checker should > not care about its order of execution, especially when considering > calling them in a parallel environment. > > - sure, we need to document these as well. Basically, any node > from the builtin ast module should be available in pylint as well, > under a visit_ method. > > - the process_module method is called whenever the checker is also > a raw checker. The checkers can be AST checkers, operating on trees, > token checkers, operating on tokens and raw checkers, operating on the > file content itself. A checker can be all of these at the same > time, if you declare the right __implements__. process_module is usually > used when you need the entire content of the file for some reason. > Of course, this can also be implemented with a visit_module() > and getting the string representation of the module node, although > we have some problems now with that, since we can't respect the > invariant that ast.to_string() == file content. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From wsha.code at gmail.com Fri Aug 26 17:42:02 2016 From: wsha.code at gmail.com (Will S) Date: Fri, 26 Aug 2016 17:42:02 -0400 Subject: [code-quality] Valid global and constant names Message-ID: I am trying to understand why pylint treats module-level global variables as constants when checking the validity of their names. I though pylint followed PEP8 but if I look here: https://www.python.org/dev/peps/pep-0008/#id42 I see that global variables should follow the same format as function names (with some caveats about beginning with a "_" or being protected by __all__). Is the problem that it is difficult to determine whether a module-level variable is a constant or a global variable, so it was decided to err on the side of constants since use of global variables is generally discouraged and the invalid-name check can be locally disabled for the few global variables that are needed? Will -------------- next part -------------- An HTML attachment was scrubbed... URL: From ben+python at benfinney.id.au Sat Aug 27 01:06:33 2016 From: ben+python at benfinney.id.au (Ben Finney) Date: Sat, 27 Aug 2016 15:06:33 +1000 Subject: [code-quality] Valid global and constant names References: Message-ID: <851t1ax0km.fsf@benfinney.id.au> Will S writes: > I am trying to understand why pylint treats module-level global > variables as constants when checking the validity of their names. One thing to realise is that this is a case where the term ?variable? doesn't really help us. The language only knows that it's a name bound to an object. The concept ?variable versus constant? is not a concept that's enforcible in Python. Public module-level names should be either code objects, or constants. Module-level names that are not constants or code objects, should be implementation-only and therefore should be named with a leading underscore for use only within the module. This is an implication from PEP 8: Global Variable Names (Let's hope that these variables are meant for use inside one module only.) > Is the problem that it is difficult to determine whether a > module-level variable is a constant or a global variable Partly, yes: Python quite deliberately doesn't have a way for defining unmodifiable name bindings, so ?constant? is only a social convention. Mostly, though, it's an opinion expressed in the style guide: Don't make a name part of the public API unless it's a code object (a function or class), or a constant. -- \ ?One of the most important things you learn from the internet | `\ is that there is no ?them? out there. It's just an awful lot of | _o__) ?us?.? ?Douglas Adams | Ben Finney