Mercurial > hg
view tests/test-demandimport.py @ 51871:cfd30df0f8e4
bundlerepo: fix mismatches with repository and revlog classes
Both pytype and PyCharm complained that `write()` and `_write()` in the
bundlephasecache class aren't proper overrides- indeed they seem to be missing
an argument that the base class has.
PyCharm and pytype also complained that the `revlog.revlog` class doesn't have a
`_chunk()` method. That looks like it was moved from revlog to `_InnerRevlog`
back in e8ad6d8de8b8, and wasn't caught because this module wasn't type checked.
However, I couldn't figure out a syntax with `revlog.revlog._inner._chunk(self, rev)`,
as it complained about passing too many args. `bundlerevlog._rawtext()` uses
this `super(...)` style to call the super class, so hopefully that works, even
with the wonky dynamic subclassing. The revlog class needed the `_InnerRevlog`
field typed because it isn't set in the constructor.
Finally, the vfs type hints look broken. This initially failed with:
File "/mnt/c/Users/Matt/hg/mercurial/bundlerepo.py", line 65, in __init__: Function readonlyvfs.__init__ was called with the wrong arguments [wrong-arg-types]
Expected: (self, vfs: mercurial.vfs.vfs)
Actually passed: (self, vfs: Callable)
Called from (traceback):
line 232, in dirlog
line 214, in __init__
I don't see a raw Callable, but I tried changing some of the vfs args to be typed
as `vfsmod.abstractvfs`, but that class doesn't have `options`, so it failed
elsewhere. `readonlyvfs` isn't a subclass of `vfs` (it's a subclass of
`abstractvfs`), so I'm not sure how to handle that. It would be a shame to have
to make a union of vfs subclasses (but not all of them have `options` either).
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Sat, 03 Aug 2024 01:33:13 -0400 |
parents | be227c60a3e0 |
children | 5713adc51f2a |
line wrap: on
line source
from mercurial import demandimport demandimport.enable() import os import subprocess import sys import types # Don't import pycompat because it has too many side-effects. ispy311 = (sys.version_info.major, sys.version_info.minor) >= (3, 11) # Only run if demandimport is allowed if subprocess.call( [os.environ['PYTHON'], '%s/hghave' % os.environ['TESTDIR'], 'demandimport'] ): sys.exit(80) # We rely on assert, which gets optimized out. if sys.flags.optimize: sys.exit(80) # The demand importer doesn't work on Python 3.5. if sys.version_info[0:2] == (3, 5): sys.exit(80) from importlib.util import _LazyModule try: from importlib.util import _Module as moduletype except ImportError: moduletype = types.ModuleType import re rsub = re.sub def f(obj): l = repr(obj) l = rsub("0x[0-9a-fA-F]+", "0x?", l) l = rsub("from '.*'", "from '?'", l) l = rsub("'<[a-z]*>'", "'<whatever>'", l) return l demandimport.disable() os.environ['HGDEMANDIMPORT'] = 'disable' # this enable call should not actually enable demandimport! demandimport.enable() from mercurial import node # We use assert instead of a unittest test case because having imports inside # functions changes behavior of the demand importer. assert not isinstance(node, _LazyModule) # now enable it for real del os.environ['HGDEMANDIMPORT'] demandimport.enable() # Test access to special attributes through demandmod proxy assert 'mercurial.error' not in sys.modules from mercurial import error as errorproxy assert isinstance(errorproxy, _LazyModule) assert f(errorproxy) == "<module 'mercurial.error' from '?'>", f(errorproxy) doc = ' '.join(errorproxy.__doc__.split()[:3]) assert doc == 'Mercurial exceptions. This', doc assert errorproxy.__name__ == 'mercurial.error', errorproxy.__name__ # __name__ must be accessible via __dict__ so the relative imports can be # resolved name = errorproxy.__dict__['__name__'] assert name == 'mercurial.error', name assert not isinstance(errorproxy, _LazyModule) assert f(errorproxy) == "<module 'mercurial.error' from '?'>", f(errorproxy) import os assert not isinstance(os, _LazyModule) if ispy311: assert f(os) == "<module 'os' (frozen)>", f(os) else: assert f(os) == "<module 'os' from '?'>", f(os) assert f(os.system) == '<built-in function system>', f(os.system) if ispy311: assert f(os) == "<module 'os' (frozen)>", f(os) else: assert f(os) == "<module 'os' from '?'>", f(os) assert 'mercurial.utils.procutil' not in sys.modules from mercurial.utils import procutil assert isinstance(procutil, _LazyModule) assert f(procutil) == "<module 'mercurial.utils.procutil' from '?'>", f( procutil ) assert f(procutil.system) == '<function system at 0x?>', f(procutil.system) assert procutil.__class__ == moduletype, procutil.__class__ assert f(procutil) == "<module 'mercurial.utils.procutil' from '?'>", f( procutil ) assert f(procutil.system) == '<function system at 0x?>', f(procutil.system) assert 'mercurial.hgweb' not in sys.modules from mercurial import hgweb assert isinstance(hgweb, _LazyModule) assert f(hgweb) == "<module 'mercurial.hgweb' from '?'>", f(hgweb) assert isinstance(hgweb.hgweb_mod, _LazyModule) assert f(hgweb.hgweb_mod) == "<module 'mercurial.hgweb.hgweb_mod' from '?'>", f( hgweb.hgweb_mod ) assert f(hgweb) == "<module 'mercurial.hgweb' from '?'>", f(hgweb) import re as fred assert not isinstance(fred, _LazyModule) assert f(fred) == "<module 're' from '?'>" import re as remod assert not isinstance(remod, _LazyModule) assert f(remod) == "<module 're' from '?'>" import sys as re assert not isinstance(re, _LazyModule) assert f(re) == "<module 'sys' (built-in)>" assert not isinstance(fred, _LazyModule) assert f(fred) == "<module 're' from '?'>", f(fred) assert f(fred.sub) == '<function sub at 0x?>', f(fred.sub) assert not isinstance(fred, _LazyModule) assert f(fred) == "<module 're' from '?'>", f(fred) remod.escape # use remod assert f(remod) == "<module 're' from '?'>", f(remod) assert not isinstance(re, _LazyModule) assert f(re) == "<module 'sys' (built-in)>" assert f(type(re.stderr)) == "<class '_io.TextIOWrapper'>", f(type(re.stderr)) assert f(re) == "<module 'sys' (built-in)>" assert 'telnetlib' not in sys.modules import telnetlib assert isinstance(telnetlib, _LazyModule) assert f(telnetlib) == "<module 'telnetlib' from '?'>" try: from telnetlib import unknownattr assert False, ( 'no demandmod should be created for attribute of non-package ' 'module:\ntelnetlib.unknownattr = %s' % f(unknownattr) ) except ImportError as inst: assert rsub(r"'", '', str(inst)).startswith( 'cannot import name unknownattr' ) # 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) == "<module 'ftplib' from '?'>", f(zipfileimp) assert not hasattr(zipfileimp, 'unknownattr') # test deactivation for issue6725 del sys.modules['telnetlib'] with demandimport.deactivated(): import telnetlib assert telnetlib.__loader__ == telnetlib.__spec__.loader assert telnetlib.__loader__.get_resource_reader