Mercurial > public > mercurial-scm > hg
comparison mercurial/interfaces/dirstate.py @ 51919:b455dfddfed0
interfaces: convert the zope `Attribute` attrs to regular fields
At this point, we should have a useful protocol class.
The file syntax requires the type to be supplied for any fields that are
declared, but we'll leave the complex ones partially unspecified for now, for
simplicity. (Also, the things documented as `Callable` are really as future
type annotating worked showed- roll with it for now, but they're marked as TODO
for fixing later.) All of the fields and all of the attrs will need type
annotations, or the type rules say they are considered to be `Any`. That can be
done in a separate pass, possibly applying the `dirstate.pyi` file generated
from the concrete class.
The first cut of this turned the `interfaceutil.Attribute` fields into plain
fields, and thus the types on them. PyCharm flagged a few things as having
incompatible signatures when the concrete dirstate class subclassed this, when
the concrete class has them declared as `@property`. So they've been changed to
`@property` here in those cases. The remaining fields that are decorated in the
concrete class have comments noting the differences. We'll see if they need to
be changed going forward, but leave them for now. We'll be in trouble if the
`@util.propertycache` is needed, because we can't import that module here at
runtime, due to circular imports.
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Thu, 26 Sep 2024 18:15:36 -0400 |
parents | 13aa17512583 |
children | 3688a984134b |
comparison
equal
deleted
inserted
replaced
51918:13aa17512583 | 51919:b455dfddfed0 |
---|---|
1 from __future__ import annotations | 1 from __future__ import annotations |
2 | 2 |
3 import contextlib | 3 import contextlib |
4 import typing | |
4 | 5 |
5 from typing import ( | 6 from typing import ( |
7 Callable, | |
6 Protocol, | 8 Protocol, |
7 ) | 9 ) |
8 | 10 |
9 from . import util as interfaceutil | 11 if typing.TYPE_CHECKING: |
12 # Almost all mercurial modules are only imported in the type checking phase | |
13 # to avoid circular imports | |
14 from .. import ( | |
15 match as matchmod, | |
16 ) | |
10 | 17 |
11 | 18 |
12 class idirstate(Protocol): | 19 class idirstate(Protocol): |
13 # TODO: convert these constructor args to fields? | 20 # TODO: convert these constructor args to fields? |
14 # def __init__( | 21 # def __init__( |
29 # the dirstate. | 36 # the dirstate. |
30 # """ | 37 # """ |
31 | 38 |
32 # TODO: all these private methods and attributes should be made | 39 # TODO: all these private methods and attributes should be made |
33 # public or removed from the interface. | 40 # public or removed from the interface. |
34 _ignore = interfaceutil.Attribute("""Matcher for ignored files.""") | 41 |
35 is_changing_any = interfaceutil.Attribute( | 42 # TODO: decorate with `@rootcache(b'.hgignore')` like dirstate class? |
43 _ignore: matchmod.basematcher | |
44 """Matcher for ignored files.""" | |
45 | |
46 @property | |
47 def is_changing_any(self) -> bool: | |
36 """True if any changes in progress.""" | 48 """True if any changes in progress.""" |
37 ) | 49 |
38 is_changing_parents = interfaceutil.Attribute( | 50 @property |
51 def is_changing_parents(self) -> bool: | |
39 """True if parents changes in progress.""" | 52 """True if parents changes in progress.""" |
40 ) | 53 |
41 is_changing_files = interfaceutil.Attribute( | 54 @property |
55 def is_changing_files(self) -> bool: | |
42 """True if file tracking changes in progress.""" | 56 """True if file tracking changes in progress.""" |
43 ) | |
44 | 57 |
45 def _ignorefiles(self): | 58 def _ignorefiles(self): |
46 """Return a list of files containing patterns to ignore.""" | 59 """Return a list of files containing patterns to ignore.""" |
47 | 60 |
48 def _ignorefileandline(self, f): | 61 def _ignorefileandline(self, f): |
49 """Given a file `f`, return the ignore file and line that ignores it.""" | 62 """Given a file `f`, return the ignore file and line that ignores it.""" |
50 | 63 |
51 _checklink = interfaceutil.Attribute("""Callable for checking symlinks.""") | 64 # TODO: decorate with `@util.propertycache` like dirstate class? |
52 _checkexec = interfaceutil.Attribute("""Callable for checking exec bits.""") | 65 # (can't because circular import) |
66 # TODO: The doc looks wrong- the core class has this as a @property, not a | |
67 # callable. | |
68 _checklink: Callable | |
69 """Callable for checking symlinks.""" | |
70 | |
71 # TODO: decorate with `@util.propertycache` like dirstate class? | |
72 # (can't because circular import) | |
73 # TODO: The doc looks wrong- the core class has this as a @property, not a | |
74 # callable. | |
75 _checkexec: Callable | |
76 """Callable for checking exec bits.""" | |
53 | 77 |
54 @contextlib.contextmanager | 78 @contextlib.contextmanager |
55 def changing_parents(self, repo): | 79 def changing_parents(self, repo): |
56 """Context manager for handling dirstate parents. | 80 """Context manager for handling dirstate parents. |
57 | 81 |