dirty-equals icon indicating copy to clipboard operation
dirty-equals copied to clipboard

More types

Open samuelcolvin opened this issue 3 years ago • 6 comments

  • [x] IsFalseLike #23
  • [x] IsTrueLike #25
  • [x] IsPartialDict #5
  • [x] IsFullDict(order_matters=False) #5
  • [x] IsIterable(*items, start=None, finish=None, order_matters=True, len=None) #7
  • [x] IsList(*items, skip=DontSkip, order_matters=True, len=None) #7
  • [x] IsTuple(*items, skip=DontSkip, order_matters=True, len=None) #7
  • [x] IsPartialIterable(items: Dict[int, Any]) #7
  • [x] IsStr(regex, min_length, max_length, upper, lower, digits)
  • [x] IsBytes(regex, min_length, max_length, upper, lower, digits)
  • [x] IsToday #20
  • [x] HasProperties #26
  • [x] HasName #26
  • [x] HasRepr #26
  • [x] HasLen #7
  • [x] IsOneOf
  • [x] EqualsFunc #4
  • [x] IsJson #4
  • [ ] IsDataclass
  • [ ] IsEnumMember(v, strict=True)

samuelcolvin avatar Jan 28 '22 11:01 samuelcolvin

Not sure if these are worth adding, but I was looking for them while reading the docs:

  • IsStream helpful for File IO
  • IsUri to know if something is a value uri/url?
  • IsFile and IsFolder maybe too much overlap with pathlib but seems almost in scope.

These are fresh on my mind from trying to think through some common ways to access "things in strings" https://github.com/jefftriplett/django-fett/blob/main/src/fett.py#L295-L328

jefftriplett avatar Feb 25 '22 17:02 jefftriplett

ye makes sense.

IsUri would be useful but I'm a bit torn about how to implement it. I don't want to duplicate the masses of URI logic from pydantic, but I also don't want to create another library or make pydantic a dependency of this. Maybe one of those other libraries like yarl could help

The other types i haven't needed since I've always used dirty-equals and equivalent for checking the response from APIs or contents of databases, where you don't get steams or files.

samuelcolvin avatar Feb 25 '22 17:02 samuelcolvin

I think IsUri would be pretty useful if poss. I'm literally about to work on something where I'd use that if it was an option.

Could keep it simple and offload some of the url validation logic to the user?

i.e. something simple like this just with urllib?

def is_uri(uri: str, required: list[str], value: dict[str, str] = None) -> bool:
    parsed: ParseResult = urlparse(url=uri)
    attributes_present: Iterator[str] = (getattr(parsed, x) for x in required)
    if value:
        values_present: Iterator[str] = (getattr(parsed, k) == v for k, v in value.items())
        return all(attributes_present) and all(values_present)
    return all(attributes_present)


is_uri(uri="https://www.example.com", required=["scheme", "netloc"])  # True
is_uri(uri="https://www.example.com", required=["scheme", "netloc", "path"])  # False
is_uri(uri="https://www.example.com/stuff", required=["scheme", "netloc", "path"])  # True
is_uri(uri="https://www.example.com/stuff", required=["scheme", "netloc", "path"], value={"path": "nothing"})  # False
is_uri(uri="https://www.example.com/stuff", required=["scheme", "netloc", "path"], value={"path": "/stuff"})  # True

osintalex avatar Apr 14 '22 17:04 osintalex

Urllib is definitely not suitable for checking urls, is easy too lenient.

Simplest solution would probably be to copy the regex and logic from pydantic. We know that's widely used and works.

Or we add a dependency like yarl.

samuelcolvin avatar Apr 14 '22 17:04 samuelcolvin

That all makes sense! Would you be interested in a PR on IsUri using the Pydantic logic? Appreciate that might be better to leave to you as the author of Pydantic 😅

I've been working on testing APIs recently and thought some of these types could be useful. Although I may be predisposed to focus on types that would be useful for cybersecurity applications and perhaps less so elsewhere. Anyhow, would you be interested in a PR on any of these?

  • IsIP for v4 and v6, possibly with subnet support
  • IsHash for different hashes, i.e. SHA256, MD5 etc.
  • IsUUID perhaps with options to check different versions
  • I'm not sure if this aligns with your vision for the library, but a way of testing if something matches a Pydantic class could be handy, i.e. IsModel(MyPydanticClass). Even though t's just syntactic sugar for testing a Pydantic class instantiates without errors, I would find it nifty to do something like the below since I so often use Pydantic models to define data/response models in API designs.
class Preferences(BaseModel):
    subscribed: bool
    services: list[str]

   assert user_data == {
       'id': IsPositiveInt, 
       'username': 'samuelcolvin', 
       'avatar_file': IsStr(regex=r'/[a-z0-9\-]{10}/example\.png'), 
       'settings_json': IsJson({'theme': 'dark', 'language': 'en'}), 
       'created_ts': IsNow(delta=3), 
       'preferences': IsModel(Preferences)
   }

osintalex avatar Jun 08 '22 23:06 osintalex

  • IsUUID is done
  • IsIP yes, PR welcome
  • IsHash yes, PR welcome
  • IsUrl yes, PR welcome, you'll need to make pydantic a dependency, but that's fine by me
  • IsModel I'm not so sure about, I don't think it's necessary, you can always create your own custom type

samuelcolvin avatar Jun 09 '22 07:06 samuelcolvin