dirty-equals
dirty-equals copied to clipboard
More types
- [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)
Not sure if these are worth adding, but I was looking for them while reading the docs:
IsStreamhelpful for File IOIsUrito know if something is a value uri/url?IsFileandIsFoldermaybe 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
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.
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
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.
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?
IsIPfor v4 and v6, possibly with subnet supportIsHashfor different hashes, i.e. SHA256, MD5 etc.IsUUIDperhaps 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)
}
IsUUIDis doneIsIPyes, PR welcomeIsHashyes, PR welcomeIsUrlyes, PR welcome, you'll need to make pydantic a dependency, but that's fine by meIsModelI'm not so sure about, I don't think it's necessary, you can always create your own custom type