-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Stdlib] Add PythonObject.__contains__
#3101
Conversation
b8315e3
to
8571772
Compare
5a8c2ad
to
b4fc045
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! Do you mind adding some unit tests please?
b4fc045
to
8d364f9
Compare
🆕 unit tests👍 yep it is important, should there be more ? Python throws an error if the object is not iterable, But mojo gets an Current PR have a debug_assert when we have the error and returns False. Is it possible to make |
@rd4com sorry this one fell off my queue, I will look at this on Monday and your comment about the re-raising an error and see what we can do about that. |
!sync |
8d364f9
to
3c96d04
Compare
Edit: see next comments, this one was for previous commitYes, it works better, but it is not yet the same error as python:
python
It could be because we are using We might need to use something like Any idea ? |
edit: implemented in next commits, see next commentsOk, according to python specification/docs Documentation: membership-test-details : We could use a new CPython also says that it would also try I'll join cpython chat channel if they have one to ask. The question would be: How to run an operator membership test from cypthon (in, not in) In addition, in a perfect world, we'd need to return an What do you think ? |
3c96d04
to
b81e384
Compare
Nice 👍 , we partially got this with last commit, it behaves more like python: in python class MyClass:
x = 1 print(123 in MyClass())
in python class MyClass:
x = 1
def __contains__(self, rhs):
return True print(123 in MyClass())
in mojo from python import Python
def main():
m = Python.import_module("myclass")
x = m.MyClass()
print(1 in x)
if we remove the
The difficulty is now to implement the last step of the "in" membership operator test.
|
stdlib/src/python/object.mojo
Outdated
@@ -1102,6 +1102,28 @@ struct PythonObject( | |||
""" | |||
return self._call_zero_arg_method("__invert__") | |||
|
|||
fn __contains__(self, rhs: PythonObject) raises -> Bool: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify, in one of your comments, you're asking about the return type here, correct? E.g. Bool
vs PythonObject
? I'm fine with Bool
as-is. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the return type of the function 👍
It should be good, Bool
can probably implicitly convert to PythonObject
if user do chaining.
(but it is something to keep in mind for the future)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly, I had the composability question in mind, and I think we're fine with Bool
for now.
For (1), are you asking about a user-defined type that implements
from https://docs.python.org/3/reference/expressions.html#membership-test-details |
Yes, we need to test the whole function (combinations of instances that: (In a way that does not pollute the python environment for other tests of |
One naive approach is just to have the different instances we want to test in their own test file with their own Python environment/CPython interpreter running. It's far from great, but an option. Could we leverage context managers and have a context managed CPython interpreter environment for each of these to avoid test pollution? |
edit: next commit have tests to assert the environement is clean between test_*.mojo
That is a great idea, context managers are good for that 👍 The difficulty is that from python import Python
def main():
A = Python()
B = Python()
A.eval("x = 123")
print(A.evaluate("x"))
print(B.evaluate("x")) The from python import Python
def main():
A = Python()
B = Python()
m = A.import_module("myclass")
print(A.import_module("sys").modules.keys()) #myclass
print(B.import_module("sys").modules.keys()) #myclass So if we import for testing it would contaminate the environment, (we should test assert that the environment stays clean with multiple test files too) Edit: Assertion done, see next commit |
b81e384
to
a8c0453
Compare
Hello, two more tests to test the testing environment:
For this to work, we need to be sure that the tests are done in that order. (A then B) What do you think ?
In addition:
|
a8c0453
to
50f4cfd
Compare
I don't know if we have a way to force the testing order of A and then B — either in lit, or how we run the tests internally in our Bazel environment (CC: @keith here). Perhaps just omit those tests for now but keep the others so we can rebase and land this? |
Signed-off-by: rd4com <[email protected]>
Signed-off-by: rd4com <[email protected]>
Signed-off-by: rd4com <[email protected]>
50f4cfd
to
9a8c755
Compare
Signed-off-by: rd4com <[email protected]>
Hello,
|
!sync |
probably not something we can enforce, probably best if we can find another way to validate this ordering. or split these tests into separate lit targets so they don't pollute the same global python environment |
✅🟣 This contribution has been merged 🟣✅ Your pull request has been merged to the internal upstream Mojo sources. It will be reflected here in the Mojo repository on the nightly branch during the next Mojo nightly release, typically within the next 24-48 hours. We use Copybara to merge external contributions, click here to learn more. |
[External] [Stdlib] Add `PythonObject.__contains__` Simple and small implementation, Improving the `🐍 Python` experience ! Example usage: ```mojo x = PythonObject([1,2,3]) if 1 in x: print("1 in x") ``` That method should be replaced by a `c-python` function if possible. Co-authored-by: rd4com <[email protected]> Closes #3101 MODULAR_ORIG_COMMIT_REV_ID: d08c1f856feda307b8da58ec0cf3442553b3acc7
Landed in 996fc97! Thank you for your contribution 🎉 |
[External] [Stdlib] Add `PythonObject.__contains__` Simple and small implementation, Improving the `🐍 Python` experience ! Example usage: ```mojo x = PythonObject([1,2,3]) if 1 in x: print("1 in x") ``` That method should be replaced by a `c-python` function if possible. Co-authored-by: rd4com <[email protected]> Closes #3101 MODULAR_ORIG_COMMIT_REV_ID: d08c1f856feda307b8da58ec0cf3442553b3acc7
Simple and small implementation,
Improving the
🐍 Python
experience !Example usage:
That method should be replaced by a
c-python
function if possible.