From 2bca1ca7247c2e3e334afcbe350849cb7e9e956f Mon Sep 17 00:00:00 2001 From: joncrall Date: Tue, 25 Oct 2022 10:09:24 -0400 Subject: [PATCH] Port editable fix --- src/xdoctest/utils/util_import.py | 43 ++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/xdoctest/utils/util_import.py b/src/xdoctest/utils/util_import.py index 2ee95639..846b623b 100644 --- a/src/xdoctest/utils/util_import.py +++ b/src/xdoctest/utils/util_import.py @@ -631,6 +631,10 @@ def check_dpath(dpath): _egglink_fname1 = _pkg_name + '.egg-link' _egglink_fname2 = _pkg_name_hypen + '.egg-link' + # FIXME! suffixed modules will clobber break! + # Currently mitigating this by looping over all possible matches, + # but it would be nice to ensure we are not matching suffixes. + # however, we should probably match and handle different versions. _editable_fname_pth_pat = '__editable__.' + _pkg_name + '-*.pth' _editable_fname_finder_py_pat = '__editable___' + _pkg_name + '_*finder.py' @@ -656,14 +660,20 @@ def check_dpath(dpath): # ultimately be good. Hopefully the new standards mean it does not # break with pytest anymore? Nope, pytest still doesn't work right # with it. - finder_fpath = new_editable_finder_paths[-1] - mapping = _static_parse('MAPPING', finder_fpath) - target = dirname(mapping[_pkg_name]) - if not exclude or normalize(target) not in real_exclude: # pragma: nobranch - modpath = check_dpath(target) - if modpath: # pragma: nobranch - found_modpath = modpath - break + for finder_fpath in new_editable_finder_paths: + mapping = _static_parse('MAPPING', finder_fpath) + try: + target = dirname(mapping[_pkg_name]) + except KeyError: + ... + else: + if not exclude or normalize(target) not in real_exclude: # pragma: nobranch + modpath = check_dpath(target) + if modpath: # pragma: nobranch + found_modpath = modpath + break + if found_modpath is not None: + break # If a finder does not exist, then the __editable__ pth file might hold # the path itself. Check for that. @@ -672,13 +682,16 @@ def check_dpath(dpath): # Disable coverage because the test that covers this is too slow. # It can be made faster, re-enable when that lands. import pathlib - editable_pth = pathlib.Path(new_editable_pth_paths[-1]) - target = editable_pth.read_text().strip().split('\n')[-1] - if not exclude or normalize(target) not in real_exclude: - modpath = check_dpath(target) - if modpath: # pragma: nobranch - found_modpath = modpath - break + for editable_pth in new_editable_pth_paths: + editable_pth = pathlib.Path(editable_pth) + target = editable_pth.read_text().strip().split('\n')[-1] + if not exclude or normalize(target) not in real_exclude: + modpath = check_dpath(target) + if modpath: # pragma: nobranch + found_modpath = modpath + break + if found_modpath is not None: + break # If file path checks fails, check for egg-link based modules # (Python usually puts egg links into sys.path, but if the user is