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)
| 3589 | |
| 3590 | |
| 3591 | def character_backward_compatibility_hook(item, parents, result, |
| 3592 | *args, **kwargs): |
| 3593 | """Previously, Fortran character was incorrectly treated as |
| 3594 | character*1. This hook fixes the usage of the corresponding |
| 3595 | variables in `check`, `dimension`, `=`, and `callstatement` |
| 3596 | expressions. |
| 3597 | |
| 3598 | The usage of `char*` in `callprotoargument` expression can be left |
| 3599 | unchanged because C `character` is C typedef of `char`, although, |
| 3600 | new implementations should use `character*` in the corresponding |
| 3601 | expressions. |
| 3602 | |
| 3603 | See https://github.com/numpy/numpy/pull/19388 for more information. |
| 3604 | |
| 3605 | """ |
| 3606 | parent_key, parent_value = parents[-1] |
| 3607 | key, value = item |
| 3608 | |
| 3609 | def fix_usage(varname, value): |
| 3610 | value = re.sub(r'[*]\s*\b' + varname + r'\b', varname, value) |
| 3611 | value = re.sub(r'\b' + varname + r'\b\s*[\[]\s*0\s*[\]]', |
| 3612 | varname, value) |
| 3613 | return value |
| 3614 | |
| 3615 | if parent_key in ['dimension', 'check']: |
| 3616 | assert parents[-3][0] == 'vars' |
| 3617 | vars_dict = parents[-3][1] |
| 3618 | elif key == '=': |
| 3619 | assert parents[-2][0] == 'vars' |
| 3620 | vars_dict = parents[-2][1] |
| 3621 | else: |
| 3622 | vars_dict = None |
| 3623 | |
| 3624 | new_value = None |
| 3625 | if vars_dict is not None: |
| 3626 | new_value = value |
| 3627 | for varname, vd in vars_dict.items(): |
| 3628 | if ischaracter(vd): |
| 3629 | new_value = fix_usage(varname, new_value) |
| 3630 | elif key == 'callstatement': |
| 3631 | vars_dict = parents[-2][1]['vars'] |
| 3632 | new_value = value |
| 3633 | for varname, vd in vars_dict.items(): |
| 3634 | if ischaracter(vd): |
| 3635 | # replace all occurrences of `<varname>` with |
| 3636 | # `&<varname>` in argument passing |
| 3637 | new_value = re.sub( |
| 3638 | r'(?<![&])\b' + varname + r'\b', '&' + varname, new_value) |
| 3639 | |
| 3640 | if new_value is not None: |
| 3641 | if new_value != value: |
| 3642 | # We report the replacements here so that downstream |
| 3643 | # software could update their source codes |
| 3644 | # accordingly. However, such updates are recommended only |
| 3645 | # when BC with numpy 1.21 or older is not required. |
| 3646 | outmess(f'character_bc_hook[{parent_key}.{key}]:' |
| 3647 | f' replaced `{value}` -> `{new_value}`\n', 1) |
| 3648 | return (key, new_value) |
nothing calls this directly
no test coverage detected
searching dependent graphs…