Skip to content

Commit 7d48320

Browse files
committed
Drop support for Python 3.5
1 parent e4aacd9 commit 7d48320

17 files changed

+51
-85
lines changed

.github/workflows/build.yml

+1-3
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,18 @@ jobs:
1616
strategy:
1717
matrix:
1818
python-version:
19-
- 3.5
2019
- 3.6
2120
- 3.7
2221
- 3.8
2322
- 3.9
2423
- "3.10"
2524
- "3.11"
2625
- "3.12"
26+
- "3.13"
2727
include:
2828
- os: ubuntu-latest
2929

3030
# older versions need older OS
31-
- python-version: 3.5
32-
os: ubuntu-20.04
3331
- python-version: 3.6
3432
os: ubuntu-20.04
3533

docs/conf.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818

1919
# -- Project information -----------------------------------------------------
2020

21-
project = 'SystemRDL Compiler'
22-
copyright = '%d, Alex Mykyta' % datetime.datetime.now().year
23-
author = 'Alex Mykyta'
21+
project = "SystemRDL Compiler"
22+
copyright = f"{datetime.datetime.now().year}, Alex Mykyta"
23+
author = "Alex Mykyta"
2424

2525

2626
# -- General configuration ---------------------------------------------------

examples/print_hierarchy.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ def enter_Component(self, node):
1515

1616
def enter_Field(self, node):
1717
# Print some stuff about the field
18-
bit_range_str = "[%d:%d]" % (node.high, node.low)
19-
sw_access_str = "sw=%s" % node.get_property('sw').name
18+
bit_range_str = f"[{node.high}:{node.low}]"
19+
sw_access_str = f"sw={node.get_property('sw').name}"
2020
print("\t"*self.indent, bit_range_str, node.get_path_segment(), sw_access_str)
2121

2222
def exit_Component(self, node):

setup.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def run_setup(with_binary):
6565
include_package_data=True,
6666
ext_modules=ext_modules,
6767
cmdclass={"build_ext": ve_build_ext},
68-
python_requires='>=3.5.2',
68+
python_requires='>=3.6',
6969
install_requires=[
7070
"antlr4-python3-runtime >= 4.11, < 4.14",
7171
"colorama",
@@ -75,7 +75,6 @@ def run_setup(with_binary):
7575
"Development Status :: 5 - Production/Stable",
7676
"Programming Language :: Python",
7777
"Programming Language :: Python :: 3",
78-
"Programming Language :: Python :: 3.5",
7978
"Programming Language :: Python :: 3.6",
8079
"Programming Language :: Python :: 3.7",
8180
"Programming Language :: Python :: 3.8",

systemrdl/compiler.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def __init__(self, **kwargs: Any):
101101

102102
# Check for stray kwargs
103103
if kwargs:
104-
raise TypeError("got an unexpected keyword argument '%s'" % list(kwargs.keys())[0])
104+
raise TypeError(f"got an unexpected keyword argument '{list(kwargs.keys())[0]}'")
105105

106106
#: Reference to the compiler's :class:`~systemrdl.messages.MessageHandler` object
107107
#:
@@ -127,9 +127,9 @@ def define_udp(
127127
)
128128

129129
if name in self.env.property_rules.rdl_properties:
130-
raise ValueError("UDP definition's name '%s' conflicts with existing built-in RDL property")
130+
raise ValueError(f"UDP definition's name '{name}' conflicts with existing built-in RDL property")
131131
if name in self.env.property_rules.user_properties:
132-
raise ValueError("UDP '%s' has already been defined")
132+
raise ValueError(f"UDP '{name}' has already been defined")
133133

134134
udp = LegacyExternalUserProperty(
135135
self.env,
@@ -156,9 +156,9 @@ def register_udp(self, definition_cls: 'Type[UDPDefinition]', soft: bool=True) -
156156
.. versionadded:: 1.25
157157
"""
158158
if definition_cls.name in self.env.property_rules.rdl_properties:
159-
raise ValueError("UDP definition's name '%s' conflicts with existing built-in RDL property")
159+
raise ValueError(f"UDP definition's name '{definition_cls.name}' conflicts with existing built-in RDL property")
160160
if definition_cls.name in self.env.property_rules.user_properties:
161-
raise ValueError("UDP '%s' has already been defined")
161+
raise ValueError(f"UDP '{definition_cls.name}' has already been defined")
162162

163163
# Wrap definition with internal UDP object & register it
164164
udp = ExternalUserProperty(self.env, definition_cls, soft)
@@ -341,11 +341,11 @@ def elaborate(self, top_def_name: Optional[str]=None, inst_name: Optional[str]=N
341341
if top_def_name is not None:
342342
# Lookup top_def_name
343343
if top_def_name not in self.root.comp_defs:
344-
self.msg.fatal("Elaboration target '%s' not found" % top_def_name)
344+
self.msg.fatal(f"Elaboration target '{top_def_name}' not found")
345345
top_def = self.root.comp_defs[top_def_name]
346346

347347
if not isinstance(top_def, comp.Addrmap):
348-
self.msg.fatal("Elaboration target '%s' is not an 'addrmap' component" % top_def_name)
348+
self.msg.fatal(f"Elaboration target '{top_def_name}' is not an 'addrmap' component")
349349
else:
350350
# Not specified. Find the last addrmap defined
351351
for comp_def in reversed(self.root.comp_defs.values()):
@@ -382,13 +382,13 @@ def elaborate(self, top_def_name: Optional[str]=None, inst_name: Optional[str]=N
382382
parameter = p
383383
break
384384
else:
385-
self.msg.fatal("Elaboration top does not have a parameter '%s' that is available for override" % param_name)
385+
self.msg.fatal(f"Elaboration top does not have a parameter '{param_name}' that is available for override")
386386

387387
literal_expr = ast.ExternalLiteral(self.env, value)
388388
assign_expr = ast.AssignmentCast(self.env, None, literal_expr, parameter.param_type)
389389
assign_type = assign_expr.predict_type()
390390
if assign_type is None:
391-
self.msg.fatal("Incorrect type for top-level parameter override of '%s'" % param_name)
391+
self.msg.fatal(f"Incorrect type for top-level parameter override of '{param_name}'")
392392

393393
parameter.expr = assign_expr
394394

systemrdl/component.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -145,15 +145,11 @@ def __deepcopy__(self: 'ComponentClass', memo: Dict[int, Any]) -> 'ComponentClas
145145

146146
def __repr__(self) -> str:
147147
if self.is_instance:
148-
name_str = "%s (%s)" % (self.inst_name, self.type_name)
148+
name_str = f"{self.inst_name} ({self.type_name})"
149149
else:
150150
name_str = self.type_name
151151

152-
return "<%s %s at 0x%x>" % (
153-
self.__class__.__qualname__,
154-
name_str,
155-
id(self)
156-
)
152+
return f"<{self.__class__.__qualname__} {name_str} at {id(self):#x}>"
157153

158154

159155
def get_child_by_name(self, inst_name: str) -> Optional['Component']:

systemrdl/core/namespace.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import sys
21
from typing import TYPE_CHECKING, Dict, List, Union, Type, Tuple
32

43
from .parameter import Parameter
@@ -11,12 +10,7 @@
1110
from .. import rdltypes
1211
from ..ast import ASTNode
1312

14-
if sys.version_info >= (3,5,4):
15-
TypeNSRef = Union[comp.Component, Type['rdltypes.UserEnum'], Type['rdltypes.UserStruct']]
16-
else:
17-
# Stub on 3.5.3 or older due to: https://github.com/python/typing/issues/266
18-
from typing import Any
19-
TypeNSRef = Any # type: ignore
13+
TypeNSRef = Union[comp.Component, Type['rdltypes.UserEnum'], Type['rdltypes.UserStruct']]
2014
TypeNSEntry = TypeNSRef
2115
TypeNSScope = Dict[str, TypeNSEntry]
2216

systemrdl/core/rdlformatcode.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ def rdlfc_to_html(text: str, node: Optional[Node]=None, md: Optional['Markdown']
5555
]
5656

5757
if is_desc:
58-
tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_spec)
58+
tok_regex = '|'.join(f"(?P<{pair[0]}>{pair[1]})" for pair in token_spec)
5959
else:
6060
# filter out tags that are not to be interpreted in 'name' properties
6161
skipset = {'img', 'list', 'bullet', 'xlist', 'br', 'p', 'xp', 'index', 'index_parent', 'name'}
62-
tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_spec if pair[0] not in skipset)
62+
tok_regex = '|'.join(f"(?P<{pair[0]}>{pair[1]})" for pair in token_spec if pair[0] not in skipset)
6363

6464
pos = 0
6565
text_segs = []

systemrdl/core/value_normalization.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def normalize_scalar(value: int) -> str:
5151
5.1.1.4 - c.1:
5252
Scalar values shall be rendered using their hexadecimal representation.
5353
"""
54-
return "%x" % value
54+
return f"{value:x}"
5555

5656

5757
def normalize_boolean(value: bool) -> str:
@@ -122,7 +122,7 @@ def normalize_struct(value: rdltypes.UserStruct, owner_node: Optional[node.Node]
122122
"""
123123
norm_elements = []
124124
for member_name, member_value in value._values.items():
125-
norm_elements.append("%s_%s" % (member_name, normalize(member_value, owner_node)))
125+
norm_elements.append(f"{member_name}_{normalize(member_value, owner_node)}")
126126

127127
norm_str = "_".join(norm_elements)
128128
md5 = hashlib.md5(norm_str.encode('utf-8')).hexdigest()
@@ -143,7 +143,7 @@ def normalize_property_ref(value: rdltypes.PropertyReference, owner_node: node.N
143143
Hash of relative path from owner of the property to the target component's
144144
property
145145
"""
146-
path = "%s->%s" % (value.node.get_rel_path(owner_node), value.name)
146+
path = f"{value.node.get_rel_path(owner_node)}->{value.name}"
147147
md5 = hashlib.md5(path.encode('utf-8')).hexdigest()
148148
return md5[:8]
149149

systemrdl/importer.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def import_file(self, path: str) -> None:
5454
# ------------------------ create_xxx_definition() -------------------------
5555
def _create_definition(self, cls: "Type[ComponentClass]", type_name: Optional[str] = None, src_ref: Optional[SourceRefBase] = None) -> "ComponentClass":
5656
if (type_name is not None) and not re.fullmatch(r"[a-zA-Z_]\w*", type_name):
57-
raise ValueError("Type name has invalid characters: '%s'" % type_name)
57+
raise ValueError(f"Type name has invalid characters: '{type_name}'")
5858
C = cls()
5959
C.type_name = type_name
6060
C.def_src_ref = src_ref or self.default_src_ref
@@ -138,7 +138,7 @@ def _instantiate(self, comp_def: "ComponentClass", inst_name: str, src_ref: Opti
138138
if comp_def.is_instance:
139139
raise ValueError("Component is already instantiated")
140140
if not re.fullmatch(r"[a-zA-Z_]\w*", inst_name):
141-
raise ValueError("Instance name has invalid characters: '%s'" % inst_name)
141+
raise ValueError(f"Instance name has invalid characters: '{inst_name}'")
142142

143143
if comp_def.type_name is None:
144144
# anonymous definition. No need to copy since it can only be used once
@@ -284,7 +284,7 @@ def add_child(self, parent: comp.Component, child: comp.Component) -> None:
284284
if isinstance(child, comp.Field):
285285
bad = False
286286
if bad:
287-
raise TypeError("Parent %s cannot be assigned child %s" % (repr(parent), repr(child)))
287+
raise TypeError(f"Parent {repr(parent)} cannot be assigned child {repr(child)}")
288288

289289
if not child.is_instance:
290290
raise ValueError("Child must be an instance if adding to a parent")
@@ -308,7 +308,7 @@ def assign_property(self, component: comp.Component, prop_name: str, value: Any,
308308

309309
rule = self.compiler.env.property_rules.lookup_property(prop_name)
310310
if rule is None:
311-
raise ValueError("Unrecognized property '%s'" % prop_name)
311+
raise ValueError(f"Unrecognized property '{prop_name}'")
312312
if isinstance(value, comp.Component):
313313
# Warn user that this is not how references work
314314
raise TypeError("Invalid assignment type")

systemrdl/messages.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def format_message(self, severity: Severity, text: str, src_ref: Optional[Source
8989
# Detailed message selection context is available
9090
lines.append(
9191
Style.BRIGHT
92-
+ "%s:%d:%d: " % (src_ref.path, src_ref.line, src_ref.line_selection[0]+1)
92+
+ f"{src_ref.path}:{src_ref.line}:{src_ref.line_selection[0]+1}: "
9393
+ color + severity.name.lower() + ": "
9494
+ Style.RESET_ALL
9595
+ text
@@ -99,7 +99,7 @@ def format_message(self, severity: Severity, text: str, src_ref: Optional[Source
9999
# Only the file path is known
100100
lines.append(
101101
Style.BRIGHT
102-
+ "%s: " % src_ref.path
102+
+ f"{src_ref.path}: "
103103
+ color + severity.name.lower() + ": "
104104
+ Style.RESET_ALL
105105
+ text

systemrdl/node.py

+5-9
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,7 @@ def __init__(self, inst: comp.Component, env: 'RDLEnvironment', parent: Optional
3434
self.parent = parent
3535

3636
def __repr__(self) -> str:
37-
return "<%s %s at 0x%x>" % (
38-
self.__class__.__qualname__,
39-
self.get_path(),
40-
id(self)
41-
)
37+
return f"<{self.__class__.__qualname__} {self.get_path()} at {id(self):#x}>"
4238

4339

4440
def __deepcopy__(self, memo: Dict[int, Any]) -> 'Node':
@@ -381,7 +377,7 @@ def get_property(self, prop_name: str, **kwargs: Any)-> Any:
381377

382378
# Check for stray kwargs
383379
if kwargs:
384-
raise TypeError("got an unexpected keyword argument '%s'" % list(kwargs.keys())[0])
380+
raise TypeError(f"got an unexpected keyword argument '{list(kwargs.keys())[0]}'")
385381

386382
if prop_name not in self.inst.properties:
387383
# Was not assigned by the user
@@ -394,9 +390,9 @@ def get_property(self, prop_name: str, **kwargs: Any)-> Any:
394390

395391
# Is it even a valid property or allowed for this component type?
396392
if rule is None:
397-
raise LookupError("Unknown property '%s'" % prop_name)
393+
raise LookupError(f"Unknown property '{prop_name}'")
398394
if type(self.inst) not in rule.bindable_to:
399-
raise LookupError("Unknown property '%s'" % prop_name)
395+
raise LookupError(f"Unknown property '{prop_name}'")
400396

401397
# Return the default value as specified by the rulebook
402398
return rule.get_default(self)
@@ -1064,7 +1060,7 @@ def get_global_type_name(self, separator: str = "__") -> Optional[str]:
10641060
# field width is the default. Skip suffix
10651061
suffix = ""
10661062
else:
1067-
suffix = "_w%d" % self.width
1063+
suffix = f"_w{self.width}"
10681064

10691065
return name + suffix
10701066

systemrdl/rdltypes/builtin_enums.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def __new__(cls) -> 'AutoNoValueEnum':
99
return obj
1010

1111
def __repr__(self) -> str:
12-
return '<%s.%s>' % (self.__class__.__name__, self.name)
12+
return f"<{self.__class__.__name__}.{self.name}>"
1313

1414
class BuiltinEnum(AutoNoValueEnum):
1515
pass
@@ -45,7 +45,7 @@ def __add__(self, other: Any) -> 'AccessType':
4545
.. versionadded:: 1.23
4646
"""
4747
if not isinstance(other, AccessType):
48-
raise TypeError("unsupported addend types: %s + %s" % (repr(self), repr(other)))
48+
raise TypeError(f"unsupported addend types: {repr(self)} + {repr(other)}")
4949

5050
pair = {other, self}
5151

systemrdl/rdltypes/references.py

+1-6
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,7 @@ def __init__(self, src_ref: 'SourceRefBase', env: 'RDLEnvironment', comp_ref: Co
115115
self.node = None # type: Node
116116

117117
def __repr__(self) -> str:
118-
return "<%s %s->%s at 0x%x>" % (
119-
self.__class__.__qualname__,
120-
self.node.get_path(),
121-
self.name,
122-
id(self)
123-
)
118+
return f"<{self.__class__.__qualname__} {self.node.get_path()}->{self.name} at {id(self):#x}>"
124119

125120
def __eq__(self, other: object) -> bool:
126121
"""

systemrdl/rdltypes/typing.py

+8-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
from typing import Type, Union, Any, TYPE_CHECKING
2-
import sys
1+
from typing import Type, Union, TYPE_CHECKING
32

43
if TYPE_CHECKING:
54
from .builtin_enums import BuiltinEnum
@@ -10,16 +9,12 @@
109
from ..node import Node
1110
from .. import component as comp
1211

13-
if sys.version_info >= (3,5,4):
14-
# RDL Types the user will encounter via the public API
15-
RDLValue = Union[
16-
int, bool, str, list,
17-
'BuiltinEnum', 'UserEnum', 'UserStruct', Type['UserEnum'],
18-
'Node', 'PropertyReference'
19-
]
20-
else:
21-
# Stub on 3.5.3 or older due to: https://github.com/python/typing/issues/266
22-
RDLValue = Any # type: ignore
12+
# RDL Types the user will encounter via the public API
13+
RDLValue = Union[
14+
int, bool, str, list,
15+
'BuiltinEnum', 'UserEnum', 'UserStruct', Type['UserEnum'],
16+
'Node', 'PropertyReference'
17+
]
2318

2419
# RDL Types used internally prior to elaboration
2520
PreElabRDLValue = Union[
@@ -28,8 +23,4 @@
2823
'PropertyReference', 'comp.Component', 'RefType'
2924
]
3025

31-
if sys.version_info >= (3,5,4):
32-
PreElabRDLType = Union[Type[PreElabRDLValue], 'ArrayedType']
33-
else:
34-
# Stub on 3.5.3 or older due to: https://github.com/python/typing/issues/266
35-
PreElabRDLType = Any # type: ignore
26+
PreElabRDLType = Union[Type[PreElabRDLValue], 'ArrayedType']

systemrdl/rdltypes/user_enum.py

+2-5
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,7 @@ def __bool__(cls) -> bool:
4242
def __contains__(cls, obj: Any) -> bool:
4343
if not isinstance(obj, UserEnum):
4444
raise TypeError(
45-
"unsupported operand type(s) for 'in': '%s' and '%s'"
46-
% (
47-
type(obj).__qualname__, cls.__class__.__qualname__
48-
)
45+
f"unsupported operand type(s) for 'in': '{type(obj).__qualname__}' and '{cls.__class__.__qualname__}'"
4946
)
5047
return isinstance(obj, cls) and obj._name in cls._member_map
5148

@@ -59,7 +56,7 @@ def __len__(cls) -> int:
5956
return len(cls._member_map)
6057

6158
def __repr__(cls) -> str:
62-
return "<UserEnum %r>" % cls.__name__
59+
return f"<UserEnum {cls.__name__}>"
6360

6461
def __reversed__(cls) -> 'Generator[UserEnum, None, None]':
6562
"""

0 commit comments

Comments
 (0)