Bug 2099815

Summary: python-proto-plus fails to build with Python 3.11
Product: [Fedora] Fedora Reporter: Major Hayden 🤠 <mhayden>
Component: python-proto-plusAssignee: Major Hayden 🤠 <mhayden>
Status: CLOSED RAWHIDE QA Contact:
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: rawhideCC: mhayden, mhroncok, python-sig
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: python-proto-plus-1.20.6-3.fc37 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2022-06-28 21:03:49 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 2016048, 2045109, 2098926, 2098927, 2098928, 2098929, 2098930, 2098931, 2098932, 2098933, 2098934, 2098935, 2098936, 2098937, 2098938, 2098939, 2098940, 2098941, 2098942, 2098943, 2098944, 2098945, 2098946, 2098947, 2098948, 2098949, 2098950, 2098951, 2098952, 2098953, 2098954, 2098955, 2098956, 2098957, 2098958, 2098959, 2098960, 2098961, 2098962, 2098963, 2098964, 2098965, 2098966, 2101476    

Description Major Hayden 🤠 2022-06-21 18:34:36 UTC
python-proto-plus cannot build properly under Python 3.11:

+ /usr/bin/pytest
============================= test session starts ==============================
platform linux -- Python 3.11.0b3, pytest-7.1.2, pluggy-1.0.0
rootdir: /builddir/build/BUILD/proto-plus-python-1.20.6
collected 253 items

tests/test_datetime_helpers.py ................................          [ 12%]
tests/test_enum_total_ordering.py .F.....                                [ 15%]
tests/test_fields_bytes.py .....                                         [ 17%]
tests/test_fields_composite.py ......                                    [ 19%]
tests/test_fields_composite_string_ref.py .....                          [ 21%]
tests/test_fields_enum.py ...................F                           [ 29%]
tests/test_fields_int.py .......                                         [ 32%]
tests/test_fields_map_composite.py .....                                 [ 34%]
tests/test_fields_map_scalar.py ....                                     [ 35%]
tests/test_fields_mitigate_collision.py .                                [ 36%]
tests/test_fields_oneof.py ..                                            [ 37%]
tests/test_fields_optional.py ..                                         [ 37%]
tests/test_fields_repeated_composite.py ...................              [ 45%]
tests/test_fields_repeated_scalar.py ..........                          [ 49%]
tests/test_fields_string.py ...                                          [ 50%]
tests/test_file_info_salting.py ..                                       [ 51%]
tests/test_file_info_salting_with_manifest.py ..                         [ 52%]
tests/test_json.py .........                                             [ 55%]
tests/test_marshal_register.py ...                                       [ 56%]
tests/test_marshal_strict.py .                                           [ 57%]
tests/test_marshal_stringy_numbers.py ...................                [ 64%]
tests/test_marshal_types_dates.py ................                       [ 71%]
tests/test_marshal_types_enum.py .....                                   [ 73%]
tests/test_marshal_types_message.py ..                                   [ 73%]
tests/test_marshal_types_struct.py .......................               [ 83%]
tests/test_marshal_types_wrappers_bool.py ........                       [ 86%]
tests/test_message.py .........................                          [ 96%]
tests/test_message_filename.py .                                         [ 96%]
tests/test_message_filename_with_and_without_manifest.py .               [ 96%]
tests/test_message_filename_with_manifest.py .                           [ 97%]
tests/test_message_nested.py ...                                         [ 98%]
tests/test_message_pickling.py .                                         [ 98%]
tests/test_modules.py ...                                                [100%]

=================================== FAILURES ===================================
____________________ test_total_ordering_w_other_enum_type _____________________

    def test_total_ordering_w_other_enum_type():
        to_compare = enums_test.OneEnum.SOME_VALUE
    
        for item in enums_test.OtherEnum:
            assert not to_compare == item
>           assert to_compare.SOME_VALUE != item

tests/test_enum_total_ordering.py:52: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <enum.property object at 0x7f48b7191c90>
instance = <OneEnum.SOME_VALUE: 1>, ownerclass = <enum 'OneEnum'>

    def __get__(self, instance, ownerclass=None):
        if instance is None:
            try:
                return ownerclass._member_map_[self.name]
            except KeyError:
                raise AttributeError(
                        '%r has no attribute %r' % (ownerclass, self.name)
                        )
        else:
            if self.fget is None:
>               raise AttributeError(
                        '%r member has no attribute %r' % (ownerclass, self.name)
                        )
E               AttributeError: <enum 'OneEnum'> member has no attribute 'SOME_VALUE'

/usr/lib64/python3.11/enum.py:198: AttributeError
_____________________________ test_enum_alias_good _____________________________

    def test_enum_alias_good():
        # Have to split good and bad enum alias into two tests so that the generated
        # file descriptor is properly created.
        # For the python runtime, aliases are allowed by default, but we want to
        # make sure that the options don't cause problems.
        # For the cpp runtime, we need to verify that we can in fact define aliases.
>       class GoodMessage(proto.Message):

tests/test_fields_enum.py:386: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_fields_enum.py:387: in GoodMessage
    class GoodEnum(proto.Enum):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

mcls = <class 'proto.enums.ProtoEnumMeta'>, name = 'GoodEnum'
bases = (<enum 'Enum'>,)
attrs = {'_generate_next_value_': <function Enum._generate_next_value_ at 0x7f48b7c4b4c0>, '__module__': 'test_fields_enum', '__qualname__': 'test_enum_alias_good.<locals>.GoodMessage.GoodEnum', 'UNKNOWN': 0, 'DEFAULT': 0}

    def __new__(mcls, name, bases, attrs):
        # Do not do any special behavior for `proto.Enum` itself.
        if bases[0] == enum.IntEnum:
            return super().__new__(mcls, name, bases, attrs)
    
        # Get the essential information about the proto package, and where
        # this component belongs within the file.
        package, marshal = _package_info.compile(name, attrs)
    
        # Determine the local path of this proto component within the file.
        local_path = tuple(attrs.get("__qualname__", name).split("."))
    
        # Sanity check: We get the wrong full name if a class is declared
        # inside a function local scope; correct this.
        if "<locals>" in local_path:
            ix = local_path.index("<locals>")
            local_path = local_path[: ix - 1] + local_path[ix + 1 :]
    
        # Determine the full name in protocol buffers.
        full_name = ".".join((package,) + local_path).lstrip(".")
        filename = _file_info._FileInfo.proto_file_name(
            attrs.get("__module__", name.lower())
        )
    
        # Retrieve any enum options.
        # We expect something that looks like an EnumOptions message,
        # either an actual instance or a dict-like representation.
        pb_options = "_pb_options"
        opts = attrs.pop(pb_options, {})
        # This is the only portable way to remove the _pb_options name
        # from the enum attrs.
        # In 3.7 onwards, we can define an _ignore_ attribute and do some
        # mucking around with that.
        if pb_options in attrs._member_names:
>           idx = attrs._member_names.index(pb_options)
E           AttributeError: 'dict' object has no attribute 'index'

../../BUILDROOT/python-proto-plus-1.20.6-1.fc37.x86_64/usr/lib/python3.11/site-packages/proto/enums.py:61: AttributeError
=========================== short test summary info ============================
FAILED tests/test_enum_total_ordering.py::test_total_ordering_w_other_enum_type
FAILED tests/test_fields_enum.py::test_enum_alias_good - AttributeError: 'dic...
======================== 2 failed, 251 passed in 0.96s =========================

Comment 1 Major Hayden 🤠 2022-06-21 18:35:28 UTC
Ticket opened upstream: https://github.com/googleapis/proto-plus-python/issues/326

This one is blocking the Google Cloud packages. 😢