syncraft 0.1.34__tar.gz → 0.1.35__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 syncraft might be problematic. Click here for more details.

Files changed (26) hide show
  1. {syncraft-0.1.34 → syncraft-0.1.35}/PKG-INFO +1 -2
  2. {syncraft-0.1.34 → syncraft-0.1.35}/README.md +0 -1
  3. {syncraft-0.1.34 → syncraft-0.1.35}/pyproject.toml +1 -1
  4. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft/algebra.py +7 -5
  5. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft/ast.py +6 -3
  6. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft/constraint.py +2 -1
  7. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft/generator.py +2 -2
  8. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft/syntax.py +2 -1
  9. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft.egg-info/PKG-INFO +1 -2
  10. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft.egg-info/SOURCES.txt +1 -0
  11. syncraft-0.1.35/tests/test_find.py +47 -0
  12. {syncraft-0.1.34 → syncraft-0.1.35}/LICENSE +0 -0
  13. {syncraft-0.1.34 → syncraft-0.1.35}/setup.cfg +0 -0
  14. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft/__init__.py +0 -0
  15. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft/diagnostic.py +0 -0
  16. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft/finder.py +0 -0
  17. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft/parser.py +0 -0
  18. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft/py.typed +0 -0
  19. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft/sqlite3.py +0 -0
  20. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft.egg-info/dependency_links.txt +0 -0
  21. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft.egg-info/requires.txt +0 -0
  22. {syncraft-0.1.34 → syncraft-0.1.35}/syncraft.egg-info/top_level.txt +0 -0
  23. {syncraft-0.1.34 → syncraft-0.1.35}/tests/test_bimap.py +0 -0
  24. {syncraft-0.1.34 → syncraft-0.1.35}/tests/test_parse.py +0 -0
  25. {syncraft-0.1.34 → syncraft-0.1.35}/tests/test_to.py +0 -0
  26. {syncraft-0.1.34 → syncraft-0.1.35}/tests/test_until.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: syncraft
3
- Version: 0.1.34
3
+ Version: 0.1.35
4
4
  Summary: Parser combinator library
5
5
  Author-email: Michael Afmokt <michael@esacca.com>
6
6
  License-Expression: MIT
@@ -29,7 +29,6 @@ pip install syncraft
29
29
 
30
30
 
31
31
  ## TODO
32
- - [ ] convert to dict/dataclass via bimap in syntax
33
32
  - [ ] define DSL over Variable to construct predicates
34
33
  - [ ] Try the parsing, generation, and data processing machinery on SQLite3 syntax. So that I can have direct feedback on the usability of this library and a fully functional SQLite3 library.
35
34
  - [ ] Make the library as fast as possible and feasible.
@@ -14,7 +14,6 @@ pip install syncraft
14
14
 
15
15
 
16
16
  ## TODO
17
- - [ ] convert to dict/dataclass via bimap in syntax
18
17
  - [ ] define DSL over Variable to construct predicates
19
18
  - [ ] Try the parsing, generation, and data processing machinery on SQLite3 syntax. So that I can have direct feedback on the usability of this library and a fully functional SQLite3 library.
20
19
  - [ ] Make the library as fast as possible and feasible.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "syncraft"
3
- version = "0.1.34"
3
+ version = "0.1.35"
4
4
  description = "Parser combinator library"
5
5
  license = "MIT"
6
6
  license-files = ["LICENSE"]
@@ -48,6 +48,7 @@ class Error:
48
48
  error: Optional[Any] = None
49
49
  state: Optional[Any] = None
50
50
  committed: bool = False
51
+ stack: Optional[str] = None
51
52
  previous: Optional[Error] = None
52
53
 
53
54
  def attach( self,
@@ -115,14 +116,15 @@ class Algebra(ABC, Generic[A, S]):
115
116
  result = Left(result.value.attach(this=self, state=input))
116
117
  except Exception as e:
117
118
  cache.pop(input, None) # Clear the cache entry on exception
118
- traceback.print_exc()
119
- print(f"Exception from self.run(S): {e}")
119
+ # traceback.print_exc()
120
+ # print(f"Exception from self.run(S): {e}")
120
121
  return Left(
121
122
  Error(
122
123
  message="Exception from self.run(S): {e}",
123
124
  this=self,
124
125
  state=input,
125
- error=e
126
+ error=e,
127
+ stack=traceback.format_exc()
126
128
  ))
127
129
  return result
128
130
 
@@ -341,8 +343,8 @@ class Algebra(ABC, Generic[A, S]):
341
343
  return self.flat_map(then_right_f).named(f'{self.name} >> {other.name}')
342
344
 
343
345
  def many(self, *, at_least: int, at_most: Optional[int]) -> Algebra[Many[A], S]:
344
- assert at_least > 0, "at_least must be greater than 0"
345
- assert at_most is None or at_least <= at_most, "at_least must be less than or equal to at_most"
346
+ if at_least <=0 or (at_most is not None and at_most < at_least):
347
+ raise ValueError(f"Invalid arguments for many: at_least={at_least}, at_most={at_most}")
346
348
  def many_run(input: S, use_cache:bool) -> Either[Any, Tuple[Many[A], S]]:
347
349
  ret: List[A] = []
348
350
  current_input = input
@@ -14,7 +14,8 @@ from enum import Enum
14
14
 
15
15
 
16
16
  def shallow_dict(a: Any)->Dict[str, Any]:
17
- assert is_dataclass(a), f"Expected dataclass instance for collector inverse, got {type(a)}"
17
+ if not is_dataclass(a):
18
+ raise ValueError(f"Expected dataclass instance for collector inverse, got {type(a)}")
18
19
  return {f.name: getattr(a, f.name) for f in fields(a)}
19
20
 
20
21
 
@@ -300,7 +301,8 @@ class Collect(Generic[A, E], AST):
300
301
  def bimap(self, r: Bimap[A, B]=Bimap.identity()) -> Tuple[B | E, Callable[[B | E], Collect[A, E]]]:
301
302
 
302
303
  def inv_one_positional(e: E) -> B:
303
- assert is_dataclass(e), f"Expected dataclass instance for collector inverse, got {type(e)}"
304
+ if not is_dataclass(e):
305
+ raise ValueError(f"Expected dataclass instance for collector inverse, got {type(e)}")
304
306
  named_dict = shallow_dict(e)
305
307
  return named_dict[fields(e)[0].name]
306
308
 
@@ -319,7 +321,8 @@ class Collect(Generic[A, E], AST):
319
321
  unnamed = [v for v in b if not isinstance(v, Marked)]
320
322
  ret: E = self.collector(*unnamed, **named)
321
323
  def invf(e: E) -> Tuple[Any, ...]:
322
- assert is_dataclass(e), f"Expected dataclass instance for collector inverse, got {type(e)}"
324
+ if not is_dataclass(e):
325
+ raise ValueError(f"Expected dataclass instance for collector inverse, got {type(e)}")
323
326
  named_dict = shallow_dict(e)
324
327
  unnamed = []
325
328
  for f in fields(e):
@@ -55,7 +55,8 @@ class Variable:
55
55
  object.__setattr__(self, '_root', self)
56
56
 
57
57
  def raw(self, b:'BoundVar') -> Tuple[Any, ...]:
58
- assert self._root is not None, "_rawf can not be None"
58
+ if self._root is None:
59
+ raise ValueError("_rawf can not be None")
59
60
  return b.get(self._root, ())
60
61
 
61
62
 
@@ -174,8 +174,8 @@ class Generator(Algebra[ParseResult[T], GenState[T]]):
174
174
 
175
175
 
176
176
  def many(self, *, at_least: int, at_most: Optional[int]) -> Algebra[Many[ParseResult[T]], GenState[T]]:
177
- assert at_least > 0, "at_least must be greater than 0"
178
- assert at_most is None or at_least <= at_most, "at_least must be less than or equal to at_most"
177
+ if at_least <=0 or (at_most is not None and at_most < at_least):
178
+ raise ValueError(f"Invalid arguments for many: at_least={at_least}, at_most={at_most}")
179
179
  def many_run(input: GenState[T], use_cache:bool) -> Either[Any, Tuple[Many[ParseResult[T]], GenState[T]]]:
180
180
  if input.pruned:
181
181
  upper = at_most if at_most is not None else at_least + 2
@@ -178,7 +178,8 @@ class Syntax(Generic[A, S]):
178
178
  raise ValueError(f"Bad data shape {a}")
179
179
 
180
180
  def i(a: Many[A]) -> Then[A, Choice[Many[Then[B|None, A]], Optional[Nothing]]]:
181
- assert len(a.value) >= 1, f"sep_by expect at least one element, got {len(a.value)}. {a}"
181
+ if not isinstance(a, Many) or len(a.value) < 1:
182
+ raise ValueError(f"sep_by inverse expect Many with at least one element, got {a}")
182
183
  if len(a.value) == 1:
183
184
  return Then(kind=ThenKind.BOTH, left=a.value[0], right=Choice(kind=ChoiceKind.RIGHT, value=Nothing()))
184
185
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: syncraft
3
- Version: 0.1.34
3
+ Version: 0.1.35
4
4
  Summary: Parser combinator library
5
5
  Author-email: Michael Afmokt <michael@esacca.com>
6
6
  License-Expression: MIT
@@ -29,7 +29,6 @@ pip install syncraft
29
29
 
30
30
 
31
31
  ## TODO
32
- - [ ] convert to dict/dataclass via bimap in syntax
33
32
  - [ ] define DSL over Variable to construct predicates
34
33
  - [ ] Try the parsing, generation, and data processing machinery on SQLite3 syntax. So that I can have direct feedback on the usability of this library and a fully functional SQLite3 library.
35
34
  - [ ] Make the library as fast as possible and feasible.
@@ -18,6 +18,7 @@ syncraft.egg-info/dependency_links.txt
18
18
  syncraft.egg-info/requires.txt
19
19
  syncraft.egg-info/top_level.txt
20
20
  tests/test_bimap.py
21
+ tests/test_find.py
21
22
  tests/test_parse.py
22
23
  tests/test_to.py
23
24
  tests/test_until.py
@@ -0,0 +1,47 @@
1
+ from __future__ import annotations
2
+ from typing import Any, List, Tuple
3
+ from syncraft.algebra import Either, Left, Right, Error
4
+ from syncraft.ast import Marked, Then, ThenKind, Many, Nothing
5
+ from syncraft.parser import literal, variable, parse, Parser, Token
6
+ from syncraft.generator import TokenGen
7
+ from rich import print
8
+ import syncraft.generator as gen
9
+ from dataclasses import dataclass
10
+ from syncraft.finder import find, matches, anything
11
+
12
+ def test_find()->None:
13
+ @dataclass
14
+ class IfThenElse:
15
+ condition: Any
16
+ then: Any
17
+ otherwise: Any
18
+
19
+ @dataclass
20
+ class While:
21
+ condition:Any
22
+ body:Any
23
+
24
+ WHILE = literal("while")
25
+ IF = literal("if")
26
+ ELSE = literal("else")
27
+ THEN = literal("then")
28
+ END = literal("end")
29
+ A = literal('a')
30
+ B = literal('b')
31
+ C = literal('c')
32
+ D = literal('d')
33
+ M = literal(',')
34
+ var = A | B | C | D
35
+ condition = var.sep_by(M).mark('condition')
36
+ ifthenelse = (IF >> condition
37
+ // THEN
38
+ + var.sep_by(M).mark('then')
39
+ // ELSE
40
+ + var.sep_by(M).mark('otherwise')
41
+ // END).to(IfThenElse).many()
42
+ syntax = (WHILE >> condition
43
+ + ifthenelse.mark('body')
44
+ // ~END).to(While)
45
+ sql = 'while b if a,b then c,d else a,d end if a,b then c,d else a,d end'
46
+ ast = parse(syntax, sql, dialect='sqlite')
47
+ print(ast)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes