Previously, Fortran character was incorrectly treated as character*1. This hook fixes the usage of the corresponding variables in `check`, `dimension`, `=`, and `callstatement` expressions. The usage of `char*` in `callprotoargument` expression can be left unchanged because C `c
(item, parents, result,
*args, **kwargs)
| 3629 | |
| 3630 | |
| 3631 | def character_backward_compatibility_hook(item, parents, result, |
| 3632 | *args, **kwargs): |
| 3633 | """Previously, Fortran character was incorrectly treated as |
| 3634 | character*1. This hook fixes the usage of the corresponding |
| 3635 | variables in `check`, `dimension`, `=`, and `callstatement` |
| 3636 | expressions. |
| 3637 | |
| 3638 | The usage of `char*` in `callprotoargument` expression can be left |
| 3639 | unchanged because C `character` is C typedef of `char`, although, |
| 3640 | new implementations should use `character*` in the corresponding |
| 3641 | expressions. |
| 3642 | |
| 3643 | See https://github.com/numpy/numpy/pull/19388 for more information. |
| 3644 | |
| 3645 | """ |
| 3646 | parent_key, parent_value = parents[-1] |
| 3647 | key, value = item |
| 3648 | |
| 3649 | def fix_usage(varname, value): |
| 3650 | value = re.sub(r'[*]\s*\b' + varname + r'\b', varname, value) |
| 3651 | value = re.sub(r'\b' + varname + r'\b\s*[\[]\s*0\s*[\]]', |
| 3652 | varname, value) |
| 3653 | return value |
| 3654 | |
| 3655 | if parent_key in ['dimension', 'check']: |
| 3656 | assert parents[-3][0] == 'vars' |
| 3657 | vars_dict = parents[-3][1] |
| 3658 | elif key == '=': |
| 3659 | assert parents[-2][0] == 'vars' |
| 3660 | vars_dict = parents[-2][1] |
| 3661 | else: |
| 3662 | vars_dict = None |
| 3663 | |
| 3664 | new_value = None |
| 3665 | if vars_dict is not None: |
| 3666 | new_value = value |
| 3667 | for varname, vd in vars_dict.items(): |
| 3668 | if ischaracter(vd): |
| 3669 | new_value = fix_usage(varname, new_value) |
| 3670 | elif key == 'callstatement': |
| 3671 | vars_dict = parents[-2][1]['vars'] |
| 3672 | new_value = value |
| 3673 | for varname, vd in vars_dict.items(): |
| 3674 | if ischaracter(vd): |
| 3675 | # replace all occurrences of `<varname>` with |
| 3676 | # `&<varname>` in argument passing |
| 3677 | new_value = re.sub( |
| 3678 | r'(?<![&])\b' + varname + r'\b', '&' + varname, new_value) |
| 3679 | |
| 3680 | if new_value is not None: |
| 3681 | if new_value != value: |
| 3682 | # We report the replacements here so that downstream |
| 3683 | # software could update their source codes |
| 3684 | # accordingly. However, such updates are recommended only |
| 3685 | # when BC with numpy 1.21 or older is not required. |
| 3686 | outmess(f'character_bc_hook[{parent_key}.{key}]:' |
| 3687 | f' replaced `{value}` -> `{new_value}`\n', 1) |
| 3688 | return (key, new_value) |
nothing calls this directly
no test coverage detected