In python, is there a "pass" equivalent for a variable assignment - python

I am using a library function called get_count_and_price which returns a 2-tuple (count,price). In many places I use both time and price. However, in some I only need time or price. So right now, if I only need count, I assign to (count,price) and leave the price unused.
This works great and causes no trouble in and of itself.
However...
I use Eclipse with PyDev, and the new version 1.5 automatically shows errors and warnings. One of the warnings it shows is unused variables. In the above example, it flags price as unused. This is the sort of behavior which is great and I really appreciate PyDev doing this for me. However, I would like to skip the assignment to price altogether. Ideally, I would like something like:
(count,None) = get_count_and_price()
Now as we all know, None cannot be assigned to. Is there something else I could do in this case?
I know I could do something like
count = get_count_and_price()[0]
but I am asking just to see if anyone has any better suggestions.

I think there's nothing wrong with using the [0] subscript, but sometimes people use the "throwaway" variable _. It's actually just like any other variable (with special usage in the console), except that some Python users decided to have it be "throwaway" as a convention.
count, _ = get_count_and_price()
About the PyDev problem, you should just use the [0] subscript anyway. But if you really want to use _ the only solution is to disable the unused variable warnings if that bothers you.

Using _ as severally proposed may have some issues (though it's mostly OK). By the Python style guidelines we use at work I'd normally use count, unused_price = ... since pylint is configured to ignore assignments to barenames starting with unused_ (and warn on USE of any such barename instead!-). But I don't know how to instruct PyDev to behave that way!

If you go to the Eclipse -> Preferences… window, you can actually specify which variable names PyDev should ignore if they're unused (I'm looking at the newest PyDev 1.5.X).
If you go to PyDev -> Editor -> Code Analysis and look at the last field that says "Don't report unused variable if name starts with"
Enter whatever names you want in there and then use that name to restrict what variable names PyDev will ignore unused warnings for.
By default, it looks like PyDev will hide unused variable warnings for any variables that have names beginning with "dummy", "_", or "unused".
As #TokenMacGuy said below, I'd recommend against using just "_" because it has special meaning in certain scenarios in Python (specifically it's used in the interactive interpreter).

We often do this.
count, _ = get_count_and_price()
or this
count, junk = get_count_and_price()

I'd rather name it _price instead, for these reasons:
It solves the conflict with gettext and the interactive prompt, which both use _
It's easy to change back into price if you end up needing it later.
As others have pointed out, the leading underscore already has a connotation of "internal" or "unused" in many languages.
So your code would end up looking like this:
(count, _price) = get_count_and_price()

I'll go after a Necromancer badge. :)
You said you're using PyDev. In PyDev (at least recent versions - I didn't check how far back), any variable name that starts with "unused" will be exempt from the Unused Variable warning. Other static analysis tool may still complain, though (pyflakes does - but it seems to ignore this warning in a tuple-unpacking context anyway).

Related

Is there a lint rule for creating python tuples without bracets?

I want linter to restrict me from using tuple by mistakingly adding a comma at the end of an assignment.
I think that explicitly creating a tuple by using brackets is the only right way to create them.
I have tried 'Pylint' with option '--enable=all', it doesn't warn me of the danger.
# this looks bad and probably was added by mistake
a = 'abc',
# this immediately informs the reader that this is a tuple
# and for sure was added deliberately
b = ('abc',)
I look for a rule for any python linter that would return a warning for the first assignment but not for the second one.
If you have any tips for looking for rules for linters they would be much appreciated.
I have found a tool that does that and even more and becomes standard: Black: https://github.com/psf/black.

Why does Pylint object to single-character variable names?

I'm still getting used to Python conventions and using Pylint to make my code more Pythonic, but I'm puzzled by the fact that Pylint doesn't like single character variable names. I have a few loops like this:
for x in x_values:
my_list.append(x)
and when I run pylint, I'm getting Invalid name "x" for type variable (should match [a-z_][a-z0-9_]{2,30} -- that suggests that a valid variable name must be between 3 and 31 characters long, but I've looked through the PEP8 naming conventions and I don't see anything explicit regarding single lower case letters, and I do see a lot of examples that use them.
Is there something I'm missing in PEP8 or is this a standard that is unique to Pylint?
A little more detail on what gurney alex noted: you can tell Pylint to make exceptions for variable names which (you pinky swear) are perfectly clear even though less than three characters. Find in or add to your pylintrc file, under the [FORMAT] header:
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_,pk,x,y
Here pk (for the primary key), x, and y are variable names I've added.
Pylint checks not only PEP8 recommendations. It has also its own recommendations, one of which is that a variable name should be descriptive and not too short.
You can use this to avoid such short names:
my_list.extend(x_values)
Or tweak Pylint's configuration to tell Pylint what variable name are good.
In explicitly typed languages, one-letter name variables can be ok-ish, because you generally get the type next to the name in the declaration of the variable or in the function / method prototype:
bool check_modality(string a, Mode b, OptionList c) {
ModalityChecker v = build_checker(a, b);
return v.check_option(c);
}
In Python, you don't get this information, so if you write:
def check_modality(a, b, c):
v = build_checker(a, b)
return v.check_option(c)
you're leaving absolutely no clue for the maintenance team as to what the function could be doing, and how it is called, and what it returns. So in Python, you tend to use descriptive names:
def check_modality(name, mode, option_list):
checker = build_checker(name, mode)
return checker.check_option(option_list)
And you even add a docstring explaining what the stuff does and what types are expected.
Nowadays there is also an option to override regexp. I.e., if you want to allow single characters as variables:
pylint --variable-rgx="[a-z0-9_]{1,30}$" <filename>
So, Pylint will match PEP8 and will not bring additional violations on top. Also you can add it to .pylintrc.
The deeper reason is that you may remember what you intended a, b, c, x, y, and z to mean when you wrote your code, but when others read it, or even when you come back to your code, the code becomes much more readable when you give it a semantic name. We're not writing stuff once on a chalkboard and then erasing it. We're writing code that might stick around for a decade or more, and be read many, many times.
Use semantic names. Semantic names I've used have been like ratio, denominator, obj_generator, path, etc. It may take an extra second or two to type them out, but the time you save trying to figure out what you wrote even half an hour from then is well worth it.
pylint now has good-names-rgxs, which adds additional regex patterns to allow for variable names.
The difference is that that variable-rgx will override any previous rules, whereas good-names-rgxs adds rules on top of existing rules. That makes it more flexible, because you don't need to worry about breaking previous rules.
Just add this line to pylintrc to allow 1 or 2 length variable names:
good-names-rgxs=^[_a-z][_a-z0-9]?$
^ # starts with
[_a-z] # 1st character required
[_a-z0-9]? # 2nd character optional
$ # ends with
The configuration that pylint itself generates will allow i, j, k, ex, Run, though not x,y,z.
The general solution is to adjust your .pylintrc, either for your account ($HOME/.pylintrc) or your project (<project>/.pylintrc).
First install pylint, perhaps inside your .env:
source myenv/bin/activate
pip install pylint
Next run pylint, but the file is too long to maintain manually right from the start, and so save on the side:
pylint --generate-rcfile > ~/.pylintrc--full
Look at the generated ~/.pylintrc--full. One block will say:
[BASIC]
# Good variable names which should always be accepted, separated by a comma.
good-names=i,
j,
k,
ex,
Run,
_
Adjust this block as you like (adding x,y,..), along with any other blocks, and copy your selected excerpts into ~/.pylintrc (or <project>/.pylintrc).

Is there a python naming convention for avoiding conflicts with standard module names?

PEP 8 recommends using a single trailing underscore to avoid conflicts with python keywords, but what about conflicts with module names for standard python modules? Should that also be a single trailing underscore?
I'm imagining something like this:
import time
time_ = time.time()
PEP 8 doesn't seem to address it directly.
The trailing underscore is obviously necessary when you're colliding with a keyword, because your code would otherwise raise a SyntaxError (or, if you're really unlucky, compile to mean something completely different than you intended).
So, even in contexts where you have a class attribute, instance attribute, function parameter, or local variable that you want to name class, you have to go with class_ instead.
But the same isn't true for time. And I think in those cases, you shouldn't postfix an underscore for time.
There's precedent for that—multiple classes in the stdlib itself have methods or data attributes named time (and none of them have time_).
Of course there's the case where you're creating a name at the same scope as the module (usually meaning a global variable or function). Then you've got much more potential for confusion, and hiding the ability to access anything on the time module for the rest of the current scope.
I think 90% of the time, the answer is going to be "That shouldn't be a global".
But that still leaves the other 10%.
And there's also the case where your name is in a restricted namespace, but that namespace is a local scope inside a function where you need to access the time module.
Or, maybe, in a long, complicated function (which you shouldn't have any of, but… sometimes you do). If it wouldn't be obvious to a human reader that time is a local rather than the module, that's just as bad as confusing the interpreter.
Here, I think that 99% of the remaining time, the answer is "Just pick a different name".
For example, look at this code:
def dostuff(iterable):
time = time.time()
for thing in iterable:
dothing(thing)
return time.time() - time # oops!
The obvious answer here is to rename the variable start or t0 or something else. Besides solving the problem, it's also a more meaningful name.
But that still leaves the 1%.
For example, there are libraries that generate Python code out of, say, a protocol specification, or a .NET or ObjC interface, where the names aren't under your control; all you can do is apply some kind of programmatic and unambiguous rule to the translated names. In that case, I think a rule that appends _ to stdlib module names as well as keywords might be a good idea.
You can probably come up with other examples where the variable can't just be arbitrarily renamed, and has to (at least potentially) live in the same scope as the time module, and so on. In any such cases, I'd go for the _ suffix.

Word delimitors for python coding style?

PEP8 use _ as a word delimitor, for example, a method named get_context_data.
caw is so cool when you want change get_context_data to set_context_data.
I googled and added set iskeyword-=_ to my vimrc.
But another problem comes with this change, I can autocomplete the method name when I type get_, menu shows me context not context_data I want, is there a way to solve the problem?
By changing the 'iskeyword' setting, you influence (and potentially break) a lot of things; among them word motions (w, e, etc.), completions (your problem here), and syntax highlighting.
I recommend keeping the original setting (after all, get_context_data as a single variable should probably also be represented by a single word). You can use my camelcasemotion plugin to work on the underscore-separated fragments. With the plugin, you can either override the original motions and text objects, or use ca,w instead of caw.
Better don't change the iskeyword option. There are alot of commands need it. If you just want to make editing underscore connected string (a_b_c_d) easier, you could try this mapping:
onoremap iu :<c-u>normal! T_vt_<cr>
onoremap au :<c-u>normal! F_vf_<cr>
with this mapping, (iu means In Underscore, you can change it). you could for example
get_cont[I]ext_data ( [I]:cursor)
you type ciu you got get_[I]_data , diu will do delete, au will do operation also on wrapped underscores.
But, for these cases, the above mapping does not work (or work unexpectedly ^_*)
g[I]et_context_data -> [I]_context_data (you could do bct_ instead)
get_context_dat[I]a -> get_context_[I] (you could do ecT_ or T_cw instead)
Because the mapping doesn't work wordwise .you can make it suit your needs however.

PEP8, locals() and interpolation

Here is some code:
foo = "Bears"
"Lions, Tigers and %(foo)s" % locals()
My PEP8 linter (SublimeLinter) complains about this, because foo is "unreferenced". My question is whether PEP8 should count this type of string interpolation as "referenced", or if there is a good reason to consider this "bad style".
Well, it isn't referenced. The part that's questionable style is using locals() to access variables instead of just accessing them by name. See this previous question for why that's a dubious idea. It's not a terrible thing, but it's not good style for a program that you want to maintain in the long term.
Edit: It's true that when you use a literal format string, it seems more explicit. But part of the point of the previous post is that in a larger program, you will probably wind up not using a literal format string. If it's a small program and you don't care, go ahead and use it. But warning about things that are likely to cause maintainability problems later is also part of what style guides and linters are for.
Also, locals isn't a canonical representation of names that are explicitly referenced in the literal. It's a canonical representation of all names in the local namespace. You can still do it if you like, but it's basically a loose/sloppy alternative to explicitly using the names you're using, which is again, exactly the sort of thing linters are supposed to warn you about.
Even if you reject BrenBarn's argument that foo isn't referenced, if you accept the argument that passing locals() in string formatting should be flagged, it may not be worth writing to code to consider foo referenced.
First, in every case where that extra code would help, the construct is not acceptable anyway, and the user is going to have to ignore a lint warning anyway. Yes, there is some harm in giving the user two lint warnings to ignore when there's only actually one problem, especially if one of the warnings is somewhat misleading. But is it enough harm to justify writing very complicated code and introduce new bugs into the linter?
You also have to consider that for this to actually work, the linter has to recognize not just % formatting, but also {} formatting, and every other kind of string formatting, HTML templating, etc. that the user could be using. In practice, this means handling various very common forms, and providing some kind of hook for the user to describe anything else.
And, on top of that, even if you don't think it should work with arbitrarily-generated format strings, it surely has to at least work with l10n. How is that going to work? If the format string is generated by something like gettext, the linter has no way of knowing whether foo is referenced, unless it can check all of the translations and see that at least one of them references foo—which means it has to understand (or have hooks to be taught) every string translation mechanism, and have access to the translation database.
So, I would suggest that, even if you consider the warning spurious in this case, you leave it there anyway. At most, add something which qualifies the warning:
foo is possibly unreferenced, but in a function that uses locals()
The following wouldn't make SublimeLinter happy either, It looks up each variable name referenced in the string and substitutes the corresponding value from the namespace mapping, which defaults to the caller's locals. As such it show the inherent limitation a utility like SublimeLinter has when trying to determine if something has been referenced in Python). My advice is just ignore SublimeLinter or add code to fake it out, like foo = foo. I've had to do something like the latter to get rid of C compiler warnings about things which were both legal and intended.
import re
import sys
SUB_RE = re.compile(r"%\((.*?)\)s")
def local_vars_subst(s, namespace=None):
if namespace is None:
namespace = sys._getframe(1).f_locals
def repl(matchobj):
var = matchobj.group(1).strip()
try:
retval = namespace[var]
except KeyError:
retval = "<undefined>"
return retval
return SUB_RE.sub(repl, s)
foo = "Bears"
print local_vars_subst("Lions, Tigers and %(foo)s")

Categories