comparison mercurial/extensions.py @ 52773:8317993a49f1 stable

extensions: allow wrapping a function with a bytes name again This backs out 7b837fabc990 and eda075d7b2ac. The cleanup to transition away from bytes broke JavaHg, which is used by hosting software SCM Manager. I'm not sure who maintains JavaHg these days, so I'm not sure how to get a build out and get everyone to upgrade. Let's revert the change for a quicker fix (and fix an unknown number of other unmaintained extensions), and rely on pytype to flag any potential issues. It's also trivial, so let's not wait until the next feature release (with the added burden for packagers this cycle in dealing with the `setup.py` changes).
author Matt Harbison <matt_harbison@yahoo.com>
date Fri, 07 Feb 2025 19:14:05 -0500
parents f4733654f144
children 42f78c859dd1
comparison
equal deleted inserted replaced
52720:b019b5798e8f 52773:8317993a49f1
621 621
622 622
623 class wrappedfunction: 623 class wrappedfunction:
624 '''context manager for temporarily wrapping a function''' 624 '''context manager for temporarily wrapping a function'''
625 625
626 def __init__(self, container, funcname, wrapper): 626 def __init__(self, container, funcname: str, wrapper):
627 assert callable(wrapper) 627 assert callable(wrapper)
628 if not isinstance(funcname, str): 628 if not isinstance(funcname, str):
629 msg = b"wrappedfunction target name should be `str`, not `bytes`" 629 # Keep this compat shim around for older/unmaintained extensions
630 raise TypeError(msg) 630 msg = b"pass wrappedfunction target name as `str`, not `bytes`"
631 util.nouideprecwarn(msg, b"6.6", stacklevel=2)
632 funcname = pycompat.sysstr(funcname)
631 self._container = container 633 self._container = container
632 self._funcname = funcname 634 self._funcname = funcname
633 self._wrapper = wrapper 635 self._wrapper = wrapper
634 636
635 def __enter__(self): 637 def __enter__(self):
637 639
638 def __exit__(self, exctype, excvalue, traceback): 640 def __exit__(self, exctype, excvalue, traceback):
639 unwrapfunction(self._container, self._funcname, self._wrapper) 641 unwrapfunction(self._container, self._funcname, self._wrapper)
640 642
641 643
642 def wrapfunction(container, funcname, wrapper): 644 def wrapfunction(container, funcname: str, wrapper):
643 """Wrap the function named funcname in container 645 """Wrap the function named funcname in container
644 646
645 Replace the funcname member in the given container with the specified 647 Replace the funcname member in the given container with the specified
646 wrapper. The container is typically a module, class, or instance. 648 wrapper. The container is typically a module, class, or instance.
647 649
673 subclass trick. 675 subclass trick.
674 """ 676 """
675 assert callable(wrapper) 677 assert callable(wrapper)
676 678
677 if not isinstance(funcname, str): 679 if not isinstance(funcname, str):
678 msg = b"wrapfunction target name should be `str`, not `bytes`" 680 # Keep this compat shim around for older/unmaintained extensions
679 raise TypeError(msg) 681 msg = b"pass wrapfunction target name as `str`, not `bytes`"
682 util.nouideprecwarn(msg, b"6.6", stacklevel=2)
683 funcname = pycompat.sysstr(funcname)
680 684
681 origfn = getattr(container, funcname) 685 origfn = getattr(container, funcname)
682 assert callable(origfn) 686 assert callable(origfn)
683 if inspect.ismodule(container): 687 if inspect.ismodule(container):
684 # origfn is not an instance or class method. "partial" can be used. 688 # origfn is not an instance or class method. "partial" can be used.