GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-113993: Allow interned strings to be mortal, and fix related issues by encukou · Pull Request #120520 · python/cpython

Conversation

@encukou

@encukou encukou commented Jun 14, 2024 •
edited by bedevere-app Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

I've spent too much time looking at this myself, it wants more eyes :)

I spent a week learning about the string interning mechanism, and wrote up how I think it should work in an InternalDocs file I'm adding here.

I found a bunch of ... quirks if not outright bugs. For example, we have duplicate singletons (e.g. _Py_ID(a) and the latin1 short string a). I don't think I can bring back mortal interned strings without getting my idea of the design in sync with the code, so, this ended up being a big PR.


  • Add an InternalDocs file describing how interning should work and how to use it.
    (Please review this first!)

  • Add internal functions to explicitly request what kind of interning is done:

    • _PyUnicode_InternMortal
    • _PyUnicode_InternImmortal
    • _PyUnicode_InternStatic
  • Switch uses of PyUnicode_InternInPlace to those.

  • Disallow using _Py_SetImmortal on strings directly.
    You should use _PyUnicode_InternImmortal instead:

    • Strings should be interned before immortalization, otherwise you're possibly
      interning a immortalizing copy.
    • _Py_SetImmortal doesn't handle the SSTATE_INTERNED_MORTAL to
      SSTATE_INTERNED_IMMORTAL update, and those flags can't be changed in
      backports, as they are now part of public API and version-specific ABI.
  • Add private _only_immortal argument for sys.XXX, used in refleak test machinery.

  • Make sure the statically allocated string singletons are unique. This means these sets are now disjoint:

    • _Py_ID
    • _Py_STR (including the empty string)
    • one-character latin-1 singletons

    Now, when you intern a singleton, that exact singleton will be interned.

  • Add a _Py_LATIN1_CHR macro, use it instead of _Py_ID/_Py_STR for one-character latin-1 singletons everywhere (including Clinic).

  • Intern _Py_STR singletons at startup.

    Try this in 3.12: (click to expand)
    import sys
    
    a = sys.intern('<module>')  # normal string
    print('a', id(a), sys.getrefcount(a))
    try:
        raise Exception()
    except Exception as err:
        b = err.__traceback__.tb_frame.f_code.co_name  # same string via _Py_STR
    
    assert sys.intern(a) is sys.intern(b)

    In 3.13 the reproducer doesn't work but I don't think the underlying unsoundness was fixed.

  • For free-threaded builds, intern _Py_LATIN1_CHR singletons at startup.

  • Beef up the tests. Cover internal details (marked with @cpython_only).

  • Add lots of assertions

  • Issue: Interned strings are immortal, despite what the documentation says #113993

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

eduardo-elizondo reacted with rocket emoji
All reactions
  • 🚀 1 reaction
encukou added 30 commits June 14, 2024 21:24
@encukou
Declare explicit interning routines
2b74021
@encukou
Use _PyUnicode_InternStatic for the statically allocated stuff
0aedb83
@encukou
Add _PyUnicode_InternStatic and extra checks
aad79b2
@encukou
Check against immortalizing un-interned strings
5413223
@encukou
Add _PyUnicode_InternImmortal & make marshal use it
23845fb
Also, the `PyUnicode_InternImmortal` function (with a public-looking name)
is switched to use this.

(I picked a relatively inconsequential module on purpose.)
@encukou
Remove special case that makes previously-immortal strings STATIC
9ece220
AFAIUI, this is now handled by the `statically_allocated` flag.
@encukou
Split _PyUnicode_InternMortal and _PyUnicode_InternImmortal
7c62641
@encukou
Do the refcnt dance in _PyUnicode_InternMortal & _PyUnicode_ClearInte…
62a35a1
…rned

Mortal interned strings don't count references from the interned_dict in
their refcount. This menans a -2 at interning time, a +2 in ClearInterned,
and special handling in unicode_dealloc.

Note that unicode_dealloc will currently immortalize an interned string.
That means we shouldn't get refleaks *yet*.
@encukou
Deallocate mortal interned strings
ac55a05
@encukou
Use _PyUnicode_InternMortal in codecs
2466ae9
@encukou
Start a notes document
032ac17
@encukou
Handle attempts to "overwrite" interned heap types by static ones
198d9c6
@encukou
Intern statically allocated non-identifier strings at init
86ccb08
@encukou
Parenthesize the LATIN1 macro argument
e34b8da
@encukou
Don't create the per-interp interned_dict until after InitStaticStrings
66338fe
@encukou
Move hashmap destroy to _PyUnicode_ClearInterned (symmetry with creat…
9f16cb0
…ion)
@encukou
Special-case short string singletons
e27abfc
@encukou
Verify we don't add process-global entries after a per-interp dict ex…
89f24df
…ists
@encukou
More editing of the InternalDocs write-up
b965acf
@encukou
Only readjust refleak tests for *immortal* interned strings
4b69712
@encukou
Be pedantic with the ref total
b2c9865
@encukou
Split InternInPlace in sysmodule
cf7cb72
@encukou
Split InternInPlace in import
85f9fe0
@encukou
Split InternInPlace in getargs
a288389
@encukou
Use mortal strings in type_setattro
6036cb1
bpo-40521 (pythonGH-84701) is now long solved.
@encukou
Use mortal string in type_module
01f2dbf
@encukou
Use mortal strings for object attributes
73f7fb3
@encukou
Use mortal strings for code object names
13be4e7
@encukou
Use mortal strings for code constants
1930919
It's marshal and the compiler that immortalize strings, not the
code object.
@encukou
Use mortals in pickle
d45f20b
@encukou encukou added the needs backport to 3.13 only security fixes label Jun 21, 2024
@encukou

encukou commented Jun 21, 2024

Copy link
Copy Markdown
Member Author

The buildbot failures are unrelated; I'll merge.

Thank you for the reviews!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@encukou
encukou merged commit 6f1d448 into python:main Jun 21, 2024
@miss-islington-app

miss-islington-app Bot commented Jun 21, 2024

Copy link
Copy Markdown

Thanks @encukou for the PR 🌮🎉.. I'm working now to backport this PR to: 3.12, 3.13.
🐍🍒⛏🤖

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the awaiting core review label Jun 21, 2024
@encukou
encukou deleted the immortal-interned branch June 21, 2024 15:19
@miss-islington-app

miss-islington-app Bot commented Jun 21, 2024

Copy link
Copy Markdown

Sorry, @encukou, I could not cleanly backport this to 3.13 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 6f1d448bc110633eda110310fd833bd46e7b30f2 3.13
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@miss-islington-app miss-islington-app Bot assigned encukou Jun 21, 2024
@miss-islington-app

miss-islington-app Bot commented Jun 21, 2024

Copy link
Copy Markdown

Sorry, @encukou, I could not cleanly backport this to 3.12 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 6f1d448bc110633eda110310fd833bd46e7b30f2 3.12
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ericsnowcurrently

ericsnowcurrently commented Jun 21, 2024

Copy link
Copy Markdown
Member

Thanks for taking care of this, @encukou!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

encukou added a commit to encukou/cpython that referenced this pull request Jun 24, 2024
@encukou @ericsnowcurrently
[3.13] pythongh-113993: Allow interned strings to be mortal, and fix …
70bfeae
…related issues (pythonGH-120520)

* Add an InternalDocs file describing how interning should work and how to use it.

* Add internal functions to *explicitly* request what kind of interning is done:
  - `_PyUnicode_InternMortal`
  - `_PyUnicode_InternImmortal`
  - `_PyUnicode_InternStatic`

* Switch uses of `PyUnicode_InternInPlace` to those.

* Disallow using `_Py_SetImmortal` on strings directly.
  You should use `_PyUnicode_InternImmortal` instead:
  - Strings should be interned before immortalization, otherwise you're possibly
    interning a immortalizing copy.
  - `_Py_SetImmortal` doesn't handle the `SSTATE_INTERNED_MORTAL` to
    `SSTATE_INTERNED_IMMORTAL` update, and those flags can't be changed in
    backports, as they are now part of public API and version-specific ABI.

* Add private `_only_immortal` argument for `sys.getunicodeinternedsize`, used in refleak test machinery.

* Make sure the statically allocated string singletons are unique. This means these sets are now disjoint:
  - `_Py_ID`
  - `_Py_STR` (including the empty string)
  - one-character latin-1 singletons

  Now, when you intern a singleton, that exact singleton will be interned.

* Add a `_Py_LATIN1_CHR` macro, use it instead of `_Py_ID`/`_Py_STR` for one-character latin-1 singletons everywhere (including Clinic).

* Intern `_Py_STR` singletons at startup.

* For free-threaded builds, intern `_Py_LATIN1_CHR` singletons at startup.

* Beef up the tests. Cover internal details (marked with `@cpython_only`).

* Add lots of assertions

Co-Authored-By: Eric Snow <[email protected]>
@bedevere-app

bedevere-app Bot commented Jun 24, 2024

Copy link
Copy Markdown

GH-120945 is a backport of this pull request to the 3.13 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the needs backport to 3.13 only security fixes label Jun 24, 2024
encukou added a commit that referenced this pull request Jun 24, 2024
@encukou @ericsnowcurrently
[3.13] gh-113993: Allow interned strings to be mortal, and fix relate…
9769b7a
…d issues (GH-120520) (GH-120945)

* Add an InternalDocs file describing how interning should work and how to use it.

* Add internal functions to *explicitly* request what kind of interning is done:
  - `_PyUnicode_InternMortal`
  - `_PyUnicode_InternImmortal`
  - `_PyUnicode_InternStatic`

* Switch uses of `PyUnicode_InternInPlace` to those.

* Disallow using `_Py_SetImmortal` on strings directly.
  You should use `_PyUnicode_InternImmortal` instead:
  - Strings should be interned before immortalization, otherwise you're possibly
    interning a immortalizing copy.
  - `_Py_SetImmortal` doesn't handle the `SSTATE_INTERNED_MORTAL` to
    `SSTATE_INTERNED_IMMORTAL` update, and those flags can't be changed in
    backports, as they are now part of public API and version-specific ABI.

* Add private `_only_immortal` argument for `sys.getunicodeinternedsize`, used in refleak test machinery.

* Make sure the statically allocated string singletons are unique. This means these sets are now disjoint:
  - `_Py_ID`
  - `_Py_STR` (including the empty string)
  - one-character latin-1 singletons

  Now, when you intern a singleton, that exact singleton will be interned.

* Add a `_Py_LATIN1_CHR` macro, use it instead of `_Py_ID`/`_Py_STR` for one-character latin-1 singletons everywhere (including Clinic).

* Intern `_Py_STR` singletons at startup.

* For free-threaded builds, intern `_Py_LATIN1_CHR` singletons at startup.

* Beef up the tests. Cover internal details (marked with `@cpython_only`).

* Add lots of assertions

Co-authored-by: Eric Snow <[email protected]>
mrahtz pushed a commit to mrahtz/cpython that referenced this pull request Jun 30, 2024
@encukou @ericsnowcurrently @mrahtz
pythongh-113993: Allow interned strings to be mortal, and fix related…
793dd86
… issues (pythonGH-120520)


* Add an InternalDocs file describing how interning should work and how to use it.

* Add internal functions to *explicitly* request what kind of interning is done:
  - `_PyUnicode_InternMortal`
  - `_PyUnicode_InternImmortal`
  - `_PyUnicode_InternStatic`

* Switch uses of `PyUnicode_InternInPlace` to those.

* Disallow using `_Py_SetImmortal` on strings directly.
  You should use `_PyUnicode_InternImmortal` instead:
  - Strings should be interned before immortalization, otherwise you're possibly
    interning a immortalizing copy.
  - `_Py_SetImmortal` doesn't handle the `SSTATE_INTERNED_MORTAL` to
    `SSTATE_INTERNED_IMMORTAL` update, and those flags can't be changed in
    backports, as they are now part of public API and version-specific ABI.

* Add private `_only_immortal` argument for `sys.getunicodeinternedsize`, used in refleak test machinery.

* Make sure the statically allocated string singletons are unique. This means these sets are now disjoint:
  - `_Py_ID`
  - `_Py_STR` (including the empty string)
  - one-character latin-1 singletons

  Now, when you intern a singleton, that exact singleton will be interned.

* Add a `_Py_LATIN1_CHR` macro, use it instead of `_Py_ID`/`_Py_STR` for one-character latin-1 singletons everywhere (including Clinic).

* Intern `_Py_STR` singletons at startup.

* For free-threaded builds, intern `_Py_LATIN1_CHR` singletons at startup.

* Beef up the tests. Cover internal details (marked with `@cpython_only`).

* Add lots of assertions

Co-Authored-By: Eric Snow <[email protected]>
@eduardo-elizondo

eduardo-elizondo commented Jul 5, 2024

Copy link
Copy Markdown
Contributor

This is great! Quick follow-up @encukou, should we rebase this one now: #113601?

encukou reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

estyxx pushed a commit to estyxx/cpython that referenced this pull request Jul 17, 2024
@encukou @ericsnowcurrently @estyxx
pythongh-113993: Allow interned strings to be mortal, and fix related…
2e12fc7
… issues (pythonGH-120520)


* Add an InternalDocs file describing how interning should work and how to use it.

* Add internal functions to *explicitly* request what kind of interning is done:
  - `_PyUnicode_InternMortal`
  - `_PyUnicode_InternImmortal`
  - `_PyUnicode_InternStatic`

* Switch uses of `PyUnicode_InternInPlace` to those.

* Disallow using `_Py_SetImmortal` on strings directly.
  You should use `_PyUnicode_InternImmortal` instead:
  - Strings should be interned before immortalization, otherwise you're possibly
    interning a immortalizing copy.
  - `_Py_SetImmortal` doesn't handle the `SSTATE_INTERNED_MORTAL` to
    `SSTATE_INTERNED_IMMORTAL` update, and those flags can't be changed in
    backports, as they are now part of public API and version-specific ABI.

* Add private `_only_immortal` argument for `sys.getunicodeinternedsize`, used in refleak test machinery.

* Make sure the statically allocated string singletons are unique. This means these sets are now disjoint:
  - `_Py_ID`
  - `_Py_STR` (including the empty string)
  - one-character latin-1 singletons

  Now, when you intern a singleton, that exact singleton will be interned.

* Add a `_Py_LATIN1_CHR` macro, use it instead of `_Py_ID`/`_Py_STR` for one-character latin-1 singletons everywhere (including Clinic).

* Intern `_Py_STR` singletons at startup.

* For free-threaded builds, intern `_Py_LATIN1_CHR` singletons at startup.

* Beef up the tests. Cover internal details (marked with `@cpython_only`).

* Add lots of assertions

Co-Authored-By: Eric Snow <[email protected]>
@encukou

encukou commented Jul 22, 2024

Copy link
Copy Markdown
Member Author

@eduardo-elizondo Yup, I've updated it, and left some notes about the docs.
If you want to delegate the writing, let me know and I'll take over the PR :)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Rogdham Rogdham mentioned this pull request Aug 9, 2024
Path.exists() - Memory leak #122849
Closed
@eduardo-elizondo

eduardo-elizondo commented Aug 11, 2024

Copy link
Copy Markdown
Contributor

@eduardo-elizondo Yup, I've updated it, and left some notes about the docs. If you want to delegate the writing, let me know and I'll take over the PR :)

Fixing them now! Let's close out in the other PR

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

encukou added a commit to encukou/cpython that referenced this pull request Aug 16, 2024
@encukou @ericsnowcurrently
[3.12] pythongh-113993: Allow interned strings to be mortal, and fix …
9fd6334
…related issues (pythonGH-120520)

* Add an InternalDocs file describing how interning should work and how to use it.

* Add internal functions to *explicitly* request what kind of interning is done:
  - `_PyUnicode_InternMortal`
  - `_PyUnicode_InternImmortal`
  - `_PyUnicode_InternStatic`

* Switch uses of `PyUnicode_InternInPlace` to those.

* Disallow using `_Py_SetImmortal` on strings directly.
  You should use `_PyUnicode_InternImmortal` instead:
  - Strings should be interned before immortalization, otherwise you're possibly
    interning a immortalizing copy.
  - `_Py_SetImmortal` doesn't handle the `SSTATE_INTERNED_MORTAL` to
    `SSTATE_INTERNED_IMMORTAL` update, and those flags can't be changed in
    backports, as they are now part of public API and version-specific ABI.

* Add private `_only_immortal` argument for `sys.getunicodeinternedsize`, used in refleak test machinery.

* Make sure the statically allocated string singletons are unique. This means these sets are now disjoint:
  - `_Py_ID`
  - `_Py_STR` (including the empty string)
  - one-character latin-1 singletons

  Now, when you intern a singleton, that exact singleton will be interned.

* Add a `_Py_LATIN1_CHR` macro, use it instead of `_Py_ID`/`_Py_STR` for one-character latin-1 singletons everywhere (including Clinic).

* Intern `_Py_STR` singletons at startup.

* Beef up the tests. Cover internal details (marked with `@cpython_only`).

* Add lots of assertions

Co-authored-by: Eric Snow <[email protected]>
@encukou encukou mentioned this pull request Aug 16, 2024
[3.12] gh-113993: Make interned strings mortal (GH-120520, GH-121364, GH-121903, GH-122303) #123065
Merged
@ZeroIntensity ZeroIntensity mentioned this pull request Aug 17, 2024
Stable ABI: Objects/bytesobject.c:122: PyBytes_FromStringAndSize: Assertion '_Py_IsImmortal(op)' failed. #123091
Closed
Yhg1s pushed a commit that referenced this pull request Sep 27, 2024
@encukou @ericsnowcurrently
[3.12] gh-113993: Make interned strings mortal (GH-120520, GH-121364, G…
49f6beb
…H-121903, GH-122303) (#123065)

This backports several PRs for gh-113993, making interned strings mortal so they can be garbage-collected when no longer needed.

* Allow interned strings to be mortal, and fix related issues (GH-120520)

  * Add an InternalDocs file describing how interning should work and how to use it.

  * Add internal functions to *explicitly* request what kind of interning is done:
    - `_PyUnicode_InternMortal`
    - `_PyUnicode_InternImmortal`
    - `_PyUnicode_InternStatic`

  * Switch uses of `PyUnicode_InternInPlace` to those.

  * Disallow using `_Py_SetImmortal` on strings directly.
    You should use `_PyUnicode_InternImmortal` instead:
    - Strings should be interned before immortalization, otherwise you're possibly
      interning a immortalizing copy.
    - `_Py_SetImmortal` doesn't handle the `SSTATE_INTERNED_MORTAL` to
      `SSTATE_INTERNED_IMMORTAL` update, and those flags can't be changed in
      backports, as they are now part of public API and version-specific ABI.

  * Add private `_only_immortal` argument for `sys.getunicodeinternedsize`, used in refleak test machinery.

   Make sure the statically allocated string singletons are unique. This means these sets are now disjoint:
    - `_Py_ID`
    - `_Py_STR` (including the empty string)
    - one-character latin-1 singletons

    Now, when you intern a singleton, that exact singleton will be interned.

  * Add a `_Py_LATIN1_CHR` macro, use it instead of `_Py_ID`/`_Py_STR` for one-character latin-1 singletons everywhere (including Clinic).

  * Intern `_Py_STR` singletons at startup.

  * Beef up the tests. Cover internal details (marked with `@cpython_only`).

  * Add lots of assertions

* Don't immortalize in PyUnicode_InternInPlace; keep immortalizing in other API (GH-121364)

  * Switch PyUnicode_InternInPlace to _PyUnicode_InternMortal, clarify docs

  * Document immortality in some functions that take `const char *`

  This is PyUnicode_InternFromString;
  PyDict_SetItemString, PyObject_SetAttrString;
  PyObject_DelAttrString; PyUnicode_InternFromString;
  and the PyModule_Add convenience functions.

  Always point out a non-immortalizing alternative.

  * Don't immortalize user-provided attr names in _ctypes

* Immortalize names in code objects to avoid crash (GH-121903)

* Intern latin-1 one-byte strings at startup (GH-122303)

There are some 3.12-specific changes, mainly to allow statically allocated strings in deepfreeze. (In 3.13, deepfreeze switched to the general `_Py_ID`/`_Py_STR`.)

Co-authored-by: Eric Snow <[email protected]>
iritkatriel
iritkatriel reviewed Nov 22, 2024
View reviewed changes
Comment thread InternalDocs/string_interning.md
@@ -0,0 +1,122 @@
# String interning

@iritkatriel iritkatriel Nov 22, 2024

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to have a link to this file from the index in InternalDocs/README.md.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

encukou reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@encukou encukou mentioned this pull request Nov 25, 2024
gh-113993: InternalDocs: Add String Interning to README #127250
Merged
@hugovk hugovk removed the needs backport to 3.12 only security fixes label Feb 25, 2025
@yuyichao yuyichao mentioned this pull request May 1, 2025
PyUnicode_InternFromString does not immortalize the string as the document claims #133260
Closed
@vstinner vstinner mentioned this pull request Sep 10, 2025
Build failure with "--with-address-sanitizer" flag #121847
Closed
@eendebakpt eendebakpt mentioned this pull request Sep 21, 2026
intern_static() never detects a failed _Py_hashtable_set() (< -1 should be < 0) #157892
Closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@iritkatriel iritkatriel iritkatriel left review comments
@ericsnowcurrently ericsnowcurrently ericsnowcurrently approved these changes
@erlend-aasland erlend-aasland Awaiting requested review from erlend-aasland erlend-aasland is a code owner
@berkerpeksag berkerpeksag Awaiting requested review from berkerpeksag
@pablogsal pablogsal Awaiting requested review from pablogsal pablogsal is a code owner
@lysnikolaou lysnikolaou Awaiting requested review from lysnikolaou lysnikolaou is a code owner
@kumaraditya303 kumaraditya303 Awaiting requested review from kumaraditya303 kumaraditya303 is a code owner
@isidentical isidentical Awaiting requested review from isidentical
@markshannon markshannon Awaiting requested review from markshannon markshannon is a code owner
@methane methane Awaiting requested review from methane methane is a code owner
+1 more reviewer
@neonene neonene neonene left review comments
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@encukou encukou

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

8 participants

@encukou @neonene @bedevere-bot @mdboom @ericsnowcurrently @eduardo-elizondo @iritkatriel @hugovk
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.