# HG changeset patch # User Pierre-Yves David # Date 2023-08-31 21:56:15 # Node ID d718eddf01d966c67120b51591bebf87581772ed # Parent 7a8ea1397816d9349470aa3a24a6f3ab18072bbf safehasattr: drop usage in favor of hasattr The two functions should now be equivalent at least in their usage in core. diff --git a/contrib/benchmarks/__init__.py b/contrib/benchmarks/__init__.py --- a/contrib/benchmarks/__init__.py +++ b/contrib/benchmarks/__init__.py @@ -40,7 +40,6 @@ from mercurial import ( extensions, hg, ui as uimod, - util, ) basedir = os.path.abspath( @@ -66,7 +65,7 @@ def runperfcommand(reponame, command, *a os.environ["HGRCPATH"] = os.environ.get("ASVHGRCPATH", "") # for "historical portability" # ui.load() has been available since d83ca85 - if util.safehasattr(uimod.ui, "load"): + if hasattr(uimod.ui, "load"): ui = uimod.ui.load() else: ui = uimod.ui() diff --git a/hgext/absorb.py b/hgext/absorb.py --- a/hgext/absorb.py +++ b/hgext/absorb.py @@ -873,7 +873,7 @@ class fixupstate: # be slow. in absorb's case, no need to invalidate fsmonitorstate. noop = lambda: 0 restore = noop - if util.safehasattr(dirstate, '_fsmonitorstate'): + if hasattr(dirstate, '_fsmonitorstate'): bak = dirstate._fsmonitorstate.invalidate def restore(): diff --git a/hgext/bugzilla.py b/hgext/bugzilla.py --- a/hgext/bugzilla.py +++ b/hgext/bugzilla.py @@ -766,13 +766,13 @@ class cookietransportrequest: # inheritance with a new-style class. class cookietransport(cookietransportrequest, xmlrpclib.Transport): def __init__(self, use_datetime=0): - if util.safehasattr(xmlrpclib.Transport, "__init__"): + if hasattr(xmlrpclib.Transport, "__init__"): xmlrpclib.Transport.__init__(self, use_datetime) class cookiesafetransport(cookietransportrequest, xmlrpclib.SafeTransport): def __init__(self, use_datetime=0): - if util.safehasattr(xmlrpclib.Transport, "__init__"): + if hasattr(xmlrpclib.Transport, "__init__"): xmlrpclib.SafeTransport.__init__(self, use_datetime) diff --git a/hgext/clonebundles.py b/hgext/clonebundles.py --- a/hgext/clonebundles.py +++ b/hgext/clonebundles.py @@ -987,7 +987,7 @@ def reposetup(ui, repo): @localrepo.unfilteredmethod def clonebundles_lock(self, wait=True): '''Lock the repository file related to clone bundles''' - if not util.safehasattr(self, '_cb_lock_ref'): + if not hasattr(self, '_cb_lock_ref'): self._cb_lock_ref = None l = self._currentlock(self._cb_lock_ref) if l is not None: diff --git a/hgext/commitextras.py b/hgext/commitextras.py --- a/hgext/commitextras.py +++ b/hgext/commitextras.py @@ -16,7 +16,6 @@ from mercurial import ( error, extensions, registrar, - util, ) cmdtable = {} @@ -52,7 +51,7 @@ def extsetup(ui): def _commit(orig, ui, repo, *pats, **opts): - if util.safehasattr(repo, 'unfiltered'): + if hasattr(repo, 'unfiltered'): repo = repo.unfiltered() class repoextra(repo.__class__): diff --git a/hgext/convert/cvsps.py b/hgext/convert/cvsps.py --- a/hgext/convert/cvsps.py +++ b/hgext/convert/cvsps.py @@ -198,9 +198,9 @@ def createlog(ui, directory=None, root=b oldlog = pickle.load(open(cachefile, b'rb')) for e in oldlog: if not ( - util.safehasattr(e, b'branchpoints') - and util.safehasattr(e, b'commitid') - and util.safehasattr(e, b'mergepoint') + hasattr(e, b'branchpoints') + and hasattr(e, b'commitid') + and hasattr(e, b'mergepoint') ): ui.status(_(b'ignoring old cache\n')) oldlog = [] diff --git a/hgext/convert/transport.py b/hgext/convert/transport.py --- a/hgext/convert/transport.py +++ b/hgext/convert/transport.py @@ -28,7 +28,6 @@ Pool = svn.core.Pool SubversionException = svn.core.SubversionException from mercurial.pycompat import getattr -from mercurial import util # Some older versions of the Python bindings need to be # explicitly initialized. But what we want to do probably @@ -63,7 +62,7 @@ def _create_auth_baton(pool): if p: providers.append(p) else: - if util.safehasattr(svn.client, 'get_windows_simple_provider'): + if hasattr(svn.client, 'get_windows_simple_provider'): providers.append(svn.client.get_windows_simple_provider(pool)) return svn.core.svn_auth_open(providers, pool) @@ -85,7 +84,7 @@ class SvnRaTransport: self.password = b'' # Only Subversion 1.4 has reparent() - if ra is None or not util.safehasattr(svn.ra, 'reparent'): + if ra is None or not hasattr(svn.ra, 'reparent'): self.client = svn.client.create_context(self.pool) ab = _create_auth_baton(self.pool) self.client.auth_baton = ab diff --git a/hgext/fastannotate/commands.py b/hgext/fastannotate/commands.py --- a/hgext/fastannotate/commands.py +++ b/hgext/fastannotate/commands.py @@ -19,7 +19,6 @@ from mercurial import ( pycompat, registrar, scmutil, - util, ) from . import ( @@ -218,7 +217,7 @@ def fastannotate(ui, repo, *pats, **opts paths = list(_matchpaths(repo, rev, pats, opts, aopts)) # for client, prefetch from the server - if util.safehasattr(repo, 'prefetchfastannotate'): + if hasattr(repo, 'prefetchfastannotate'): repo.prefetchfastannotate(paths) for path in paths: @@ -273,7 +272,7 @@ def _annotatewrapper(orig, ui, repo, *pa # check if we need to do prefetch (client-side) rev = opts.get('rev') - if util.safehasattr(repo, 'prefetchfastannotate') and rev is not None: + if hasattr(repo, 'prefetchfastannotate') and rev is not None: paths = list(_matchpaths(repo, rev, pats, pycompat.byteskwargs(opts))) repo.prefetchfastannotate(paths) @@ -320,7 +319,7 @@ def debugbuildannotatecache(ui, repo, *p ctx = logcmdutil.revsingle(repo, rev) m = scmutil.match(ctx, pats, opts) paths = list(ctx.walk(m)) - if util.safehasattr(repo, 'prefetchfastannotate'): + if hasattr(repo, 'prefetchfastannotate'): # client if opts.get(b'REV'): raise error.Abort(_(b'--rev cannot be used for client')) diff --git a/hgext/fastannotate/context.py b/hgext/fastannotate/context.py --- a/hgext/fastannotate/context.py +++ b/hgext/fastannotate/context.py @@ -324,7 +324,7 @@ class _annotatecontext: b'(resolved fctx: %s)\n' % ( self.path, - stringutil.pprint(util.safehasattr(revfctx, 'node')), + stringutil.pprint(hasattr(revfctx, 'node')), ) ) return self.annotatedirectly(revfctx, showpath, showlines) diff --git a/hgext/fsmonitor/__init__.py b/hgext/fsmonitor/__init__.py --- a/hgext/fsmonitor/__init__.py +++ b/hgext/fsmonitor/__init__.py @@ -332,7 +332,7 @@ def overridewalk(orig, self, match, subr matchfn = match.matchfn matchalways = match.always() dmap = self._map - if util.safehasattr(dmap, b'_map'): + if hasattr(dmap, b'_map'): # for better performance, directly access the inner dirstate map if the # standard dirstate implementation is in use. dmap = dmap._map @@ -744,7 +744,7 @@ def makedirstate(repo, dirstate): def wrapdirstate(orig, self): ds = orig(self) # only override the dirstate when Watchman is available for the repo - if util.safehasattr(self, b'_fsmonitorstate'): + if hasattr(self, b'_fsmonitorstate'): makedirstate(self, ds) return ds @@ -811,7 +811,7 @@ class state_update: self.oldnode = self.repo[b'.'].node() if self.repo.currentwlock() is None: - if util.safehasattr(self.repo, b'wlocknostateupdate'): + if hasattr(self.repo, b'wlocknostateupdate'): self._lock = self.repo.wlocknostateupdate() else: self._lock = self.repo.wlock() @@ -839,7 +839,7 @@ class state_update: self._lock.release() def _state(self, cmd, commithash, status=b'ok'): - if not util.safehasattr(self.repo, b'_watchmanclient'): + if not hasattr(self.repo, b'_watchmanclient'): return False try: self.repo._watchmanclient.command( diff --git a/hgext/fsmonitor/watchmanclient.py b/hgext/fsmonitor/watchmanclient.py --- a/hgext/fsmonitor/watchmanclient.py +++ b/hgext/fsmonitor/watchmanclient.py @@ -69,7 +69,7 @@ class client: def getcurrentclock(self): result = self.command(b'clock') - if not util.safehasattr(result, 'clock'): + if not hasattr(result, 'clock'): raise Unavailable( b'clock result is missing clock value', invalidate=True ) diff --git a/hgext/journal.py b/hgext/journal.py --- a/hgext/journal.py +++ b/hgext/journal.py @@ -103,7 +103,7 @@ def _setupdirstate(repo, dirstate): def wrapdirstate(orig, repo): """Make journal storage available to the dirstate object""" dirstate = orig(repo) - if util.safehasattr(repo, 'journal'): + if hasattr(repo, 'journal'): _setupdirstate(repo, dirstate) return dirstate @@ -112,7 +112,7 @@ def recorddirstateparents(dirstate, old, """Records all dirstate parent changes in the journal.""" old = list(old) new = list(new) - if util.safehasattr(dirstate, 'journalstorage'): + if hasattr(dirstate, 'journalstorage'): # only record two hashes if there was a merge oldhashes = old[:1] if old[1] == dirstate._nodeconstants.nullid else old newhashes = new[:1] if new[1] == dirstate._nodeconstants.nullid else new @@ -125,7 +125,7 @@ def recorddirstateparents(dirstate, old, def recordbookmarks(orig, store, fp): """Records all bookmark changes in the journal.""" repo = store._repo - if util.safehasattr(repo, 'journal'): + if hasattr(repo, 'journal'): oldmarks = bookmarks.bmstore(repo) all_marks = set(b for b, n in oldmarks.items()) all_marks.update(b for b, n in store.items()) @@ -185,11 +185,7 @@ def wrappostshare(orig, sourcerepo, dest def unsharejournal(orig, ui, repo, repopath): """Copy shared journal entries into this repo when unsharing""" - if ( - repo.path == repopath - and repo.shared() - and util.safehasattr(repo, 'journal') - ): + if repo.path == repopath and repo.shared() and hasattr(repo, 'journal'): sharedrepo = hg.sharedreposource(repo) sharedfeatures = _readsharedfeatures(repo) if sharedrepo and sharedfeatures > {b'journal'}: diff --git a/hgext/largefiles/lfutil.py b/hgext/largefiles/lfutil.py --- a/hgext/largefiles/lfutil.py +++ b/hgext/largefiles/lfutil.py @@ -814,7 +814,7 @@ def getstatuswriter(ui, repo, forcibly=N Otherwise, this returns the function to always write out (or ignore if ``not forcibly``) status. """ - if forcibly is None and util.safehasattr(repo, '_largefilesenabled'): + if forcibly is None and hasattr(repo, '_largefilesenabled'): return repo._lfstatuswriters[-1] else: if forcibly: diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py --- a/hgext/largefiles/overrides.py +++ b/hgext/largefiles/overrides.py @@ -1167,7 +1167,7 @@ def hgclone(orig, ui, opts, *args, **kwa @eh.wrapcommand(b'rebase', extension=b'rebase') def overriderebasecmd(orig, ui, repo, **opts): - if not util.safehasattr(repo, '_largefilesenabled'): + if not hasattr(repo, '_largefilesenabled'): return orig(ui, repo, **opts) resuming = opts.get('continue') @@ -1298,7 +1298,7 @@ def overridearchive( # allow only hgsubrepos to set this, instead of the current scheme # where the parent sets this for the child. with ( - util.safehasattr(sub, '_repo') + hasattr(sub, '_repo') and lfstatus(sub._repo) or util.nullcontextmanager() ): @@ -1309,7 +1309,7 @@ def overridearchive( @eh.wrapfunction(subrepo.hgsubrepo, 'archive') def hgsubrepoarchive(orig, repo, archiver, prefix, match=None, decode=True): - lfenabled = util.safehasattr(repo._repo, '_largefilesenabled') + lfenabled = hasattr(repo._repo, '_largefilesenabled') if not lfenabled or not repo._repo.lfstatus: return orig(repo, archiver, prefix, match, decode) @@ -1364,7 +1364,7 @@ def hgsubrepoarchive(orig, repo, archive # would allow only hgsubrepos to set this, instead of the current scheme # where the parent sets this for the child. with ( - util.safehasattr(sub, '_repo') + hasattr(sub, '_repo') and lfstatus(sub._repo) or util.nullcontextmanager() ): diff --git a/hgext/largefiles/storefactory.py b/hgext/largefiles/storefactory.py --- a/hgext/largefiles/storefactory.py +++ b/hgext/largefiles/storefactory.py @@ -57,7 +57,7 @@ def openstore(repo=None, remote=None, pu # The path could be a scheme so use Mercurial's normal functionality # to resolve the scheme to a repository and use its path - path = util.safehasattr(remote, 'url') and remote.url() or remote.path + path = hasattr(remote, 'url') and remote.url() or remote.path match = _scheme_re.match(path) if not match: # regular filesystem path diff --git a/hgext/lfs/blobstore.py b/hgext/lfs/blobstore.py --- a/hgext/lfs/blobstore.py +++ b/hgext/lfs/blobstore.py @@ -271,7 +271,7 @@ def _urlerrorreason(urlerror): if isinstance(urlerror.reason, Exception): inst = urlerror.reason - if util.safehasattr(inst, 'reason'): + if hasattr(inst, 'reason'): try: # usually it is in the form (errno, strerror) reason = inst.reason.args[1] except (AttributeError, IndexError): @@ -751,7 +751,7 @@ def remote(repo, remote=None): if lfsurl is None: if remote: path = remote - elif util.safehasattr(repo, '_subtoppath'): + elif hasattr(repo, '_subtoppath'): # The pull command sets this during the optional update phase, which # tells exactly where the pull originated, whether 'paths.default' # or explicit. diff --git a/hgext/lfs/wireprotolfsserver.py b/hgext/lfs/wireprotolfsserver.py --- a/hgext/lfs/wireprotolfsserver.py +++ b/hgext/lfs/wireprotolfsserver.py @@ -16,7 +16,6 @@ from mercurial.hgweb import common as hg from mercurial import ( exthelper, pycompat, - util, wireprotoserver, ) @@ -44,7 +43,7 @@ def handlewsgirequest(orig, rctx, req, r if not rctx.repo.ui.configbool(b'experimental', b'lfs.serve'): return False - if not util.safehasattr(rctx.repo.svfs, 'lfslocalblobstore'): + if not hasattr(rctx.repo.svfs, 'lfslocalblobstore'): return False if not req.dispatchpath: diff --git a/hgext/lfs/wrapper.py b/hgext/lfs/wrapper.py --- a/hgext/lfs/wrapper.py +++ b/hgext/lfs/wrapper.py @@ -26,7 +26,6 @@ from mercurial import ( localrepo, revlog, scmutil, - util, vfs as vfsmod, wireprotov1server, ) @@ -72,7 +71,7 @@ def allsupportedversions(orig, ui): def _capabilities(orig, repo, proto): '''Wrap server command to announce lfs server capability''' caps = orig(repo, proto) - if util.safehasattr(repo.svfs, 'lfslocalblobstore'): + if hasattr(repo.svfs, 'lfslocalblobstore'): # Advertise a slightly different capability when lfs is *required*, so # that the client knows it MUST load the extension. If lfs is not # required on the server, there's no reason to autoload the extension @@ -335,14 +334,14 @@ def vfsinit(orig, self, othervfs): # also copy lfs blobstores. note: this can run before reposetup, so lfs # blobstore attributes are not always ready at this time. for name in ['lfslocalblobstore', 'lfsremoteblobstore']: - if util.safehasattr(othervfs, name): + if hasattr(othervfs, name): setattr(self, name, getattr(othervfs, name)) def _prefetchfiles(repo, revmatches): """Ensure that required LFS blobs are present, fetching them as a group if needed.""" - if not util.safehasattr(repo.svfs, 'lfslocalblobstore'): + if not hasattr(repo.svfs, 'lfslocalblobstore'): return pointers = [] @@ -366,7 +365,7 @@ def _prefetchfiles(repo, revmatches): def _canskipupload(repo): # Skip if this hasn't been passed to reposetup() - if not util.safehasattr(repo.svfs, 'lfsremoteblobstore'): + if not hasattr(repo.svfs, 'lfsremoteblobstore'): return True # if remotestore is a null store, upload is a no-op and can be skipped @@ -375,7 +374,7 @@ def _canskipupload(repo): def candownload(repo): # Skip if this hasn't been passed to reposetup() - if not util.safehasattr(repo.svfs, 'lfsremoteblobstore'): + if not hasattr(repo.svfs, 'lfsremoteblobstore'): return False # if remotestore is a null store, downloads will lead to nothing @@ -524,7 +523,7 @@ def upgradefinishdatamigration(orig, ui, orig(ui, srcrepo, dstrepo, requirements) # Skip if this hasn't been passed to reposetup() - if util.safehasattr(srcrepo.svfs, 'lfslocalblobstore') and util.safehasattr( + if hasattr(srcrepo.svfs, 'lfslocalblobstore') and hasattr( dstrepo.svfs, 'lfslocalblobstore' ): srclfsvfs = srcrepo.svfs.lfslocalblobstore.vfs diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -4186,7 +4186,7 @@ def reposetup(ui, repo): def mqimport(orig, ui, repo, *args, **kwargs): - if util.safehasattr(repo, 'abortifwdirpatched') and not kwargs.get( + if hasattr(repo, 'abortifwdirpatched') and not kwargs.get( 'no_commit', False ): repo.abortifwdirpatched( diff --git a/hgext/narrow/narrowbundle2.py b/hgext/narrow/narrowbundle2.py --- a/hgext/narrow/narrowbundle2.py +++ b/hgext/narrow/narrowbundle2.py @@ -259,7 +259,7 @@ def _handlechangespec(op, inpart): # will currently always be there when using the core+narrowhg server, but # other servers may include a changespec part even when not widening (e.g. # because we're deepening a shallow repo). - if util.safehasattr(repo, 'setnewnarrowpats'): + if hasattr(repo, 'setnewnarrowpats'): op.gettransaction() repo.setnewnarrowpats() @@ -333,9 +333,9 @@ def setup(): def wrappedcghandler(op, inpart): origcghandler(op, inpart) - if util.safehasattr(op, '_widen_bundle'): + if hasattr(op, '_widen_bundle'): handlechangegroup_widen(op, inpart) - if util.safehasattr(op, '_bookmarksbackup'): + if hasattr(op, '_bookmarksbackup'): localrepo.localrepository._bookmarks.set( op.repo, op._bookmarksbackup ) diff --git a/hgext/relink.py b/hgext/relink.py --- a/hgext/relink.py +++ b/hgext/relink.py @@ -60,9 +60,7 @@ def relink(ui, repo, origin=None, **opts command is running. (Both repositories will be locked against writes.) """ - if not util.safehasattr(util, 'samefile') or not util.safehasattr( - util, 'samedevice' - ): + if not hasattr(util, 'samefile') or not hasattr(util, 'samedevice'): raise error.Abort(_(b'hardlinks are not supported on this system')) if origin is None and b'default-relink' in ui.paths: diff --git a/hgext/remotefilelog/__init__.py b/hgext/remotefilelog/__init__.py --- a/hgext/remotefilelog/__init__.py +++ b/hgext/remotefilelog/__init__.py @@ -425,7 +425,7 @@ def cloneshallow(orig, ui, repo, *args, finally: if opts.get('shallow'): for r in repos: - if util.safehasattr(r, 'fileservice'): + if hasattr(r, 'fileservice'): r.fileservice.close() @@ -904,7 +904,7 @@ def gcclient(ui, cachepath): if not isenabled(repo): continue - if not util.safehasattr(repo, 'name'): + if not hasattr(repo, 'name'): ui.warn( _(b"repo %s is a misconfigured remotefilelog repo\n") % path ) @@ -1034,7 +1034,7 @@ def wcpprefetch(ui, repo, **kwargs): bgprefetchrevs = revdatelimit(ui, bgprefetchrevs) def anon(unused_success): - if util.safehasattr(repo, 'ranprefetch') and repo.ranprefetch: + if hasattr(repo, 'ranprefetch') and repo.ranprefetch: return repo.ranprefetch = True repo.backgroundprefetch(bgprefetchrevs, repack=bgrepack) @@ -1080,9 +1080,9 @@ def exchangepull(orig, repo, remote, *ar source, heads=heads, common=common, bundlecaps=bundlecaps, **kwargs ) - if util.safehasattr(remote, '_callstream'): + if hasattr(remote, '_callstream'): remote._localrepo = repo - elif util.safehasattr(remote, 'getbundle'): + elif hasattr(remote, 'getbundle'): extensions.wrapfunction(remote, 'getbundle', localgetbundle) return orig(repo, remote, *args, **kwargs) diff --git a/hgext/remotefilelog/basestore.py b/hgext/remotefilelog/basestore.py --- a/hgext/remotefilelog/basestore.py +++ b/hgext/remotefilelog/basestore.py @@ -415,7 +415,7 @@ class baseunionstore: def markforrefresh(self): for store in self.stores: - if util.safehasattr(store, b'markforrefresh'): + if hasattr(store, b'markforrefresh'): store.markforrefresh() @staticmethod diff --git a/hgext/remotefilelog/connectionpool.py b/hgext/remotefilelog/connectionpool.py --- a/hgext/remotefilelog/connectionpool.py +++ b/hgext/remotefilelog/connectionpool.py @@ -9,7 +9,6 @@ from mercurial import ( hg, sshpeer, - util, ) _sshv1peer = sshpeer.sshv1peer @@ -41,14 +40,14 @@ class connectionpool: if conn is None: peer = hg.peer(self._repo.ui, {}, path) - if util.safehasattr(peer, '_cleanup'): + if hasattr(peer, '_cleanup'): class mypeer(peer.__class__): def _cleanup(self, warn=None): # close pipee first so peer.cleanup reading it won't # deadlock, if there are other processes with pipeo # open (i.e. us). - if util.safehasattr(self, 'pipee'): + if hasattr(self, 'pipee'): self.pipee.close() return super(mypeer, self)._cleanup() @@ -83,5 +82,5 @@ class connection: self.close() def close(self): - if util.safehasattr(self.peer, 'cleanup'): + if hasattr(self.peer, 'cleanup'): self.peer.cleanup() diff --git a/hgext/remotefilelog/fileserverclient.py b/hgext/remotefilelog/fileserverclient.py --- a/hgext/remotefilelog/fileserverclient.py +++ b/hgext/remotefilelog/fileserverclient.py @@ -92,7 +92,7 @@ def peersetup(ui, peer): not in self.capabilities() ): return - if not util.safehasattr(self, '_localrepo'): + if not hasattr(self, '_localrepo'): return if ( constants.SHALLOWREPO_REQUIREMENT @@ -132,7 +132,7 @@ def peersetup(ui, peer): def _callstream(self, command, **opts): supertype = super(remotefilepeer, self) - if not util.safehasattr(supertype, '_sendrequest'): + if not hasattr(supertype, '_sendrequest'): self._updatecallstreamopts(command, pycompat.byteskwargs(opts)) return super(remotefilepeer, self)._callstream(command, **opts) @@ -641,9 +641,7 @@ class fileserverclient: self._lfsprefetch(fileids) def _lfsprefetch(self, fileids): - if not _lfsmod or not util.safehasattr( - self.repo.svfs, b'lfslocalblobstore' - ): + if not _lfsmod or not hasattr(self.repo.svfs, b'lfslocalblobstore'): return if not _lfsmod.wrapper.candownload(self.repo): return diff --git a/hgext/remotefilelog/remotefilelogserver.py b/hgext/remotefilelog/remotefilelogserver.py --- a/hgext/remotefilelog/remotefilelogserver.py +++ b/hgext/remotefilelog/remotefilelogserver.py @@ -228,7 +228,7 @@ def onetimesetup(ui): # When generating file blobs, taking the real path is too slow on large # repos, so force it to just return the linkrev directly. repo = self._repo - if util.safehasattr(repo, 'forcelinkrev') and repo.forcelinkrev: + if hasattr(repo, 'forcelinkrev') and repo.forcelinkrev: return self._filelog.linkrev(self._filelog.rev(self._filenode)) return orig(self, *args, **kwargs) diff --git a/hgext/remotefilelog/repack.py b/hgext/remotefilelog/repack.py --- a/hgext/remotefilelog/repack.py +++ b/hgext/remotefilelog/repack.py @@ -49,7 +49,7 @@ def backgroundrepack(repo, incremental=T def fullrepack(repo, options=None): """If ``packsonly`` is True, stores creating only loose objects are skipped.""" - if util.safehasattr(repo, 'shareddatastores'): + if hasattr(repo, 'shareddatastores'): datasource = contentstore.unioncontentstore(*repo.shareddatastores) historysource = metadatastore.unionmetadatastore( *repo.sharedhistorystores, allowincomplete=True @@ -67,7 +67,7 @@ def fullrepack(repo, options=None): options=options, ) - if util.safehasattr(repo.manifestlog, 'datastore'): + if hasattr(repo.manifestlog, 'datastore'): localdata, shareddata = _getmanifeststores(repo) lpackpath, ldstores, lhstores = localdata spackpath, sdstores, shstores = shareddata @@ -107,7 +107,7 @@ def incrementalrepack(repo, options=None """This repacks the repo by looking at the distribution of pack files in the repo and performing the most minimal repack to keep the repo in good shape. """ - if util.safehasattr(repo, 'shareddatastores'): + if hasattr(repo, 'shareddatastores'): packpath = shallowutil.getcachepackpath( repo, constants.FILEPACK_CATEGORY ) @@ -120,7 +120,7 @@ def incrementalrepack(repo, options=None options=options, ) - if util.safehasattr(repo.manifestlog, 'datastore'): + if hasattr(repo.manifestlog, 'datastore'): localdata, shareddata = _getmanifeststores(repo) lpackpath, ldstores, lhstores = localdata spackpath, sdstores, shstores = shareddata @@ -895,7 +895,7 @@ class repackentry: def repacklockvfs(repo): - if util.safehasattr(repo, 'name'): + if hasattr(repo, 'name'): # Lock in the shared cache so repacks across multiple copies of the same # repo are coordinated. sharedcachepath = shallowutil.getcachepackpath( diff --git a/hgext/remotefilelog/shallowrepo.py b/hgext/remotefilelog/shallowrepo.py --- a/hgext/remotefilelog/shallowrepo.py +++ b/hgext/remotefilelog/shallowrepo.py @@ -340,7 +340,7 @@ def wraprepo(repo): repo.excludepattern = repo.ui.configlist( b"remotefilelog", b"excludepattern", None ) - if not util.safehasattr(repo, 'connectionpool'): + if not hasattr(repo, 'connectionpool'): repo.connectionpool = connectionpool.connectionpool(repo) if repo.includepattern or repo.excludepattern: diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py --- a/mercurial/bundle2.py +++ b/mercurial/bundle2.py @@ -980,7 +980,7 @@ class unbundle20(unpackermixin): def close(self): """close underlying file""" - if util.safehasattr(self._fp, 'close'): + if hasattr(self._fp, 'close'): return self._fp.close() @@ -1068,7 +1068,7 @@ class bundlepart: The new part have the very same content but no partid assigned yet. Parts with generated data cannot be copied.""" - assert not util.safehasattr(self.data, 'next') + assert not hasattr(self.data, 'next') return self.__class__( self.type, self._mandatoryparams, @@ -1137,9 +1137,7 @@ class bundlepart: msg.append(b')') if not self.data: msg.append(b' empty payload') - elif util.safehasattr(self.data, 'next') or util.safehasattr( - self.data, '__next__' - ): + elif hasattr(self.data, 'next') or hasattr(self.data, '__next__'): msg.append(b' streamed payload') else: msg.append(b' %i bytes payload' % len(self.data)) @@ -1233,9 +1231,7 @@ class bundlepart: Exists to handle the different methods to provide data to a part.""" # we only support fixed size data now. # This will be improved in the future. - if util.safehasattr(self.data, 'next') or util.safehasattr( - self.data, '__next__' - ): + if hasattr(self.data, 'next') or hasattr(self.data, '__next__'): buff = util.chunkbuffer(self.data) chunk = buff.read(preferedchunksize) while chunk: @@ -1380,9 +1376,7 @@ class unbundlepart(unpackermixin): def __init__(self, ui, header, fp): super(unbundlepart, self).__init__(fp) - self._seekable = util.safehasattr(fp, 'seek') and util.safehasattr( - fp, 'tell' - ) + self._seekable = hasattr(fp, 'seek') and hasattr(fp, 'tell') self.ui = ui # unbundle state attr self._headerdata = header diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py --- a/mercurial/bundlerepo.py +++ b/mercurial/bundlerepo.py @@ -245,7 +245,7 @@ class bundlepeer(localrepo.localpeer): class bundlephasecache(phases.phasecache): def __init__(self, *args, **kwargs): super(bundlephasecache, self).__init__(*args, **kwargs) - if util.safehasattr(self, 'opener'): + if hasattr(self, 'opener'): self.opener = vfsmod.readonlyvfs(self.opener) def write(self): diff --git a/mercurial/changegroup.py b/mercurial/changegroup.py --- a/mercurial/changegroup.py +++ b/mercurial/changegroup.py @@ -1043,7 +1043,7 @@ def _resolvenarrowrevisioninfo( return i # We failed to resolve a parent for this node, so # we crash the changegroup construction. - if util.safehasattr(store, 'target'): + if hasattr(store, 'target'): target = store.display_id else: # some revlog not actually a revlog diff --git a/mercurial/chgserver.py b/mercurial/chgserver.py --- a/mercurial/chgserver.py +++ b/mercurial/chgserver.py @@ -236,7 +236,7 @@ def _newchgui(srcui, csystem, attachio): # will behave differently (i.e. write to stdout). if ( out is not self.fout - or not util.safehasattr(self.fout, 'fileno') + or not hasattr(self.fout, 'fileno') or self.fout.fileno() != procutil.stdout.fileno() or self._finoutredirected ): @@ -262,7 +262,7 @@ def _loadnewui(srcui, args, cdebug): newui = srcui.__class__.load() for a in ['fin', 'fout', 'ferr', 'environ']: setattr(newui, a, getattr(srcui, a)) - if util.safehasattr(srcui, '_csystem'): + if hasattr(srcui, '_csystem'): newui._csystem = srcui._csystem # command line args @@ -603,7 +603,7 @@ class chgcmdserver(commandserver.server) } ) - if util.safehasattr(procutil, 'setprocname'): + if hasattr(procutil, 'setprocname'): def setprocname(self): """Change process title""" diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -1449,7 +1449,7 @@ def openstorage(repo, cmd, file_, opts, if returnrevlog: if isinstance(r, revlog.revlog): pass - elif util.safehasattr(r, '_revlog'): + elif hasattr(r, '_revlog'): r = r._revlog # pytype: disable=attribute-error elif r is not None: raise error.InputError( diff --git a/mercurial/commandserver.py b/mercurial/commandserver.py --- a/mercurial/commandserver.py +++ b/mercurial/commandserver.py @@ -332,7 +332,7 @@ class server: # any kind of interaction must use server channels, but chg may # replace channels by fully functional tty files. so nontty is # enforced only if cin is a channel. - if not util.safehasattr(self.cin, 'fileno'): + if not hasattr(self.cin, 'fileno'): ui.setconfig(b'ui', b'nontty', b'true', b'commandserver') req = dispatch.request( @@ -384,7 +384,7 @@ class server: if self.cmsg: hellomsg += b'message-encoding: %s\n' % self.cmsg.encoding hellomsg += b'pid: %d' % procutil.getpid() - if util.safehasattr(os, 'getpgid'): + if hasattr(os, 'getpgid'): hellomsg += b'\n' hellomsg += b'pgid: %d' % os.getpgid(0) @@ -559,7 +559,7 @@ class unixforkingservice: self.ui = ui self.repo = repo self.address = opts[b'address'] - if not util.safehasattr(socket, 'AF_UNIX'): + if not hasattr(socket, 'AF_UNIX'): raise error.Abort(_(b'unsupported platform')) if not self.address: raise error.Abort(_(b'no socket path specified with --address')) @@ -588,7 +588,7 @@ class unixforkingservice: o = socket.socketpair(socket.AF_UNIX, socket.SOCK_DGRAM) self._mainipc, self._workeripc = o self._servicehandler.bindsocket(self._sock, self.address) - if util.safehasattr(procutil, 'unblocksignal'): + if hasattr(procutil, 'unblocksignal'): procutil.unblocksignal(signal.SIGCHLD) o = signal.signal(signal.SIGCHLD, self._sigchldhandler) self._oldsigchldhandler = o diff --git a/mercurial/crecord.py b/mercurial/crecord.py --- a/mercurial/crecord.py +++ b/mercurial/crecord.py @@ -573,7 +573,7 @@ def chunkselector(ui, headerlist, operat ui.write(_(b'starting interactive selection\n')) chunkselector = curseschunkselector(headerlist, ui, operation) origsigtstp = sentinel = object() - if util.safehasattr(signal, 'SIGTSTP'): + if hasattr(signal, 'SIGTSTP'): origsigtstp = signal.getsignal(signal.SIGTSTP) try: with util.with_lc_ctype(): @@ -1944,7 +1944,7 @@ are you sure you want to review/edit and """ origsigwinch = sentinel = object() - if util.safehasattr(signal, 'SIGWINCH'): + if hasattr(signal, 'SIGWINCH'): origsigwinch = signal.signal(signal.SIGWINCH, self.sigwinchhandler) try: return self._main(stdscr) diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -1282,7 +1282,7 @@ def debugdiscovery(ui, repo, remoteurl=b if opts.get(b'old'): def doit(pushedrevs, remoteheads, remote=remote): - if not util.safehasattr(remote, 'branches'): + if not hasattr(remote, 'branches'): # enable in-client legacy support remote = localrepo.locallegacypeer(remote.local()) if remote_revs: @@ -1482,7 +1482,7 @@ def debugextensions(ui, repo, **opts): isinternal = extensions.ismoduleinternal(extmod) extsource = None - if util.safehasattr(extmod, '__file__'): + if hasattr(extmod, '__file__'): extsource = pycompat.fsencode(extmod.__file__) elif getattr(sys, 'oxidized', False): extsource = pycompat.sysexecutable @@ -1722,7 +1722,7 @@ def debugformat(ui, repo, **opts): if fm.isplain(): def formatvalue(value): - if util.safehasattr(value, 'startswith'): + if hasattr(value, 'startswith'): return value if value: return b'yes' @@ -1947,7 +1947,7 @@ def debugindexstats(ui, repo): """show stats related to the changelog index""" repo.changelog.shortest(repo.nullid, 1) index = repo.changelog.index - if not util.safehasattr(index, 'stats'): + if not hasattr(index, 'stats'): raise error.Abort(_(b'debugindexstats only works with native code')) for k, v in sorted(index.stats().items()): ui.write(b'%s: %d\n' % (k, v)) @@ -1983,7 +1983,7 @@ def debuginstall(ui, **opts): # Python pythonlib = None - if util.safehasattr(os, '__file__'): + if hasattr(os, '__file__'): pythonlib = os.path.dirname(pycompat.fsencode(os.__file__)) elif getattr(sys, 'oxidized', False): pythonlib = pycompat.sysexecutable @@ -2065,7 +2065,7 @@ def debuginstall(ui, **opts): # compiled modules hgmodules = None - if util.safehasattr(sys.modules[__name__], '__file__'): + if hasattr(sys.modules[__name__], '__file__'): hgmodules = os.path.dirname(pycompat.fsencode(__file__)) elif getattr(sys, 'oxidized', False): hgmodules = pycompat.sysexecutable @@ -2649,7 +2649,7 @@ def debugnodemap(ui, repo, file_=None, * if isinstance(r, (manifest.manifestrevlog, filelog.filelog)): r = r._revlog if opts['dump_new']: - if util.safehasattr(r.index, "nodemap_data_all"): + if hasattr(r.index, "nodemap_data_all"): data = r.index.nodemap_data_all() else: data = nodemap.persistent_data(r.index) diff --git a/mercurial/dirstatemap.py b/mercurial/dirstatemap.py --- a/mercurial/dirstatemap.py +++ b/mercurial/dirstatemap.py @@ -377,7 +377,7 @@ class dirstatemap(_dirstatemapcommon): return # TODO: adjust this estimate for dirstate-v2 - if util.safehasattr(parsers, 'dict_new_presized'): + if hasattr(parsers, 'dict_new_presized'): # Make an estimate of the number of files in the dirstate based on # its size. This trades wasting some memory for avoiding costly # resizes. Each entry have a prefix of 17 bytes followed by one or diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py --- a/mercurial/dispatch.py +++ b/mercurial/dispatch.py @@ -107,7 +107,7 @@ class request: def _flushstdio(ui, err): status = None # In all cases we try to flush stdio streams. - if util.safehasattr(ui, 'fout'): + if hasattr(ui, 'fout'): assert ui is not None # help pytype assert ui.fout is not None # help pytype try: @@ -116,7 +116,7 @@ def _flushstdio(ui, err): err = e status = -1 - if util.safehasattr(ui, 'ferr'): + if hasattr(ui, 'ferr'): assert ui is not None # help pytype assert ui.ferr is not None # help pytype try: @@ -170,7 +170,7 @@ def initstdio(): "newline": "\n", "line_buffering": sys.stdout.line_buffering, } - if util.safehasattr(sys.stdout, "write_through"): + if hasattr(sys.stdout, "write_through"): # pytype: disable=attribute-error kwargs["write_through"] = sys.stdout.write_through # pytype: enable=attribute-error @@ -183,7 +183,7 @@ def initstdio(): "newline": "\n", "line_buffering": sys.stderr.line_buffering, } - if util.safehasattr(sys.stderr, "write_through"): + if hasattr(sys.stderr, "write_through"): # pytype: disable=attribute-error kwargs["write_through"] = sys.stderr.write_through # pytype: enable=attribute-error @@ -520,7 +520,7 @@ def _callcatch(ui, func): def aliasargs(fn, givenargs): args = [] # only care about alias 'args', ignore 'args' set by extensions.wrapfunction - if not util.safehasattr(fn, '_origfunc'): + if not hasattr(fn, '_origfunc'): args = getattr(fn, 'args', args) if args: cmd = b' '.join(map(procutil.shellquote, args)) @@ -708,7 +708,7 @@ class cmdalias: } if name not in adefaults: raise AttributeError(name) - if self.badalias or util.safehasattr(self, 'shell'): + if self.badalias or hasattr(self, 'shell'): return adefaults[name] return getattr(self.fn, name) @@ -734,7 +734,7 @@ class cmdalias: self.name, self.definition, ) - if util.safehasattr(self, 'shell'): + if hasattr(self, 'shell'): return self.fn(ui, *args, **opts) else: try: @@ -1024,7 +1024,7 @@ def _checkshellalias(lui, ui, args): cmd = aliases[0] fn = entry[0] - if cmd and util.safehasattr(fn, 'shell'): + if cmd and hasattr(fn, 'shell'): # shell alias shouldn't receive early options which are consumed by hg _earlyopts, args = _earlysplitopts(args) d = lambda: fn(ui, *args[1:]) diff --git a/mercurial/extensions.py b/mercurial/extensions.py --- a/mercurial/extensions.py +++ b/mercurial/extensions.py @@ -172,7 +172,7 @@ def _validatecmdtable(ui, cmdtable): """Check if extension commands have required attributes""" for c, e in cmdtable.items(): f = e[0] - missing = [a for a in _cmdfuncattrs if not util.safehasattr(f, a)] + missing = [a for a in _cmdfuncattrs if not hasattr(f, a)] if not missing: continue msg = b'missing attributes: %s' @@ -742,7 +742,7 @@ def _disabledpaths(): # The hgext might not have a __file__ attribute (e.g. in PyOxidizer) and # it might not be on a filesystem even if it does. - if util.safehasattr(hgext, '__file__'): + if hasattr(hgext, '__file__'): extpath = os.path.dirname( util.abspath(pycompat.fsencode(hgext.__file__)) ) @@ -857,7 +857,7 @@ def disabled_help(name): # The extensions are filesystem based, so either an error occurred # or all are enabled. - if util.safehasattr(hgext, '__file__'): + if hasattr(hgext, '__file__'): return if name in _order: # enabled @@ -987,13 +987,13 @@ def notloaded(): def moduleversion(module): '''return version information from given module as a string''' - if util.safehasattr(module, 'getversion') and callable(module.getversion): + if hasattr(module, 'getversion') and callable(module.getversion): try: version = module.getversion() except Exception: version = b'unknown' - elif util.safehasattr(module, '__version__'): + elif hasattr(module, '__version__'): version = module.__version__ else: version = b'' diff --git a/mercurial/help.py b/mercurial/help.py --- a/mercurial/help.py +++ b/mercurial/help.py @@ -43,7 +43,6 @@ from . import ( templatefuncs, templatekw, ui as uimod, - util, ) from .hgweb import webcommands from .utils import ( @@ -810,7 +809,7 @@ def help_( doc = gettext(pycompat.getdoc(entry[0])) if not doc: doc = _(b"(no help text available)") - if util.safehasattr(entry[0], 'definition'): # aliased command + if hasattr(entry[0], 'definition'): # aliased command source = entry[0].source if entry[0].definition.startswith(b'!'): # shell alias doc = _(b'shell alias for: %s\n\n%s\n\ndefined by: %s\n') % ( diff --git a/mercurial/hg.py b/mercurial/hg.py --- a/mercurial/hg.py +++ b/mercurial/hg.py @@ -66,7 +66,7 @@ sharedbookmarks = b'bookmarks' def addbranchrevs(lrepo, other, branches, revs, remotehidden=False): - if util.safehasattr(other, 'peer'): + if hasattr(other, 'peer'): # a courtesy to callers using a localrepo for other peer = other.peer(remotehidden=remotehidden) else: @@ -174,7 +174,7 @@ def islocal(repo): cls.instance # make sure we load the module else: cls = LocalFactory - if util.safehasattr(cls, 'islocal'): + if hasattr(cls, 'islocal'): return cls.islocal(repo) # pytype: disable=module-attr return False repo.ui.deprecwarn(b"use obj.local() instead of islocal(obj)", b"6.4") @@ -254,7 +254,7 @@ def peer( '''return a repository peer for the specified path''' ui = getattr(uiorrepo, 'ui', uiorrepo) rui = remoteui(uiorrepo, opts) - if util.safehasattr(path, 'url'): + if hasattr(path, 'url'): # this is already a urlutil.path object peer_path = path else: @@ -317,7 +317,7 @@ def sharedreposource(repo): if repo.sharedpath == repo.path: return None - if util.safehasattr(repo, 'srcrepo') and repo.srcrepo: + if hasattr(repo, 'srcrepo') and repo.srcrepo: return repo.srcrepo # the sharedpath always ends in the .hg; we want the path to the repo @@ -340,7 +340,7 @@ def share( '''create a shared repository''' not_local_msg = _(b'can only share local repositories') - if util.safehasattr(source, 'local'): + if hasattr(source, 'local'): if source.local() is None: raise error.Abort(not_local_msg) elif not islocal(source): @@ -729,7 +729,7 @@ def clone( branches = (src_path.branch, branch or []) source = src_path.loc else: - if util.safehasattr(source, 'peer'): + if hasattr(source, 'peer'): srcpeer = source.peer() # in case we were called with a localrepo else: srcpeer = source @@ -1567,7 +1567,7 @@ def verify(repo, level=None): def remoteui(src, opts): """build a remote ui from ui or repo and opts""" - if util.safehasattr(src, 'baseui'): # looks like a repository + if hasattr(src, 'baseui'): # looks like a repository dst = src.baseui.copy() # drop repo-specific config src = src.ui # copy target options from repo else: # assume it's a global ui object diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -34,7 +34,6 @@ from .. import ( templater, templateutil, ui as uimod, - util, wireprotoserver, ) @@ -403,7 +402,7 @@ class hgweb: cmd = cmd[style + 1 :] # avoid accepting e.g. style parameter as command - if util.safehasattr(webcommands, pycompat.sysstr(cmd)): + if hasattr(webcommands, pycompat.sysstr(cmd)): req.qsparams[b'cmd'] = cmd if cmd == b'static': @@ -478,7 +477,7 @@ class hgweb: except (error.LookupError, error.RepoLookupError) as err: msg = pycompat.bytestr(err) - if util.safehasattr(err, 'name') and not isinstance( + if hasattr(err, 'name') and not isinstance( err, error.ManifestLookupError ): msg = b'revision not found: %s' % err.name diff --git a/mercurial/hgweb/server.py b/mercurial/hgweb/server.py --- a/mercurial/hgweb/server.py +++ b/mercurial/hgweb/server.py @@ -100,7 +100,7 @@ class _httprequesthandler(httpservermod. def log_request(self, code='-', size='-'): xheaders = [] - if util.safehasattr(self, 'headers'): + if hasattr(self, 'headers'): xheaders = [ h for h in self.headers.items() if h[0].startswith('x-') ] @@ -214,7 +214,7 @@ class _httprequesthandler(httpservermod. env['wsgi.multithread'] = isinstance( self.server, socketserver.ThreadingMixIn ) - if util.safehasattr(socketserver, 'ForkingMixIn'): + if hasattr(socketserver, 'ForkingMixIn'): env['wsgi.multiprocess'] = isinstance( self.server, socketserver.ForkingMixIn ) @@ -344,7 +344,7 @@ try: threading.active_count() # silence pyflakes and bypass demandimport _mixin = socketserver.ThreadingMixIn except ImportError: - if util.safehasattr(os, "fork"): + if hasattr(os, "fork"): _mixin = socketserver.ForkingMixIn else: diff --git a/mercurial/hgweb/webutil.py b/mercurial/hgweb/webutil.py --- a/mercurial/hgweb/webutil.py +++ b/mercurial/hgweb/webutil.py @@ -211,7 +211,7 @@ def _ctxsgen(context, ctxs): b'description': s.description(), b'branch': s.branch(), } - if util.safehasattr(s, 'path'): + if hasattr(s, 'path'): d[b'file'] = s.path() yield d diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py --- a/mercurial/httppeer.py +++ b/mercurial/httppeer.py @@ -65,7 +65,7 @@ def encodevalueinheaders(value, header, class _multifile: def __init__(self, *fileobjs): for f in fileobjs: - if not util.safehasattr(f, 'length'): + if not hasattr(f, 'length'): raise ValueError( b'_multifile only supports file objects that ' b'have a length but this one does not:', @@ -180,7 +180,7 @@ def makev1commandrequest( qs = b'?%s' % urlreq.urlencode(q) cu = b"%s%s" % (repobaseurl, qs) size = 0 - if util.safehasattr(data, 'length'): + if hasattr(data, 'length'): size = data.length elif data is not None: size = len(data) diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -420,7 +420,7 @@ class localpeer(repository.peer): try: bundle = exchange.readbundle(self.ui, bundle, None) ret = exchange.unbundle(self._repo, bundle, heads, b'push', url) - if util.safehasattr(ret, 'getchunks'): + if hasattr(ret, 'getchunks'): # This is a bundle20 object, turn it into an unbundler. # This little dance should be dropped eventually when the # API is finally improved. @@ -1461,7 +1461,7 @@ class localrepository: if self.ui.configbool(b'devel', b'all-warnings') or self.ui.configbool( b'devel', b'check-locks' ): - if util.safehasattr(self.svfs, 'vfs'): # this is filtervfs + if hasattr(self.svfs, 'vfs'): # this is filtervfs self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit) else: # standard vfs self.svfs.audit = self._getsvfsward(self.svfs.audit) @@ -1523,8 +1523,8 @@ class localrepository: repo = rref() if ( repo is None - or not util.safehasattr(repo, '_wlockref') - or not util.safehasattr(repo, '_lockref') + or not hasattr(repo, '_wlockref') + or not hasattr(repo, '_lockref') ): return if mode in (None, b'r', b'rb'): @@ -1572,7 +1572,7 @@ class localrepository: def checksvfs(path, mode=None): ret = origfunc(path, mode=mode) repo = rref() - if repo is None or not util.safehasattr(repo, '_lockref'): + if repo is None or not hasattr(repo, '_lockref'): return if mode in (None, b'r', b'rb'): return diff --git a/mercurial/manifest.py b/mercurial/manifest.py --- a/mercurial/manifest.py +++ b/mercurial/manifest.py @@ -1628,7 +1628,7 @@ class manifestrevlog: def _setupmanifestcachehooks(self, repo): """Persist the manifestfulltextcache on lock release""" - if not util.safehasattr(repo, '_wlockref'): + if not hasattr(repo, '_wlockref'): return self._fulltextcache._opener = repo.wcachevfs diff --git a/mercurial/mdiff.py b/mercurial/mdiff.py --- a/mercurial/mdiff.py +++ b/mercurial/mdiff.py @@ -211,11 +211,7 @@ def blocksinrange(blocks, rangeb): def chooseblocksfunc(opts=None): - if ( - opts is None - or not opts.xdiff - or not util.safehasattr(bdiff, 'xdiffblocks') - ): + if opts is None or not opts.xdiff or not hasattr(bdiff, 'xdiffblocks'): return bdiff.blocks else: return bdiff.xdiffblocks diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -168,7 +168,7 @@ def split(stream): mimeheaders = [b'content-type'] - if not util.safehasattr(stream, 'next'): + if not hasattr(stream, 'next'): # http responses, for example, have readline but not next stream = fiter(stream) @@ -1703,7 +1703,7 @@ def reversehunks(hunks): newhunks = [] for c in hunks: - if util.safehasattr(c, 'reversehunk'): + if hasattr(c, 'reversehunk'): c = c.reversehunk() newhunks.append(c) return newhunks diff --git a/mercurial/pathutil.py b/mercurial/pathutil.py --- a/mercurial/pathutil.py +++ b/mercurial/pathutil.py @@ -377,7 +377,7 @@ class dirs: return d in self._dirs -if util.safehasattr(parsers, 'dirs'): +if hasattr(parsers, 'dirs'): dirs = parsers.dirs if rustdirs is not None: diff --git a/mercurial/pvec.py b/mercurial/pvec.py --- a/mercurial/pvec.py +++ b/mercurial/pvec.py @@ -159,7 +159,7 @@ def _flipbit(v, node): def ctxpvec(ctx): '''construct a pvec for ctx while filling in the cache''' r = ctx.repo() - if not util.safehasattr(r, "_pveccache"): + if not hasattr(r, "_pveccache"): r._pveccache = {} pvc = r._pveccache if ctx.rev() not in pvc: diff --git a/mercurial/registrar.py b/mercurial/registrar.py --- a/mercurial/registrar.py +++ b/mercurial/registrar.py @@ -10,7 +10,6 @@ from . import ( configitems, error, pycompat, - util, ) # unlike the other registered items, config options are neither functions or @@ -64,7 +63,7 @@ class _funcregistrarbase: msg = b'duplicate registration for name: "%s"' % name raise error.ProgrammingError(msg) - if func.__doc__ and not util.safehasattr(func, '_origdoc'): + if func.__doc__ and not hasattr(func, '_origdoc'): func._origdoc = func.__doc__.strip() doc = pycompat.sysbytes(func._origdoc) func.__doc__ = pycompat.sysstr(self._formatdoc(decl, doc)) diff --git a/mercurial/repoview.py b/mercurial/repoview.py --- a/mercurial/repoview.py +++ b/mercurial/repoview.py @@ -296,13 +296,12 @@ class filteredchangelogmixin: This returns a version of 'revs' to be used thereafter by the caller. In particular, if revs is an iterator, it is converted into a set. """ - safehasattr = util.safehasattr - if safehasattr(revs, '__next__'): + if hasattr(revs, '__next__'): # Note that inspect.isgenerator() is not true for iterators, revs = set(revs) filteredrevs = self.filteredrevs - if safehasattr(revs, 'first'): # smartset + if hasattr(revs, 'first'): # smartset offenders = revs & filteredrevs else: offenders = filteredrevs.intersection(revs) diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -167,7 +167,7 @@ def _verify_revision(rl, skipflags, stat # We also consider we have a "fast" implementation in "pure" python because # people using pure don't really have performance consideration (and a # wheelbarrow of other slowness source) -HAS_FAST_PERSISTENT_NODEMAP = rustrevlog is not None or util.safehasattr( +HAS_FAST_PERSISTENT_NODEMAP = rustrevlog is not None or hasattr( parsers, 'BaseIndexObject' ) @@ -214,7 +214,7 @@ def parse_index_cl_v2(data, inline): return index, cache -if util.safehasattr(parsers, 'parse_index_devel_nodemap'): +if hasattr(parsers, 'parse_index_devel_nodemap'): def parse_index_v1_nodemap(data, inline): index, cache = parsers.parse_index_devel_nodemap(data, inline) @@ -730,7 +730,7 @@ class revlog: use_nodemap = ( not self._inline and self._nodemap_file is not None - and util.safehasattr(index, 'update_nodemap_data') + and hasattr(index, 'update_nodemap_data') ) if use_nodemap: nodemap_data = nodemaputil.persisted_data(self) @@ -911,7 +911,7 @@ class revlog: use_nodemap = ( not self._inline and self._nodemap_file is not None - and util.safehasattr(self.index, 'update_nodemap_data') + and hasattr(self.index, 'update_nodemap_data') ) if use_nodemap: nodemap_data = nodemaputil.persisted_data(self) @@ -1887,7 +1887,7 @@ class revlog: """tells whether rev is a snapshot""" if not self._sparserevlog: return self.deltaparent(rev) == nullrev - elif util.safehasattr(self.index, 'issnapshot'): + elif hasattr(self.index, 'issnapshot'): # directly assign the method to cache the testing and access self.issnapshot = self.index.issnapshot return self.issnapshot(rev) diff --git a/mercurial/revlogutils/debug.py b/mercurial/revlogutils/debug.py --- a/mercurial/revlogutils/debug.py +++ b/mercurial/revlogutils/debug.py @@ -13,7 +13,6 @@ from .. import ( mdiff, node as nodemod, revlogutils, - util, ) from . import ( @@ -409,7 +408,7 @@ def debug_revlog(ui, revlog): numother_nad += 1 # Obtain data on the raw chunks in the revlog. - if util.safehasattr(r, '_getsegmentforrevs'): + if hasattr(r, '_getsegmentforrevs'): segment = r._getsegmentforrevs(rev, rev)[1] else: segment = r._revlog._getsegmentforrevs(rev, rev)[1] diff --git a/mercurial/revlogutils/deltas.py b/mercurial/revlogutils/deltas.py --- a/mercurial/revlogutils/deltas.py +++ b/mercurial/revlogutils/deltas.py @@ -1060,7 +1060,7 @@ class SnapshotCache: end_rev < self._start_rev or end_rev > self._end_rev ), (self._start_rev, self._end_rev, start_rev, end_rev) cache = self.snapshots - if util.safehasattr(revlog.index, 'findsnapshots'): + if hasattr(revlog.index, 'findsnapshots'): revlog.index.findsnapshots(cache, start_rev, end_rev) else: deltaparent = revlog.deltaparent diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py --- a/mercurial/revlogutils/nodemap.py +++ b/mercurial/revlogutils/nodemap.py @@ -174,9 +174,9 @@ def persist_nodemap(tr, revlog, pending= msg = "calling persist nodemap on a revlog without the feature enabled" raise error.ProgrammingError(msg) - can_incremental = util.safehasattr(revlog.index, "nodemap_data_incremental") + can_incremental = hasattr(revlog.index, "nodemap_data_incremental") ondisk_docket = revlog._nodemap_docket - feed_data = util.safehasattr(revlog.index, "update_nodemap_data") + feed_data = hasattr(revlog.index, "update_nodemap_data") use_mmap = revlog.opener.options.get(b"persistent-nodemap.mmap") data = None @@ -216,7 +216,7 @@ def persist_nodemap(tr, revlog, pending= # otherwise fallback to a full new export target_docket = NodeMapDocket() datafile = _rawdata_filepath(revlog, target_docket) - if util.safehasattr(revlog.index, "nodemap_data_all"): + if hasattr(revlog.index, "nodemap_data_all"): data = revlog.index.nodemap_data_all() else: data = persistent_data(revlog.index) diff --git a/mercurial/rewriteutil.py b/mercurial/rewriteutil.py --- a/mercurial/rewriteutil.py +++ b/mercurial/rewriteutil.py @@ -21,7 +21,6 @@ from . import ( obsutil, revset, scmutil, - util, ) @@ -77,7 +76,7 @@ def precheck(repo, revs, action=b'rewrit hint = _(b"no changeset checked out") raise error.InputError(msg, hint=hint) - if any(util.safehasattr(r, 'rev') for r in revs): + if any(hasattr(r, 'rev') for r in revs): repo.ui.develwarn(b"rewriteutil.precheck called with ctx not revs") revs = (r.rev() for r in revs) diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -233,11 +233,7 @@ def callcatch(ui, func): reason = encoding.unitolocal(reason) ui.error(_(b"abort: error: %s\n") % stringutil.forcebytestr(reason)) except (IOError, OSError) as inst: - if ( - util.safehasattr(inst, "args") - and inst.args - and inst.args[0] == errno.EPIPE - ): + if hasattr(inst, "args") and inst.args and inst.args[0] == errno.EPIPE: pass elif getattr(inst, "strerror", None): # common IOError or OSError if getattr(inst, "filename", None) is not None: @@ -561,11 +557,11 @@ def shortesthexnodeidprefix(repo, node, if cache is not None: nodetree = cache.get(b'disambiguationnodetree') if not nodetree: - if util.safehasattr(parsers, 'nodetree'): + if hasattr(parsers, 'nodetree'): # The CExt is the only implementation to provide a nodetree # class so far. index = cl.index - if util.safehasattr(index, 'get_cindex'): + if hasattr(index, 'get_cindex'): # the rust wrapped need to give access to its internal index index = index.get_cindex() nodetree = parsers.nodetree(index, len(revs)) @@ -1066,7 +1062,7 @@ def cleanupnodes( return # translate mapping's other forms - if not util.safehasattr(replacements, 'items'): + if not hasattr(replacements, 'items'): replacements = {(n,): () for n in replacements} else: # upgrading non tuple "source" to tuple ones for BC diff --git a/mercurial/shelve.py b/mercurial/shelve.py --- a/mercurial/shelve.py +++ b/mercurial/shelve.py @@ -516,7 +516,7 @@ def mutableancestors(ctx): def getcommitfunc(extra, interactive, editor=False): def commitfunc(ui, repo, message, match, opts): - hasmq = util.safehasattr(repo, 'mq') + hasmq = hasattr(repo, 'mq') if hasmq: saved, repo.mq.checkapplied = repo.mq.checkapplied, False diff --git a/mercurial/smartset.py b/mercurial/smartset.py --- a/mercurial/smartset.py +++ b/mercurial/smartset.py @@ -137,7 +137,7 @@ class abstractsmartset: This is part of the mandatory API for smartset.""" # builtin cannot be cached. but do not needs to - if cache and util.safehasattr(condition, '__code__'): + if cache and hasattr(condition, '__code__'): condition = util.cachefunc(condition) return filteredset(self, condition, condrepr) @@ -1127,7 +1127,7 @@ class fullreposet(_spanset): This boldly assumes the other contains valid revs only. """ # other not a smartset, make is so - if not util.safehasattr(other, 'isascending'): + if not hasattr(other, 'isascending'): # filter out hidden revision # (this boldly assumes all smartset are pure) # diff --git a/mercurial/sslutil.py b/mercurial/sslutil.py --- a/mercurial/sslutil.py +++ b/mercurial/sslutil.py @@ -50,11 +50,11 @@ hassni = getattr(ssl, 'HAS_SNI', False) # were defined only if compiled against a OpenSSL version with TLS 1.1 / 1.2 # support. At the mentioned commit, they were unconditionally defined. supportedprotocols = set() -if getattr(ssl, 'HAS_TLSv1', util.safehasattr(ssl, 'PROTOCOL_TLSv1')): +if getattr(ssl, 'HAS_TLSv1', hasattr(ssl, 'PROTOCOL_TLSv1')): supportedprotocols.add(b'tls1.0') -if getattr(ssl, 'HAS_TLSv1_1', util.safehasattr(ssl, 'PROTOCOL_TLSv1_1')): +if getattr(ssl, 'HAS_TLSv1_1', hasattr(ssl, 'PROTOCOL_TLSv1_1')): supportedprotocols.add(b'tls1.1') -if getattr(ssl, 'HAS_TLSv1_2', util.safehasattr(ssl, 'PROTOCOL_TLSv1_2')): +if getattr(ssl, 'HAS_TLSv1_2', hasattr(ssl, 'PROTOCOL_TLSv1_2')): supportedprotocols.add(b'tls1.2') @@ -312,7 +312,7 @@ def wrapsocket(sock, keyfile, certfile, # is loaded and contains that removed CA, you've just undone the user's # choice. - if util.safehasattr(ssl, 'TLSVersion'): + if hasattr(ssl, 'TLSVersion'): # python 3.7+ sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) minimumprotocol = settings[b'minimumprotocol'] @@ -419,7 +419,7 @@ def wrapsocket(sock, keyfile, certfile, pass # Try to print more helpful error messages for known failures. - if util.safehasattr(e, 'reason'): + if hasattr(e, 'reason'): # This error occurs when the client and server don't share a # common/supported SSL/TLS protocol. We've disabled SSLv2 and SSLv3 # outright. Hopefully the reason for this error is that we require @@ -546,7 +546,7 @@ def wrapserversocket( _(b'referenced certificate file (%s) does not exist') % f ) - if util.safehasattr(ssl, 'TLSVersion'): + if hasattr(ssl, 'TLSVersion'): # python 3.7+ sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) sslcontext.options |= getattr(ssl, 'OP_NO_COMPRESSION', 0) @@ -628,7 +628,7 @@ def wrapserversocket( # Otherwise, use the list of more secure ciphers if found in the ssl module. if exactprotocol: sslcontext.set_ciphers('DEFAULT:@SECLEVEL=0') - elif util.safehasattr(ssl, '_RESTRICTED_SERVER_CIPHERS'): + elif hasattr(ssl, '_RESTRICTED_SERVER_CIPHERS'): sslcontext.options |= getattr(ssl, 'OP_CIPHER_SERVER_PREFERENCE', 0) # pytype: disable=module-attr sslcontext.set_ciphers(ssl._RESTRICTED_SERVER_CIPHERS) diff --git a/mercurial/streamclone.py b/mercurial/streamclone.py --- a/mercurial/streamclone.py +++ b/mercurial/streamclone.py @@ -428,7 +428,7 @@ def consumev1(repo, fp, filecount, bytec with repo.svfs.backgroundclosing(repo.ui, expectedcount=filecount): for i in range(filecount): # XXX doesn't support '\n' or '\r' in filenames - if util.safehasattr(fp, 'readline'): + if hasattr(fp, 'readline'): l = fp.readline() else: # inline clonebundles use a chunkbuffer, so no readline diff --git a/mercurial/strip.py b/mercurial/strip.py --- a/mercurial/strip.py +++ b/mercurial/strip.py @@ -12,7 +12,6 @@ from . import ( registrar, repair, scmutil, - util, ) release = lockmod.release @@ -36,7 +35,7 @@ def _findupdatetarget(repo, nodes): currentbranch = repo[None].branch() if ( - util.safehasattr(repo, 'mq') + hasattr(repo, 'mq') and p2 != repo.nullid and p2 in [x.node for x in repo.mq.applied] ): diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py --- a/mercurial/subrepo.py +++ b/mercurial/subrepo.py @@ -1136,7 +1136,7 @@ class svnsubrepo(abstractsubrepo): # --non-interactive. if commands[0] in (b'update', b'checkout', b'commit'): cmd.append(b'--non-interactive') - if util.safehasattr(subprocess, 'CREATE_NO_WINDOW'): + if hasattr(subprocess, 'CREATE_NO_WINDOW'): # On Windows, prevent command prompts windows from popping up when # running in pythonw. extrakw['creationflags'] = getattr(subprocess, 'CREATE_NO_WINDOW') @@ -1511,7 +1511,7 @@ class gitsubrepo(abstractsubrepo): # the end of git diff arguments is used for paths commands.insert(1, b'--color') extrakw = {} - if util.safehasattr(subprocess, 'CREATE_NO_WINDOW'): + if hasattr(subprocess, 'CREATE_NO_WINDOW'): # On Windows, prevent command prompts windows from popping up when # running in pythonw. extrakw['creationflags'] = getattr(subprocess, 'CREATE_NO_WINDOW') diff --git a/mercurial/subrepoutil.py b/mercurial/subrepoutil.py --- a/mercurial/subrepoutil.py +++ b/mercurial/subrepoutil.py @@ -384,7 +384,7 @@ def repo_rel_or_abs_source(repo): Either absolute or relative the outermost repo""" parent = repo chunks = [] - while util.safehasattr(parent, '_subparent'): + while hasattr(parent, '_subparent'): source = urlutil.url(parent._subsource) chunks.append(bytes(source)) if source.isabs(): @@ -400,7 +400,7 @@ def reporelpath(repo): # type: (localrepo.localrepository) -> bytes """return path to this (sub)repo as seen from outermost repo""" parent = repo - while util.safehasattr(parent, '_subparent'): + while hasattr(parent, '_subparent'): parent = parent._subparent return repo.root[len(pathutil.normasprefix(parent.root)) :] @@ -415,7 +415,7 @@ def _abssource(repo, push=False, abort=T # type: (localrepo.localrepository, bool, bool) -> Optional[bytes] """return pull/push path of repo - either based on parent repo .hgsub info or on the top repo config. Abort or return None if no source found.""" - if util.safehasattr(repo, '_subparent'): + if hasattr(repo, '_subparent'): source = urlutil.url(repo._subsource) if source.isabs(): return bytes(source) @@ -428,7 +428,7 @@ def _abssource(repo, push=False, abort=T return bytes(parent) else: # recursion reached top repo path = None - if util.safehasattr(repo, '_subtoppath'): + if hasattr(repo, '_subtoppath'): path = repo._subtoppath elif push and repo.ui.config(b'paths', b'default-push'): path = repo.ui.config(b'paths', b'default-push') diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py --- a/mercurial/templatefilters.py +++ b/mercurial/templatefilters.py @@ -339,14 +339,14 @@ def json(obj, paranoid=True): raise error.ProgrammingError( b'Mercurial only does output with bytes: %r' % obj ) - elif util.safehasattr(obj, 'keys'): + elif hasattr(obj, 'keys'): out = [ b'"%s": %s' % (encoding.jsonescape(k, paranoid=paranoid), json(v, paranoid)) for k, v in sorted(obj.items()) ] return b'{' + b', '.join(out) + b'}' - elif util.safehasattr(obj, '__iter__'): + elif hasattr(obj, '__iter__'): out = [json(i, paranoid) for i in obj] return b'[' + b', '.join(out) + b']' raise error.ProgrammingError(b'cannot encode %r' % obj) diff --git a/mercurial/templateutil.py b/mercurial/templateutil.py --- a/mercurial/templateutil.py +++ b/mercurial/templateutil.py @@ -281,7 +281,7 @@ class hybrid(wrapped): def getmember(self, context, mapping, key): # TODO: maybe split hybrid list/dict types? - if not util.safehasattr(self._values, 'get'): + if not hasattr(self._values, 'get'): raise error.ParseError(_(b'not a dictionary')) key = unwrapastype(context, mapping, key, self._keytype) return self._wrapvalue(key, self._values.get(key)) @@ -301,13 +301,13 @@ class hybrid(wrapped): def _wrapvalue(self, key, val): if val is None: return - if util.safehasattr(val, '_makemap'): + if hasattr(val, '_makemap'): # a nested hybrid list/dict, which has its own way of map operation return val return hybriditem(None, key, val, self._makemap) def filter(self, context, mapping, select): - if util.safehasattr(self._values, 'get'): + if hasattr(self._values, 'get'): values = { k: v for k, v in self._values.items() @@ -341,7 +341,7 @@ class hybrid(wrapped): def tovalue(self, context, mapping): # TODO: make it non-recursive for trivial lists/dicts xs = self._values - if util.safehasattr(xs, 'get'): + if hasattr(xs, 'get'): return {k: unwrapvalue(context, mapping, v) for k, v in xs.items()} return [unwrapvalue(context, mapping, x) for x in xs] @@ -858,7 +858,7 @@ def flatten(context, mapping, thing): ) elif thing is None: pass - elif not util.safehasattr(thing, '__iter__'): + elif not hasattr(thing, '__iter__'): yield pycompat.bytestr(thing) else: for i in thing: @@ -868,7 +868,7 @@ def flatten(context, mapping, thing): yield i elif i is None: pass - elif not util.safehasattr(i, '__iter__'): + elif not hasattr(i, '__iter__'): yield pycompat.bytestr(i) else: for j in flatten(context, mapping, i): diff --git a/mercurial/ui.py b/mercurial/ui.py --- a/mercurial/ui.py +++ b/mercurial/ui.py @@ -1467,7 +1467,7 @@ class ui: self.flush() wasformatted = self.formatted() - if util.safehasattr(signal, "SIGPIPE"): + if hasattr(signal, "SIGPIPE"): signal.signal(signal.SIGPIPE, _catchterm) if self._runpager(pagercmd, pagerenv): self.pageractive = True @@ -1547,7 +1547,7 @@ class ui: @self.atexit def killpager(): - if util.safehasattr(signal, "SIGINT"): + if hasattr(signal, "SIGINT"): signal.signal(signal.SIGINT, signal.SIG_IGN) # restore original fds, closing pager.stdin copies in the process os.dup2(stdoutfd, procutil.stdout.fileno()) diff --git a/mercurial/upgrade_utils/actions.py b/mercurial/upgrade_utils/actions.py --- a/mercurial/upgrade_utils/actions.py +++ b/mercurial/upgrade_utils/actions.py @@ -671,7 +671,7 @@ def determine_upgrade_actions( newactions = [] for d in format_upgrades: - if util.safehasattr(d, '_requirement'): + if hasattr(d, '_requirement'): name = d._requirement else: name = None diff --git a/mercurial/url.py b/mercurial/url.py --- a/mercurial/url.py +++ b/mercurial/url.py @@ -190,7 +190,7 @@ def _gen_sendfile(orgsend): return _sendfile -has_https = util.safehasattr(urlreq, 'httpshandler') +has_https = hasattr(urlreq, 'httpshandler') class httpconnection(keepalive.HTTPConnection): diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -2583,7 +2583,7 @@ class atomictempfile: self._fp.close() def __del__(self): - if safehasattr(self, '_fp'): # constructor actually did something + if hasattr(self, '_fp'): # constructor actually did something self.discard() def __enter__(self): diff --git a/mercurial/utils/compression.py b/mercurial/utils/compression.py --- a/mercurial/utils/compression.py +++ b/mercurial/utils/compression.py @@ -16,8 +16,6 @@ from .. import ( ) from . import stringutil -safehasattr = pycompat.safehasattr - _ = i18n._ @@ -340,7 +338,7 @@ class compressionengine: class _CompressedStreamReader: def __init__(self, fh): - if safehasattr(fh, 'unbufferedread'): + if hasattr(fh, 'unbufferedread'): self._reader = fh.unbufferedread else: self._reader = fh.read diff --git a/mercurial/utils/resourceutil.py b/mercurial/utils/resourceutil.py --- a/mercurial/utils/resourceutil.py +++ b/mercurial/utils/resourceutil.py @@ -22,8 +22,8 @@ def mainfrozen(): (portable, not much used). """ return ( - pycompat.safehasattr(sys, "frozen") # new py2exe - or pycompat.safehasattr(sys, "importers") # old py2exe + hasattr(sys, "frozen") # new py2exe + or hasattr(sys, "importers") # old py2exe or _imp.is_frozen("__main__") # tools/freeze ) @@ -59,7 +59,7 @@ try: from importlib import resources # pytype: disable=import-error # Force loading of the resources module - if pycompat.safehasattr(resources, 'files'): + if hasattr(resources, 'files'): resources.files # pytype: disable=module-attr else: resources.open_binary # pytype: disable=module-attr @@ -95,7 +95,7 @@ else: from .. import encoding def open_resource(package, name): - if pycompat.safehasattr(resources, 'files'): + if hasattr(resources, 'files'): return ( resources.files( # pytype: disable=module-attr pycompat.sysstr(package) diff --git a/mercurial/wireprotov1peer.py b/mercurial/wireprotov1peer.py --- a/mercurial/wireprotov1peer.py +++ b/mercurial/wireprotov1peer.py @@ -499,7 +499,7 @@ class wirepeer(repository.peer): else: heads = wireprototypes.encodelist(heads) - if util.safehasattr(bundle, 'deltaheader'): + if hasattr(bundle, 'deltaheader'): # this a bundle10, do the old style call sequence ret, output = self._callpush(b"unbundle", bundle, heads=heads) if ret == b"": diff --git a/mercurial/wireprotov1server.py b/mercurial/wireprotov1server.py --- a/mercurial/wireprotov1server.py +++ b/mercurial/wireprotov1server.py @@ -721,7 +721,7 @@ def unbundle(repo, proto, heads): r = exchange.unbundle( repo, gen, their_heads, b'serve', proto.client() ) - if util.safehasattr(r, 'addpart'): + if hasattr(r, 'addpart'): # The return looks streamable, we are in the bundle2 case # and should return a stream. return wireprototypes.streamreslegacy(gen=r.getchunks()) diff --git a/tests/test-ancestor.py b/tests/test-ancestor.py --- a/tests/test-ancestor.py +++ b/tests/test-ancestor.py @@ -12,7 +12,6 @@ from mercurial import ( debugcommands, hg, ui as uimod, - util, ) @@ -416,7 +415,7 @@ def test_gca(): for i, (dag, tests) in enumerate(dagtests): repo = hg.repository(u, b'gca%d' % i, create=1) cl = repo.changelog - if not util.safehasattr(cl.index, 'ancestors'): + if not hasattr(cl.index, 'ancestors'): # C version not available return diff --git a/tests/test-demandimport.py b/tests/test-demandimport.py --- a/tests/test-demandimport.py +++ b/tests/test-demandimport.py @@ -179,15 +179,13 @@ except ImportError as inst: 'cannot import name unknownattr' ) -from mercurial import util - # Unlike the import statement, __import__() function should not raise # ImportError even if fromlist has an unknown item # (see Python/import.c:import_module_level() and ensure_fromlist()) assert 'ftplib' not in sys.modules zipfileimp = __import__('ftplib', globals(), locals(), ['unknownattr']) assert f(zipfileimp) == "", f(zipfileimp) -assert not util.safehasattr(zipfileimp, 'unknownattr') +assert not hasattr(zipfileimp, 'unknownattr') # test deactivation for issue6725 diff --git a/tests/test-remotefilelog-bundle2-legacy.t b/tests/test-remotefilelog-bundle2-legacy.t --- a/tests/test-remotefilelog-bundle2-legacy.t +++ b/tests/test-remotefilelog-bundle2-legacy.t @@ -11,7 +11,7 @@ without changegroup2 support > command = registrar.command(cmdtable) > @command('testcg2', norepo=True) > def testcg2(ui): - > if not util.safehasattr(changegroup, 'cg2packer'): + > if not hasattr(changegroup, 'cg2packer'): > sys.exit(80) > EOF $ cat >> $HGRCPATH << EOF