-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix windows long paths #2566
Fix windows long paths #2566
Conversation
2984db2
to
8337c6b
Compare
9d3b858
to
eee4180
Compare
6830c7d
to
f4b93c8
Compare
… hit path length limits
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.
There is much about the need for this change that is unfortunate, but from what I can see, the changes here look excellent. I suspect the integration tests will be the best indicator of success - this LGTM when the tests pass (though I did have one question about them!).
): | ||
# all our hard work and the path was still too long. Log and | ||
# continue. | ||
logger.debug( |
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.
👍
temp_dir = magic_prefix + temp_dir | ||
outer = tempfile.mkdtemp(prefix='dbt-int-test-', dir=temp_dir) | ||
# then inside _that_ directory make a new one that gets us to just | ||
# barely 260 total. I picked 250 to account for the '\' and anything |
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.
is there a reason we want to just barely eclipse 260 chars instead of going for, say, 300 chars? I just want to make sure I understand the logic behind this test.
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.
Yeah! We have to os.chdir
into the directory we build here, and the \\?\
doesn't work for os.chdir
because the underlying windows APIs for that function don't handle it.
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.
thanks, i hate it
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.
Nice, thanks for the comments around the windows nuances
resolves #2558
Description
This PR makes long paths on windows work. The issue described in #2558 no longer occurs, though there are a couple caveats:
dbt deps
and the total path length includingdbt_modules
is >= 260, I think dbt will fail, because we'll try tocd
into a directory duringdeps
that will have a total length >= 260 and that isn't allowed ever, apparently. It will tell you the file path is too long, which is nice.dbt clean
successfully removes things fromtarget
, which satisfies me.How this works:
First, this code checks that it needs to run at all. If the system isn't running windows, the path is under 250 chars (python likes to append things like
'*.*'
in various places), or the windows function that tells us long paths are enabled is set, we don't do anything to the path.If the path needs to be massaged, dbt will prepend
\\?\
(escaped to'\\\\?\\'
) to paths that we'll read/write from, which means we access it as a win32 File Namespace. This tells windows to skip path parsing, which bypasses MAX_PATH. There are some restrictions: Paths must be absolute, paths must not have any/
in them, and something about UNC paths that I hope I got right 😬 Those caveats actually aren't a big deal for dbt.I am happy to report that very new versions of windows 10/windows server 2019 with a certain registry key/group policy setting actually don't have this problem at all with long paths, because starting with 3.6, python opts out of
MAX_PATH
with a compile-time options, and those versions of Windows know how to handle that. So in 10 years or whatever it takes for us to drop support, we can just not care about this at all.I found this blog post from project zero helpful. They're approaching it from a security standpoint but there are some very helpful charts. Note that we actually don't want the "NT Path", (it's distinct from the "win32 file namespace", so ignore that part). And we don't care about "drive-relative paths" because that's a cmd.exe thing.
Checklist
CHANGELOG.md
and added information about my change to the "dbt next" section.