Skip to content
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

remove alterations of sys.path #3305

Merged
merged 7 commits into from
Sep 16, 2019
Merged

Conversation

ltalirz
Copy link
Member

@ltalirz ltalirz commented Sep 10, 2019

fix #3293

python allows to modify the search path for modules programmatically via the sys.path variable (sys.path is initialized from the PYTHONPATH environment variable).
Doing so, however, can easily have unintended consequences (one of them surfaced in #3293) - in particular, when new paths are inserted at the beginning of sys.path.

AiiDA was manipulating sys.path in a number of places:

  1. sys.path.insert(0, os.path.abspath(os.curdir))

  2. sys.path.insert(0, os.path.abspath('.'))

  3. sys.path.insert(0, ROOT_DIR)

  4. path.insert(0, os.curdir)

  5. sys.path = [BASE_DIR] + sys.path

This PR removes/remedies those manipulations (except for point 4, which is part of shutil.which and is relevant only for sys.platform == 'win32').

@ltalirz ltalirz force-pushed the issue_3293_sys_path branch from d1c2f95 to 158ef25 Compare September 10, 2019 13:45
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.dialects.postgresql import UUID

from aiida.common import exceptions
from aiida.common.timezone import get_current_timezone
from aiida.manage.configuration import get_profile, settings

# Assumes that parent directory of aiida is root for
# things like templates/, SQL/ etc. If not, change what follows...
Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure what exactly this comment means / why this should be needed.
Anyhow, it seems the code works also without this

 * remove sys.path modification from cmd_run
 * remove sys.path modification from aiida sphinxext test
   sphinxext test was using sys.path to add python module
   to the path for autodoc.
   Now simply changing to appropriate directory when making the
   documentation.
 * undo sys.path modification in validate_consistency.py
 * remove sys.path modification from settings.py
@ltalirz ltalirz force-pushed the issue_3293_sys_path branch 2 times, most recently from 2390530 to 2767d7c Compare September 10, 2019 14:56
@ltalirz ltalirz force-pushed the issue_3293_sys_path branch from 2767d7c to 547e8b5 Compare September 10, 2019 16:36
Copy link
Contributor

@CasperWA CasperWA left a comment

Choose a reason for hiding this comment

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

Excellent work @ltalirz, it's always nice to remove more files from the linter's exclusion list :)

I have only a few questions and comments, the final review I will leave for @giovannipizzi and/or @sphuber, I think. Especially @giovannipizzi, since he may be the original author of many of the lines?

import aiida # pylint: disable=wrong-import-position
version = aiida.__version__
# Clean up sys.path again
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems weird, but I guess this is the main reason why this PR is relevant, I presume? To make sure sys.path is properly cleaned up from AiiDA side?

Copy link
Member Author

Choose a reason for hiding this comment

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

What is weird about this? It's just adding a path to import a module (which we need just for the aiida version) and then cleaning up the path again so that things aren't messed up further down the line.

Copy link
Contributor

Choose a reason for hiding this comment

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

It just seems intuitively inelegant that's all - this of course does not mean it isn't the best way to do it :)
I was wondering however, if one could not use importlib instead or similar, i.e., if it is absolutely necessary to add a path to sys.path? But I may be missing when this file is used/its purpose?

Copy link
Member Author

Choose a reason for hiding this comment

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

Feel free to suggest a better approach

Copy link
Member

Choose a reason for hiding this comment

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

You can do something like the following:

import pkgutil

loaders = [
    module_loader for (module_loader, name, ispkg) 
    in pkgutil.iter_modules(path=['ROOT_DIR'])
    if name == 'aiida' and ispkg]

if not loaders:
    raise ImportError("xxx") # or ignore?
loader = loaders[0]
version = loader.find_module('aiida').load_module('aiida').__version__
print(version)

@ltalirz
Copy link
Member Author

ltalirz commented Sep 11, 2019

@giovannipizzi Casper is done with his review - could you please give a quick look as well?

Copy link
Member

@giovannipizzi giovannipizzi left a comment

Choose a reason for hiding this comment

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

Just one change (on the lines of @CasperWA's suggestion).
If it keeps working, I think it's good to do.

Also, did you check if this fixed the issue with the tests not working for modules names sqlachemy, django, ...?

BTW, do you know why coverage dropped to ~30%?

import aiida # pylint: disable=wrong-import-position
version = aiida.__version__
# Clean up sys.path again
Copy link
Member

Choose a reason for hiding this comment

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

You can do something like the following:

import pkgutil

loaders = [
    module_loader for (module_loader, name, ispkg) 
    in pkgutil.iter_modules(path=['ROOT_DIR'])
    if name == 'aiida' and ispkg]

if not loaders:
    raise ImportError("xxx") # or ignore?
loader = loaders[0]
version = loader.find_module('aiida').load_module('aiida').__version__
print(version)

@ltalirz
Copy link
Member Author

ltalirz commented Sep 12, 2019

@giovannipizzi Thanks - I've implemented your suggestion and checked that it works.
Not quite sure whether this is really more elegant, but it does have the advantage of leaving the sys.path untouched (I checked).

Also, did you check if this fixed the issue with the tests not working for modules names sqlachemy, django, ...?

I don't remember exactly what the problem was but issues related to name clashes with modules/folders inside aiida/backends might be resolved.

BTW, do you know why coverage dropped to ~30%?

It happened on the merge done via travis, so no idea...

@ltalirz ltalirz merged commit 6299cf6 into aiidateam:develop Sep 16, 2019
d-tomerini pushed a commit to d-tomerini/aiida_core that referenced this pull request Sep 30, 2019
python allows to modify the search path for modules programmatically via the `sys.path` variable (`sys.path` is initialized from the `PYTHONPATH` environment variable).
Doing so, however, can easily have unintended consequences (one of them surfaced in aiidateam#3293) - in particular, when new paths are inserted at the *beginning* of `sys.path`.

AiiDA was manipulating `sys.path` in a number of places:

1. https://github.com/aiidateam/aiida-core/blob/a500d2b2801efa393ce6f567dc9893a62696b8f1/aiida/cmdline/commands/cmd_run.py#L113

1. https://github.com/aiidateam/aiida-core/blob/d750d513f7adf5126d43a230c9fb378de02f0772/aiida/sphinxext/tests/workchain_source/conf.py#L32

1. https://github.com/aiidateam/aiida-core/blob/cc94a1e0127cd9cab0a4049e69a9fa31cb82941c/utils/validate_consistency.py#L190

1. https://github.com/aiidateam/aiida-core/blob/cc94a1e0127cd9cab0a4049e69a9fa31cb82941c/aiida/common/files.py#L194

1. https://github.com/aiidateam/aiida-core/blob/91b205bcdeebc3d6f9a019c77c38ffdf6fc95321/aiida/backends/djsite/settings.py#L31

This PR removes/remedies those manipulations (except for point 4, which is part of `shutil.which` and is relevant only for `sys.platform == 'win32'`).
d-tomerini pushed a commit to d-tomerini/aiida_core that referenced this pull request Oct 16, 2019
python allows to modify the search path for modules programmatically via the `sys.path` variable (`sys.path` is initialized from the `PYTHONPATH` environment variable).
Doing so, however, can easily have unintended consequences (one of them surfaced in aiidateam#3293) - in particular, when new paths are inserted at the *beginning* of `sys.path`.

AiiDA was manipulating `sys.path` in a number of places:

1. https://github.com/aiidateam/aiida-core/blob/a500d2b2801efa393ce6f567dc9893a62696b8f1/aiida/cmdline/commands/cmd_run.py#L113

1. https://github.com/aiidateam/aiida-core/blob/d750d513f7adf5126d43a230c9fb378de02f0772/aiida/sphinxext/tests/workchain_source/conf.py#L32

1. https://github.com/aiidateam/aiida-core/blob/cc94a1e0127cd9cab0a4049e69a9fa31cb82941c/utils/validate_consistency.py#L190

1. https://github.com/aiidateam/aiida-core/blob/cc94a1e0127cd9cab0a4049e69a9fa31cb82941c/aiida/common/files.py#L194

1. https://github.com/aiidateam/aiida-core/blob/91b205bcdeebc3d6f9a019c77c38ffdf6fc95321/aiida/backends/djsite/settings.py#L31

This PR removes/remedies those manipulations (except for point 4, which is part of `shutil.which` and is relevant only for `sys.platform == 'win32'`).
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.

verdi shell imports deprecated module
3 participants