comparison mercurial/localrepo.py @ 49571:8fa3f7c3a9ad

typing: add basic type hints to localrepo.py There's a lot more that could be done, but this sticks to the obviously correct stuff that is either related to existing imports or primitives. Hopefully this helps smoke out more path related bytes vs str issues in TortoiseHg. I'm avoiding the interfaces for now, because they seem to confuse pytype and/or PyCharm. It might be worth typing the return of `makelocalrepository` to `localrepository`, but that leaks an implementation detail, so that can be revisited later.
author Matt Harbison <matt_harbison@yahoo.com>
date Wed, 02 Nov 2022 16:43:01 -0400
parents 4367c46a89ee
children 18282cf18aa2
comparison
equal deleted inserted replaced
49570:3a2b6158374a 49571:8fa3f7c3a9ad
13 import sys 13 import sys
14 import time 14 import time
15 import weakref 15 import weakref
16 16
17 from concurrent import futures 17 from concurrent import futures
18 from typing import (
19 Optional,
20 )
21
18 from .i18n import _ 22 from .i18n import _
19 from .node import ( 23 from .node import (
20 bin, 24 bin,
21 hex, 25 hex,
22 nullrev, 26 nullrev,
524 # a missing file translates to no requirements. 528 # a missing file translates to no requirements.
525 read = vfs.tryread if allowmissing else vfs.read 529 read = vfs.tryread if allowmissing else vfs.read
526 return set(read(b'requires').splitlines()) 530 return set(read(b'requires').splitlines())
527 531
528 532
529 def makelocalrepository(baseui, path, intents=None): 533 def makelocalrepository(baseui, path: bytes, intents=None):
530 """Create a local repository object. 534 """Create a local repository object.
531 535
532 Given arguments needed to construct a local repository, this function 536 Given arguments needed to construct a local repository, this function
533 performs various early repository loading functionality (such as 537 performs various early repository loading functionality (such as
534 reading the ``.hg/requires`` and ``.hg/hgrc`` files), validates that 538 reading the ``.hg/requires`` and ``.hg/hgrc`` files), validates that
843 features=features, 847 features=features,
844 intents=intents, 848 intents=intents,
845 ) 849 )
846 850
847 851
848 def loadhgrc(ui, wdirvfs, hgvfs, requirements, sharedvfs=None): 852 def loadhgrc(
853 ui,
854 wdirvfs: vfsmod.vfs,
855 hgvfs: vfsmod.vfs,
856 requirements,
857 sharedvfs: Optional[vfsmod.vfs] = None,
858 ):
849 """Load hgrc files/content into a ui instance. 859 """Load hgrc files/content into a ui instance.
850 860
851 This is called during repository opening to load any additional 861 This is called during repository opening to load any additional
852 config files or settings relevant to the current repository. 862 config files or settings relevant to the current repository.
853 863
1321 1331
1322 def __init__( 1332 def __init__(
1323 self, 1333 self,
1324 baseui, 1334 baseui,
1325 ui, 1335 ui,
1326 origroot, 1336 origroot: bytes,
1327 wdirvfs, 1337 wdirvfs: vfsmod.vfs,
1328 hgvfs, 1338 hgvfs: vfsmod.vfs,
1329 requirements, 1339 requirements,
1330 supportedrequirements, 1340 supportedrequirements,
1331 sharedpath, 1341 sharedpath: bytes,
1332 store, 1342 store,
1333 cachevfs, 1343 cachevfs: vfsmod.vfs,
1334 wcachevfs, 1344 wcachevfs: vfsmod.vfs,
1335 features, 1345 features,
1336 intents=None, 1346 intents=None,
1337 ): 1347 ):
1338 """Create a new local repository instance. 1348 """Create a new local repository instance.
1339 1349
1975 return len(unfi.changelog) 1985 return len(unfi.changelog)
1976 1986
1977 def __iter__(self): 1987 def __iter__(self):
1978 return iter(self.changelog) 1988 return iter(self.changelog)
1979 1989
1980 def revs(self, expr, *args): 1990 def revs(self, expr: bytes, *args):
1981 """Find revisions matching a revset. 1991 """Find revisions matching a revset.
1982 1992
1983 The revset is specified as a string ``expr`` that may contain 1993 The revset is specified as a string ``expr`` that may contain
1984 %-formatting to escape certain types. See ``revsetlang.formatspec``. 1994 %-formatting to escape certain types. See ``revsetlang.formatspec``.
1985 1995
1991 that contains integer revisions. 2001 that contains integer revisions.
1992 """ 2002 """
1993 tree = revsetlang.spectree(expr, *args) 2003 tree = revsetlang.spectree(expr, *args)
1994 return revset.makematcher(tree)(self) 2004 return revset.makematcher(tree)(self)
1995 2005
1996 def set(self, expr, *args): 2006 def set(self, expr: bytes, *args):
1997 """Find revisions matching a revset and emit changectx instances. 2007 """Find revisions matching a revset and emit changectx instances.
1998 2008
1999 This is a convenience wrapper around ``revs()`` that iterates the 2009 This is a convenience wrapper around ``revs()`` that iterates the
2000 result and is a generator of changectx instances. 2010 result and is a generator of changectx instances.
2001 2011
2003 user aliases, consider calling ``scmutil.revrange()``. 2013 user aliases, consider calling ``scmutil.revrange()``.
2004 """ 2014 """
2005 for r in self.revs(expr, *args): 2015 for r in self.revs(expr, *args):
2006 yield self[r] 2016 yield self[r]
2007 2017
2008 def anyrevs(self, specs, user=False, localalias=None): 2018 def anyrevs(self, specs: bytes, user=False, localalias=None):
2009 """Find revisions matching one of the given revsets. 2019 """Find revisions matching one of the given revsets.
2010 2020
2011 Revset aliases from the configuration are not expanded by default. To 2021 Revset aliases from the configuration are not expanded by default. To
2012 expand user aliases, specify ``user=True``. To provide some local 2022 expand user aliases, specify ``user=True``. To provide some local
2013 definitions overriding user aliases, set ``localalias`` to 2023 definitions overriding user aliases, set ``localalias`` to
2028 ) 2038 )
2029 else: 2039 else:
2030 m = revset.matchany(None, specs, localalias=localalias) 2040 m = revset.matchany(None, specs, localalias=localalias)
2031 return m(self) 2041 return m(self)
2032 2042
2033 def url(self): 2043 def url(self) -> bytes:
2034 return b'file:' + self.root 2044 return b'file:' + self.root
2035 2045
2036 def hook(self, name, throw=False, **args): 2046 def hook(self, name, throw=False, **args):
2037 """Call a hook, passing this repo instance. 2047 """Call a hook, passing this repo instance.
2038 2048
2227 '''the type of shared repository (None if not shared)''' 2237 '''the type of shared repository (None if not shared)'''
2228 if self.sharedpath != self.path: 2238 if self.sharedpath != self.path:
2229 return b'store' 2239 return b'store'
2230 return None 2240 return None
2231 2241
2232 def wjoin(self, f, *insidef): 2242 def wjoin(self, f: bytes, *insidef: bytes) -> bytes:
2233 return self.vfs.reljoin(self.root, f, *insidef) 2243 return self.vfs.reljoin(self.root, f, *insidef)
2234 2244
2235 def setparents(self, p1, p2=None): 2245 def setparents(self, p1, p2=None):
2236 if p2 is None: 2246 if p2 is None:
2237 p2 = self.nullid 2247 p2 = self.nullid
2238 self[None].setparents(p1, p2) 2248 self[None].setparents(p1, p2)
2239 self._quick_access_changeid_invalidate() 2249 self._quick_access_changeid_invalidate()
2240 2250
2241 def filectx(self, path, changeid=None, fileid=None, changectx=None): 2251 def filectx(self, path: bytes, changeid=None, fileid=None, changectx=None):
2242 """changeid must be a changeset revision, if specified. 2252 """changeid must be a changeset revision, if specified.
2243 fileid can be a file revision or node.""" 2253 fileid can be a file revision or node."""
2244 return context.filectx( 2254 return context.filectx(
2245 self, path, changeid, fileid, changectx=changectx 2255 self, path, changeid, fileid, changectx=changectx
2246 ) 2256 )
2247 2257
2248 def getcwd(self): 2258 def getcwd(self) -> bytes:
2249 return self.dirstate.getcwd() 2259 return self.dirstate.getcwd()
2250 2260
2251 def pathto(self, f, cwd=None): 2261 def pathto(self, f: bytes, cwd: Optional[bytes] = None) -> bytes:
2252 return self.dirstate.pathto(f, cwd) 2262 return self.dirstate.pathto(f, cwd)
2253 2263
2254 def _loadfilter(self, filter): 2264 def _loadfilter(self, filter):
2255 if filter not in self._filterpats: 2265 if filter not in self._filterpats:
2256 l = [] 2266 l = []
2298 return self._loadfilter(b'decode') 2308 return self._loadfilter(b'decode')
2299 2309
2300 def adddatafilter(self, name, filter): 2310 def adddatafilter(self, name, filter):
2301 self._datafilters[name] = filter 2311 self._datafilters[name] = filter
2302 2312
2303 def wread(self, filename): 2313 def wread(self, filename: bytes) -> bytes:
2304 if self.wvfs.islink(filename): 2314 if self.wvfs.islink(filename):
2305 data = self.wvfs.readlink(filename) 2315 data = self.wvfs.readlink(filename)
2306 else: 2316 else:
2307 data = self.wvfs.read(filename) 2317 data = self.wvfs.read(filename)
2308 return self._filter(self._encodefilterpats, filename, data) 2318 return self._filter(self._encodefilterpats, filename, data)
2309 2319
2310 def wwrite(self, filename, data, flags, backgroundclose=False, **kwargs): 2320 def wwrite(
2321 self,
2322 filename: bytes,
2323 data: bytes,
2324 flags: bytes,
2325 backgroundclose=False,
2326 **kwargs
2327 ) -> int:
2311 """write ``data`` into ``filename`` in the working directory 2328 """write ``data`` into ``filename`` in the working directory
2312 2329
2313 This returns length of written (maybe decoded) data. 2330 This returns length of written (maybe decoded) data.
2314 """ 2331 """
2315 data = self._filter(self._decodefilterpats, filename, data) 2332 data = self._filter(self._decodefilterpats, filename, data)
2323 self.wvfs.setflags(filename, False, True) 2340 self.wvfs.setflags(filename, False, True)
2324 else: 2341 else:
2325 self.wvfs.setflags(filename, False, False) 2342 self.wvfs.setflags(filename, False, False)
2326 return len(data) 2343 return len(data)
2327 2344
2328 def wwritedata(self, filename, data): 2345 def wwritedata(self, filename: bytes, data: bytes) -> bytes:
2329 return self._filter(self._decodefilterpats, filename, data) 2346 return self._filter(self._decodefilterpats, filename, data)
2330 2347
2331 def currenttransaction(self): 2348 def currenttransaction(self):
2332 """return the current transaction or None if non exists""" 2349 """return the current transaction or None if non exists"""
2333 if self._transref: 2350 if self._transref:
3518 pass 3535 pass
3519 3536
3520 return a 3537 return a
3521 3538
3522 3539
3523 def undoname(fn): 3540 def undoname(fn: bytes) -> bytes:
3524 base, name = os.path.split(fn) 3541 base, name = os.path.split(fn)
3525 assert name.startswith(b'journal') 3542 assert name.startswith(b'journal')
3526 return os.path.join(base, name.replace(b'journal', b'undo', 1)) 3543 return os.path.join(base, name.replace(b'journal', b'undo', 1))
3527 3544
3528 3545
3529 def instance(ui, path, create, intents=None, createopts=None): 3546 def instance(ui, path: bytes, create, intents=None, createopts=None):
3530 3547
3531 # prevent cyclic import localrepo -> upgrade -> localrepo 3548 # prevent cyclic import localrepo -> upgrade -> localrepo
3532 from . import upgrade 3549 from . import upgrade
3533 3550
3534 localpath = urlutil.urllocalpath(path) 3551 localpath = urlutil.urllocalpath(path)
3541 repo = repo_maker() 3558 repo = repo_maker()
3542 repo = upgrade.may_auto_upgrade(repo, repo_maker) 3559 repo = upgrade.may_auto_upgrade(repo, repo_maker)
3543 return repo 3560 return repo
3544 3561
3545 3562
3546 def islocal(path): 3563 def islocal(path: bytes) -> bool:
3547 return True 3564 return True
3548 3565
3549 3566
3550 def defaultcreateopts(ui, createopts=None): 3567 def defaultcreateopts(ui, createopts=None):
3551 """Populate the default creation options for a repository. 3568 """Populate the default creation options for a repository.
3799 } 3816 }
3800 3817
3801 return {k: v for k, v in createopts.items() if k not in known} 3818 return {k: v for k, v in createopts.items() if k not in known}
3802 3819
3803 3820
3804 def createrepository(ui, path, createopts=None, requirements=None): 3821 def createrepository(ui, path: bytes, createopts=None, requirements=None):
3805 """Create a new repository in a vfs. 3822 """Create a new repository in a vfs.
3806 3823
3807 ``path`` path to the new repo's working directory. 3824 ``path`` path to the new repo's working directory.
3808 ``createopts`` options for the new repository. 3825 ``createopts`` options for the new repository.
3809 ``requirement`` predefined set of requirements. 3826 ``requirement`` predefined set of requirements.