| 239 | |
| 240 | |
| 241 | class ColumnSpec(namedtuple('ColumnSpec', 'field label fmt')): |
| 242 | |
| 243 | REGEX = re.compile(textwrap.dedent(r''' |
| 244 | ^ |
| 245 | (?: |
| 246 | \[ |
| 247 | ( |
| 248 | (?: [^\s\]] [^\]]* )? |
| 249 | [^\s\]] |
| 250 | ) # <label> |
| 251 | ] |
| 252 | )? |
| 253 | ( [-\w]+ ) # <field> |
| 254 | (?: |
| 255 | (?: |
| 256 | : |
| 257 | ( [<^>] ) # <align> |
| 258 | ( \d+ )? # <width1> |
| 259 | ) |
| 260 | | |
| 261 | (?: |
| 262 | (?: |
| 263 | : |
| 264 | ( \d+ ) # <width2> |
| 265 | )? |
| 266 | (?: |
| 267 | : |
| 268 | ( .*? ) # <fmt> |
| 269 | )? |
| 270 | ) |
| 271 | )? |
| 272 | $ |
| 273 | '''), re.VERBOSE) |
| 274 | |
| 275 | @classmethod |
| 276 | def from_raw(cls, raw): |
| 277 | if not raw: |
| 278 | raise ValueError('missing column spec') |
| 279 | elif isinstance(raw, cls): |
| 280 | return raw |
| 281 | |
| 282 | if isinstance(raw, str): |
| 283 | *values, _ = cls._parse(raw) |
| 284 | else: |
| 285 | *values, _ = cls._normalize(raw) |
| 286 | if values is None: |
| 287 | raise ValueError(f'unsupported column spec {raw!r}') |
| 288 | return cls(*values) |
| 289 | |
| 290 | @classmethod |
| 291 | def parse(cls, specstr): |
| 292 | parsed = cls._parse(specstr) |
| 293 | if not parsed: |
| 294 | return None |
| 295 | *values, _ = parsed |
| 296 | return cls(*values) |
| 297 | |
| 298 | @classmethod |
nothing calls this directly
no test coverage detected
searching dependent graphs…