ericmj / decimal

Arbitrary precision decimal arithmetic

Home Page:https://hexdocs.pm/decimal/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dialyzer warning when passing float to `Decimal.new/1`

tetiana12345678 opened this issue · comments

Hey @ericmj

We have updated decimal to version 1.5.0 and running dialyzer on our project producing an error:

The call 'Elixir.Decimal':new(float()) breaks the contract (t() | integer() | 'Elixir.String':t()) -> t()

I can see that you have plans to depricate Decimal.new/1 which accepts float here https://github.com/ericmj/decimal/blob/master/lib/decimal.ex#L1034 in version 1.6

I am wondering if typespec for Decimal.new/1 in version 1.5 should include float @spec new(t | integer | String.t() | float) :: t to make transition smoother.

I am happy to submit a PR, but wanted to highlight this first and see what you think :)

Good question! On one hand it might be surprising and/or annoying change, on the other soft deprecating it means removing it from docs and since specs are kinda part of docs I'm not sure.

It probably doesn't matter anyway, but did you get this dialyzer error on "your" code or via things like ecto etc that depend on decimal?

Hey @wojtekmach It's on our code. It was easy to fix, just had to investigate a bit what was going on. What happen is we updated ecto, which updated decimal and we were calling Decimal.new/1 passing in float directly.

I think removing the type from the typespec is a good way to do the deprecation for a thing like that - it's hard to make the compiler produce a warning statically otherwise.

I wasn't really sure what the best solution was here so thanks for the inputs. In this case I think the typespecs helped since it showed that deprecated code was being called.

@michalmuskala @ericmj I think it still boils down to whether we consider dialyzer warning to be soft deprecation or a regular deprecation and I'm not sure we have a clear answer (maybe we have :))

If it's ok to consider typespec change as soft deprecation (even though it warns) we keep things as is, if it's part of regular deprecation cycle we should revert typespec change, cut new patch release, and remove the type in next minor release.

I'd keep things as is. Thanks @tetiana12345678, it's an interesting issue that I don't remember being brought up elsewhere :)

For anyone else trying to work around this, if you're using dialyxir you can add any substring of the warning to your .dialyzer-ignore-warnings file, eg:

The call 'Elixir.Decimal':new(float()) breaks the contract (t() | integer() | 'Elixir.String':t()) -> t()

Unfortunately, the ignore code I posted above fixes one dialyzer error, but creates others. I am currently using a fork of the repo based on the one line change in #85 to get around dialyzer failures, which cause our CI build to fail.

@harlantwood does the warning come from the code you own or from dependencies? If it's your code that shouldn't be too hard to change (but yeah, sorry for inconvenience), if it's dependencies' we should open issues to move them off that.

Um, somewhat embarrassingly, when I switched back to your latest released version the problem has gone away. I guess it was our code, and we stopped passing floats to Decimal.new.