Skip to content

Add framework attribute in sys module #1343

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

Merged
merged 1 commit into from
Sep 10, 2019

Conversation

vazrupe
Copy link
Contributor

@vazrupe vazrupe commented Sep 5, 2019

Fixes #1342

Copy link
Member

@coolreader18 coolreader18 left a comment

Choose a reason for hiding this comment

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

Looks good, thanks for contributing!

@@ -225,6 +225,12 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef, builtins: PyObjectR
"unknown".to_string()
};

let framework = if cfg!(target_of = "macos") {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
let framework = if cfg!(target_of = "macos") {
let framework = if cfg!(target_os = "macos") {

@youknowone
Copy link
Member

youknowone commented Sep 5, 2019

Thanks for the contribution.

Here are a few concerns about this patch (and the issue too).

  • It seems it is not defined in document. https://docs.python.org/3/library/sys.html Please share if you know any use case of this attribute.
  • It seems it is expected to refer actual python framework (which is linked?). My pyenv python build in macos have just empty string. Probably this must be just empty string because RustPython is never built as Python.framework.
➜  ~ python
Python 3.7.0 (default, Aug 24 2018, 13:00:59)
[Clang 9.1.0 (clang-902.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.framework
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'sys' has no attribute 'framework'
>>> sys._framework
''
  • Writing a test code is recommended
  • This patch defines the attribute for all platforms. It seems it is not defined out of macOS. Check #[cfg(target_os = "macos")] and extend_class! for optional attribute.
➜  ~ python
Python 3.6.3 (default, Oct 12 2017, 21:12:06)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
p>>> import sys
>>> sys._framework
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'sys' has no attribute '_framework'
>>>

@vazrupe
Copy link
Contributor Author

vazrupe commented Sep 7, 2019

@youknowone

Thank you for comment.

Currently this code only affects the site module. Where to use:

RustPython/Lib/site.py

Lines 257 to 259 in 1dceae9

if sys.platform == "darwin" and sys._framework:
return joinuser("~", "Library", sys._framework,
"%d.%d" % sys.version_info[:2])

RustPython/Lib/site.py

Lines 271 to 272 in 1dceae9

if sys.platform == 'darwin' and sys._framework:
return f'{userbase}/lib/python/site-packages'

CPython also uses the sysconfig module. This is the same code as _getuserbase() in the site module.

    if sys.platform == "darwin" and sys._framework:
        return joinuser("~", "Library", sys._framework,
                        "%d.%d" % sys.version_info[:2])

site.getuserbase() returns the user base directory.

This function works as follows on my system:

$ python3     # is system python
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import site
>>> site.getuserbase()
'/Users/vazrupe/Library/Python/3.7'
>>> import sys
>>> sys._framework
'Python'

$ pyenv shell 3.7.0
$ python
Python 3.7.0 (default, Sep  7 2019, 14:41:54)
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import site
>>> site.getuserbase()
'/Users/vazrupe/.local'
>>> import sys
>>> sys._framework
''

As you commented, this value seems to be an empty string. In such a case, the following value will always be returned.

And this attribute is defined on all platforms. However, it is only implemented in 3.7+ and up, so it cannot be used in lower versions.

For example, in my windows(anaconda 3.7.3) environment it would run:

PS> python
Python 3.7.3 (default, Apr 24 2019, 15:29:51) [MSC v.1915 64 bit (AMD64)] :: Anaconda, Inc. on win32

Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys._framework
''

In a Mac(use pyenv 3.6.6) environment, it runs like this:

$ pyenv shell 3.6.6
$ python
Python 3.6.6 (default, Sep  7 2019, 14:35:29)
[GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys._framework
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'sys' has no attribute '_framework'

Thanks for reading!

@youknowone
Copy link
Member

Thanks for detailed explanation. I am sorry to confuse it.

It seems CI fails because RustPython CI now tests only with CPython 3.6.
Instead of testing private attributes, how about testing site.py feature which uses _framework attribute?

@vazrupe
Copy link
Contributor Author

vazrupe commented Sep 8, 2019

I apologize for writing the wrong test case first. For RustPython developers using mac, this test may fail even with Python 3.7+. Actually this test fails on my Mac.

This is because the system python on Mac is built with Python.framework. So test code should look like this:

assert sys._framework == "" or sys._framework == "Python"

I thought about testing in the site module, but I didn't think of a good way. 😢 Also, the method does not seem to be suitable for solving this problem.

There are a few things to think about for this test.

  • We expect RustPython's sys._framework to be built with an empty string.
  • If running on system python on Mac, sys._framework can be 'Python'.
  • Since this attribute is implemented in python 3.7+, an earlier version will throw an AttributeError.

The best code I can think of is this:

try:
    assert sys._framework == ""
except AttributeError:
    assert "%d.%d" % sys.version_info[:2] < "3.7"
except AssertionError:
    assert sys.platform == "darwin" and sys._framework == "Python"

What do you think about this solution?

@youknowone
Copy link
Member

now, actually, the code itself looks totally fine. but not sure the test code is fit for the goal of snippet tests.
@coolreader18 how do you think about the test code?

@youknowone youknowone dismissed coolreader18’s stale review September 10, 2019 18:00

Resolved as suggested

@youknowone youknowone merged commit 65c90ab into RustPython:master Sep 10, 2019
@ChJR ChJR mentioned this pull request Sep 24, 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.

module 'sys' has no attribute '_framework' (mac)
3 participants