Author: Ronan Lamy <ronan.l...@gmail.com> Branch: var-in-Some Changeset: r71629:0ea1c56e5066 Date: 2014-05-21 04:17 +0100 http://bitbucket.org/pypy/pypy/changeset/0ea1c56e5066/
Log: hg merge default diff --git a/pypy/doc/Makefile b/pypy/doc/Makefile --- a/pypy/doc/Makefile +++ b/pypy/doc/Makefile @@ -7,63 +7,80 @@ PAPER = BUILDDIR = _build +# User-friendly check for sphinx-build +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex man changes linkcheck doctest +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make <target>' where <target> is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " man to make manual pages" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " xml to make Docutils-native XML files" + @echo " pseudoxml to make pseudoxml-XML files for display purposes" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: - -rm -rf $(BUILDDIR)/* + rm -rf $(BUILDDIR)/* html: - # python config/generate.py #readthedocs will not run this Makefile $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: - # python config/generate.py #readthedocs will not run this Makefile $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + pickle: - # python config/generate.py #readthedocs will not run this Makefile $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: - # python config/generate.py #readthedocs will not run this Makefile $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: - # python config/generate.py #readthedocs will not run this Makefile $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: - # python config/generate.py #readthedocs will not run this Makefile $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ @@ -72,35 +89,89 @@ @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/PyPy.qhc" +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/PyPy" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/PyPy" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + latex: - # python config/generate.py #readthedocs will not run this Makefile $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +latexpdfja: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through platex and dvipdfmx..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." man: - # python config/generate.py #readthedocs will not run this Makefile $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man" + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: - # python config/generate.py #readthedocs will not run this Makefile $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: - # python config/generate.py #readthedocs will not run this Makefile $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: - # python config/generate.py #readthedocs will not run this Makefile $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml + @echo + @echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py --- a/pypy/doc/conf.py +++ b/pypy/doc/conf.py @@ -18,11 +18,31 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.append(os.path.abspath('.')) + +# -- Read The Docs theme config ------------------------------------------------ + +# on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' + +if not on_rtd: # only import and set the theme if we're building docs locally + try: + import sphinx_rtd_theme + html_theme = 'sphinx_rtd_theme' + html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + except ImportError: + print('sphinx_rtd_theme is not installed') + html_theme = 'default' + +# otherwise, readthedocs.org uses their theme by default, so no need to specify it + + # -- General configuration ----------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.ifconfig', 'sphinx.ext.graphviz', 'pypyconfig'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', 'sphinx.ext.ifconfig', 'sphinx.ext.graphviz', + 'pypyconfig'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -91,7 +111,7 @@ # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. -html_theme = 'default' +#html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst --- a/pypy/doc/how-to-release.rst +++ b/pypy/doc/how-to-release.rst @@ -28,7 +28,6 @@ pypy/doc/tool/makecontributor.py generates the list of contributors * rename pypy/doc/whatsnew_head.rst to whatsnew_VERSION.rst and create a fresh whatsnew_head.rst after the release -* change the tracker to have a new release tag to file bugs against * go to pypy/tool/release and run: force-builds.py <release branch> * wait for builds to complete, make sure there are no failures diff --git a/pypy/doc/index-of-release-notes.rst b/pypy/doc/index-of-release-notes.rst --- a/pypy/doc/index-of-release-notes.rst +++ b/pypy/doc/index-of-release-notes.rst @@ -1,19 +1,42 @@ Historical release notes ------------------------- +======================== + +Cpython 2.7 compatible versions +=============================== .. toctree:: + release-2.3.0.rst + release-2.2.1.rst + release-2.2.0.rst + release-2.1.0.rst + release-2.1.0-beta2.rst + release-2.1.0-beta1.rst + release-2.1.0.rst + release-2.0.2.rst + release-2.0.1.rst + release-2.0.0.rst + release-2.0.0-beta2.rst + release-2.0.0-beta1.rst + release-1.9.0.rst + release-1.8.0.rst + release-1.7.0.rst + release-1.6.0.rst + release-1.5.0.rst + release-1.4.1.rst + release-1.4.0beta.rst + release-1.4.0.rst + release-1.3.0.rst + release-1.2.0.rst + release-1.1.0.rst + release-1.0.0.rst + release-0.99.0.rst + release-0.9.0.rst + release-0.8.0.rst + release-0.7.0.rst release-0.6 - release-0.7.0.rst - release-0.8.0.rst - release-0.9.0.rst - release-0.99.0.rst - release-1.0.0.rst - release-1.1.0.rst - release-1.2.0.rst - release-1.3.0.rst - release-1.4.0.rst - release-1.4.0beta.rst - release-1.4.1.rst - release-1.5.0.rst - release-1.6.0.rst + +Cpython 3.2 compatible versions +=============================== +.. toctree:: + release-pypy3-2.1.0-beta1.rst diff --git a/pypy/doc/make.bat b/pypy/doc/make.bat --- a/pypy/doc/make.bat +++ b/pypy/doc/make.bat @@ -2,11 +2,15 @@ REM Command file for Sphinx documentation -set SPHINXBUILD=sphinx-build +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help @@ -14,16 +18,25 @@ if "%1" == "help" ( :help echo.Please use `make ^<target^>` where ^<target^> is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. changes to make an overview over all changed/added/deprecated items - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled goto end ) @@ -33,8 +46,34 @@ goto end ) + +REM Check if sphinx-build is available and fallback to Python version if any +%SPHINXBUILD% 2> nul +if errorlevel 9009 goto sphinx_python +goto sphinx_ok + +:sphinx_python + +set SPHINXBUILD=python -m sphinx.__init__ +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +:sphinx_ok + + if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end @@ -42,13 +81,23 @@ if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end @@ -56,6 +105,7 @@ if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end @@ -63,6 +113,7 @@ if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. @@ -71,6 +122,7 @@ if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: @@ -80,15 +132,85 @@ goto end ) +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end @@ -96,6 +218,7 @@ if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. @@ -104,10 +227,27 @@ if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + :end diff --git a/pypy/doc/whatsnew-2.3.1.rst b/pypy/doc/whatsnew-2.3.1.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/whatsnew-2.3.1.rst @@ -0,0 +1,13 @@ +======================= +What's new since PyPy 2.3? +======================= + +.. this is a revision shortly after release-2.3 +.. startrev: 394146e9bb67 + +Move builtin ``struct`` module to ``_struct`` to allow ``pypy "-m idlelib.idle"`` + +Support compilation with gcc-4.9 + +Fixes for issues #1769, #1764, #1762, #1752 + diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst --- a/pypy/doc/whatsnew-head.rst +++ b/pypy/doc/whatsnew-head.rst @@ -1,6 +1,13 @@ ======================= -What's new in PyPy 2.3+ +What's new in PyPy 2.4+ ======================= .. this is a revision shortly after release-2.3.x -.. startrev: f556d32f8319 +.. startrev: b2cc67adbaad + +Added support for the stdlib gdbm module via cffi + +Annotator cleanups + +.. branch: release-2.3.x + diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py --- a/pypy/interpreter/app_main.py +++ b/pypy/interpreter/app_main.py @@ -85,7 +85,7 @@ if softspace: stdout.write('\n') - except SystemExit, e: + except SystemExit as e: handle_sys_exit(e) except: display_exception() @@ -590,6 +590,11 @@ # handle the case where no command/filename/module is specified # on the command-line. + try: + from _ast import PyCF_ACCEPT_NULL_BYTES + except ImportError: + PyCF_ACCEPT_NULL_BYTES = 0 + # update sys.path *after* loading site.py, in case there is a # "site.py" file in the script's directory. Only run this if we're # executing the interactive prompt, if we're running a script we @@ -603,17 +608,17 @@ python_startup = readenv and os.getenv('PYTHONSTARTUP') if python_startup: try: - f = open(python_startup) - startup = f.read() - f.close() - except IOError, e: + with open(python_startup) as f: + startup = f.read() + except IOError as e: print >> sys.stderr, "Could not open PYTHONSTARTUP" print >> sys.stderr, "IOError:", e else: def run_it(): co_python_startup = compile(startup, python_startup, - 'exec') + 'exec', + PyCF_ACCEPT_NULL_BYTES) exec co_python_startup in mainmodule.__dict__ mainmodule.__file__ = python_startup run_toplevel(run_it) @@ -626,7 +631,8 @@ else: # If not interactive, just read and execute stdin normally. def run_it(): - co_stdin = compile(sys.stdin.read(), '<stdin>', 'exec') + co_stdin = compile(sys.stdin.read(), '<stdin>', 'exec', + PyCF_ACCEPT_NULL_BYTES) exec co_stdin in mainmodule.__dict__ mainmodule.__file__ = '<stdin>' success = run_toplevel(run_it) @@ -660,7 +666,7 @@ args = (execfile, filename, mainmodule.__dict__) success = run_toplevel(*args) - except SystemExit, e: + except SystemExit as e: status = e.code if inspect_requested(): display_exception() @@ -676,7 +682,7 @@ readenv and os.getenv('PYPY_IRC_TOPIC')) success = run_toplevel(interactive_console, mainmodule, quiet=not irc_topic) - except SystemExit, e: + except SystemExit as e: status = e.code else: status = not success @@ -726,10 +732,10 @@ setup_bootstrap_path(executable) try: cmdline = parse_command_line(argv) - except CommandLineError, e: + except CommandLineError as e: print_error(str(e)) return 2 - except SystemExit, e: + except SystemExit as e: return e.code or 0 setup_and_fix_paths(**cmdline) return run_command_line(**cmdline) diff --git a/pypy/interpreter/astcompiler/consts.py b/pypy/interpreter/astcompiler/consts.py --- a/pypy/interpreter/astcompiler/consts.py +++ b/pypy/interpreter/astcompiler/consts.py @@ -22,3 +22,4 @@ PyCF_SOURCE_IS_UTF8 = 0x0100 PyCF_DONT_IMPLY_DEDENT = 0x0200 PyCF_ONLY_AST = 0x0400 +PyCF_ACCEPT_NULL_BYTES = 0x10000000 # PyPy only, for compile() diff --git a/pypy/module/__builtin__/__init__.py b/pypy/module/__builtin__/__init__.py --- a/pypy/module/__builtin__/__init__.py +++ b/pypy/module/__builtin__/__init__.py @@ -33,7 +33,7 @@ interpleveldefs = { # constants - '__debug__' : '(space.w_True)', # XXX + '__debug__' : '(space.w_True)', 'None' : '(space.w_None)', 'False' : '(space.w_False)', 'True' : '(space.w_True)', diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py --- a/pypy/module/__builtin__/compiling.py +++ b/pypy/module/__builtin__/compiling.py @@ -24,7 +24,8 @@ """ ec = space.getexecutioncontext() if flags & ~(ec.compiler.compiler_flags | consts.PyCF_ONLY_AST | - consts.PyCF_DONT_IMPLY_DEDENT | consts.PyCF_SOURCE_IS_UTF8): + consts.PyCF_DONT_IMPLY_DEDENT | consts.PyCF_SOURCE_IS_UTF8 | + consts.PyCF_ACCEPT_NULL_BYTES): raise OperationError(space.w_ValueError, space.wrap("compile() unrecognized flags")) @@ -53,9 +54,10 @@ else: source = space.readbuf_w(w_source).as_str() - if '\x00' in source: - raise OperationError(space.w_TypeError, space.wrap( - "compile() expected string without null bytes")) + if not (flags & consts.PyCF_ACCEPT_NULL_BYTES): + if '\x00' in source: + raise OperationError(space.w_TypeError, space.wrap( + "compile() expected string without null bytes")) if flags & consts.PyCF_ONLY_AST: code = ec.compiler.compile_to_ast(source, filename, mode, flags) diff --git a/pypy/module/__builtin__/test/test_builtin.py b/pypy/module/__builtin__/test/test_builtin.py --- a/pypy/module/__builtin__/test/test_builtin.py +++ b/pypy/module/__builtin__/test/test_builtin.py @@ -610,6 +610,16 @@ firstlineno = co.co_firstlineno assert firstlineno == 2 + def test_compile_null_bytes(self): + import _ast + raises(TypeError, compile, '\x00', 'mymod', 'exec', 0) + raises(SyntaxError, compile, '\x00', 'mymod', 'exec', + _ast.PyCF_ACCEPT_NULL_BYTES) + src = "#abc\x00def\n" + raises(TypeError, compile, src, 'mymod', 'exec') + raises(TypeError, compile, src, 'mymod', 'exec', 0) + compile(src, 'mymod', 'exec', _ast.PyCF_ACCEPT_NULL_BYTES) # works + def test_print_function(self): import __builtin__ import sys diff --git a/pypy/module/_ast/__init__.py b/pypy/module/_ast/__init__.py --- a/pypy/module/_ast/__init__.py +++ b/pypy/module/_ast/__init__.py @@ -6,6 +6,8 @@ interpleveldefs = { "PyCF_ONLY_AST" : "space.wrap(%s)" % consts.PyCF_ONLY_AST, + "PyCF_ACCEPT_NULL_BYTES": + "space.wrap(%s)" % consts.PyCF_ACCEPT_NULL_BYTES, "__version__" : "space.wrap('82160')", # from CPython's svn. } appleveldefs = {} diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py --- a/pypy/module/_file/interp_file.py +++ b/pypy/module/_file/interp_file.py @@ -209,11 +209,13 @@ while size > 0: # "peeks" on the underlying stream to see how many chars # we can safely read without reading past an end-of-line - peeked = stream.peek() - pn = peeked.find("\n", 0, size) + startindex, peeked = stream.peek() + assert 0 <= startindex <= len(peeked) + endindex = startindex + size + pn = peeked.find("\n", startindex, endindex) if pn < 0: - pn = min(size-1, len(peeked)) - c = stream.read(pn + 1) + pn = min(endindex - 1, len(peeked)) + c = stream.read(pn - startindex + 1) if not c: break result.append(c) diff --git a/pypy/module/bz2/interp_bz2.py b/pypy/module/bz2/interp_bz2.py --- a/pypy/module/bz2/interp_bz2.py +++ b/pypy/module/bz2/interp_bz2.py @@ -458,9 +458,7 @@ return result def peek(self): - pos = self.pos - assert pos >= 0 - return self.buffer[pos:] + return (self.pos, self.buffer) def try_to_find_file_descriptor(self): return self.stream.try_to_find_file_descriptor() diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py --- a/rpython/annotator/annrpython.py +++ b/rpython/annotator/annrpython.py @@ -10,6 +10,7 @@ c_last_exception, checkgraph) from rpython.translator import simplify, transform from rpython.annotator import model as annmodel, signature +from rpython.annotator.argument import simple_args from rpython.annotator.value import AnnotatedValue from rpython.annotator.bookkeeper import Bookkeeper @@ -92,7 +93,7 @@ def get_call_parameters(self, function, args_s, policy): desc = self.bookkeeper.getdesc(function) - args = self.bookkeeper.build_args("simple_call", args_s[:]) + args = simple_args(args_s) result = [] def schedule(graph, inputcells): result.append((graph, inputcells)) diff --git a/rpython/annotator/argument.py b/rpython/annotator/argument.py --- a/rpython/annotator/argument.py +++ b/rpython/annotator/argument.py @@ -171,6 +171,12 @@ def rawshape(args): return args._rawshape() +def simple_args(args_s): + return ArgumentsForTranslation(list(args_s)) + +def complex_args(args_s): + return ArgumentsForTranslation.fromshape(args_s[0].const, + list(args_s[1:])) # # ArgErr family of exceptions raised in case of argument mismatch. diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -8,7 +8,7 @@ SomeObject, SomeInteger, SomeBool, s_Bool, SomeString, SomeChar, SomeList, SomeDict, SomeOrderedDict, SomeUnicodeCodePoint, SomeUnicodeString, SomeTuple, SomeImpossibleValue, s_ImpossibleValue, SomeInstance, - SomeBuiltin, SomeIterator, SomePBC, SomeFloat, s_None, SomeByteArray, + SomeBuiltinMethod, SomeIterator, SomePBC, SomeFloat, s_None, SomeByteArray, SomeWeakRef, SomeSingleFloat, SomeLongFloat, SomeType, SomeConstantType, unionof, UnionError, read_can_only_throw, add_knowntypedata, @@ -697,15 +697,14 @@ return SomeIterator(s_cont, *iter1.variant) -class __extend__(pairtype(SomeBuiltin, SomeBuiltin)): - +class __extend__(pairtype(SomeBuiltinMethod, SomeBuiltinMethod)): def union((bltn1, bltn2)): if (bltn1.analyser != bltn2.analyser or - bltn1.methodname != bltn2.methodname or - bltn1.s_self is None or bltn2.s_self is None): + bltn1.methodname != bltn2.methodname): raise UnionError(bltn1, bltn2) s_self = unionof(bltn1.s_self, bltn2.s_self) - return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname) + return SomeBuiltinMethod(bltn1.analyser, s_self, + methodname=bltn1.methodname) @op.is_.register(SomePBC, SomePBC) def is__PBC_PBC(pbc1, pbc2): diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py --- a/rpython/annotator/bookkeeper.py +++ b/rpython/annotator/bookkeeper.py @@ -18,7 +18,7 @@ from rpython.annotator.dictdef import DictDef from rpython.annotator import description from rpython.annotator.signature import annotationoftype -from rpython.annotator.argument import ArgumentsForTranslation +from rpython.annotator.argument import simple_args, complex_args from rpython.rlib.objectmodel import r_dict, Symbolic from rpython.tool.algo.unionfind import UnionFind from rpython.rtyper import extregistry @@ -538,7 +538,7 @@ del emulated_pbc_calls[other_key] emulated_pbc_calls[unique_key] = pbc, args_s - args = self.build_args("simple_call", args_s) + args = simple_args(args_s) if callback is None: emulated = True else: @@ -564,11 +564,9 @@ def build_args(self, op, args_s): if op == "simple_call": - return ArgumentsForTranslation(list(args_s)) + return simple_args(args_s) elif op == "call_args": - return ArgumentsForTranslation.fromshape( - args_s[0].const, # shape - list(args_s[1:])) + return complex_args(args_s) def ondegenerated(self, what, s_value, where=None, called_from_graph=None): self.annotator.ondegenerated(what, s_value, where=where, diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py --- a/rpython/annotator/builtin.py +++ b/rpython/annotator/builtin.py @@ -14,6 +14,7 @@ from rpython.flowspace.model import Constant import rpython.rlib.rarithmetic import rpython.rlib.objectmodel +from rpython.annotator.model import AnnotatorError def constpropagate(func, args_s, s_result): @@ -211,7 +212,7 @@ def builtin_tuple(s_iterable): if isinstance(s_iterable, SomeTuple): return s_iterable - return AnnotatorError("tuple(): argument must be another tuple") + raise AnnotatorError("tuple(): argument must be another tuple") def builtin_list(s_iterable): if isinstance(s_iterable, SomeList): diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py --- a/rpython/annotator/model.py +++ b/rpython/annotator/model.py @@ -536,7 +536,15 @@ class SomeBuiltinMethod(SomeBuiltin): """ Stands for a built-in method which has got special meaning """ - knowntype = MethodType + def __init__(self, analyser, s_self, methodname): + if isinstance(analyser, MethodType): + analyser = descriptor.InstanceMethod( + analyser.im_func, + analyser.im_self, + analyser.im_class) + self.analyser = analyser + self.s_self = s_self + self.methodname = methodname class SomeImpossibleValue(SomeObject): diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py --- a/rpython/annotator/unaryop.py +++ b/rpython/annotator/unaryop.py @@ -7,14 +7,15 @@ from rpython.flowspace.operation import op from rpython.annotator.model import (SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, SomeDict, SomeTuple, SomeImpossibleValue, - SomeUnicodeCodePoint, SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, - SomePBC, SomeType, s_ImpossibleValue, + SomeUnicodeCodePoint, SomeInstance, SomeBuiltin, SomeBuiltinMethod, + SomeFloat, SomeIterator, SomePBC, SomeType, s_ImpossibleValue, s_Bool, s_None, unionof, add_knowntypedata, HarmlesslyBlocked, SomeWeakRef, SomeUnicodeString, SomeByteArray) from rpython.annotator.bookkeeper import getbookkeeper, immutablevalue from rpython.annotator import builtin from rpython.annotator.binaryop import _clone ## XXX where to put this? from rpython.annotator.model import AnnotatorError +from rpython.annotator.argument import simple_args, complex_args UNARY_OPERATIONS = set([oper.opname for oper in op.__dict__.values() if oper.dispatch == 1]) @@ -106,7 +107,7 @@ except AttributeError: return None else: - return SomeBuiltin(analyser, self, name) + return SomeBuiltinMethod(analyser, self, name) def getattr(self, s_attr): # get a SomeBuiltin if the SomeObject has @@ -131,10 +132,10 @@ return self # default unbound __get__ implementation def simple_call(self, *args_s): - return self.call(getbookkeeper().build_args("simple_call", args_s)) + return self.call(simple_args(args_s)) def call_args(self, *args_s): - return self.call(getbookkeeper().build_args("call_args", args_s)) + return self.call(complex_args(args_s)) def call(self, args, implicit_init=False): raise AnnotatorError("Cannot prove that the object is callable") @@ -684,31 +685,38 @@ bk = getbookkeeper() # record for calltables bk.emulate_pbc_call(bk.position_key, s_iterable, []) - return s_iterable.call(bk.build_args("simple_call", [])) + return s_iterable.call(simple_args([])) def next(self): s_next = self._true_getattr('next') bk = getbookkeeper() # record for calltables bk.emulate_pbc_call(bk.position_key, s_next, []) - return s_next.call(bk.build_args("simple_call", [])) + return s_next.call(simple_args([])) class __extend__(SomeBuiltin): + def simple_call(self, *args): + return self.analyser(*args) + + def call(self, args, implicit_init=False): + args_s, kwds = args.unpack() + # prefix keyword arguments with 's_' + kwds_s = {} + for key, s_value in kwds.items(): + kwds_s['s_'+key] = s_value + return self.analyser(*args_s, **kwds_s) + + +class __extend__(SomeBuiltinMethod): def _can_only_throw(self, *args): analyser_func = getattr(self.analyser, 'im_func', None) can_only_throw = getattr(analyser_func, 'can_only_throw', None) if can_only_throw is None or isinstance(can_only_throw, list): return can_only_throw - if self.s_self is not None: - return can_only_throw(self.s_self, *args) - else: - return can_only_throw(*args) + return can_only_throw(self.s_self, *args) def simple_call(self, *args): - if self.s_self is not None: - return self.analyser(self.s_self, *args) - else: - return self.analyser(*args) + return self.analyser(self.s_self, *args) simple_call.can_only_throw = _can_only_throw def call(self, args, implicit_init=False): @@ -717,10 +725,7 @@ kwds_s = {} for key, s_value in kwds.items(): kwds_s['s_'+key] = s_value - if self.s_self is not None: - return self.analyser(self.s_self, *args_s, **kwds_s) - else: - return self.analyser(*args_s, **kwds_s) + return self.analyser(self.s_self, *args_s, **kwds_s) class __extend__(SomePBC): diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py --- a/rpython/memory/gc/incminimark.py +++ b/rpython/memory/gc/incminimark.py @@ -1861,20 +1861,26 @@ #END MARKING elif self.gc_state == STATE_SWEEPING: # - # Walk all rawmalloced objects and free the ones that don't - # have the GCFLAG_VISITED flag. Visit at most 'limit' objects. - limit = self.nursery_size // self.ac.page_size - remaining = self.free_unvisited_rawmalloc_objects_step(limit) - # - # Ask the ArenaCollection to visit a fraction of the objects. - # Free the ones that have not been visited above, and reset - # GCFLAG_VISITED on the others. Visit at most '3 * limit' - # pages minus the number of objects already visited above. - done = self.ac.mass_free_incremental(self._free_if_unvisited, - 2 * limit + remaining) + if self.raw_malloc_might_sweep.non_empty(): + # Walk all rawmalloced objects and free the ones that don't + # have the GCFLAG_VISITED flag. Visit at most 'limit' objects. + # This limit is conservatively high enough to guarantee that + # a total object size of at least '3 * nursery_size' bytes + # is processed. + limit = 3 * self.nursery_size // self.small_request_threshold + self.free_unvisited_rawmalloc_objects_step(limit) + done = False # the 2nd half below must still be done + else: + # Ask the ArenaCollection to visit a fraction of the objects. + # Free the ones that have not been visited above, and reset + # GCFLAG_VISITED on the others. Visit at most '3 * + # nursery_size' bytes. + limit = 3 * self.nursery_size // self.ac.page_size + done = self.ac.mass_free_incremental(self._free_if_unvisited, + limit) # XXX tweak the limits above # - if remaining > 0 and done: + if done: self.num_major_collects += 1 # # We also need to reset the GCFLAG_VISITED on prebuilt GC objects. diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py --- a/rpython/rlib/rbigint.py +++ b/rpython/rlib/rbigint.py @@ -177,7 +177,7 @@ if intval < 0: sign = -1 - ival = r_uint(-intval) + ival = -r_uint(intval) elif intval > 0: sign = 1 ival = r_uint(intval) diff --git a/rpython/rlib/streamio.py b/rpython/rlib/streamio.py --- a/rpython/rlib/streamio.py +++ b/rpython/rlib/streamio.py @@ -234,11 +234,12 @@ while True: # "peeks" on the underlying stream to see how many characters # we can safely read without reading past an end-of-line - peeked = self.peek() - pn = peeked.find("\n") + startindex, peeked = self.peek() + assert 0 <= startindex <= len(peeked) + pn = peeked.find("\n", startindex) if pn < 0: pn = len(peeked) - c = self.read(pn + 1) + c = self.read(pn - startindex + 1) if not c: break result.append(c) @@ -265,7 +266,7 @@ pass def peek(self): - return '' + return (0, '') def try_to_find_file_descriptor(self): return -1 @@ -553,7 +554,7 @@ else: difpos = offset if -self.pos <= difpos <= currentsize: - self.pos += difpos + self.pos += intmask(difpos) return if whence == 1: offset -= currentsize @@ -705,9 +706,7 @@ return "".join(chunks) def peek(self): - pos = self.pos - assert pos >= 0 - return self.buf[pos:] + return (self.pos, self.buf) write = PassThrough("write", flush_buffers=True) truncate = PassThrough("truncate", flush_buffers=True) @@ -970,12 +969,13 @@ while True: # "peeks" on the underlying stream to see how many characters # we can safely read without reading past an end-of-line - peeked = self.base.peek() - pn = peeked.find("\n") - pr = peeked.find("\r") + startindex, peeked = self.base.peek() + assert 0 <= startindex <= len(peeked) + pn = peeked.find("\n", startindex) + pr = peeked.find("\r", startindex) if pn < 0: pn = len(peeked) if pr < 0: pr = len(peeked) - c = self.read(min(pn, pr) + 1) + c = self.read(min(pn, pr) - startindex + 1) if not c: break result.append(c) @@ -1028,7 +1028,7 @@ self.buf = "" def peek(self): - return self.buf + return (0, self.buf) write = PassThrough("write", flush_buffers=True) truncate = PassThrough("truncate", flush_buffers=True) diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py --- a/rpython/rlib/test/test_rbigint.py +++ b/rpython/rlib/test/test_rbigint.py @@ -12,6 +12,7 @@ _store_digit, _mask_digit, InvalidEndiannessError, InvalidSignednessError) from rpython.rlib.rfloat import NAN from rpython.rtyper.test.test_llinterp import interpret +from rpython.translator.c.test.test_standalone import StandaloneTests class TestRLong(object): @@ -849,3 +850,17 @@ py.test.raises(InvalidSignednessError, i.tobytes, 3, 'little', signed=False) py.test.raises(OverflowError, i.tobytes, 2, 'little', signed=True) + +class TestTranslated(StandaloneTests): + + def test_gcc_4_9(self): + MIN = -sys.maxint-1 + + def entry_point(argv): + print rbigint.fromint(MIN+1)._digits + print rbigint.fromint(MIN)._digits + return 0 + + t, cbuilder = self.compile(entry_point) + data = cbuilder.cmdexec('hi there') + assert data == '[%d]\n[0, 1]\n' % sys.maxint diff --git a/rpython/rtyper/lltypesystem/rstr.py b/rpython/rtyper/lltypesystem/rstr.py --- a/rpython/rtyper/lltypesystem/rstr.py +++ b/rpython/rtyper/lltypesystem/rstr.py @@ -834,6 +834,7 @@ def ll_stringslice_startonly(s1, start): return LLHelpers._ll_stringslice(s1, start, len(s1.chars)) + @signature(types.any(), types.int(), types.int(), returns=types.any()) def ll_stringslice_startstop(s1, start, stop): if jit.we_are_jitted(): if stop > len(s1.chars): diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py --- a/rpython/rtyper/rbuiltin.py +++ b/rpython/rtyper/rbuiltin.py @@ -11,37 +11,32 @@ class __extend__(annmodel.SomeBuiltin): def rtyper_makerepr(self, rtyper): - if self.s_self is None: - # built-in function case - if not self.is_constant(): - raise TyperError("non-constant built-in function!") - return BuiltinFunctionRepr(self.const) - else: - # built-in method case - assert self.methodname is not None - result = BuiltinMethodRepr(rtyper, self.s_self, self.methodname) - return result + if not self.is_constant(): + raise TyperError("non-constant built-in function!") + return BuiltinFunctionRepr(self.const) + def rtyper_makekey(self): - if self.s_self is None: - # built-in function case + const = getattr(self, 'const', None) + if extregistry.is_registered(const): + const = extregistry.lookup(const) + return self.__class__, const - const = getattr(self, 'const', None) +class __extend__(annmodel.SomeBuiltinMethod): + def rtyper_makerepr(self, rtyper): + assert self.methodname is not None + result = BuiltinMethodRepr(rtyper, self.s_self, self.methodname) + return result - if extregistry.is_registered(const): - const = extregistry.lookup(const) - - return self.__class__, const - else: - # built-in method case - # NOTE: we hash by id of self.s_self here. This appears to be - # necessary because it ends up in hop.args_s[0] in the method call, - # and there is no telling what information the called - # rtype_method_xxx() will read from that hop.args_s[0]. - # See test_method_join in test_rbuiltin. - # There is no problem with self.s_self being garbage-collected and - # its id reused, because the BuiltinMethodRepr keeps a reference - # to it. - return (self.__class__, self.methodname, id(self.s_self)) + def rtyper_makekey(self): + # NOTE: we hash by id of self.s_self here. This appears to be + # necessary because it ends up in hop.args_s[0] in the method call, + # and there is no telling what information the called + # rtype_method_xxx() will read from that hop.args_s[0]. + # See test_method_join in test_rbuiltin. + # There is no problem with self.s_self being garbage-collected and + # its id reused, because the BuiltinMethodRepr keeps a reference + # to it. + return (self.__class__, self.methodname, id(self.s_self)) def call_args_expand(hop, takes_kwds = True): hop = hop.copy() diff --git a/rpython/rtyper/rpbc.py b/rpython/rtyper/rpbc.py --- a/rpython/rtyper/rpbc.py +++ b/rpython/rtyper/rpbc.py @@ -2,6 +2,7 @@ from rpython.annotator import model as annmodel, description from rpython.flowspace.model import Constant +from rpython.annotator.argument import simple_args from rpython.rtyper import rclass, callparse from rpython.rtyper.annlowlevel import llstr from rpython.rtyper.error import TyperError @@ -290,7 +291,7 @@ bk = self.rtyper.annotator.bookkeeper descs = list(s_pbc.descriptions) vfcs = description.FunctionDesc.variant_for_call_site - args = bk.build_args("simple_call", args_s) + args = simple_args(args_s) shape, index = vfcs(bk, self.callfamily, descs, args, op) funcdesc, = descs row_of_one_graph = self.callfamily.calltables[shape][index] _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit