clear-skies 2.0.11__py3-none-any.whl → 2.0.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of clear-skies might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clear-skies
3
- Version: 2.0.11
3
+ Version: 2.0.12
4
4
  Summary: A framework for building backends in the cloud
5
5
  Project-URL: Documentation, https://clearskies.io/
6
6
  Project-URL: Repository, https://github.com/clearskies-py/clearskies
@@ -207,7 +207,7 @@ clearskies/functional/string.py,sha256=ZnkOjx8nxqZq2TV0CIb-Kz4onGoyekTX_WkLJM6XT
207
207
  clearskies/functional/validations.py,sha256=cPYOTwWomlQrPvqPP_Jdlds7zZ5H9GABCP5pnGzC9T4,2821
208
208
  clearskies/input_outputs/__init__.py,sha256=9qeKJULw3MQ3zqkgBZice5d7qqRgsP3y-wkhWO2Y9vM,362
209
209
  clearskies/input_outputs/cli.py,sha256=t7uWqLi6VI3i_zuyoKLdIq3vUwr19lQZoJmuAxVEvgg,5741
210
- clearskies/input_outputs/headers.py,sha256=qdnPEUJ2amKUdzasbTQb015KGzJP-d4RjIbtrPdqTqM,1680
210
+ clearskies/input_outputs/headers.py,sha256=AnyqI64kploPX7qiBfQCD9w8b2FYWVIuwaXVafbpIiM,2085
211
211
  clearskies/input_outputs/input_output.py,sha256=tJQVN3U3MX_jpwsXJ-g-K1cdqQwyuSarTjo3JOp7zQQ,5154
212
212
  clearskies/input_outputs/programmatic.py,sha256=OCRq0M42cKZKgk4YAfJyTWo3T4jNRmnGmVr7zCTovpg,1658
213
213
  clearskies/input_outputs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -251,7 +251,7 @@ clearskies/validators/minimum_value.py,sha256=NDLcG6xCemlv3kfr-RiUaM3x2INS1GJGMB
251
251
  clearskies/validators/required.py,sha256=GWxyexwj-K6DunZWNEnZxW6tQGAFd4oOCvQrW1s1K9k,1308
252
252
  clearskies/validators/timedelta.py,sha256=DJ0pTm-SSUtjZ7phGoD6vjb086vXPzvLLijkU-jQlOs,1892
253
253
  clearskies/validators/unique.py,sha256=GFEQOMYRIO9pSGHHj6zf1GdnJ0UM7Dm4ZO4uGn19BZo,991
254
- clear_skies-2.0.11.dist-info/METADATA,sha256=KsFDLUKDhP1zHg3H2qmyDILiNZ4Ko0LfYTVyXUNywVM,2114
255
- clear_skies-2.0.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
256
- clear_skies-2.0.11.dist-info/licenses/LICENSE,sha256=3Ehd0g3YOpCj8sqj0Xjq5qbOtjjgk9qzhhD9YjRQgOA,1053
257
- clear_skies-2.0.11.dist-info/RECORD,,
254
+ clear_skies-2.0.12.dist-info/METADATA,sha256=Lq1xv-aCUbaeDxJUtsjY36pQDKoGhV7JMQ7i0nhjKsM,2114
255
+ clear_skies-2.0.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
256
+ clear_skies-2.0.12.dist-info/licenses/LICENSE,sha256=3Ehd0g3YOpCj8sqj0Xjq5qbOtjjgk9qzhhD9YjRQgOA,1053
257
+ clear_skies-2.0.12.dist-info/RECORD,,
@@ -1,47 +1,53 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import re
4
+ from typing import TypeVar
4
5
 
6
+ _T = TypeVar("_T")
5
7
 
6
- class Headers:
7
- _headers: dict[str, str] = {}
8
+
9
+ class Headers(dict[str, str]):
8
10
  _duck_cheat = "headers"
9
11
 
10
- def __init__(self, headers: dict[str, str] = {}):
11
- self.__dict__["_headers"] = (
12
+ def __init__(self, headers: dict[str, str] = {}) -> None:
13
+ normalized_headers = (
12
14
  {key.upper().replace("_", "-"): value for (key, value) in headers.items()} if headers else {}
13
15
  )
16
+ super().__init__(normalized_headers)
14
17
 
15
- def __contains__(self, key: str):
16
- return key.upper().replace("_", "-") in self._headers
18
+ def __contains__(self, key: object) -> bool:
19
+ if not isinstance(key, str):
20
+ return False
21
+ return super().__contains__(key.upper().replace("_", "-"))
17
22
 
18
- def __getattr__(self, key: str) -> str | None:
19
- return self._headers.get(key.upper().replace("_", "-"), None)
23
+ def __getitem__(self, key: str) -> str:
24
+ return super().__getitem__(key.upper().replace("_", "-"))
20
25
 
21
- def __setattr__(self, key: str, value: str) -> None:
26
+ def __setitem__(self, key: str, value: str) -> None:
22
27
  if not isinstance(key, str):
23
28
  raise TypeError(
24
- f"Header keys must be strings, but an object of type '{value.__class__.__name__}' was provided."
29
+ f"Header keys must be strings, but an object of type '{key.__class__.__name__}' was provided."
25
30
  )
26
31
  if not isinstance(value, str):
27
32
  raise TypeError(
28
33
  f"Header values must be strings, but an object of type '{value.__class__.__name__}' was provided."
29
34
  )
30
- self._headers[re.sub("\\s+", " ", key.upper().replace("_", "-"))] = re.sub("\\s+", " ", value.strip())
35
+ normalized_key = re.sub("\\s+", " ", key.upper().replace("_", "-"))
36
+ normalized_value = re.sub("\\s+", " ", value.strip())
37
+ super().__setitem__(normalized_key, normalized_value)
31
38
 
32
- def get(self, key, default=None):
33
- if key not in self:
34
- return default
35
- return self.__getattr__(key)
36
-
37
- def keys(self) -> list[str]:
38
- return list(self._headers.keys())
39
-
40
- def values(self) -> list[str]:
41
- return list(self._headers.keys())
39
+ def __getattr__(self, key: str) -> str | None:
40
+ return self.get(key.upper().replace("_", "-"), None)
42
41
 
43
- def items(self) -> list[tuple[str]]:
44
- return list(self._headers.items()) # type: ignore
42
+ def __setattr__(self, key: str, value: str) -> None:
43
+ if key.startswith("_") or key == "_duck_cheat":
44
+ # Allow setting private attributes and special attributes normally
45
+ super().__setattr__(key, value)
46
+ else:
47
+ self.__setitem__(key, value)
48
+
49
+ def get(self, key: str, default: _T = None) -> str | _T: # type: ignore[assignment]
50
+ return super().get(key.upper().replace("_", "-"), default)
45
51
 
46
52
  def add(self, key: str, value: str) -> None:
47
53
  """Add a header. This expects a string with a colon separating the key and value."""