Import completion not suggesting private symbol included in __all__
I have a project structured like
appname:
- utils:
- __init__.py
- _util1.py -> contains a function called `util1`
- _util2.py -> contains a function called `util2`
__init__.py imports all the _utilx.py modules and populates __all__ with the right util methods but auto-import doesn't suggest appname.utils.utilx when trying to use utilx
when I rename _util1.py to change util1.py, auto-import starts working again. Is this expected?
Thanks for the issue.
I believe this is by design as talked about here: https://github.com/microsoft/pylance-release/issues/2490
One way to work around this is to explicitly import all of the private members in your __init__.py. They'll then end up in the utils package:
# __init__.py
from _utils1 import *
from _utils2 import *
# test.py
import appname.utils
appname.utils.util1() # This should be available now
@rchiodo I've looked at #2490 and I understand that symbols inside files starting with an underscore will not show up. However, here, I'm explicitly importing symbols from the private symbols in my init.py and then adding it to __all__ in my init.py (which is not private). So the functions that were added to __all__ should be picked up by the autocomplete right?
Sorry but privates are still excluded even if included in __all__. Only if you do what I suggested will they end up being exported from __init__
this might work too in the __init__.py
from _utils1 import util1 as util1
“from X import A as A” (a redundant symbol alias), see https://microsoft.github.io/pyright/#/typed-libraries
This makes it seem like including them in __all__ should work:
A module can expose an __all__ symbol at the module level that provides a list of names that are considered part of the interface. The __all__ symbol indicates which symbols are included in a wildcard import. All symbols included in the __all__ list are considered public even if the other rules above would otherwise indicate that they were private. For example, this allows symbols whose names begin with an underscore to be included in the interface.
Reopening.
Hi, is there a timeline on when this might get fixed? wanted to let my team so we can figure out a workaround accordingly :)
Generally, upvotes determine the priority of things. This item having a single upvote means it's low priority at the moment.
@mayankj, I wasn't sure if utils was a directory within your workspace or a package in your environment, so I tried it both ways.
I know it's been a while since you opened this issue, but if you can provide any guidance on how to repro this, I'd appreciate it.
Local files
If it's a directory in your workspace, then I believe you are hitting https://github.com/microsoft/pylance-release/issues/5159.
Here's how I set that up:
<workspace-root>\utils\__init__.py
from _util1 import util1
from _util2 import util2
__all__ = [ "util1", "util2" ]
<workspace-root>\utils\_util1.py
def util1(): pass
<workspace-root>\utils\_util2.py
def util2(): pass
<workspace-root>\test.py
Tried auto-import here. It fails. -- https://github.com/microsoft/pylance-release/issues/5159
Package
I wasn't able to repro any issues when utils was a package in my venv. I tried downgrading to 2023.4.30 which was the latest stable release when you filed this issue, and I couldn't repro it there either.
Here's how I set that up:
<workspace-root>\.venv\lib\site-packages\utils\__init__.py
from ._util1 import util1
from ._util2 import util2
__all__ = [ "util1", "util2" ]
<workspace-root>\.venv\lib\site-packages\utils\__init__.py
def util1(): pass
<workspace-root>\.venv\lib\site-packages\utils\__init__.py
def util2(): pass
<workspace-root>\test.py
Tried auto-import here and succeeded.
@debonte, you're correct - it is a directory in our workspace
Thanks for confirming. I'm resolving this as a duplicate of #5159.