[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 02/22] qapi/source: [RFC] add "with_column" contextmanager
From: |
John Snow |
Subject: |
[PATCH 02/22] qapi/source: [RFC] add "with_column" contextmanager |
Date: |
Wed, 21 Apr 2021 23:07:00 -0400 |
This is a silly one, but... it's important to have fun.
This patch isn't *needed*, it's here as an RFC. In trying to experiment
with different ways to solve the problem addressed by the previous
commit, I kept getting confused at how the "source location" string with
line and column number was built across two different classes.
(i.e. QAPISourceError appends the column, but QAPISourceInfo does not
track column information natively.)
I was afraid to try and fully implement column number directly in
QAPISourceInfo on the chance that it might have undesirable effects, so
I came up with a quick "hack" to centralize the 'location' information
generation.
It's a little goofy, but it works :')
Signed-off-by: John Snow <jsnow@redhat.com>
---
scripts/qapi/error.py | 8 +++-----
scripts/qapi/source.py | 23 ++++++++++++++++++++++-
2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/scripts/qapi/error.py b/scripts/qapi/error.py
index e35e4ddb26a..6b04f56f8a2 100644
--- a/scripts/qapi/error.py
+++ b/scripts/qapi/error.py
@@ -39,11 +39,9 @@ def __init__(self,
def __str__(self) -> str:
assert self.info is not None
- loc = str(self.info)
- if self.col is not None:
- assert self.info.line is not None
- loc += ':%s' % self.col
- return loc + ': ' + self.msg
+ with self.info.at_column(self.col):
+ loc = str(self.info)
+ return f"{loc}: {self.msg}"
class QAPISemError(QAPISourceError):
diff --git a/scripts/qapi/source.py b/scripts/qapi/source.py
index 1ade864d7b9..21090b9fe78 100644
--- a/scripts/qapi/source.py
+++ b/scripts/qapi/source.py
@@ -9,8 +9,14 @@
# This work is licensed under the terms of the GNU GPL, version 2.
# See the COPYING file in the top-level directory.
+from contextlib import contextmanager
import copy
-from typing import List, Optional, TypeVar
+from typing import (
+ Iterator,
+ List,
+ Optional,
+ TypeVar,
+)
class QAPISchemaPragma:
@@ -35,6 +41,7 @@ def __init__(self, fname: str, line: int,
parent: Optional['QAPISourceInfo']):
self.fname = fname
self.line = line
+ self._column: Optional[int] = None
self.parent = parent
self.pragma: QAPISchemaPragma = (
parent.pragma if parent else QAPISchemaPragma()
@@ -52,9 +59,14 @@ def next_line(self: T) -> T:
return info
def loc(self) -> str:
+ # column cannot be provided meaningfully when line is absent.
+ assert self.line or self._column is None
+
ret = self.fname
if self.line is not None:
ret += ':%d' % self.line
+ if self._column is not None:
+ ret += ':%d' % self._column
return ret
def in_defn(self) -> str:
@@ -71,5 +83,14 @@ def include_path(self) -> str:
parent = parent.parent
return ret
+ @contextmanager
+ def at_column(self, column: Optional[int]) -> Iterator[None]:
+ current_column = self._column
+ try:
+ self._column = column
+ yield
+ finally:
+ self._column = current_column
+
def __str__(self) -> str:
return self.include_path() + self.in_defn() + self.loc()
--
2.30.2
[PATCH 02/22] qapi/source: [RFC] add "with_column" contextmanager,
John Snow <=
[PATCH 11/22] qapi/parser: Rework _check_pragma_list_of_str as a TypeGuard, John Snow, 2021/04/21
[PATCH 15/22] qapi/parser: allow 'ch' variable name, John Snow, 2021/04/21
[PATCH 16/22] qapi/parser: add docstrings, John Snow, 2021/04/21