From: John Snow <jsnow@redhat.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Cleber Rosa" <crosa@redhat.com>,
qemu-devel@nongnu.org, "Eduardo Habkost" <ehabkost@redhat.com>
Subject: Re: [PATCH 08/12] qapi/schema: make QAPISourceInfo mandatory
Date: Thu, 17 Dec 2020 12:02:29 -0500 [thread overview]
Message-ID: <e9f43898-1c0b-54e3-59a7-d9064c2d86ea@redhat.com> (raw)
In-Reply-To: <87pn38lv1d.fsf@dusky.pond.sub.org>
On 12/17/20 3:02 AM, Markus Armbruster wrote:
> John Snow <jsnow@redhat.com> writes:
>
>> On 12/16/20 5:18 AM, Markus Armbruster wrote:
>>> John Snow <jsnow@redhat.com> writes:
>>>
>>>> --
>>>>
>>>> events.py had an info to route, was it by choice that it wasn't before?
>>>
>>> See below.
>>>
>>> I figure this is intentionally below the -- line, but ...
>>>
>>>> Signed-off-by: John Snow <jsnow@redhat.com>
>>>
>>> ... this should be above it.
>>>
>>
>> Script failure. Or human failure, because I used '--' instead of '---'.
>>
>>>> ---
>>>> scripts/qapi/events.py | 2 +-
>>>> scripts/qapi/schema.py | 23 +++++++++++++----------
>>>> scripts/qapi/types.py | 9 +++++----
>>>> scripts/qapi/visit.py | 6 +++---
>>>> 4 files changed, 22 insertions(+), 18 deletions(-)
>>>>
>>>> diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
>>>> index 9851653b9d11..9ba4f109028d 100644
>>>> --- a/scripts/qapi/events.py
>>>> +++ b/scripts/qapi/events.py
>>>> @@ -225,7 +225,7 @@ def visit_event(self,
>>>> self._event_emit_name))
>>>> # Note: we generate the enum member regardless of @ifcond, to
>>>> # keep the enumeration usable in target-independent code.
>>>> - self._event_enum_members.append(QAPISchemaEnumMember(name, None))
>>>> + self._event_enum_members.append(QAPISchemaEnumMember(name, info))
>>>
>>> We pass None because errors should never happen, and None makes that
>>> quite clear.
>>>
>>
>> Not clear: *why* should errors never happen? This is the only place we
>> pass None for SourceInfo that isn't explicitly a literal built-in type.
>> This is not obvious.
>
> You're right, but there are two separate "unclarities".
>
> Passing None effectively asserts "errors never happen". We neglect to
> explain why, leaving the reader guessing.
>
> Passing @info "fixes" that by removing the assertion. Now we have a
> more subtle problem: will errors make sense with this @info? Normally,
> all members of an enum share one info. Only this enum's members don't.
> It turns out the question is moot because @info is not actually used.
> But will it remain moot? My point isn't that these are important
> questions to answer. It is that we're replacing the relatively obvious
> question "why are we asserting errors can't happen" by more subtle ones.
> Feels like sweeping dirt under the rug.
>
I'll grant you that. I'm going wide instead of deep, here. There were
200+ errors to fix, and not every last one got the same level of attention.
I definitely did just sweep some dirt under the rug.
>>> We don't actually have a built-in QAPISchemaEnumType for the event enum.
>>> We merely generate a C enum QAPIEvent along with macro QAPIEvent_str(),
>>> by passing self._event_emit_name, self._event_enum_members straight to
>>> gen_enum() and gen_enum_lookup().
>>>
>>> If we did build a QAPISchemaEnumType, and used it to diagnose clashes,
>>> then clashes would be reported like
>>>
>>> mumble.json: In event 'A-B':
>>> mumble.json: 2: value 'A-B' collides with value 'A_B'
>>>
>>> leaving you guessing what "value" means, and where 'A_B' may be.
>>>
>>> Bug: we don't diagnose certain event name clashes. I'll fix it.
>>>
>>
>> Not clear to me: If I want interface consistency, what *should* be
>> passed downwards as the info? it's not quite a builtin as much as it is
>> an inferred enum,
>
> True.
>
>> so should I just ... leave it like this, or wait for
>> you to offer a better fix?
>
> Waiting for some better fix feels undavisable. We want to get type
> checking in place sooner rather than later.
>
OK. You mentioned fixing the conflicts, so I had thought maybe that was
near-term instead of long-term. We have cleared that misunderstanding up ;)
> Aside: a possible fix is decoupling gen_enum_lookup() and gen_enum()
> from QAPISchemaEnumMember, so we don't have to make up
> QAPISchemaEnumMembers here.
>
I'm not sure I have the broader picture here to do this, or the time to
focus on it. It's a bit of a deeper fix than the rest of the minor
refactorings I do in these series.
> I think there are two interpretations of your QAPISourceInfo work's aim:
>
> 1. Narrow: use a special QAPISourceInfo rather then None as "no errors
> shall happen" poison.
>
> QAPISourceInfo.builtin() returns this poison. The name "builtin" is
> less than ideal.
>
I did intend it to be used for explicit built-in types; this is an
"inferred" type, and I'd use a differently named poison for it, I suppose.
> 2. Ambitious: eliminate "no errors shall happen".
>
> We're discussing this in reply of PATCH 06. I think we need to reach a
> conclusion there before we can decide here.
>
OK, I'll head over there. I'm still a bit confused over here, but we'll
get to it.
>>>>
>>>>
>>>> def gen_events(schema: QAPISchema,
>>>> diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
>>>> index 720449feee4d..d5f19732b516 100644
>>>> --- a/scripts/qapi/schema.py
>>>> +++ b/scripts/qapi/schema.py
>>>> @@ -23,6 +23,7 @@
>>>> from .error import QAPIError, QAPISemError
>>>> from .expr import check_exprs
>>>> from .parser import QAPISchemaParser
>>>> +from .source import QAPISourceInfo
>>>>
>>>>
>>>> class QAPISchemaEntity:
>>>> @@ -36,10 +37,10 @@ def __init__(self, name, info, doc, ifcond=None, features=None):
>>>> self.name = name
>>>> self._module = None
>>>> # For explicitly defined entities, info points to the (explicit)
>>>> - # definition. For builtins (and their arrays), info is None.
>>>> - # For implicitly defined entities, info points to a place that
>>>> - # triggered the implicit definition (there may be more than one
>>>> - # such place).
>>>> + # definition. For builtins (and their arrays), info is a null-object
>>>> + # sentinel that evaluates to False. For implicitly defined entities,
>>>> + # info points to a place that triggered the implicit definition
>>>> + # (there may be more than one such place).
>>>
>>> s/builtins/built-in types/
>>>
>>> The meaning of "a null object sentinel" is less than clear. Perhaps "a
>>> special object".
>>>
>>
>> OK.
>>
>>>> self.info = info
>>>> self.doc = doc
>>>> self._ifcond = ifcond or []
>>>> @@ -209,7 +210,7 @@ class QAPISchemaBuiltinType(QAPISchemaType):
>>>> meta = 'built-in'
>>>>
>>>> def __init__(self, name, json_type, c_type):
>>>> - super().__init__(name, None, None)
>>>> + super().__init__(name, QAPISourceInfo.builtin(), None)
>>>> assert not c_type or isinstance(c_type, str)
>>>> assert json_type in ('string', 'number', 'int', 'boolean', 'null',
>>>> 'value')
>>>> @@ -871,7 +872,7 @@ def resolve_type(self, name, info, what):
>>>> return typ
>>>>
>>>> def _module_name(self, fname):
>>>> - if fname is None:
>>>> + if not fname:
>>>> return None
>>>> return os.path.relpath(fname, self._schema_dir)
>>>>
>>>
>>> Sure this hunk belongs to this patch?
>>>
>>
>> Accident.
>>
>> "info and info.fname" does not behave the same with a falsey info object
>> as it does when info was genuinely None; I compensated for that *here*,
>> but I should have compensated for it elsewhere.
>>
>>>> @@ -897,9 +898,11 @@ def _def_builtin_type(self, name, json_type, c_type):
>>>> # be nice, but we can't as long as their generated code
>>>> # (qapi-builtin-types.[ch]) may be shared by some other
>>>> # schema.
>>>> - self._make_array_type(name, None)
>>>> + self._make_array_type(name, QAPISourceInfo.builtin())
>>>>
>>>> def _def_predefineds(self):
>>>> + info = QAPISourceInfo.builtin()
>>>> +
>>>
>>> Everything else gets its very own copy of the "no source info" object,
>>> except for the stuff defined here, which gets to share one. Isn't that
>>> odd?
>>>
>>
>> It's also the only function where we define so many built-ins in the
>> same place, so spiritually they do have the same SourceInfo, right? :)
>>
>> (OK, no, it wasn't a conscious design choice, but it also seems
>> harmless. I am going to assume you'd prefer I not do this?)
>
> It is harmless. It just made me wonder why we create more than one such
> QAPISourceInfo in the first place. Method builtin() could return the
> same one every time. It could even be an attribute instead of a method.
> Anyway, no big deal.
>
I could conceivably use source line information and stuff, to be
needlessly fancy about it. Nah. I just think singleton patterns are kind
of weird to implement in Python, so I didn't.
--js
next prev parent reply other threads:[~2020-12-17 17:22 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-14 23:53 [PATCH 00/12] qapi: static typing conversion, pt1.5 John Snow
2020-12-14 23:53 ` [PATCH 01/12] qapi/commands: assert arg_type is not None John Snow
2020-12-14 23:53 ` [PATCH 02/12] qapi/events: fix visit_event typing John Snow
2020-12-14 23:53 ` [PATCH 03/12] qapi/main: handle theoretical None-return from re.match() John Snow
2020-12-16 8:23 ` Markus Armbruster
2020-12-16 17:11 ` John Snow
2020-12-14 23:53 ` [PATCH 04/12] qapi/gen: assert that _start_if is not None in _wrap_ifcond John Snow
2020-12-16 8:26 ` Markus Armbruster
2020-12-16 17:13 ` John Snow
2020-12-17 7:24 ` Markus Armbruster
2020-12-14 23:53 ` [PATCH 05/12] qapi/gen: use './builtin' for the built-in module name John Snow
2020-12-16 8:35 ` Markus Armbruster
2020-12-16 17:27 ` John Snow
2020-12-14 23:53 ` [PATCH 06/12] qapi/source: Add builtin null-object sentinel John Snow
2020-12-16 9:22 ` Markus Armbruster
2020-12-16 17:53 ` John Snow
2020-12-17 12:33 ` Markus Armbruster
2020-12-18 19:14 ` John Snow
2020-12-16 19:11 ` John Snow
2020-12-17 11:56 ` Markus Armbruster
2020-12-18 19:22 ` John Snow
2020-12-14 23:53 ` [PATCH 07/12] qapi/gen: write _genc/_genh access shims John Snow
2020-12-14 23:53 ` [PATCH 08/12] qapi/schema: make QAPISourceInfo mandatory John Snow
2020-12-16 10:18 ` Markus Armbruster
2020-12-16 18:41 ` John Snow
2020-12-17 8:02 ` Markus Armbruster
2020-12-17 17:02 ` John Snow [this message]
2020-12-18 5:24 ` Markus Armbruster
2020-12-18 19:17 ` John Snow
2020-12-18 20:57 ` Markus Armbruster
2020-12-18 21:30 ` John Snow
2020-12-14 23:53 ` [PATCH 09/12] qapi/gen: move write method to QAPIGenC, make fname a str John Snow
2020-12-16 10:31 ` Markus Armbruster
2020-12-14 23:53 ` [PATCH 10/12] tests/qapi-schema: Add quotes to module name in test output John Snow
2020-12-14 23:53 ` [PATCH 11/12] qapi/schema: Name the builtin module "" instead of None John Snow
2020-12-16 10:42 ` Markus Armbruster
2020-12-16 18:57 ` John Snow
2020-12-17 11:09 ` Markus Armbruster
2020-12-17 21:07 ` John Snow
2020-12-18 5:31 ` Markus Armbruster
2020-12-14 23:53 ` [PATCH 12/12] qapi: enable strict-optional checks John Snow
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e9f43898-1c0b-54e3-59a7-d9064c2d86ea@redhat.com \
--to=jsnow@redhat.com \
--cc=armbru@redhat.com \
--cc=crosa@redhat.com \
--cc=ehabkost@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).