Skip to content

Conversation

@makarchuk
Copy link
Contributor

Implemented float conversion for functions in math module

let value = objfloat::get_value(value).is_infinite();
if args.args.len() != 1 {
return Err(vm.new_type_error(format!(
"erf() takes exactly one argument ({} given)",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error string contains the wrong function name erf. Maybe it makes sense to create a seperate function for this double extraction. The code is now copy pasted about 3 times. Please create a helper function which checks the amount of arguments and extracts the floating point number.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely agree with you that this copy-paste is horrible solution. I hoped to start a discussion from it.

I think this helper should be integrated into arg_check macro.

Whereve arguments are parsed and one of them is expected to be float it can actually be any other real number type macro should really check make_float, otherwise it'll be cpython incompatible

In [1]: class A:
   ...:     def __float__(self):
   ...:         return 1.0
   ...:     

In [2]: float(A())
Out[2]: 1.0

In [3]: import math

In [4]: math.log(A())
Out[4]: 0.0

So I hope you can give an advice on this one. what'd be the best way to aproach it?
Should it be just hardcoded into a macro as a special case?

I'm also pretty sure that the same implicit conversion should be done for for int

For example in this case I'm passing True as a port number for socket and it only fails, because of premissions, (it works from root!).

In [1]: import socket
In [3]: s = socket.socket()
In [4]: s.bind(('localhost', True))
---------------------------------------------------------------------------
PermissionError                           Traceback (most recent call last)
<ipython-input-4-ced4611914b1> in <module>()
----> 1 s.bind(('localhost', True))

PermissionError: [Errno 13] Permission denied

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not yet place this automatic coercion in the arg_check macro yet. This macro is used really a lot. I suggest to create a helper function like coerce_into_float or something like that and place that in objfloat.rs for now. We can always extend the arg_check macro later when we require this logic in all places.

Basically my doubt is: Are you sure we always need to convert int to float at all function calls?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, fair point.

One more question then, if you don't mind:

Can arg_check be used to check just a number of arguments, without checking a type?

It'll be handy to use arg_check to control a number of arguments a new helper function, to control their types.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is possible. I believe you can set the type to None, and then it will extract the correct amount of arguments into the given rust names.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's great. I'll try to come back with a fix as soon as possible

Copy link
Contributor

@windelbouwman windelbouwman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please create a helper function to extract the proper arguments as mentioned in another comment.

@makarchuk
Copy link
Contributor Author

Sorry, I'm not sure it's ok here, but I have a habbit of force-pushing development branches occasionally, so I did this.

Anyway. It went ok without much code duplication without helper method, since I'm using (as you've adviced) arg_check to check number of arguments.

I've also added python based test for this.

@makarchuk
Copy link
Contributor Author

I see that Travis build failed with

----------------------------- Captured stderr call -----------------------------
Traceback (most recent call last):
  File "/home/travis/build/RustPython/RustPython/tests/snippets/math.py", line 20, in <module>
    import math
  File "/home/travis/build/RustPython/RustPython/tests/snippets/math.py", line 21, in <module>
    assert(math.exp(2) == math.exp(2.0))
AttributeError: module 'math' has no attribute 'exp'

Which I don't really understand. It might be platform-dependent

makarchuk and others added 3 commits February 5, 2019 19:21
Assuming `exp` function was missing for platform-dependant reasons, let's try to test it with `sin` instead
@windelbouwman windelbouwman merged commit 87ceed7 into RustPython:master Feb 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants