jsonpointer 3.2.1__tar.gz → 3.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jsonpointer
3
- Version: 3.2.1
3
+ Version: 3.3
4
4
  Summary: Identify specific nodes in a JSON document (RFC 6901)
5
5
  Home-page: https://github.com/stefankoegl/python-json-pointer
6
6
  Author: Stefan Kögl
@@ -27,6 +27,8 @@ parser.add_argument('FILE', type=str, nargs='+',
27
27
  help='Files for which the pointer should be resolved')
28
28
  parser.add_argument('--indent', type=int, default=None,
29
29
  help='Indent output by n spaces')
30
+ parser.add_argument('--continue-on-error', action='store_true',
31
+ help='Continue with remaining files after JSON or text decoding errors')
30
32
  parser.add_argument('-v', '--version', action='version',
31
33
  version='%(prog)s ' + jsonpointer.__version__)
32
34
 
@@ -77,8 +79,8 @@ def parse_pointer(args):
77
79
  def resolve_files():
78
80
  """ Resolve a JSON pointer on JSON files
79
81
 
80
- Returns False if the pointer could not be resolved on at least one
81
- file. """
82
+ Returns False if the pointer could not be resolved on at least one file,
83
+ or if --continue-on-error skipped a JSON or text decoding error. """
82
84
  args = parser.parse_args()
83
85
 
84
86
  ptr, files = parse_pointer(args)
@@ -90,7 +92,16 @@ def resolve_files():
90
92
  except argparse.ArgumentTypeError as e:
91
93
  parser.error(str(e))
92
94
 
93
- doc = json.load(f)
95
+ try:
96
+ doc = json.load(f)
97
+ except (json.JSONDecodeError, UnicodeDecodeError) as e:
98
+ if not args.continue_on_error:
99
+ raise
100
+ print('Could not parse JSON in %r: %s' % (name, e),
101
+ file=sys.stderr)
102
+ ok = False
103
+ continue
104
+
94
105
  try:
95
106
  result = jsonpointer.resolve_pointer(doc, ptr)
96
107
  print(json.dumps(result, indent=args.indent))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jsonpointer
3
- Version: 3.2.1
3
+ Version: 3.3
4
4
  Summary: Identify specific nodes in a JSON document (RFC 6901)
5
5
  Home-page: https://github.com/stefankoegl/python-json-pointer
6
6
  Author: Stefan Kögl
@@ -32,7 +32,7 @@
32
32
 
33
33
  # Will be parsed by setup.py to determine package metadata
34
34
  __author__ = 'Stefan Kögl <stefan@skoegl.net>'
35
- __version__ = '3.2.1'
35
+ __version__ = '3.3'
36
36
  __website__ = 'https://github.com/stefankoegl/python-json-pointer'
37
37
  __license__ = 'Modified BSD License'
38
38
 
@@ -307,7 +307,7 @@ class JsonPointer:
307
307
  suffix_parts = suffix
308
308
  try:
309
309
  return self.__class__.from_parts(chain(self.parts, suffix_parts))
310
- except: # noqa E722
310
+ except Exception:
311
311
  raise JsonPointerException("Invalid suffix")
312
312
 
313
313
  def __truediv__(self, suffix):
@@ -196,6 +196,19 @@ class ComparisonTests(unittest.TestCase):
196
196
  ptr12e = self.ptr1 / ["a", "b"]
197
197
  self.assertEqual(ptr12e.path, "/a/b/c/a/b")
198
198
 
199
+ def test_join_preserves_control_flow_exceptions(self):
200
+ for exception_type in (KeyboardInterrupt, SystemExit, GeneratorExit):
201
+ with self.subTest(exception_type=exception_type):
202
+ error = exception_type()
203
+
204
+ def parts():
205
+ yield 'valid'
206
+ raise error
207
+
208
+ with self.assertRaises(exception_type) as caught:
209
+ self.ptr1.join(parts())
210
+ self.assertIs(caught.exception, error)
211
+
199
212
  def test_join_subclass(self):
200
213
  class Pointer(JsonPointer):
201
214
  pass
@@ -494,7 +507,7 @@ class CommandLineTests(unittest.TestCase):
494
507
  f.write(content)
495
508
 
496
509
  def _run(self, *args):
497
- env = dict(os.environ, PYTHONPATH=self.ROOT)
510
+ env = dict(os.environ, PYTHONPATH=self.ROOT, PYTHONUTF8='1')
498
511
  return subprocess.run([sys.executable, self.SCRIPT] + list(args),
499
512
  cwd=self.dir, env=env, capture_output=True,
500
513
  text=True)
@@ -571,6 +584,92 @@ class CommandLineTests(unittest.TestCase):
571
584
  self.assertIn('Could not resolve pointer', proc.stderr)
572
585
  self.assertEqual(proc.stdout, '1\n')
573
586
 
587
+ def test_invalid_json(self):
588
+ for content in ('', '{"a": }', '{"a": 1}\n{"a": 2}'):
589
+ with self.subTest(content=content):
590
+ self._write('invalid.json', content)
591
+ proc = self._run('--continue-on-error', '/a', 'invalid.json')
592
+ self.assertEqual(proc.returncode, 1)
593
+ self.assertEqual(proc.stdout, '')
594
+ self.assertIn("Could not parse JSON in 'invalid.json':",
595
+ proc.stderr)
596
+ self.assertIn('line ', proc.stderr)
597
+ self.assertNotIn('Traceback', proc.stderr)
598
+
599
+ def test_invalid_json_in_one_file(self):
600
+ self._write('invalid.json', '{"a": }')
601
+ for index in range(3):
602
+ with self.subTest(index=index):
603
+ files = ['a.json', 'b.json']
604
+ files.insert(index, 'invalid.json')
605
+ proc = self._run('--continue-on-error', '/a', *files)
606
+ self.assertEqual(proc.returncode, 1)
607
+ self.assertEqual(proc.stdout, self.A_OUT + self.B_OUT)
608
+ self.assertIn("Could not parse JSON in 'invalid.json':",
609
+ proc.stderr)
610
+ self.assertNotIn('Traceback', proc.stderr)
611
+
612
+ def test_invalid_json_and_unresolvable_pointer(self):
613
+ self._write('invalid.json', '{"a": }')
614
+ proc = self._run('--continue-on-error', '/b',
615
+ 'invalid.json', 'a.json', 'b.json')
616
+ self.assertEqual(proc.returncode, 1)
617
+ self.assertEqual(proc.stdout, '1\n')
618
+ self.assertIn("Could not parse JSON in 'invalid.json':", proc.stderr)
619
+ self.assertIn('Could not resolve pointer:', proc.stderr)
620
+ self.assertNotIn('Traceback', proc.stderr)
621
+
622
+ def test_invalid_json_stops_without_continue_on_error(self):
623
+ self._write('invalid.json', '{"a": }')
624
+ for index in range(3):
625
+ with self.subTest(index=index):
626
+ files = ['a.json', 'b.json']
627
+ files.insert(index, 'invalid.json')
628
+ proc = self._run('/a', *files)
629
+ self.assertEqual(proc.returncode, 1)
630
+ self.assertEqual(proc.stdout,
631
+ ''.join([self.A_OUT, self.B_OUT][:index]))
632
+ self.assertIn('JSONDecodeError', proc.stderr)
633
+
634
+ def test_invalid_encoding_in_one_file(self):
635
+ with open(os.path.join(self.dir, 'invalid.json'), 'wb') as f:
636
+ f.write(b'{"a":"\xff"}')
637
+ for index in range(3):
638
+ with self.subTest(index=index):
639
+ files = ['a.json', 'b.json']
640
+ files.insert(index, 'invalid.json')
641
+ proc = self._run('--continue-on-error', '/a', *files)
642
+ self.assertEqual(proc.returncode, 1)
643
+ self.assertEqual(proc.stdout, self.A_OUT + self.B_OUT)
644
+ self.assertIn("Could not parse JSON in 'invalid.json':",
645
+ proc.stderr)
646
+ self.assertIn('decode', proc.stderr)
647
+ self.assertNotIn('Traceback', proc.stderr)
648
+
649
+ def test_invalid_encoding_stops_without_continue_on_error(self):
650
+ with open(os.path.join(self.dir, 'invalid.json'), 'wb') as f:
651
+ f.write(b'{"a":"\xff"}')
652
+ proc = self._run('/a', 'a.json', 'invalid.json', 'b.json')
653
+ self.assertEqual(proc.returncode, 1)
654
+ self.assertEqual(proc.stdout, self.A_OUT)
655
+ self.assertIn('UnicodeDecodeError', proc.stderr)
656
+
657
+ def test_continue_on_error_with_valid_files(self):
658
+ for pointer in (['/a'], ['-p', '/a'], ['-f', 'ptr.txt']):
659
+ with self.subTest(pointer=pointer):
660
+ proc = self._run('--continue-on-error', *pointer,
661
+ 'a.json', 'b.json')
662
+ self.assertEqual(proc.returncode, 0, proc.stderr)
663
+ self.assertEqual(proc.stdout, self.A_OUT + self.B_OUT)
664
+ self.assertEqual(proc.stderr, '')
665
+
666
+ def test_continue_on_error_does_not_skip_missing_files(self):
667
+ proc = self._run('--continue-on-error', '/a',
668
+ 'a.json', 'missing.json', 'b.json')
669
+ self.assertEqual(proc.returncode, 2)
670
+ self.assertEqual(proc.stdout, self.A_OUT)
671
+ self.assertIn('missing.json', proc.stderr)
672
+
574
673
  def test_pointer_file_requires_value(self):
575
674
  proc = self._run('-f', '-p', '/a', 'a.json')
576
675
  self.assertEqual(proc.returncode, 2)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes