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-157757: Fix to make `lazy import a.b as c` import the module `a.b` by brittanyrey · Pull Request #158092 · python/cpython

Conversation

@brittanyrey

@brittanyrey brittanyrey commented Sep 24, 2026 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown
Contributor

Bug: import a.b as c compiles to IMPORT_NAME a.b followed by IMPORT_FROM b. Lazily, IMPORT_NAME leaves a placeholder holding "a.b", and IMPORT_FROM rewrote it into the placeholder lazy from a import b produces. Reification then imported a alone and read b off it, so the module a.b was never imported under its own name: an attribute of the package shadowing it answered instead, and math.pi, which no module backs, bound the float where the eager statement raises ModuleNotFoundError.

Fix: Follow @pablogsal's suggestion to have each deferred IMPORT_FROM keep the previous placeholder and the attribute name. Reification runs the original import and then applies the recorded lookups in order with _PyEval_ImportFrom, as the eager statement does.

For lazy from a import b, c, the import gets only the name being resolved as the fromlist, so accessing b doesn't import a.c.

  • Issue: lazy import a.b as c resolves b as an attribute of a instead of importing the module a.b #157757

Sorry, something went wrong.

Uh oh!

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

All reactions
@brittanyrey
brittanyrey requested review from DinoV, FFY00, Yhg1s, brettcannon, ericsnowcurrently, kumaraditya303, markshannon, ncoghlan, pablogsal and warsaw as code owners September 24, 2026 14:38
@bedevere-app bedevere-app Bot mentioned this pull request Sep 24, 2026
lazy import a.b as c resolves b as an attribute of a instead of importing the module a.b #157757
Closed
@bedevere-app bedevere-app Bot added the awaiting review label Sep 24, 2026
@johnslavik
johnslavik requested review from encukou and johnslavik September 24, 2026 14:59
@hugovk hugovk added interpreter-core (Objects, Python, Grammar, and Parser dirs) release-blocker topic-lazy-imports labels Sep 24, 2026
@github-project-automation github-project-automation Bot added this to Release and Deferred blockers 🚫 Sep 24, 2026
@github-project-automation github-project-automation Bot moved this to Todo in Release and Deferred blockers 🚫 Sep 24, 2026
@brittanyrey brittanyrey changed the title gh-157757: [RFC] Import the module a lazy import a.b as c names gh-157757: Import the module a lazy import a.b as c names Sep 24, 2026
@brittanyrey brittanyrey changed the title gh-157757: Import the module a lazy import a.b as c names gh-157757: Fix to make lazy import a.b as c import the module a.b Sep 24, 2026
@pablogsal

pablogsal commented Sep 24, 2026

Copy link
Copy Markdown
Member

Hmm, maybe we can have each deferred IMPORT_FROM hold onto the previous placeholder and the attribute name?

For import a.b.c as d, we’d keep the original import of "a.b.c", then record the lookup of b, then c. When resolving it, we could walk back to the original import and apply those lookups in order with _PyEval_ImportFrom. Each step would just add one node, without copying the previous names.

Perhaps we can use the existing fields for this: lz_from could hold either the module name or the previous placeholder, and lz_attr could hold the fromlist or the attribute name. That would also handle a custom __lazy_import__ returning a placeholder for a different module name, since we’d keep the actual lookups instead of reconstructing them from that name.

I prototyped this and it seems to work.

We would keep the intermediate placeholders around until resolution, so it uses more memory. I think it’s worth considering, though. It follows what the bytecode does and avoids needing the extra flag.

brittanyrey 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.

@brittanyrey

brittanyrey commented Sep 24, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @pablogsal! That was very useful context + direction.
I had initially held off from publishing this one since the new lz_dotted_as felt like overkill for a single corner case

All reactions

Sorry, something went wrong.

Uh oh!

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

@brettcannon
brettcannon removed their request for review September 24, 2026 20:00
pablogsal
pablogsal reviewed Sep 25, 2026
View reviewed changes
Comment thread Python/import.c Resolved

Uh oh!

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

@pablogsal

pablogsal commented Sep 25, 2026

Copy link
Copy Markdown
Member

Yep, I think the chaining is much nicer than the flag: we just replay the same IMPORT_FROM lookups the eager bytecode does, so there is no special case for import a.b as c anymore and custom __lazy_import__ placeholders work too. I left a small comment about empty fromlist tuples, otherwise this looks good to me. Thanks a lot for working on this!

brittanyrey reacted with heart emoji
All reactions
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

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

@brittanyrey

brittanyrey commented Sep 26, 2026

Copy link
Copy Markdown
Contributor Author

Moved the change into the constructor + added two tests

All reactions

Sorry, something went wrong.

Uh oh!

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

brittanyrey added 3 commits September 26, 2026 20:43
@brittanyrey @pablogsal
Import the module a lazy import a.b as c names
0090e4b
`import a.b as c` compiles to `IMPORT_NAME a.b` followed by `IMPORT_FROM b`.
Lazily, IMPORT_NAME leaves a placeholder holding "a.b", and IMPORT_FROM
rewrote it into the placeholder `lazy from a import b` produces.  Reification
then imported `a` alone and read `b` off it, so the module `a.b` was never
imported under its own name: an attribute of the package shadowing it answered
instead, and `math.pi`, which no module backs, bound the float where the eager
statement raises ModuleNotFoundError.

Mark the dotted import on the placeholder and keep the whole name on it.
Reification imports that name and then walks its components with IMPORT_FROM,
which is what the eager statement does.

The test pinning `lazy import math.pi as pi` as working is inverted, since the
eager statement raises.
@brittanyrey @pablogsal
Stop excluding test_trace from the lazy-imports-all run
ba730e1
It passes now that a lazy `import a.b as c` imports the module: the
KeyError on 'test.tracedmodules.testmod' came from the submodule never
being imported under its own name.
@brittanyrey @pablogsal
Rename lz_submodule to lz_dotted_as and trim the comments
1226e44
The flag means "bind the whole dotted name, not the root", which the old
name did not say, and import.c already has unrelated lazy_pending_submodules
machinery to be confused with.
brittanyrey and others added 4 commits September 26, 2026 20:43
@brittanyrey @pablogsal
Chain lazy IMPORT_FROM placeholders instead of flagging dotted imports
855d3f8
Each deferred IMPORT_FROM off a placeholder without a fromlist now keeps
the previous placeholder in lz_from and the attribute name in lz_attr.
Reification walks back to the placeholder IMPORT_NAME left, runs that
import, and replays the lookups in order with _PyEval_ImportFrom, which
is what the eager bytecode does.  This drops the lz_dotted_as flag and
also follows a custom __lazy_import__ that returns a placeholder for a
different module name.
@brittanyrey @pablogsal
Chain every deferred IMPORT_FROM onto the previous placeholder
867e6ed
`lazy from a import b` now records its lookup the same way as `import
a.b as c`, so a placeholder holds either the module name and fromlist or
the previous placeholder and an attribute name, and reification has a
single path.  The import passes only the name being resolved as the
fromlist, so accessing b still does not import the other names'
submodules.
@brittanyrey @pablogsal
Treat an empty fromlist on a lazy import placeholder as no fromlist
5f48508
__import__("a.b", fromlist=()) returns the top-level package `a`, the same
as fromlist=None, but the placeholder kept the empty tuple.  Every consumer
of lz_attr then read it as a real fromlist: reification narrowed it to the
chained attribute and replayed the lookups on `a.b`, _PyEval_LazyImportFrom
took the attribute off sys.modules["a.b"], and the repr named `a.b.attr`.

_PyLazyImport_New already collapses None to NULL for exactly this reason,
so collapse an empty tuple there too and every site follows.
@pablogsal
pythongh-157757: Preserve empty fromlists for custom import hooks
48244f1
@pablogsal
pablogsal force-pushed the b-gh157757-lazy-dotted-as branch from c10339c to 48244f1 Compare September 26, 2026 19:46
pablogsal
pablogsal approved these changes Sep 26, 2026
View reviewed changes
@pablogsal
pablogsal enabled auto-merge (squash) September 26, 2026 19:46
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting review labels Sep 26, 2026
@hugovk hugovk added the needs backport to 3.15 bugs and security fixes label Sep 26, 2026
@pablogsal
pablogsal merged commit 1e8ff18 into python:main Sep 26, 2026
66 checks passed

Uh oh!

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

@github-project-automation github-project-automation Bot moved this from Todo to Done in Release and Deferred blockers 🚫 Sep 26, 2026
@miss-islington-app

miss-islington-app Bot commented Sep 26, 2026

Copy link
Copy Markdown

Thanks @brittanyrey for the PR, and @pablogsal for merging it 🌮🎉.. I'm working now to backport this PR to: 3.15.
🐍🍒⛏🤖 I'm not a witch! I'm not a witch!

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 merge label Sep 26, 2026
@miss-islington-app

miss-islington-app Bot commented Sep 26, 2026

Copy link
Copy Markdown

Sorry, @brittanyrey and @pablogsal, I could not cleanly backport this to 3.15 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 1e8ff18a1215b711136b4377282e392583847d62 3.15
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 pablogsal Sep 26, 2026
@pablogsal

pablogsal commented Sep 26, 2026

Copy link
Copy Markdown
Member

Great work on the lazy import fix, @brittanyrey! Thanks a lot! ❤️

hugovk reacted with hooray emoji hugovk reacted with heart emoji hugovk reacted with rocket emoji
All reactions
  • 🎉 1 reaction
  • ❤️ 1 reaction
  • 🚀 1 reaction

Sorry, something went wrong.

Uh oh!

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

@pablogsal pablogsal mentioned this pull request Sep 26, 2026
[3.15] gh-157757: Fix to make lazy import a.b as c import the module a.b (GH-158092) #158257
Merged
@bedevere-app

bedevere-app Bot commented Sep 26, 2026

Copy link
Copy Markdown

GH-158257 is a backport of this pull request to the 3.15 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.15 bugs and security fixes label Sep 26, 2026
pablogsal added a commit that referenced this pull request Sep 26, 2026
@pablogsal @brittanyrey
[3.15] gh-157757: Fix to make lazy import a.b as c import the modul…
1a2d24e
…e `a.b` (GH-158092) (#158257)

gh-157757: Fix to make `lazy import a.b as c` import the module `a.b` (#158092)

* Import the module a lazy `import a.b as c` names

`import a.b as c` compiles to `IMPORT_NAME a.b` followed by `IMPORT_FROM b`.
Lazily, IMPORT_NAME leaves a placeholder holding "a.b", and IMPORT_FROM
rewrote it into the placeholder `lazy from a import b` produces.  Reification
then imported `a` alone and read `b` off it, so the module `a.b` was never
imported under its own name: an attribute of the package shadowing it answered
instead, and `math.pi`, which no module backs, bound the float where the eager
statement raises ModuleNotFoundError.

Mark the dotted import on the placeholder and keep the whole name on it.
Reification imports that name and then walks its components with IMPORT_FROM,
which is what the eager statement does.

The test pinning `lazy import math.pi as pi` as working is inverted, since the
eager statement raises.

* Stop excluding test_trace from the lazy-imports-all run

It passes now that a lazy `import a.b as c` imports the module: the
KeyError on 'test.tracedmodules.testmod' came from the submodule never
being imported under its own name.

* Rename lz_submodule to lz_dotted_as and trim the comments

The flag means "bind the whole dotted name, not the root", which the old
name did not say, and import.c already has unrelated lazy_pending_submodules
machinery to be confused with.

* Chain lazy IMPORT_FROM placeholders instead of flagging dotted imports

Each deferred IMPORT_FROM off a placeholder without a fromlist now keeps
the previous placeholder in lz_from and the attribute name in lz_attr.
Reification walks back to the placeholder IMPORT_NAME left, runs that
import, and replays the lookups in order with _PyEval_ImportFrom, which
is what the eager bytecode does.  This drops the lz_dotted_as flag and
also follows a custom __lazy_import__ that returns a placeholder for a
different module name.

* Chain every deferred IMPORT_FROM onto the previous placeholder

`lazy from a import b` now records its lookup the same way as `import
a.b as c`, so a placeholder holds either the module name and fromlist or
the previous placeholder and an attribute name, and reification has a
single path.  The import passes only the name being resolved as the
fromlist, so accessing b still does not import the other names'
submodules.

* Treat an empty fromlist on a lazy import placeholder as no fromlist

__import__("a.b", fromlist=()) returns the top-level package `a`, the same
as fromlist=None, but the placeholder kept the empty tuple.  Every consumer
of lz_attr then read it as a real fromlist: reification narrowed it to the
chained attribute and replayed the lookups on `a.b`, _PyEval_LazyImportFrom
took the attribute off sys.modules["a.b"], and the repr named `a.b.attr`.

_PyLazyImport_New already collapses None to NULL for exactly this reason,
so collapse an empty tuple there too and every site follows.

* gh-157757: Preserve empty fromlists for custom import hooks

---------


(cherry picked from commit 1e8ff18)

Co-authored-by: Brittany Reynoso <[email protected]>
@hugovk hugovk mentioned this pull request Sep 28, 2026
lazy import a.b as c incorrectly binds to a.b.b #157614
Open
Kronuz pushed a commit to Kronuz/cpython that referenced this pull request Oct 1, 2026
@pablogsal @brittanyrey @Kronuz
[3.15] pythongh-157757: Fix to make lazy import a.b as c import the…
0bf1009
… module `a.b` (pythonGH-158092) (python#158257)

pythongh-157757: Fix to make `lazy import a.b as c` import the module `a.b` (python#158092)

* Import the module a lazy `import a.b as c` names

`import a.b as c` compiles to `IMPORT_NAME a.b` followed by `IMPORT_FROM b`.
Lazily, IMPORT_NAME leaves a placeholder holding "a.b", and IMPORT_FROM
rewrote it into the placeholder `lazy from a import b` produces.  Reification
then imported `a` alone and read `b` off it, so the module `a.b` was never
imported under its own name: an attribute of the package shadowing it answered
instead, and `math.pi`, which no module backs, bound the float where the eager
statement raises ModuleNotFoundError.

Mark the dotted import on the placeholder and keep the whole name on it.
Reification imports that name and then walks its components with IMPORT_FROM,
which is what the eager statement does.

The test pinning `lazy import math.pi as pi` as working is inverted, since the
eager statement raises.

* Stop excluding test_trace from the lazy-imports-all run

It passes now that a lazy `import a.b as c` imports the module: the
KeyError on 'test.tracedmodules.testmod' came from the submodule never
being imported under its own name.

* Rename lz_submodule to lz_dotted_as and trim the comments

The flag means "bind the whole dotted name, not the root", which the old
name did not say, and import.c already has unrelated lazy_pending_submodules
machinery to be confused with.

* Chain lazy IMPORT_FROM placeholders instead of flagging dotted imports

Each deferred IMPORT_FROM off a placeholder without a fromlist now keeps
the previous placeholder in lz_from and the attribute name in lz_attr.
Reification walks back to the placeholder IMPORT_NAME left, runs that
import, and replays the lookups in order with _PyEval_ImportFrom, which
is what the eager bytecode does.  This drops the lz_dotted_as flag and
also follows a custom __lazy_import__ that returns a placeholder for a
different module name.

* Chain every deferred IMPORT_FROM onto the previous placeholder

`lazy from a import b` now records its lookup the same way as `import
a.b as c`, so a placeholder holds either the module name and fromlist or
the previous placeholder and an attribute name, and reification has a
single path.  The import passes only the name being resolved as the
fromlist, so accessing b still does not import the other names'
submodules.

* Treat an empty fromlist on a lazy import placeholder as no fromlist

__import__("a.b", fromlist=()) returns the top-level package `a`, the same
as fromlist=None, but the placeholder kept the empty tuple.  Every consumer
of lz_attr then read it as a real fromlist: reification narrowed it to the
chained attribute and replayed the lookups on `a.b`, _PyEval_LazyImportFrom
took the attribute off sys.modules["a.b"], and the repr named `a.b.attr`.

_PyLazyImport_New already collapses None to NULL for exactly this reason,
so collapse an empty tuple there too and every site follows.

* pythongh-157757: Preserve empty fromlists for custom import hooks

---------

(cherry picked from commit 1e8ff18)

Co-authored-by: Brittany Reynoso <[email protected]>
(cherry picked from commit 1a2d24e)
Kronuz added a commit to Kronuz/cpython that referenced this pull request Oct 1, 2026
@Kronuz
Guard chained lazy-import resolver against non-tuple lz_attr
2ea30ab
The nested-placeholder replay path in _PyImport_LoadLazyImportTstate
called PyTuple_GET_SIZE(root->lz_attr) without a PyTuple_Check, while the
sibling _PyEval_LazyImportFrom path added in the same upstream change
(pythongh-157757 / pythonGH-158092) guards the identical access with PyTuple_Check,
as does the fromlist handling a few lines below. _PyLazyImport_New
accepts a Unicode fromlist by design, so the tuple invariant on lz_attr
is maintained only by callers; match the sibling guard to harden the
reifier for a fleet-wide patch.

No reachable Python path currently builds a root placeholder with a
Unicode lz_attr (the builtin __lazy_import__ normalizes a str fromlist
to a tuple before storing), so this is defense-in-depth and a
consistency fix rather than a live crash. Behaviour of normal dotted
lazy imports is unchanged; upstream test_lazy_import (133) and the
LinkedIn local lazy suite pass.
@brittanyrey
brittanyrey deleted the b-gh157757-lazy-dotted-as branch October 1, 2026 21:36
Kronuz pushed a commit to Kronuz/cpython that referenced this pull request Oct 5, 2026
@pablogsal @brittanyrey @Kronuz
[3.15] pythongh-157757: Fix to make lazy import a.b as c import the…
2279ffb
… module `a.b` (pythonGH-158092) (python#158257)

pythongh-157757: Fix to make `lazy import a.b as c` import the module `a.b` (python#158092)

* Import the module a lazy `import a.b as c` names

`import a.b as c` compiles to `IMPORT_NAME a.b` followed by `IMPORT_FROM b`.
Lazily, IMPORT_NAME leaves a placeholder holding "a.b", and IMPORT_FROM
rewrote it into the placeholder `lazy from a import b` produces.  Reification
then imported `a` alone and read `b` off it, so the module `a.b` was never
imported under its own name: an attribute of the package shadowing it answered
instead, and `math.pi`, which no module backs, bound the float where the eager
statement raises ModuleNotFoundError.

Mark the dotted import on the placeholder and keep the whole name on it.
Reification imports that name and then walks its components with IMPORT_FROM,
which is what the eager statement does.

The test pinning `lazy import math.pi as pi` as working is inverted, since the
eager statement raises.

* Stop excluding test_trace from the lazy-imports-all run

It passes now that a lazy `import a.b as c` imports the module: the
KeyError on 'test.tracedmodules.testmod' came from the submodule never
being imported under its own name.

* Rename lz_submodule to lz_dotted_as and trim the comments

The flag means "bind the whole dotted name, not the root", which the old
name did not say, and import.c already has unrelated lazy_pending_submodules
machinery to be confused with.

* Chain lazy IMPORT_FROM placeholders instead of flagging dotted imports

Each deferred IMPORT_FROM off a placeholder without a fromlist now keeps
the previous placeholder in lz_from and the attribute name in lz_attr.
Reification walks back to the placeholder IMPORT_NAME left, runs that
import, and replays the lookups in order with _PyEval_ImportFrom, which
is what the eager bytecode does.  This drops the lz_dotted_as flag and
also follows a custom __lazy_import__ that returns a placeholder for a
different module name.

* Chain every deferred IMPORT_FROM onto the previous placeholder

`lazy from a import b` now records its lookup the same way as `import
a.b as c`, so a placeholder holds either the module name and fromlist or
the previous placeholder and an attribute name, and reification has a
single path.  The import passes only the name being resolved as the
fromlist, so accessing b still does not import the other names'
submodules.

* Treat an empty fromlist on a lazy import placeholder as no fromlist

__import__("a.b", fromlist=()) returns the top-level package `a`, the same
as fromlist=None, but the placeholder kept the empty tuple.  Every consumer
of lz_attr then read it as a real fromlist: reification narrowed it to the
chained attribute and replayed the lookups on `a.b`, _PyEval_LazyImportFrom
took the attribute off sys.modules["a.b"], and the repr named `a.b.attr`.

_PyLazyImport_New already collapses None to NULL for exactly this reason,
so collapse an empty tuple there too and every site follows.

* pythongh-157757: Preserve empty fromlists for custom import hooks

---------

(cherry picked from commit 1e8ff18)

Co-authored-by: Brittany Reynoso <[email protected]>
(cherry picked from commit 1a2d24e)
Kronuz added a commit to Kronuz/cpython that referenced this pull request Oct 5, 2026
@Kronuz
Guard chained lazy-import resolver against non-tuple lz_attr
b68a11b
The nested-placeholder replay path in _PyImport_LoadLazyImportTstate
called PyTuple_GET_SIZE(root->lz_attr) without a PyTuple_Check, while the
sibling _PyEval_LazyImportFrom path added in the same upstream change
(pythongh-157757 / pythonGH-158092) guards the identical access with PyTuple_Check,
as does the fromlist handling a few lines below. _PyLazyImport_New
accepts a Unicode fromlist by design, so the tuple invariant on lz_attr
is maintained only by callers; match the sibling guard to harden the
reifier for a fleet-wide patch.

No reachable Python path currently builds a root placeholder with a
Unicode lz_attr (the builtin __lazy_import__ normalizes a str fromlist
to a tuple before storing), so this is defense-in-depth and a
consistency fix rather than a live crash. Behaviour of normal dotted
lazy imports is unchanged; upstream test_lazy_import (133) and the
LinkedIn local lazy suite pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@pablogsal pablogsal pablogsal approved these changes
@Yhg1s Yhg1s Awaiting requested review from Yhg1s Yhg1s is a code owner
@DinoV DinoV Awaiting requested review from DinoV DinoV is a code owner
@ericsnowcurrently ericsnowcurrently Awaiting requested review from ericsnowcurrently ericsnowcurrently is a code owner
@ncoghlan ncoghlan Awaiting requested review from ncoghlan ncoghlan is a code owner
@warsaw warsaw Awaiting requested review from warsaw warsaw is a code owner
@FFY00 FFY00 Awaiting requested review from FFY00 FFY00 is a code owner
@kumaraditya303 kumaraditya303 Awaiting requested review from kumaraditya303 kumaraditya303 is a code owner
@markshannon markshannon Awaiting requested review from markshannon markshannon is a code owner
@johnslavik johnslavik Awaiting requested review from johnslavik
@encukou encukou Awaiting requested review from encukou

Uh oh!

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

Assignees

@pablogsal pablogsal

Labels

interpreter-core (Objects, Python, Grammar, and Parser dirs) release-blocker topic-lazy-imports

Projects

Release and Deferred blockers 🚫
Status: Done

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.

3 participants

@brittanyrey @pablogsal @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.