test_scope.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  1. import unittest
  2. import weakref
  3. from test.support import check_syntax_error, cpython_only
  4. from test.support import gc_collect
  5. class ScopeTests(unittest.TestCase):
  6. def testSimpleNesting(self):
  7. def make_adder(x):
  8. def adder(y):
  9. return x + y
  10. return adder
  11. inc = make_adder(1)
  12. plus10 = make_adder(10)
  13. self.assertEqual(inc(1), 2)
  14. self.assertEqual(plus10(-2), 8)
  15. def testExtraNesting(self):
  16. def make_adder2(x):
  17. def extra(): # check freevars passing through non-use scopes
  18. def adder(y):
  19. return x + y
  20. return adder
  21. return extra()
  22. inc = make_adder2(1)
  23. plus10 = make_adder2(10)
  24. self.assertEqual(inc(1), 2)
  25. self.assertEqual(plus10(-2), 8)
  26. def testSimpleAndRebinding(self):
  27. def make_adder3(x):
  28. def adder(y):
  29. return x + y
  30. x = x + 1 # check tracking of assignment to x in defining scope
  31. return adder
  32. inc = make_adder3(0)
  33. plus10 = make_adder3(9)
  34. self.assertEqual(inc(1), 2)
  35. self.assertEqual(plus10(-2), 8)
  36. def testNestingGlobalNoFree(self):
  37. def make_adder4(): # XXX add exta level of indirection
  38. def nest():
  39. def nest():
  40. def adder(y):
  41. return global_x + y # check that plain old globals work
  42. return adder
  43. return nest()
  44. return nest()
  45. global_x = 1
  46. adder = make_adder4()
  47. self.assertEqual(adder(1), 2)
  48. global_x = 10
  49. self.assertEqual(adder(-2), 8)
  50. def testNestingThroughClass(self):
  51. def make_adder5(x):
  52. class Adder:
  53. def __call__(self, y):
  54. return x + y
  55. return Adder()
  56. inc = make_adder5(1)
  57. plus10 = make_adder5(10)
  58. self.assertEqual(inc(1), 2)
  59. self.assertEqual(plus10(-2), 8)
  60. def testNestingPlusFreeRefToGlobal(self):
  61. def make_adder6(x):
  62. global global_nest_x
  63. def adder(y):
  64. return global_nest_x + y
  65. global_nest_x = x
  66. return adder
  67. inc = make_adder6(1)
  68. plus10 = make_adder6(10)
  69. self.assertEqual(inc(1), 11) # there's only one global
  70. self.assertEqual(plus10(-2), 8)
  71. def testNearestEnclosingScope(self):
  72. def f(x):
  73. def g(y):
  74. x = 42 # check that this masks binding in f()
  75. def h(z):
  76. return x + z
  77. return h
  78. return g(2)
  79. test_func = f(10)
  80. self.assertEqual(test_func(5), 47)
  81. def testMixedFreevarsAndCellvars(self):
  82. def identity(x):
  83. return x
  84. def f(x, y, z):
  85. def g(a, b, c):
  86. a = a + x # 3
  87. def h():
  88. # z * (4 + 9)
  89. # 3 * 13
  90. return identity(z * (b + y))
  91. y = c + z # 9
  92. return h
  93. return g
  94. g = f(1, 2, 3)
  95. h = g(2, 4, 6)
  96. self.assertEqual(h(), 39)
  97. def testFreeVarInMethod(self):
  98. def test():
  99. method_and_var = "var"
  100. class Test:
  101. def method_and_var(self):
  102. return "method"
  103. def test(self):
  104. return method_and_var
  105. def actual_global(self):
  106. return str("global")
  107. def str(self):
  108. return str(self)
  109. return Test()
  110. t = test()
  111. self.assertEqual(t.test(), "var")
  112. self.assertEqual(t.method_and_var(), "method")
  113. self.assertEqual(t.actual_global(), "global")
  114. method_and_var = "var"
  115. class Test:
  116. # this class is not nested, so the rules are different
  117. def method_and_var(self):
  118. return "method"
  119. def test(self):
  120. return method_and_var
  121. def actual_global(self):
  122. return str("global")
  123. def str(self):
  124. return str(self)
  125. t = Test()
  126. self.assertEqual(t.test(), "var")
  127. self.assertEqual(t.method_and_var(), "method")
  128. self.assertEqual(t.actual_global(), "global")
  129. def testCellIsKwonlyArg(self):
  130. # Issue 1409: Initialisation of a cell value,
  131. # when it comes from a keyword-only parameter
  132. def foo(*, a=17):
  133. def bar():
  134. return a + 5
  135. return bar() + 3
  136. self.assertEqual(foo(a=42), 50)
  137. self.assertEqual(foo(), 25)
  138. def testCellIsArgAndEscapes(self):
  139. # We need to be sure that a cell passed in as an arg still
  140. # gets wrapped in a new cell if the arg escapes into an
  141. # inner function (closure).
  142. def external():
  143. value = 42
  144. def inner():
  145. return value
  146. cell, = inner.__closure__
  147. return cell
  148. cell_ext = external()
  149. def spam(arg):
  150. def eggs():
  151. return arg
  152. return eggs
  153. eggs = spam(cell_ext)
  154. cell_closure, = eggs.__closure__
  155. cell_eggs = eggs()
  156. self.assertIs(cell_eggs, cell_ext)
  157. self.assertIsNot(cell_eggs, cell_closure)
  158. def testCellIsLocalAndEscapes(self):
  159. # We need to be sure that a cell bound to a local still
  160. # gets wrapped in a new cell if the local escapes into an
  161. # inner function (closure).
  162. def external():
  163. value = 42
  164. def inner():
  165. return value
  166. cell, = inner.__closure__
  167. return cell
  168. cell_ext = external()
  169. def spam(arg):
  170. cell = arg
  171. def eggs():
  172. return cell
  173. return eggs
  174. eggs = spam(cell_ext)
  175. cell_closure, = eggs.__closure__
  176. cell_eggs = eggs()
  177. self.assertIs(cell_eggs, cell_ext)
  178. self.assertIsNot(cell_eggs, cell_closure)
  179. def testRecursion(self):
  180. def f(x):
  181. def fact(n):
  182. if n == 0:
  183. return 1
  184. else:
  185. return n * fact(n - 1)
  186. if x >= 0:
  187. return fact(x)
  188. else:
  189. raise ValueError("x must be >= 0")
  190. self.assertEqual(f(6), 720)
  191. def testUnoptimizedNamespaces(self):
  192. check_syntax_error(self, """if 1:
  193. def unoptimized_clash1(strip):
  194. def f(s):
  195. from sys import *
  196. return getrefcount(s) # ambiguity: free or local
  197. return f
  198. """)
  199. check_syntax_error(self, """if 1:
  200. def unoptimized_clash2():
  201. from sys import *
  202. def f(s):
  203. return getrefcount(s) # ambiguity: global or local
  204. return f
  205. """)
  206. check_syntax_error(self, """if 1:
  207. def unoptimized_clash2():
  208. from sys import *
  209. def g():
  210. def f(s):
  211. return getrefcount(s) # ambiguity: global or local
  212. return f
  213. """)
  214. check_syntax_error(self, """if 1:
  215. def f():
  216. def g():
  217. from sys import *
  218. return getrefcount # global or local?
  219. """)
  220. def testLambdas(self):
  221. f1 = lambda x: lambda y: x + y
  222. inc = f1(1)
  223. plus10 = f1(10)
  224. self.assertEqual(inc(1), 2)
  225. self.assertEqual(plus10(5), 15)
  226. f2 = lambda x: (lambda : lambda y: x + y)()
  227. inc = f2(1)
  228. plus10 = f2(10)
  229. self.assertEqual(inc(1), 2)
  230. self.assertEqual(plus10(5), 15)
  231. f3 = lambda x: lambda y: global_x + y
  232. global_x = 1
  233. inc = f3(None)
  234. self.assertEqual(inc(2), 3)
  235. f8 = lambda x, y, z: lambda a, b, c: lambda : z * (b + y)
  236. g = f8(1, 2, 3)
  237. h = g(2, 4, 6)
  238. self.assertEqual(h(), 18)
  239. def testUnboundLocal(self):
  240. def errorInOuter():
  241. print(y)
  242. def inner():
  243. return y
  244. y = 1
  245. def errorInInner():
  246. def inner():
  247. return y
  248. inner()
  249. y = 1
  250. self.assertRaises(UnboundLocalError, errorInOuter)
  251. self.assertRaises(NameError, errorInInner)
  252. def testUnboundLocal_AfterDel(self):
  253. # #4617: It is now legal to delete a cell variable.
  254. # The following functions must obviously compile,
  255. # and give the correct error when accessing the deleted name.
  256. def errorInOuter():
  257. y = 1
  258. del y
  259. print(y)
  260. def inner():
  261. return y
  262. def errorInInner():
  263. def inner():
  264. return y
  265. y = 1
  266. del y
  267. inner()
  268. self.assertRaises(UnboundLocalError, errorInOuter)
  269. self.assertRaises(NameError, errorInInner)
  270. def testUnboundLocal_AugAssign(self):
  271. # test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation
  272. exec("""if 1:
  273. global_x = 1
  274. def f():
  275. global_x += 1
  276. try:
  277. f()
  278. except UnboundLocalError:
  279. pass
  280. else:
  281. fail('scope of global_x not correctly determined')
  282. """, {'fail': self.fail})
  283. def testComplexDefinitions(self):
  284. def makeReturner(*lst):
  285. def returner():
  286. return lst
  287. return returner
  288. self.assertEqual(makeReturner(1,2,3)(), (1,2,3))
  289. def makeReturner2(**kwargs):
  290. def returner():
  291. return kwargs
  292. return returner
  293. self.assertEqual(makeReturner2(a=11)()['a'], 11)
  294. def testScopeOfGlobalStmt(self):
  295. # Examples posted by Samuele Pedroni to python-dev on 3/1/2001
  296. exec("""if 1:
  297. # I
  298. x = 7
  299. def f():
  300. x = 1
  301. def g():
  302. global x
  303. def i():
  304. def h():
  305. return x
  306. return h()
  307. return i()
  308. return g()
  309. self.assertEqual(f(), 7)
  310. self.assertEqual(x, 7)
  311. # II
  312. x = 7
  313. def f():
  314. x = 1
  315. def g():
  316. x = 2
  317. def i():
  318. def h():
  319. return x
  320. return h()
  321. return i()
  322. return g()
  323. self.assertEqual(f(), 2)
  324. self.assertEqual(x, 7)
  325. # III
  326. x = 7
  327. def f():
  328. x = 1
  329. def g():
  330. global x
  331. x = 2
  332. def i():
  333. def h():
  334. return x
  335. return h()
  336. return i()
  337. return g()
  338. self.assertEqual(f(), 2)
  339. self.assertEqual(x, 2)
  340. # IV
  341. x = 7
  342. def f():
  343. x = 3
  344. def g():
  345. global x
  346. x = 2
  347. def i():
  348. def h():
  349. return x
  350. return h()
  351. return i()
  352. return g()
  353. self.assertEqual(f(), 2)
  354. self.assertEqual(x, 2)
  355. # XXX what about global statements in class blocks?
  356. # do they affect methods?
  357. x = 12
  358. class Global:
  359. global x
  360. x = 13
  361. def set(self, val):
  362. x = val
  363. def get(self):
  364. return x
  365. g = Global()
  366. self.assertEqual(g.get(), 13)
  367. g.set(15)
  368. self.assertEqual(g.get(), 13)
  369. """)
  370. def testLeaks(self):
  371. class Foo:
  372. count = 0
  373. def __init__(self):
  374. Foo.count += 1
  375. def __del__(self):
  376. Foo.count -= 1
  377. def f1():
  378. x = Foo()
  379. def f2():
  380. return x
  381. f2()
  382. for i in range(100):
  383. f1()
  384. gc_collect() # For PyPy or other GCs.
  385. self.assertEqual(Foo.count, 0)
  386. def testClassAndGlobal(self):
  387. exec("""if 1:
  388. def test(x):
  389. class Foo:
  390. global x
  391. def __call__(self, y):
  392. return x + y
  393. return Foo()
  394. x = 0
  395. self.assertEqual(test(6)(2), 8)
  396. x = -1
  397. self.assertEqual(test(3)(2), 5)
  398. looked_up_by_load_name = False
  399. class X:
  400. # Implicit globals inside classes are be looked up by LOAD_NAME, not
  401. # LOAD_GLOBAL.
  402. locals()['looked_up_by_load_name'] = True
  403. passed = looked_up_by_load_name
  404. self.assertTrue(X.passed)
  405. """)
  406. def testLocalsFunction(self):
  407. def f(x):
  408. def g(y):
  409. def h(z):
  410. return y + z
  411. w = x + y
  412. y += 3
  413. return locals()
  414. return g
  415. d = f(2)(4)
  416. self.assertIn('h', d)
  417. del d['h']
  418. self.assertEqual(d, {'x': 2, 'y': 7, 'w': 6})
  419. def testLocalsClass(self):
  420. # This test verifies that calling locals() does not pollute
  421. # the local namespace of the class with free variables. Old
  422. # versions of Python had a bug, where a free variable being
  423. # passed through a class namespace would be inserted into
  424. # locals() by locals() or exec or a trace function.
  425. #
  426. # The real bug lies in frame code that copies variables
  427. # between fast locals and the locals dict, e.g. when executing
  428. # a trace function.
  429. def f(x):
  430. class C:
  431. x = 12
  432. def m(self):
  433. return x
  434. locals()
  435. return C
  436. self.assertEqual(f(1).x, 12)
  437. def f(x):
  438. class C:
  439. y = x
  440. def m(self):
  441. return x
  442. z = list(locals())
  443. return C
  444. varnames = f(1).z
  445. self.assertNotIn("x", varnames)
  446. self.assertIn("y", varnames)
  447. @cpython_only
  448. def testLocalsClass_WithTrace(self):
  449. # Issue23728: after the trace function returns, the locals()
  450. # dictionary is used to update all variables, this used to
  451. # include free variables. But in class statements, free
  452. # variables are not inserted...
  453. import sys
  454. self.addCleanup(sys.settrace, sys.gettrace())
  455. sys.settrace(lambda a,b,c:None)
  456. x = 12
  457. class C:
  458. def f(self):
  459. return x
  460. self.assertEqual(x, 12) # Used to raise UnboundLocalError
  461. def testBoundAndFree(self):
  462. # var is bound and free in class
  463. def f(x):
  464. class C:
  465. def m(self):
  466. return x
  467. a = x
  468. return C
  469. inst = f(3)()
  470. self.assertEqual(inst.a, inst.m())
  471. @cpython_only
  472. def testInteractionWithTraceFunc(self):
  473. import sys
  474. def tracer(a,b,c):
  475. return tracer
  476. def adaptgetter(name, klass, getter):
  477. kind, des = getter
  478. if kind == 1: # AV happens when stepping from this line to next
  479. if des == "":
  480. des = "_%s__%s" % (klass.__name__, name)
  481. return lambda obj: getattr(obj, des)
  482. class TestClass:
  483. pass
  484. self.addCleanup(sys.settrace, sys.gettrace())
  485. sys.settrace(tracer)
  486. adaptgetter("foo", TestClass, (1, ""))
  487. sys.settrace(None)
  488. self.assertRaises(TypeError, sys.settrace)
  489. def testEvalExecFreeVars(self):
  490. def f(x):
  491. return lambda: x + 1
  492. g = f(3)
  493. self.assertRaises(TypeError, eval, g.__code__)
  494. try:
  495. exec(g.__code__, {})
  496. except TypeError:
  497. pass
  498. else:
  499. self.fail("exec should have failed, because code contained free vars")
  500. def testListCompLocalVars(self):
  501. try:
  502. print(bad)
  503. except NameError:
  504. pass
  505. else:
  506. print("bad should not be defined")
  507. def x():
  508. [bad for s in 'a b' for bad in s.split()]
  509. x()
  510. try:
  511. print(bad)
  512. except NameError:
  513. pass
  514. def testEvalFreeVars(self):
  515. def f(x):
  516. def g():
  517. x
  518. eval("x + 1")
  519. return g
  520. f(4)()
  521. def testFreeingCell(self):
  522. # Test what happens when a finalizer accesses
  523. # the cell where the object was stored.
  524. class Special:
  525. def __del__(self):
  526. nestedcell_get()
  527. def testNonLocalFunction(self):
  528. def f(x):
  529. def inc():
  530. nonlocal x
  531. x += 1
  532. return x
  533. def dec():
  534. nonlocal x
  535. x -= 1
  536. return x
  537. return inc, dec
  538. inc, dec = f(0)
  539. self.assertEqual(inc(), 1)
  540. self.assertEqual(inc(), 2)
  541. self.assertEqual(dec(), 1)
  542. self.assertEqual(dec(), 0)
  543. def testNonLocalMethod(self):
  544. def f(x):
  545. class c:
  546. def inc(self):
  547. nonlocal x
  548. x += 1
  549. return x
  550. def dec(self):
  551. nonlocal x
  552. x -= 1
  553. return x
  554. return c()
  555. c = f(0)
  556. self.assertEqual(c.inc(), 1)
  557. self.assertEqual(c.inc(), 2)
  558. self.assertEqual(c.dec(), 1)
  559. self.assertEqual(c.dec(), 0)
  560. def testGlobalInParallelNestedFunctions(self):
  561. # A symbol table bug leaked the global statement from one
  562. # function to other nested functions in the same block.
  563. # This test verifies that a global statement in the first
  564. # function does not affect the second function.
  565. local_ns = {}
  566. global_ns = {}
  567. exec("""if 1:
  568. def f():
  569. y = 1
  570. def g():
  571. global y
  572. return y
  573. def h():
  574. return y + 1
  575. return g, h
  576. y = 9
  577. g, h = f()
  578. result9 = g()
  579. result2 = h()
  580. """, local_ns, global_ns)
  581. self.assertEqual(2, global_ns["result2"])
  582. self.assertEqual(9, global_ns["result9"])
  583. def testNonLocalClass(self):
  584. def f(x):
  585. class c:
  586. nonlocal x
  587. x += 1
  588. def get(self):
  589. return x
  590. return c()
  591. c = f(0)
  592. self.assertEqual(c.get(), 1)
  593. self.assertNotIn("x", c.__class__.__dict__)
  594. def testNonLocalGenerator(self):
  595. def f(x):
  596. def g(y):
  597. nonlocal x
  598. for i in range(y):
  599. x += 1
  600. yield x
  601. return g
  602. g = f(0)
  603. self.assertEqual(list(g(5)), [1, 2, 3, 4, 5])
  604. def testNestedNonLocal(self):
  605. def f(x):
  606. def g():
  607. nonlocal x
  608. x -= 2
  609. def h():
  610. nonlocal x
  611. x += 4
  612. return x
  613. return h
  614. return g
  615. g = f(1)
  616. h = g()
  617. self.assertEqual(h(), 3)
  618. def testTopIsNotSignificant(self):
  619. # See #9997.
  620. def top(a):
  621. pass
  622. def b():
  623. global a
  624. def testClassNamespaceOverridesClosure(self):
  625. # See #17853.
  626. x = 42
  627. class X:
  628. locals()["x"] = 43
  629. y = x
  630. self.assertEqual(X.y, 43)
  631. class X:
  632. locals()["x"] = 43
  633. del x
  634. self.assertFalse(hasattr(X, "x"))
  635. self.assertEqual(x, 42)
  636. @cpython_only
  637. def testCellLeak(self):
  638. # Issue 17927.
  639. #
  640. # The issue was that if self was part of a cycle involving the
  641. # frame of a method call, *and* the method contained a nested
  642. # function referencing self, thereby forcing 'self' into a
  643. # cell, setting self to None would not be enough to break the
  644. # frame -- the frame had another reference to the instance,
  645. # which could not be cleared by the code running in the frame
  646. # (though it will be cleared when the frame is collected).
  647. # Without the lambda, setting self to None is enough to break
  648. # the cycle.
  649. class Tester:
  650. def dig(self):
  651. if 0:
  652. lambda: self
  653. try:
  654. 1/0
  655. except Exception as exc:
  656. self.exc = exc
  657. self = None # Break the cycle
  658. tester = Tester()
  659. tester.dig()
  660. ref = weakref.ref(tester)
  661. del tester
  662. gc_collect() # For PyPy or other GCs.
  663. self.assertIsNone(ref())
  664. if __name__ == '__main__':
  665. unittest.main()