Skip to content

Commit

Permalink
Support module with __file__=None. Fixes microsoft#475
Browse files Browse the repository at this point in the history
  • Loading branch information
fabioz committed Nov 27, 2020
1 parent d0bb24a commit 792458b
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 26 deletions.
30 changes: 15 additions & 15 deletions src/debugpy/_vendored/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,14 @@
VENDORED_ROOT = os.path.dirname(os.path.abspath(__file__))
# TODO: Move the "pydevd" git submodule to the debugpy/_vendored directory
# and then drop the following fallback.
if 'pydevd' not in os.listdir(VENDORED_ROOT):
if "pydevd" not in os.listdir(VENDORED_ROOT):
VENDORED_ROOT = os.path.dirname(VENDORED_ROOT)


def list_all(resolve=False):
"""Return the list of vendored projects."""
# TODO: Derive from os.listdir(VENDORED_ROOT)?
projects = [
'pydevd',
]
projects = ["pydevd"]
if not resolve:
return projects
return [project_root(name) for name in projects]
Expand All @@ -37,7 +35,7 @@ def project_root(project):
projects (e.g. "debugpy/_vendored/") will be returned.
"""
if not project:
project = ''
project = ""
return os.path.join(VENDORED_ROOT, project)


Expand All @@ -63,17 +61,14 @@ def iter_packaging_files(project):
prune_dir = None
exclude_file = None
try:
mod = import_module('._{}_packaging'.format(project), __name__)
mod = import_module("._{}_packaging".format(project), __name__)
except ImportError:
pass
else:
prune_dir = getattr(mod, 'prune_dir', prune_dir)
exclude_file = getattr(mod, 'exclude_file', exclude_file)
prune_dir = getattr(mod, "prune_dir", prune_dir)
exclude_file = getattr(mod, "exclude_file", exclude_file)
results = iter_project_files(
project,
relative=True,
prune_dir=prune_dir,
exclude_file=exclude_file,
project, relative=True, prune_dir=prune_dir, exclude_file=exclude_file
)
for _, _, filename in results:
yield filename
Expand All @@ -89,6 +84,7 @@ def match(name, module):
return True
else:
return False

return match


Expand All @@ -101,10 +97,14 @@ def check_modules(project, match, root=None):
for modname, mod in list(sys.modules.items()):
if not match(modname, mod):
continue
if not hasattr(mod, '__file__'): # extension module
try:
filename = getattr(mod, "__file__", None)
except: # In theory it's possible that any error is raised when accessing __file__
filename = None
if not filename: # extension module
extensions.append(modname)
elif not mod.__file__.startswith(root):
unvendored[modname] = mod.__file__
elif not filename.startswith(root):
unvendored[modname] = filename
return unvendored, extensions


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,14 @@ def get_file(mod):
try:
f = inspect.getsourcefile(mod) or inspect.getfile(mod)
except:
if hasattr_checked(mod, '__file__'):
f = mod.__file__
if f.lower(f[-4:]) in ['.pyc', '.pyo']:
filename = f[:-4] + '.py'
if os.path.exists(filename):
f = filename
try:
f = getattr(mod, '__file__', None)
except:
f = None
if f and f.lower(f[-4:]) in ['.pyc', '.pyo']:
filename = f[:-4] + '.py'
if os.path.exists(filename):
f = filename

return f

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ def Find(name):
parent = mod
foundAs = ''

if hasattr(mod, '__file__'):
f = mod.__file__
try:
f = getattr(mod, '__file__', None)
except:
f = None


components = name.split('.')
Expand Down
9 changes: 6 additions & 3 deletions src/debugpy/_vendored/pydevd/stubs/_get_tips.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,12 @@ def GetFile(mod):
try:
f = inspect.getsourcefile(mod) or inspect.getfile(mod)
except:
if hasattr(mod, '__file__'):
f = mod.__file__
if f.lower(f[-4:]) in ['.pyc', '.pyo']:
try:
f = getattr(mod, '__file__', None)
except:
pass
else:
if f and f.lower(f[-4:]) in ['.pyc', '.pyo']:
filename = f[:-4] + '.py'
if os.path.exists(filename):
f = filename
Expand Down
34 changes: 34 additions & 0 deletions tests/tests/test_vendoring.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
def test_vendoring(pyfile):
@pyfile
def import_debugpy():
import sys

class Dummy(object):
__file__ = None

class Dummy2(object):
pass

class Dummy3(object):
def __getattribute__(self, *args, **kwargs):
raise AssertionError('Error')

sys.modules["pydev_dummy"] = Dummy()
sys.modules["pydev_dummy2"] = Dummy2()
sys.modules["pydev_dummy3"] = Dummy3()

sys.modules["_pydev_dummy"] = Dummy()
sys.modules["_pydev_dummy2"] = Dummy2()
sys.modules["_pydev_dummy3"] = Dummy3()

from debugpy._vendored import force_pydevd # noqa

print("Properly applied pydevd vendoring.")

import subprocess
import sys

output = subprocess.check_output([sys.executable, "-u", import_debugpy.strpath])
output = output.decode("utf-8")
if "Properly applied pydevd vendoring." not in output:
raise AssertionError(output)

0 comments on commit 792458b

Please sign in to comment.