Hacker News new | past | comments | ask | show | jobs | submit login

A number is also a string. Crazy, right?



The following code will only validate when gameServerVersion is a hex string between 9 and 32 characters:

  #!/usr/bin/env python
  import sys
  import re
  from typing import Annotated
  from pydantic import BaseModel, AfterValidator, validator
  from pydantic_yaml import parse_yaml_raw_as
  
  
  def validate_commit_id(s: str) -> str:
    assert re.search(r"^[0-9a-f]{9,32}$", s), f"{s} is not a commit id"
    return s
  
  
  CommitId = Annotated[str, AfterValidator(validate_commit_id)]
  
  
  class Model(BaseModel):
    gameServerVersion: CommitId
  
  
  def main():
    text = sys.stdin.read()
    conf = parse_yaml_raw_as(Model, text)
    print(conf)
  
  
  if __name__ == "__main__":
    main()
    
It would have prevented the Git Hash Bug originally described:

  $ cat conf.yaml
  gameServerVersion: 556474e378
  $ python parse.py < conf.yaml
  pydantic_core._pydantic_core.ValidationError: 1 validation error for Model
  gameServerVersion
    Input should be a valid string [type=string_type, input_value=inf, input_type=float]
  
  $ cat conf.yaml
  gameServerVersion: "556474e378"
  $ python parse.py < conf.yaml
  gameServerVersion='556474e378'
  
  $ cat conf.yaml
  gameServerVersion: "Infinity"
  $ python parse.py < conf.yaml
  pydantic_core._pydantic_core.ValidationError: 1 validation error for Model
  gameServerVersion
    Assertion failed, Infinity is not a commit id [type=assertion_error, input_value='Infinity', input_type=str]

It's just good practice to validate things on the way in. Even if they were using JSON as their config file, they should still validate it.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: