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-75723: Idempotent `.pth` execution in `site.addsitedir` by asottile · Pull Request #147951 · python/cpython

Conversation

@asottile

@asottile asottile commented Mar 31, 2026 •
edited by bedevere-app Bot
Loading

Uh oh!

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

Copy link
Copy Markdown
Contributor
  • Issue: pth files in site-packages of venvs are executed twice #75723

Sorry, something went wrong.

Uh oh!

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

johnslavik and tcely reacted with thumbs up emoji qexat, mrswats, MajorTanya, jabdinghoff, hassaanalansary, alexprengere, Martin005, Ttibsi, BookCatKid, edgarrmondragon, and 6 more reacted with hooray emoji
All reactions
  • 👍 2 reactions
  • 🎉 16 reactions
@asottile
Idempotent .pth execution in site.addsitedir
6c342df
@asottile
asottile requested a review from FFY00 as a code owner March 31, 2026 20:17
@bedevere-app bedevere-app Bot added the awaiting review label Mar 31, 2026
@bedevere-app bedevere-app Bot mentioned this pull request Mar 31, 2026
pth files in site-packages of venvs are executed twice #75723
Closed
@tcely

tcely commented Apr 1, 2026 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown

@asottile

Do you have any ideas how to explain the test failure?

cpython/Lib/test/test_xmlrpc.py

Lines 479 to 489 in 4810bed

class DateTimeTestCase(unittest.TestCase):
def test_default(self):
with mock.patch('time.localtime') as localtime_mock:
time_struct = time.struct_time(
[2013, 7, 15, 0, 24, 49, 0, 196, 0])
localtime_mock.return_value = time_struct
localtime = time.localtime()
t = xmlrpclib.DateTime()
self.assertEqual(str(t),
time.strftime("%Y%m%dT%H:%M:%S", localtime))


   FAIL: test_default (test.test_xmlrpc.DateTimeTestCase.test_default)
   ----------------------------------------------------------------------
   Traceback (most recent call last):
     File "/Users/runner/Library/Developer/CoreSimulator/Devices/CED4C8DA-56B5-4FBF-A288-C5C2C197B3AD/data/Containers/Bundle/Application/4B219D99-CC21-4E94-B496-5F175FEC5822/iOSTestbed.app/python/lib/python3.15/test/test_xmlrpc.py", line 487, in test_default
       self.assertEqual(str(t),
       ~~~~~~~~~~~~~~~~^^^^^^^^
                        time.strftime("%Y%m%dT%H:%M:%S", localtime))
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   AssertionError: '20260331T20:39:38' != '20130715T00:24:49'
   - 20260331T20:39:38
   + 20130715T00:24:49
   
   
   ----------------------------------------------------------------------
   Ran 93 tests in 27.345s
   
   FAILED (failures=1)
   test test_xmlrpc failed
All reactions

Sorry, something went wrong.

Uh oh!

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

@FFY00 FFY00 added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 2, 2026
@bedevere-bot

bedevere-bot commented Apr 2, 2026

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @FFY00 for commit 6c342df 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F147951%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

All reactions

Sorry, something went wrong.

Uh oh!

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

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Apr 2, 2026
@FFY00

FFY00 commented Apr 2, 2026

Copy link
Copy Markdown
Member

The test_xmlrpc failure on iOS only seems weird, I triggered a re-run.

All reactions

Sorry, something went wrong.

Uh oh!

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

@FFY00

FFY00 commented Apr 2, 2026

Copy link
Copy Markdown
Member

Well, the test is still failing. It seems like the time.localtime mock is not being installed in xmlrpc.client, or is losing the side effect after one call, weird.

I am gonna sync with main, just to be sure this is not a known issue.

All reactions

Sorry, something went wrong.

Uh oh!

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

Merge branch 'main' into asottile-pythongh-75723
96ed0e8
FFY00
FFY00 requested changes Apr 2, 2026
View reviewed changes

@FFY00 FFY00 left a comment

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.

This looks okay, overall. There is just the test_xmlrpc failure we need to fix, and the news text that should be updated.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Misc/NEWS.d/next/Core_and_Builtins/2026-03-31-16-15-15.gh-issue-75723.BZ4Rsn.rst Resolved

Uh oh!

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

@bedevere-app bedevere-app Bot removed the awaiting review label Apr 2, 2026
@bedevere-app

bedevere-app Bot commented Apr 2, 2026

Copy link
Copy Markdown

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

All reactions

Sorry, something went wrong.

Uh oh!

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

@bedevere-app bedevere-app Bot added the awaiting changes label Apr 2, 2026
@tcely

tcely commented Apr 2, 2026

Copy link
Copy Markdown

@FFY00 After looking into the code for a bit, this is the best test refinement I have come up with:

def test_default(self):
    # Patch BOTH time and localtime inside the client module
    with mock.patch('xmlrpc.client.time.time') as time_mock, \
         mock.patch('xmlrpc.client.time.localtime') as localtime_mock:
        
        # 1. Force the 'current' time to be a specific float
        time_mock.return_value = 1373847889.0 
        
        # 2. Force the conversion to be your specific struct
        time_struct = time.struct_time([2013, 7, 15, 0, 24, 49, 0, 196, 0])
        localtime_mock.return_value = time_struct
        
        t = xmlrpclib.DateTime()
        
        self.assertEqual(str(t), "20130715T00:24:49")
All reactions

Sorry, something went wrong.

Uh oh!

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

@picnixz

picnixz commented Apr 2, 2026 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown
Member

I think this can be simplified as follows:

@mock.patch('xmlrpc.client.time.time', return_value=1373847889.0)
@mock.patch(
    'xmlrpc.client.time.localtime',
    return_value=time.struct_time([2013, 7, 15, 0, 24, 49, 0, 196, 0]),
)
def test_default(self, *_):
    t = xmlrpclib.DateTime()
    
    self.assertEqual(str(t), "20130715T00:24:49")
All reactions

Sorry, something went wrong.

Uh oh!

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

@asottile
potentially fix monkeypatch leak?
c44e192
tcely
tcely reviewed Apr 5, 2026
View reviewed changes
Comment thread Misc/NEWS.d/next/Core_and_Builtins/2026-03-31-16-15-15.gh-issue-75723.BZ4Rsn.rst Resolved

Uh oh!

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

@asottile

asottile commented Apr 5, 2026

Copy link
Copy Markdown
Contributor Author

I didn't expect the Spanish Inquisition

MajorTanya and mrswats reacted with eyes emoji
All reactions
  • 👀 2 reactions

Sorry, something went wrong.

Uh oh!

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

@bedevere-app bedevere-app Bot added awaiting change review and removed awaiting changes labels Apr 5, 2026
@bedevere-app

bedevere-app Bot commented Apr 5, 2026

Copy link
Copy Markdown

Nobody expects the Spanish Inquisition!

@FFY00: please review the changes made to this pull request.

All reactions

Sorry, something went wrong.

Uh oh!

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

@bedevere-app
bedevere-app Bot requested a review from FFY00 April 5, 2026 18:43
@asottile
fix blind copy paste of recommendation
f077abd
johnslavik
johnslavik approved these changes Apr 5, 2026
View reviewed changes

@johnslavik johnslavik left a comment •
edited
Loading

Uh oh!

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

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.

<insert a cat picture>

Small nits

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Lib/test/test_site.py
Comment on lines +449 to +453
PROG = f'''\
if {self.imported!r} in sys.modules:
open({self.idempotent_fail_path!r}, 'a+').close()
'''
print(f"import sys; exec({PROG!r})", file=FILE)

@johnslavik johnslavik Apr 5, 2026

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.

Consider this (zero effort because dedent is already imported)

Suggested change
PROG = f'''\
if {self.imported!r} in sys.modules:
open({self.idempotent_fail_path!r}, 'a+').close()
'''
print(f"import sys; exec({PROG!r})", file=FILE)
PROG = dedent(f'''\
if {self.imported!r} in sys.modules:
open({self.idempotent_fail_path!r}, 'a+').close()
''')
print(f"import sys; exec({PROG!r})", file=FILE)

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Lib/test/test_site.py Resolved

Uh oh!

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

@johnslavik

johnslavik commented Apr 5, 2026 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown
Member

I'm adding backport labels, but take them off if you see any room for surprise in the implications of this change and we want to sell this as a feature

All reactions

Sorry, something went wrong.

Uh oh!

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

@johnslavik johnslavik added needs backport to 3.13 only security fixes needs backport to 3.14 bugs and security fixes labels Apr 5, 2026
picnixz
picnixz reviewed Apr 5, 2026
View reviewed changes
Comment thread Misc/NEWS.d/next/Core_and_Builtins/2026-03-31-16-15-15.gh-issue-75723.BZ4Rsn.rst Resolved

Uh oh!

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

asottile added 3 commits April 7, 2026 16:04
@asottile
Update 2026-03-31-16-15-15.gh-issue-75723.BZ4Rsn.rst
aeee2ff
@asottile
Merge remote-tracking branch 'origin/main' into asottile-pythongh-75723
4005472
@asottile
fix implicit merge conflict with 24c4aec
66ebfc9
@emmatyping

emmatyping commented May 3, 2026

Copy link
Copy Markdown
Member

It looks like the macOS failure is an instance of #149156

All reactions

Sorry, something went wrong.

Uh oh!

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

@asottile

asottile commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

@warsaw @brettcannon this also fixes the same double call bug with the new pep 829 implementation

MajorTanya, mrswats, and warsaw reacted with eyes emoji
All reactions
  • 👀 3 reactions

Sorry, something went wrong.

Uh oh!

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

@zsol-openai

This comment was marked as resolved.

Sign in to view
@asottile

This comment was marked as resolved.

Sign in to view
@zsol-openai

This comment was marked as resolved.

Sign in to view
@warsaw warsaw self-assigned this May 8, 2026
@warsaw

warsaw commented May 8, 2026

Copy link
Copy Markdown
Member

I want to fix and test this differently in Python 3.15, but this looks pretty good for 3.14 and 3.13. Once I land that in main (and not backport), I'll get this in shape for those older branches.

Thanks for both finding and fixing this bug!

All reactions

Sorry, something went wrong.

Uh oh!

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

warsaw added a commit that referenced this pull request May 11, 2026
@warsaw @asottile @FFY00
gh-75723: Fix double evaluation of .pth and .site files in venvs (#14…
1978785
…9583)

* Idempotent `.pth` execution in `site.addsitedir`
* potentially fix monkeypatch leak?

* fix blind copy paste of recommendation

* Update 2026-03-31-16-15-15.gh-issue-75723.BZ4Rsn.rst

* fix implicit merge conflict with 24c4aec

* Add failing tests for gh-75723

Based on @asottle branch !asottle-gh-75723 but refactored for `main`.
This will need a different backport.

* Repair gh-75723

The original fix is here: #147951
but I'm refactoring a bit for `main`.

* Refactor _make_mod() so we can use it to create package modules too

* Add myself to CODEOWNERS for the site module

---------

Co-authored-by: anthony sottile <[email protected]>
Co-authored-by: Filipe Laíns <[email protected]>
@tcely

tcely commented May 22, 2026

Copy link
Copy Markdown

@warsaw @asottile

Anything left for this? Perhaps a mention of which pull request was actually merged with the similar changes. There has been a lot to keep track of since this was opened.

All reactions

Sorry, something went wrong.

Uh oh!

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

@asottile

asottile commented May 27, 2026

Copy link
Copy Markdown
Contributor Author

yeah this can be closed out -- superseded by #149799

All reactions

Sorry, something went wrong.

Uh oh!

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

@asottile asottile closed this May 27, 2026
@asottile
asottile deleted the asottile-gh-75723 branch May 27, 2026 12:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@picnixz picnixz picnixz left review comments
@johnslavik johnslavik johnslavik approved these changes
@FFY00 FFY00 Awaiting requested review from FFY00 FFY00 is a code owner
+1 more reviewer
@tcely tcely tcely left review comments
Reviewers whose approvals may not affect merge requirements

Uh oh!

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

Assignees

@warsaw warsaw

Labels

awaiting change review needs backport to 3.13 only security fixes needs backport to 3.14 bugs and security fixes

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.

9 participants

@asottile @tcely @bedevere-bot @FFY00 @picnixz @johnslavik @emmatyping @zsol-openai @warsaw
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 01402520 — 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.