@@ -5280,6 +5280,261 @@ def f(**kwargs):
5280
5280
assert next (extract_node (code ).infer ()).as_string () == "{'f': 1}"
5281
5281
5282
5282
5283
+ @pytest .mark .parametrize (
5284
+ "op,result" ,
5285
+ [
5286
+ ("<" , False ),
5287
+ ("<=" , True ),
5288
+ ("==" , True ),
5289
+ (">=" , True ),
5290
+ (">" , False ),
5291
+ ("!=" , False ),
5292
+ ],
5293
+ )
5294
+ def test_compare (op , result ) -> None :
5295
+ code = """
5296
+ 123 {} 123
5297
+ """ .format (
5298
+ op
5299
+ )
5300
+ node = extract_node (code )
5301
+ inferred = next (node .infer ())
5302
+ assert inferred .value == result
5303
+
5304
+
5305
+ @pytest .mark .xfail (reason = "uninferable" )
5306
+ @pytest .mark .parametrize (
5307
+ "op,result" ,
5308
+ [
5309
+ ("is" , True ),
5310
+ ("is not" , False ),
5311
+ ],
5312
+ )
5313
+ def test_compare_identity (op , result ) -> None :
5314
+ code = """
5315
+ obj = object()
5316
+ obj {} obj
5317
+ """ .format (
5318
+ op
5319
+ )
5320
+ node = extract_node (code )
5321
+ inferred = next (node .infer ())
5322
+ assert inferred .value == result
5323
+
5324
+
5325
+ @pytest .mark .parametrize (
5326
+ "op,result" ,
5327
+ [
5328
+ ("in" , True ),
5329
+ ("not in" , False ),
5330
+ ],
5331
+ )
5332
+ def test_compare_membership (op , result ) -> None :
5333
+ code = """
5334
+ 1 {} [1, 2, 3]
5335
+ """ .format (
5336
+ op
5337
+ )
5338
+ node = extract_node (code )
5339
+ inferred = next (node .infer ())
5340
+ assert inferred .value == result
5341
+
5342
+
5343
+ @pytest .mark .parametrize (
5344
+ "lhs,rhs,result" ,
5345
+ [
5346
+ (1 , 1 , True ),
5347
+ (1 , 1.1 , True ),
5348
+ (1.1 , 1 , False ),
5349
+ (1.0 , 1.0 , True ),
5350
+ ("abc" , "def" , True ),
5351
+ ("abc" , "" , False ),
5352
+ ([], [1 ], True ),
5353
+ ((1 , 2 ), (2 , 3 ), True ),
5354
+ ((1 , 0 ), (1 ,), False ),
5355
+ (True , True , True ),
5356
+ (True , False , False ),
5357
+ (False , 1 , True ),
5358
+ (1 + 0j , 2 + 0j , util .Uninferable ),
5359
+ (+ 0.0 , - 0.0 , True ),
5360
+ (0 , "1" , util .Uninferable ),
5361
+ (b"\x00 " , b"\x01 " , True ),
5362
+ ],
5363
+ )
5364
+ def test_compare_lesseq_types (lhs , rhs , result ) -> None :
5365
+ code = """
5366
+ {lhs!r} <= {rhs!r}
5367
+ """ .format (
5368
+ lhs = lhs , rhs = rhs
5369
+ )
5370
+ node = extract_node (code )
5371
+ inferred = next (node .infer ())
5372
+ assert inferred .value == result
5373
+
5374
+
5375
+ def test_compare_chained () -> None :
5376
+ code = """
5377
+ 3 < 5 > 3
5378
+ """
5379
+ node = extract_node (code )
5380
+ inferred = next (node .infer ())
5381
+ assert inferred .value is True
5382
+
5383
+
5384
+ def test_compare_inferred_members () -> None :
5385
+ code = """
5386
+ a = 11
5387
+ b = 13
5388
+ a < b
5389
+ """
5390
+ node = extract_node (code )
5391
+ inferred = next (node .infer ())
5392
+ assert inferred .value is True
5393
+
5394
+
5395
+ def test_compare_instance_members () -> None :
5396
+ code = """
5397
+ class A:
5398
+ value = 123
5399
+ class B:
5400
+ @property
5401
+ def value(self):
5402
+ return 456
5403
+ A().value < B().value
5404
+ """
5405
+ node = extract_node (code )
5406
+ inferred = next (node .infer ())
5407
+ assert inferred .value is True
5408
+
5409
+
5410
+ @pytest .mark .xfail (reason = "unimplemented" )
5411
+ def test_compare_dynamic () -> None :
5412
+ code = """
5413
+ class A:
5414
+ def __le__(self, other):
5415
+ return True
5416
+ A() <= None
5417
+ """
5418
+ node = extract_node (code )
5419
+ inferred = next (node .infer ())
5420
+ assert inferred .value is True
5421
+
5422
+
5423
+ def test_compare_uninferable_member () -> None :
5424
+ code = """
5425
+ from unknown import UNKNOWN
5426
+ 0 <= UNKNOWN
5427
+ """
5428
+ node = extract_node (code )
5429
+ inferred = next (node .infer ())
5430
+ assert inferred is util .Uninferable
5431
+
5432
+
5433
+ def test_compare_chained_comparisons_shortcircuit_on_false () -> None :
5434
+ code = """
5435
+ from unknown import UNKNOWN
5436
+ 2 < 1 < UNKNOWN
5437
+ """
5438
+ node = extract_node (code )
5439
+ inferred = next (node .infer ())
5440
+ assert inferred .value is False
5441
+
5442
+
5443
+ def test_compare_chained_comparisons_continue_on_true () -> None :
5444
+ code = """
5445
+ from unknown import UNKNOWN
5446
+ 1 < 2 < UNKNOWN
5447
+ """
5448
+ node = extract_node (code )
5449
+ inferred = next (node .infer ())
5450
+ assert inferred is util .Uninferable
5451
+
5452
+
5453
+ @pytest .mark .xfail (reason = "unimplemented" )
5454
+ def test_compare_known_false_branch () -> None :
5455
+ code = """
5456
+ a = 'hello'
5457
+ if 1 < 2:
5458
+ a = 'goodbye'
5459
+ a
5460
+ """
5461
+ node = extract_node (code )
5462
+ inferred = list (node .infer ())
5463
+ assert len (inferred ) == 1
5464
+ assert isinstance (inferred [0 ], nodes .Const )
5465
+ assert inferred [0 ].value == "hello"
5466
+
5467
+
5468
+ def test_compare_ifexp_constant () -> None :
5469
+ code = """
5470
+ a = 'hello' if 1 < 2 else 'goodbye'
5471
+ a
5472
+ """
5473
+ node = extract_node (code )
5474
+ inferred = list (node .infer ())
5475
+ assert len (inferred ) == 1
5476
+ assert isinstance (inferred [0 ], nodes .Const )
5477
+ assert inferred [0 ].value == "hello"
5478
+
5479
+
5480
+ def test_compare_typeerror () -> None :
5481
+ code = """
5482
+ 123 <= "abc"
5483
+ """
5484
+ node = extract_node (code )
5485
+ inferred = list (node .infer ())
5486
+ assert len (inferred ) == 1
5487
+ assert inferred [0 ] is util .Uninferable
5488
+
5489
+
5490
+ def test_compare_multiple_possibilites () -> None :
5491
+ code = """
5492
+ from unknown import UNKNOWN
5493
+ a = 1
5494
+ if UNKNOWN:
5495
+ a = 2
5496
+ b = 3
5497
+ if UNKNOWN:
5498
+ b = 4
5499
+ a < b
5500
+ """
5501
+ node = extract_node (code )
5502
+ inferred = list (node .infer ())
5503
+ assert len (inferred ) == 1
5504
+ # All possible combinations are true: (1 < 3), (1 < 4), (2 < 3), (2 < 4)
5505
+ assert inferred [0 ].value is True
5506
+
5507
+
5508
+ def test_compare_ambiguous_multiple_possibilites () -> None :
5509
+ code = """
5510
+ from unknown import UNKNOWN
5511
+ a = 1
5512
+ if UNKNOWN:
5513
+ a = 3
5514
+ b = 2
5515
+ if UNKNOWN:
5516
+ b = 4
5517
+ a < b
5518
+ """
5519
+ node = extract_node (code )
5520
+ inferred = list (node .infer ())
5521
+ assert len (inferred ) == 1
5522
+ # Not all possible combinations are true: (1 < 2), (1 < 4), (3 !< 2), (3 < 4)
5523
+ assert inferred [0 ] is util .Uninferable
5524
+
5525
+
5526
+ def test_compare_nonliteral () -> None :
5527
+ code = """
5528
+ def func(a, b):
5529
+ return (a, b) <= (1, 2) #@
5530
+ """
5531
+ return_node = extract_node (code )
5532
+ node = return_node .value
5533
+ inferred = list (node .infer ()) # should not raise ValueError
5534
+ assert len (inferred ) == 1
5535
+ assert inferred [0 ] is util .Uninferable
5536
+
5537
+
5283
5538
def test_limit_inference_result_amount () -> None :
5284
5539
"""Test setting limit inference result amount"""
5285
5540
code = """
@@ -5560,7 +5815,7 @@ def method(self):
5560
5815
""" ,
5561
5816
],
5562
5817
)
5563
- def test_subclass_of_exception (code ):
5818
+ def test_subclass_of_exception (code ) -> None :
5564
5819
inferred = next (extract_node (code ).infer ())
5565
5820
assert isinstance (inferred , Instance )
5566
5821
args = next (inferred .igetattr ("args" ))
@@ -5721,7 +5976,7 @@ def test(self):
5721
5976
),
5722
5977
],
5723
5978
)
5724
- def test_inference_is_limited_to_the_boundnode (code , instance_name ):
5979
+ def test_inference_is_limited_to_the_boundnode (code , instance_name ) -> None :
5725
5980
node = extract_node (code )
5726
5981
inferred = next (node .infer ())
5727
5982
assert isinstance (inferred , Instance )
0 commit comments