hh-applicant-tool 0.5.5__tar.gz → 0.5.6__tar.gz

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 hh-applicant-tool might be problematic. Click here for more details.

Files changed (30) hide show
  1. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/PKG-INFO +1 -1
  2. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/api/client.py +2 -2
  3. hh_applicant_tool-0.5.6/hh_applicant_tool/jsonc.py +138 -0
  4. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/utils.py +2 -4
  5. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/pyproject.toml +1 -1
  6. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/README.md +0 -0
  7. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/__init__.py +0 -0
  8. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/__main__.py +0 -0
  9. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/ai/__init__.py +0 -0
  10. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/ai/blackbox.py +0 -0
  11. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/api/__init__.py +0 -0
  12. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/api/errors.py +0 -0
  13. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/color_log.py +0 -0
  14. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/constants.py +0 -0
  15. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/main.py +0 -0
  16. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/mixins.py +0 -0
  17. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/operations/__init__.py +0 -0
  18. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/operations/apply_similar.py +0 -0
  19. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/operations/authorize.py +0 -0
  20. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/operations/call_api.py +0 -0
  21. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/operations/clear_negotiations.py +0 -0
  22. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/operations/config.py +0 -0
  23. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/operations/get_employer_contacts.py +0 -0
  24. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/operations/list_resumes.py +0 -0
  25. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/operations/refresh_token.py +0 -0
  26. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/operations/reply_employers.py +0 -0
  27. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/operations/update_resumes.py +0 -0
  28. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/operations/whoami.py +0 -0
  29. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/telemetry_client.py +0 -0
  30. {hh_applicant_tool-0.5.5 → hh_applicant_tool-0.5.6}/hh_applicant_tool/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: hh-applicant-tool
3
- Version: 0.5.5
3
+ Version: 0.5.6
4
4
  Summary:
5
5
  Author: Senior YAML Developer
6
6
  Author-email: yamldeveloper@proton.me
@@ -117,8 +117,8 @@ class BaseClient:
117
117
  try:
118
118
  rv = response.json()
119
119
  except json.decoder.JSONDecodeError:
120
- if response.status_code not in [201, 204]:
121
- raise
120
+ # if response.status_code not in [201, 204]:
121
+ # raise
122
122
  rv = {}
123
123
  finally:
124
124
  logger.debug(
@@ -0,0 +1,138 @@
1
+ import re
2
+ import enum
3
+ from dataclasses import dataclass
4
+ import ast
5
+ from typing import Any, Iterator
6
+ from collections import OrderedDict
7
+
8
+
9
+ class TokenType(enum.Enum):
10
+ WHITESPACE = r"\s+"
11
+ COMMENT = r"//.*|/\*[\s\S]*?\*/"
12
+ NUMBER = r"-?\d+(?:\.\d+)?"
13
+ STRING = r'"(?:\\"|[^"]+)*"'
14
+ KEYWORD = r"null|true|false"
15
+ OPEN_CURLY = r"\{"
16
+ CLOSE_CURLY = r"\}"
17
+ OPEN_SQUARE = r"\["
18
+ CLOSE_SQUARE = r"\]"
19
+ COLON = r":"
20
+ COMMA = r","
21
+ UNKNOWN = r"."
22
+ EOF = r"$"
23
+
24
+
25
+ @dataclass(frozen=True)
26
+ class Token:
27
+ token_type: TokenType
28
+ value: str
29
+
30
+
31
+ def tokenize(s: str) -> Iterator[Token]:
32
+ token_patterns = "|".join(f"(?P<{t.name}>{t.value})" for t in TokenType)
33
+ regex = re.compile(token_patterns, re.MULTILINE)
34
+ for m in regex.finditer(s):
35
+ assert type(m.lastgroup) is str
36
+ yield Token(TokenType[m.lastgroup], m.group())
37
+
38
+
39
+ class JSONCParser:
40
+ def parse(self, s: str) -> Any:
41
+ self.token_it = filter(
42
+ lambda t: t.token_type not in [TokenType.COMMENT, TokenType.WHITESPACE],
43
+ tokenize(s),
44
+ )
45
+ self.next_token = None
46
+ self.advance()
47
+ result = self.parse_value()
48
+ self.expect(TokenType.EOF)
49
+ return result
50
+
51
+ def parse_object(self) -> dict:
52
+ # obj = OrderedDict()
53
+ obj = {}
54
+
55
+ while True:
56
+ self.expect(TokenType.STRING)
57
+ key = ast.literal_eval(self.token.value)
58
+ self.expect(TokenType.COLON)
59
+ value = self.parse_value()
60
+ obj[key] = value
61
+ if not self.match(TokenType.COMMA):
62
+ break
63
+
64
+ self.expect(TokenType.CLOSE_CURLY)
65
+ return obj
66
+
67
+ def parse_array(self) -> list:
68
+ arr = []
69
+
70
+ while True:
71
+ arr.append(self.parse_value())
72
+ if not self.match(TokenType.COMMA):
73
+ break
74
+
75
+ self.expect(TokenType.CLOSE_SQUARE)
76
+ return arr
77
+
78
+ def parse_value(self) -> Any:
79
+ if self.match(TokenType.OPEN_CURLY):
80
+ return self.parse_object()
81
+ elif self.match(TokenType.OPEN_SQUARE):
82
+ return self.parse_array()
83
+ elif self.match(TokenType.STRING):
84
+ return ast.literal_eval(self.token.value)
85
+ elif self.match(TokenType.NUMBER):
86
+ num = self.token.value
87
+ return float(num) if "." in num else int(num)
88
+ elif self.match(TokenType.KEYWORD):
89
+ return {"null": None, "true": True, "false": False}[self.token.value]
90
+ else:
91
+ raise SyntaxError(f"Unexpected token: {self.token.token_type.name}")
92
+
93
+ def advance(self):
94
+ self.token, self.next_token = (
95
+ self.next_token,
96
+ next(self.token_it, Token(TokenType.EOF, "")),
97
+ )
98
+ # print(f"{self.token =}, {self.next_token =}")
99
+
100
+ def match(self, token_type: TokenType) -> bool:
101
+ if self.next_token.token_type == token_type:
102
+ self.advance()
103
+ return True
104
+ return False
105
+
106
+ def expect(self, token_type: TokenType):
107
+ if not self.match(token_type):
108
+ raise SyntaxError(
109
+ f"Expected {token_type.name}, got {self.next_token.token_type.name}"
110
+ )
111
+
112
+
113
+ def parse_jsonc(s: str) -> Any:
114
+ return JSONCParser().parse(s)
115
+
116
+
117
+ if __name__ == "__main__":
118
+ json_str = """\
119
+ {
120
+ // Это комментарий
121
+ "name": "John",
122
+ "age": 30,
123
+ "scores": [95.5, 88, null],
124
+ "metadata": {
125
+ "active": true,
126
+ /* Многострочный
127
+ комментарий */
128
+ "tags": [ "foo", "bar" ]
129
+ }
130
+ }
131
+ """
132
+ try:
133
+ result = parse_jsonc(json_str)
134
+ import pprint
135
+
136
+ pprint.pprint(result)
137
+ except SyntaxError as e:
138
+ print(f"Syntax error: {e}")
@@ -14,6 +14,7 @@ from threading import Lock
14
14
  from typing import Any
15
15
 
16
16
  from .constants import INVALID_ISO8601_FORMAT
17
+ from .jsonc import parse_jsonc
17
18
 
18
19
  print_err = partial(print, file=sys.stderr, flush=True)
19
20
 
@@ -45,10 +46,7 @@ class Config(dict):
45
46
  if self._config_path.exists():
46
47
  with self._lock:
47
48
  with self._config_path.open("r", encoding="utf-8", errors="replace") as f:
48
- try:
49
- self.update(json.load(f))
50
- except ValueError:
51
- pass
49
+ self.update(json.load(f))
52
50
 
53
51
  def save(self, *args: Any, **kwargs: Any) -> None:
54
52
  self.update(*args, **kwargs)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "hh-applicant-tool"
3
- version = "0.5.5"
3
+ version = "0.5.6"
4
4
  description = ""
5
5
  authors = ["Senior YAML Developer <yamldeveloper@proton.me>"]
6
6
  readme = "README.md"