singer-python 5.14.1__tar.gz → 5.14.2__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.
Files changed (37) hide show
  1. {singer-python-5.14.1/singer_python.egg-info → singer_python-5.14.2}/PKG-INFO +9 -2
  2. {singer-python-5.14.1 → singer_python-5.14.2}/setup.py +1 -1
  3. {singer-python-5.14.1 → singer_python-5.14.2}/singer/schema_generation.py +15 -16
  4. {singer-python-5.14.1 → singer_python-5.14.2}/singer/transform.py +2 -0
  5. {singer-python-5.14.1 → singer_python-5.14.2/singer_python.egg-info}/PKG-INFO +9 -2
  6. {singer-python-5.14.1 → singer_python-5.14.2}/tests/test_schema_generation.py +13 -17
  7. {singer-python-5.14.1 → singer_python-5.14.2}/LICENSE +0 -0
  8. {singer-python-5.14.1 → singer_python-5.14.2}/README.md +0 -0
  9. {singer-python-5.14.1 → singer_python-5.14.2}/setup.cfg +0 -0
  10. {singer-python-5.14.1 → singer_python-5.14.2}/singer/__init__.py +0 -0
  11. {singer-python-5.14.1 → singer_python-5.14.2}/singer/bookmarks.py +0 -0
  12. {singer-python-5.14.1 → singer_python-5.14.2}/singer/catalog.py +0 -0
  13. {singer-python-5.14.1 → singer_python-5.14.2}/singer/exceptions.py +0 -0
  14. {singer-python-5.14.1 → singer_python-5.14.2}/singer/logger.py +0 -0
  15. {singer-python-5.14.1 → singer_python-5.14.2}/singer/logging.conf +0 -0
  16. {singer-python-5.14.1 → singer_python-5.14.2}/singer/messages.py +0 -0
  17. {singer-python-5.14.1 → singer_python-5.14.2}/singer/metadata.py +0 -0
  18. {singer-python-5.14.1 → singer_python-5.14.2}/singer/metrics.py +0 -0
  19. {singer-python-5.14.1 → singer_python-5.14.2}/singer/requests.py +0 -0
  20. {singer-python-5.14.1 → singer_python-5.14.2}/singer/schema.py +0 -0
  21. {singer-python-5.14.1 → singer_python-5.14.2}/singer/statediff.py +0 -0
  22. {singer-python-5.14.1 → singer_python-5.14.2}/singer/utils.py +0 -0
  23. {singer-python-5.14.1 → singer_python-5.14.2}/singer_python.egg-info/SOURCES.txt +0 -0
  24. {singer-python-5.14.1 → singer_python-5.14.2}/singer_python.egg-info/dependency_links.txt +0 -0
  25. {singer-python-5.14.1 → singer_python-5.14.2}/singer_python.egg-info/requires.txt +0 -0
  26. {singer-python-5.14.1 → singer_python-5.14.2}/singer_python.egg-info/top_level.txt +0 -0
  27. {singer-python-5.14.1 → singer_python-5.14.2}/tests/__init__.py +0 -0
  28. {singer-python-5.14.1 → singer_python-5.14.2}/tests/test_bookmarks.py +0 -0
  29. {singer-python-5.14.1 → singer_python-5.14.2}/tests/test_catalog.py +0 -0
  30. {singer-python-5.14.1 → singer_python-5.14.2}/tests/test_exceptions.py +0 -0
  31. {singer-python-5.14.1 → singer_python-5.14.2}/tests/test_metadata.py +0 -0
  32. {singer-python-5.14.1 → singer_python-5.14.2}/tests/test_metrics.py +0 -0
  33. {singer-python-5.14.1 → singer_python-5.14.2}/tests/test_schema.py +0 -0
  34. {singer-python-5.14.1 → singer_python-5.14.2}/tests/test_singer.py +0 -0
  35. {singer-python-5.14.1 → singer_python-5.14.2}/tests/test_statediff.py +0 -0
  36. {singer-python-5.14.1 → singer_python-5.14.2}/tests/test_transform.py +0 -0
  37. {singer-python-5.14.1 → singer_python-5.14.2}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: singer-python
3
- Version: 5.14.1
3
+ Version: 5.14.2
4
4
  Summary: Singer.io utility library
5
5
  Home-page: http://singer.io
6
6
  Author: Stitch
@@ -18,3 +18,10 @@ Requires-Dist: ipython; extra == "dev"
18
18
  Requires-Dist: ipdb; extra == "dev"
19
19
  Requires-Dist: nose; extra == "dev"
20
20
  Requires-Dist: singer-tools; extra == "dev"
21
+ Dynamic: author
22
+ Dynamic: classifier
23
+ Dynamic: home-page
24
+ Dynamic: license-file
25
+ Dynamic: provides-extra
26
+ Dynamic: requires-dist
27
+ Dynamic: summary
@@ -4,7 +4,7 @@ from setuptools import setup, find_packages
4
4
  import subprocess
5
5
 
6
6
  setup(name="singer-python",
7
- version='5.14.1',
7
+ version='5.14.2',
8
8
  description="Singer.io utility library",
9
9
  author="Stitch",
10
10
  classifiers=['Programming Language :: Python :: 3 :: Only'],
@@ -1,6 +1,3 @@
1
- import dateutil.parser
2
-
3
-
4
1
  def add_observation(acc, path):
5
2
 
6
3
  node = acc
@@ -37,13 +34,6 @@ def add_observations(acc, path, data):
37
34
  return acc
38
35
  except (ValueError, TypeError):
39
36
  pass
40
- try:
41
- # If the string parses as a date, add an observation that it's a date
42
- dateutil.parser.parse(data)
43
- add_observation(acc, path + ["date"])
44
- return acc
45
- except (dateutil.parser.ParserError, OverflowError):
46
- pass
47
37
  add_observation(acc, path + ["string"])
48
38
  elif isinstance(data, bool):
49
39
  add_observation(acc, path + ["boolean"])
@@ -59,9 +49,13 @@ def add_observations(acc, path, data):
59
49
  return acc
60
50
 
61
51
  def to_json_schema(obs):
62
- result = {'type': ['null']}
52
+ types = []
53
+ # add schema types in a specific order to anyOf list
54
+ for key in ['array', 'object', 'number', 'integer', 'boolean', 'string', 'null']:
55
+ if key not in obs:
56
+ continue
63
57
 
64
- for key in obs:
58
+ result = {'type': ['null']}
65
59
 
66
60
  if key == 'object':
67
61
  result['type'] += ['object']
@@ -74,9 +68,6 @@ def to_json_schema(obs):
74
68
  result['type'] += ['array']
75
69
  result['items'] = to_json_schema(obs['array'])
76
70
 
77
- elif key == 'date':
78
- result['type'] += ['string']
79
- result['format'] = 'date-time'
80
71
  elif key == 'string':
81
72
  result['type'] += ['string']
82
73
 
@@ -97,7 +88,15 @@ def to_json_schema(obs):
97
88
  else:
98
89
  raise Exception("Unexpected data type " + key)
99
90
 
100
- return result
91
+ types.append(result)
92
+
93
+ if len(types) == 0:
94
+ return {'type': ['null', 'string']}
95
+
96
+ if len(types) == 1:
97
+ return types[0]
98
+
99
+ return {'anyOf': types}
101
100
 
102
101
  def generate_schema(records):
103
102
  obs = {}
@@ -185,6 +185,8 @@ class Transformer:
185
185
  success, transformed_data = self.transform_recur(data, subschema, path)
186
186
  if success:
187
187
  return success, transformed_data
188
+ else:
189
+ self.errors.pop()
188
190
  else: # pylint: disable=useless-else-on-loop
189
191
  # exhaused all schemas and didn't return, so we failed :-(
190
192
  self.errors.append(Error(path, data, schema, logging_level=LOGGER.level))
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: singer-python
3
- Version: 5.14.1
3
+ Version: 5.14.2
4
4
  Summary: Singer.io utility library
5
5
  Home-page: http://singer.io
6
6
  Author: Stitch
@@ -18,3 +18,10 @@ Requires-Dist: ipython; extra == "dev"
18
18
  Requires-Dist: ipdb; extra == "dev"
19
19
  Requires-Dist: nose; extra == "dev"
20
20
  Requires-Dist: singer-tools; extra == "dev"
21
+ Dynamic: author
22
+ Dynamic: classifier
23
+ Dynamic: home-page
24
+ Dynamic: license-file
25
+ Dynamic: provides-extra
26
+ Dynamic: requires-dist
27
+ Dynamic: summary
@@ -10,7 +10,7 @@ class TestSchemaGeneration(unittest.TestCase):
10
10
  'a': {'type': ['null', 'integer']},
11
11
  'b': {'type': ['null', 'string']},
12
12
  'c': {'type': ['null', 'boolean']},
13
- 'dt': {'type': ['null', 'string'], 'format': 'date-time'}
13
+ 'dt': {'type': ['null', 'string']}
14
14
  }
15
15
  }
16
16
  self.assertEqual(expected_schema, generate_schema(records))
@@ -23,24 +23,20 @@ class TestSchemaGeneration(unittest.TestCase):
23
23
  ]
24
24
  expected_schema = {
25
25
  'type': ['null', 'object'],
26
- 'properties': {
27
- 'a': {'type': {'null', 'integer', 'string', 'boolean'}},
28
- 'b': {'type': ['null', 'string']},
29
- 'c': {'type': {'null', 'integer', 'string'}, 'format': 'singer.decimal'},
30
- 'd': {
31
- 'type': {'null', 'array', 'object'},
32
- 'items': {'type': {'null', 'integer', 'string'}},
33
- 'properties': {'one': {'type': ['null', 'integer']},
34
- 'two': {'type': ['null', 'string']}}
35
-
36
- }
37
- }
26
+ 'properties': {'a': {'anyOf': [{'type': ['null', 'integer']},
27
+ {'type': ['null', 'boolean']},
28
+ {'type': ['null', 'string']}]},
29
+ 'b': {'type': ['null', 'string']},
30
+ 'c': {'anyOf': [{'type': ['null', 'string'], 'format': 'singer.decimal'},
31
+ {'type': ['null', 'integer']}]},
32
+ 'd': {'anyOf': [{'type': ['null', 'array'],
33
+ 'items': {'anyOf': [{'type': ['null', 'integer']},
34
+ {'type': ['null', 'string']}]}},
35
+ {'type': ['null', 'object'],
36
+ 'properties': {'one': {'type': ['null', 'integer']},
37
+ 'two': {'type': ['null', 'string']}}}]}}
38
38
  }
39
39
  actual_schema = generate_schema(records)
40
- actual_schema['properties']['a']['type'] = set(actual_schema['properties']['a']['type'])
41
- actual_schema['properties']['c']['type'] = set(actual_schema['properties']['c']['type'])
42
- actual_schema['properties']['d']['type'] = set(actual_schema['properties']['d']['type'])
43
- actual_schema['properties']['d']['items']['type'] = set(actual_schema['properties']['d']['items']['type'])
44
40
  self.assertEqual(expected_schema, actual_schema)
45
41
 
46
42
  def test_nested_structue_schema(self):
File without changes
File without changes
File without changes