Merge pull request #23816 from VadimLevin:dev/vlevin/export-all-caps-enum-constants

Export enums ALL_CAPS version to typing stub files #23816

- Export ALL_CAPS versions alongside from normal names for enum constants, since both versions are available in runtime
- Change enum names entries comments to documentary strings

Before patch
```python
RMat_Access_R: int
RMat_Access_W: int
RMat_Access = int  # One of [R, W]
```
After patch
```python
RMat_Access_R: int
RMAT_ACCESS_R: int
RMat_Access_W: int
RMAT_ACCESS_W: int
RMat_Access = int
"""One of [RMat_Access_R, RMAT_ACCESS_R, RMat_Access_W, RMAT_ACCESS_W]"""
```

Resolves: #23776

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
pull/23821/head
Vadim Levin 2 years ago committed by GitHub
parent 496474392e
commit 94703fc5b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 36
      modules/python/src2/typing_stubs_generation/generation.py

@ -2,8 +2,9 @@ __all__ = ("generate_typing_stubs", )
from io import StringIO from io import StringIO
from pathlib import Path from pathlib import Path
import re
from typing import (Generator, Type, Callable, NamedTuple, Union, Set, Dict, from typing import (Generator, Type, Callable, NamedTuple, Union, Set, Dict,
Collection) Collection, Tuple, List)
import warnings import warnings
from .ast_utils import get_enclosing_namespace, get_enum_module_and_export_name from .ast_utils import get_enclosing_namespace, get_enum_module_and_export_name
@ -272,7 +273,8 @@ def _generate_class_stub(class_node: ClassNode, output_stream: StringIO,
def _generate_constant_stub(constant_node: ConstantNode, def _generate_constant_stub(constant_node: ConstantNode,
output_stream: StringIO, indent: int = 0, output_stream: StringIO, indent: int = 0,
extra_export_prefix: str = "") -> None: extra_export_prefix: str = "",
generate_uppercase_version: bool = True) -> Tuple[str, ...]:
"""Generates stub for the provided constant node. """Generates stub for the provided constant node.
Args: Args:
@ -280,19 +282,33 @@ def _generate_constant_stub(constant_node: ConstantNode,
output_stream (StringIO): Output stream for constant stub. output_stream (StringIO): Output stream for constant stub.
indent (int, optional): Indent used for each line written to indent (int, optional): Indent used for each line written to
`output_stream`. Defaults to 0. `output_stream`. Defaults to 0.
extra_export_prefix (str, optional) Extra prefix added to the export extra_export_prefix (str, optional): Extra prefix added to the export
constant name. Defaults to empty string. constant name. Defaults to empty string.
generate_uppercase_version (bool, optional): Generate uppercase version
alongside the normal one. Defaults to True.
Returns:
Tuple[str, ...]: exported constants names.
""" """
def write_constant_to_stream(export_name: str) -> None:
output_stream.write( output_stream.write(
"{indent}{prefix}{name}: {value_type}\n".format( "{indent}{name}: {value_type}\n".format(
prefix=extra_export_prefix, name=export_name,
name=constant_node.export_name,
value_type=constant_node.value_type, value_type=constant_node.value_type,
indent=" " * indent indent=" " * indent
) )
) )
export_name = extra_export_prefix + constant_node.export_name
write_constant_to_stream(export_name)
if generate_uppercase_version:
uppercase_name = re.sub(r"([a-z])([A-Z])", r"\1_\2", export_name).upper()
if export_name != uppercase_name:
write_constant_to_stream(uppercase_name)
return export_name, uppercase_name
return export_name,
def _generate_enumeration_stub(enumeration_node: EnumerationNode, def _generate_enumeration_stub(enumeration_node: EnumerationNode,
output_stream: StringIO, indent: int = 0, output_stream: StringIO, indent: int = 0,
@ -356,18 +372,20 @@ def _generate_enumeration_stub(enumeration_node: EnumerationNode,
entries_extra_prefix = extra_export_prefix entries_extra_prefix = extra_export_prefix
if enumeration_node.is_scoped: if enumeration_node.is_scoped:
entries_extra_prefix += enumeration_node.export_name + "_" entries_extra_prefix += enumeration_node.export_name + "_"
generated_constants_entries: List[str] = []
for entry in enumeration_node.constants.values(): for entry in enumeration_node.constants.values():
generated_constants_entries.extend(
_generate_constant_stub(entry, output_stream, indent, entries_extra_prefix) _generate_constant_stub(entry, output_stream, indent, entries_extra_prefix)
)
# Unnamed enumerations are skipped as definition # Unnamed enumerations are skipped as definition
if enumeration_node.export_name.endswith("<unnamed>"): if enumeration_node.export_name.endswith("<unnamed>"):
output_stream.write("\n") output_stream.write("\n")
return return
output_stream.write( output_stream.write(
"{indent}{export_prefix}{name} = int # One of [{entries}]\n\n".format( '{indent}{export_prefix}{name} = int\n{indent}"""One of [{entries}]"""\n\n'.format(
export_prefix=extra_export_prefix, export_prefix=extra_export_prefix,
name=enumeration_node.export_name, name=enumeration_node.export_name,
entries=", ".join(entry.export_name entries=", ".join(generated_constants_entries),
for entry in enumeration_node.constants.values()),
indent=" " * indent indent=" " * indent
) )
) )

Loading…
Cancel
Save