wemake-python-styleguide
wemake-python-styleguide copied to clipboard
Forbid types in variable name
Rule request
Thesis
Forbid using built-in type name in the variable name, either as prefix or suffix. It applies to all variable definitions: function arguments, assignments, with.
# bad
username_str = 'root'
username_str = current_user()
USERNAME_STR = 'root'
str_username = 'root'
# good
username = current_user()
username: str = current_user()
stranger = 'root'
default_user = User()
The rule should be applied to built-in types only: str, int, float, set, dict, and so on. Having context = Context() is fine.
Reasoning
Type annotations are better, they can be statically checked. Names can get outdated.
Good one! Are there any exceptions?
I guess there are: like list - it can me a lot of things, not just list() type.
I'd be confused if variable somethiing_list has type set or whatever ;)
It can have other types as well, for example: module_list = ModuleList()
Good point. Let's try to classify then
- Abbreviated, can be safely banned:
int(integer),bool(boolean),dict(dictionary). - Joined words, can be banned:
frozenset(frozen set),bytearray(byte array). - Real words but rarely used, consider banning:
float(hard to imagine context where it means something except floating point number),tuple(I know it is used for database entities but word "record" is a better synonym),bytes(can be something like "bytes_count", probably),complex(same as float, what else can be complex if not numbers). - Real words, proceed carefully:
set,list,slice,type,range.
I'm not sure about this one. I feel like there's a valid use case. Suppose you have a consuming API that takes a string but your data structure is using an int and the API doesn't auto-cast. Performing a cast every time seems silly. What would you propose the variable name be?
user = User(123)
user_id_as_str = str(user.id)
some_api(user_id_as_str)
some_other_api(user_id_as_str)
# etc..
We can probably move this to typed-linter, because it has type information, which will make the implementation way easier.
We can probably move this to typed-linter, because it has type information, which will make the implementation way easier.
- My philosophy is "something is better than nothing". It's ok to cover only some cases, not all.
- The issue is about the type information in the name independently of the actual type. If the name says
strbut the actual type isint, It's even worse.
What would you propose the variable name be?
In your sample, user_id doesn't conflict with anything, so it should be just user_id, why not.
Suppose you have a consuming API that takes a string but your data structure is using an int and the API doesn't auto-cast.
I can't recall such API, TBH, where int should be explicitly cast to str. For instance:
import requests
requests.get('http://httpbin.org/get', params=dict(id=1)).json()['args']
# {'id': '1'}