Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Too many false positives - what's the use? #1861

stanislavkozlovski started this conversation in General
Discussion options

Hey! I am heavily using typing annotations in my code and trying to get help with mypy to ensure I don't miss anything, but after running it on my code I find it gives me so many false positives that it's useless to me. It requires me to be overly verbose just to please it, and most of the things it points out aren't problems to me.

Here are some examples:

mypy . --explicit-package-bases
utils/byte_utils.py:44: error: Returning Any from function declared to return "float" [no-any-return]

byte_utils

class DataUnit(ABC):
 value: float
 @property
 @abstractmethod
 def base(self) -> int:
 pass
 @property
 @abstractmethod
 def steps(self) -> int:
 """
 The amount of steps to convert to bytes.
 """
 pass
code:44 def to_bytes(self) -> float:
 return self.value * (self.base ** self.steps)

It's obvious this is a float being returned - isn't it?

Then:

utils/cost_utils.py:29: error: Item "int" of "Union[int, float, PriceRepresentation]" has no attribute "value" [union-attr]
utils/cost_utils.py:29: error: Item "float" of "Union[int, float, PriceRepresentation]" has no attribute "value" [union-attr]
 def __init__(self, dollar_price: typing.Union[typing.Union[int, float], PriceRepresentation], time_unit: TimeUnit):
 if not isinstance(dollar_price, int) and not isinstance(dollar_price, float) and not isinstance(dollar_price, PriceRepresentation):
 raise ValueError(f"dollar_price must be an int, float or PriceRepresentation, got {type(dollar_price)}")
 self.dollar_price: float = float(dollar_price) if (
 isinstance(dollar_price, float) or isinstance(dollar_price, int)
 ) else dollar_price.value
 self.time_unit: TimeUnit = time_unit
 self._per_second_cost = self.dollar_price / self.time_unit.to_seconds()

^ this is a bit dirty by me - having to check instances and convert, but still - I handle it properly and i'll never call .value on a non-PriceRepresentation class

then:

deployers/instance_deployer.py:66: error: "list[InstanceDeployment]" has no attribute "is_empty" [attr-defined]
options: List[InstanceDeployment] = _collect_minimum_number_of_instances_satisfying_constraints(
 min_num_disks=minimum_applicable_disk_deployment.num_volumes,
 min_cpus=required_cpus, vms=vms_to_choose_from)
options: InstanceDeploymentOptions = InstanceDeploymentOptions(
 deployment_matching_constraints=deployment_matching_constraints,
 cheaper_options=cheaper_deployment_options
 )
 if options.is_empty():
 raise DeploymentSolutionNotFound("No deployment options were found.")

It doesn't seem to support changing variable types?

Then

deployers/disk_deployer.py:51: error: Argument "capacity" to "VirtualVolume" has incompatible type "DataUnit"; expected "Gigabyte" [arg-type]
 gb_space_per_disk = Terabyte(total_tb_to_persist.value / num_disks).convert_to(Gigabyte)
 volume = VirtualVolume(
 capacity=gb_space_per_disk,
 type=volume_type
 )

when the constructor accepts a GB precisely:

class VirtualVolume:
 def __init__(self, capacity: Gigabyte, type: VirtualVolumeType):

for some reason, it can't figure out that Gigabyte inherits DataUnit

Can you please tell me if my code is wrong, or I'm using mypy wrong, or my expectations aren't in order? At this point, I really don't see a way I can use mypy in a way that's useful to me

You must be logged in to vote

Replies: 1 comment

Comment options

It's obvious this is a float being returned - isn't it?

The Any is because we define int ** int as returning Any in some cases, because it may return a float (if there are negative numbers involved). The option you are using here (--warn-return-any) is quite strict and I wouldn't recommend turning it on if you're just getting started with typing.

^ this is a bit dirty by me - having to check instances and convert, but still - I handle it properly and i'll never call .value on a non-PriceRepresentation class

I tried something resembling your snippet in mypy-playground and couldn't reproduce this error: https://mypy-play.net/?mypy=latest&python=3.12&flags=strict&gist=8c91ef07f1b622146546b04ea36dc4a4 . If you can provide a self-contained piece of code exhibiting this error, please report a bug to mypy.

It doesn't seem to support changing variable types?

You can turn on the --allow-redefinition flag and this code should be accepted.

for some reason, it can't figure out that Gigabyte inherits DataUnit

As far as the type checker sees, you are passing an instance of the parent class when only the child class is accepted. The constructor requires an object of type Gigabyte, but the value is of type DataUnit.

Possibly the convert_to() method needs to have a generic return type, so that if you pass Gigabyte it returns Gigabyte.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /