diff options
author | AlexSm <alex@ydb.tech> | 2024-01-18 11:28:56 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-18 11:28:56 +0100 |
commit | 9d0a3761b3201e0d9db879a7adf91876ebdb0564 (patch) | |
tree | 541d11ac878c18efd7ebca81e35112aa0fef995b /library | |
parent | 404ef8886ecc9736bc58ade6da2fbd83b486a408 (diff) | |
download | ydb-9d0a3761b3201e0d9db879a7adf91876ebdb0564.tar.gz |
Library import 8 (#1074)
* Library import 8
* Add contrib/libs/cxxsupp/libcxx/include/__verbose_abort
Diffstat (limited to 'library')
24 files changed, 316 insertions, 64 deletions
diff --git a/library/cpp/http/fetch/exthttpcodes.h b/library/cpp/http/fetch/exthttpcodes.h index 49e7e5e62d..764e637fee 100644 --- a/library/cpp/http/fetch/exthttpcodes.h +++ b/library/cpp/http/fetch/exthttpcodes.h @@ -50,6 +50,7 @@ enum ExtHttpCodes { HTTP_FETCHER_MB_ERROR = 1041, HTTP_SSL_CERT_ERROR = 1042, HTTP_FIREWALL_REJECT = 1043, + HTTP_INTERNAL_DNS_ERROR = 1047, HTTP_PROXY_REQUEST_CANCELED = 1051, // Custom (replace HTTP 200/304) diff --git a/library/cpp/http/fetch/http_digest.cpp b/library/cpp/http/fetch/http_digest.cpp index 4dff4b047d..5adf391709 100644 --- a/library/cpp/http/fetch/http_digest.cpp +++ b/library/cpp/http/fetch/http_digest.cpp @@ -47,21 +47,19 @@ const char* httpDigestHandler::getHeaderInstruction() const { } /************************************************************/ -void httpDigestHandler::generateCNonce(char* outCNonce) { - if (!*outCNonce) - sprintf(outCNonce, "%ld", (long)time(nullptr)); -} - -/************************************************************/ -inline void addMD5(MD5& ctx, const char* value) { +Y_FORCE_INLINE void addMD5(MD5& ctx, const char* value) { ctx.Update((const unsigned char*)(value), strlen(value)); } -inline void addMD5(MD5& ctx, const char* value, int len) { +Y_FORCE_INLINE void addMD5(MD5& ctx, const char* value, int len) { ctx.Update((const unsigned char*)(value), len); } -inline void addMD5Sep(MD5& ctx) { +Y_FORCE_INLINE void addMD5(MD5& ctx, std::string_view str) { + ctx.Update(str); +} + +Y_FORCE_INLINE void addMD5Sep(MD5& ctx) { addMD5(ctx, ":", 1); } @@ -69,7 +67,7 @@ inline void addMD5Sep(MD5& ctx) { /* calculate H(A1) as per spec */ void httpDigestHandler::digestCalcHA1(const THttpAuthHeader& hd, char* outSessionKey, - char* outCNonce) { + const std::string& outCNonce) { MD5 ctx; ctx.Init(); addMD5(ctx, User_); @@ -82,8 +80,6 @@ void httpDigestHandler::digestCalcHA1(const THttpAuthHeader& hd, unsigned char digest[16]; ctx.Final(digest); - generateCNonce(outCNonce); - ctx.Init(); ctx.Update(digest, 16); addMD5Sep(ctx); @@ -103,7 +99,7 @@ void httpDigestHandler::digestCalcResponse(const THttpAuthHeader& hd, const char* method, const char* nonceCount, char* outResponse, - char* outCNonce) { + const std::string& outCNonce) { char HA1[33]; digestCalcHA1(hd, HA1, outCNonce); @@ -123,9 +119,6 @@ void httpDigestHandler::digestCalcResponse(const THttpAuthHeader& hd, addMD5Sep(ctx); if (hd.qop_auth) { - if (!*outCNonce) - generateCNonce(outCNonce); - addMD5(ctx, nonceCount, 8); addMD5Sep(ctx); addMD5(ctx, outCNonce); @@ -141,7 +134,7 @@ void httpDigestHandler::digestCalcResponse(const THttpAuthHeader& hd, bool httpDigestHandler::processHeader(const THttpAuthHeader* header, const char* path, const char* method, - const char* cnonce) { + const char* cnonceIn) { if (!User_ || !header || !header->use_auth || !header->realm || !header->nonce) return false; @@ -161,16 +154,12 @@ bool httpDigestHandler::processHeader(const THttpAuthHeader* header, NonceCount_++; char nonceCount[20]; - sprintf(nonceCount, "%08d", NonceCount_); + snprintf(nonceCount, sizeof(nonceCount), "%08d", NonceCount_); - char CNonce[50]; - if (cnonce) - strcpy(CNonce, cnonce); - else - CNonce[0] = 0; + std::string cNonce = cnonceIn ? std::string(cnonceIn) : std::to_string(time(nullptr)); char response[33]; - digestCalcResponse(*header, path, method, nonceCount, response, CNonce); + digestCalcResponse(*header, path, method, nonceCount, response, cNonce); //digest-response = 1#( username | realm | nonce | digest-uri // | response | [ algorithm ] | [cnonce] | @@ -189,8 +178,8 @@ bool httpDigestHandler::processHeader(const THttpAuthHeader* header, if (header->qop_auth) out << ", qop=auth"; out << ", nc=" << nonceCount; - if (CNonce[0]) - out << ", cnonce=\"" << CNonce << "\""; + if (!cNonce.empty()) + out << ", cnonce=\"" << cNonce << "\""; out << ", response=\"" << response << "\""; if (header->opaque) out << ", opaque=\"" << header->opaque << "\""; diff --git a/library/cpp/http/fetch/http_digest.h b/library/cpp/http/fetch/http_digest.h index 3b1872d70b..e5ffa3c69e 100644 --- a/library/cpp/http/fetch/http_digest.h +++ b/library/cpp/http/fetch/http_digest.h @@ -2,11 +2,13 @@ #include "httpheader.h" +#include <string> + #include <util/system/compat.h> #include <library/cpp/http/misc/httpcodes.h> class httpDigestHandler { -protected: +private: const char* User_; const char* Password_; char* Nonce_; @@ -15,18 +17,16 @@ protected: void clear(); - void generateCNonce(char* outCNonce); - void digestCalcHA1(const THttpAuthHeader& hd, char* outSessionKey, - char* outCNonce); + const std::string& outCNonce); void digestCalcResponse(const THttpAuthHeader& hd, const char* method, const char* path, const char* nonceCount, char* outResponse, - char* outCNonce); + const std::string& outCNonce); public: httpDigestHandler(); diff --git a/library/cpp/http/fetch/httpagent.h b/library/cpp/http/fetch/httpagent.h index c66af00ced..18f10c160e 100644 --- a/library/cpp/http/fetch/httpagent.h +++ b/library/cpp/http/fetch/httpagent.h @@ -172,9 +172,9 @@ public: Hostheader = (char*)malloc((HostheaderLen = reqHostheaderLen)); } if (port == 80) - sprintf(Hostheader, "Host: %s\r\n", hostname); + snprintf(Hostheader, HostheaderLen, "Host: %s\r\n", hostname); else - sprintf(Hostheader, "Host: %s:%u\r\n", hostname, port); + snprintf(Hostheader, HostheaderLen, "Host: %s:%u\r\n", hostname, port); pHostBeg = strchr(Hostheader, ' ') + 1; pHostEnd = strchr(pHostBeg, '\r'); // convert hostname to lower case since some web server don't like @@ -195,7 +195,7 @@ public: delete[] Hostheader; Hostheader = new char[(HostheaderLen = reqHostheaderLen)]; } - sprintf(Hostheader, "Host: %s\r\n", host); + snprintf(Hostheader, HostheaderLen, "Host: %s\r\n", host); } void SetSocket(SOCKET fd) { diff --git a/library/cpp/http/fetch/httpload.cpp b/library/cpp/http/fetch/httpload.cpp index f3f6c5245e..65631203e5 100644 --- a/library/cpp/http/fetch/httpload.cpp +++ b/library/cpp/http/fetch/httpload.cpp @@ -259,9 +259,10 @@ bool httpLoadAgent::doSetHost(const TAddrList& addrs) { return false; if (RealHost_) { + size_t reqHostheaderLen = strlen(RealHost_) + 20; free(Hostheader); - Hostheader = (char*)malloc(strlen(RealHost_) + 20); - sprintf(Hostheader, "Host: %s\r\n", RealHost_); + Hostheader = (char*)malloc((HostheaderLen = reqHostheaderLen)); + snprintf(Hostheader, HostheaderLen, "Host: %s\r\n", RealHost_); } if (!URL_.IsNull(THttpURL::FlagAuth)) { diff --git a/library/cpp/unified_agent_client/client.h b/library/cpp/unified_agent_client/client.h index 62e1210803..e58ffc8b11 100644 --- a/library/cpp/unified_agent_client/client.h +++ b/library/cpp/unified_agent_client/client.h @@ -40,8 +40,8 @@ namespace NUnifiedAgent { // TLog instance for client library's own logs. // // Default: TLoggerOperator<TGlobalLog>::Log() - TClientParameters& SetLog(TLog& log) { - Log = log; + TClientParameters& SetLog(TLog log) { + Log = std::move(log); return *this; } diff --git a/library/cpp/yt/memory/blob.h b/library/cpp/yt/memory/blob.h index 0a1318c231..42cab83017 100644 --- a/library/cpp/yt/memory/blob.h +++ b/library/cpp/yt/memory/blob.h @@ -3,6 +3,8 @@ #include "ref.h" #include "ref_counted.h" +#include <library/cpp/yt/misc/port.h> + namespace NYT { //////////////////////////////////////////////////////////////////////////////// diff --git a/library/cpp/yt/memory/chunked_memory_pool.h b/library/cpp/yt/memory/chunked_memory_pool.h index a22e2ec27c..d5771480ac 100644 --- a/library/cpp/yt/memory/chunked_memory_pool.h +++ b/library/cpp/yt/memory/chunked_memory_pool.h @@ -3,6 +3,8 @@ #include "public.h" #include "ref.h" +#include <library/cpp/yt/misc/port.h> + #include <util/generic/size_literals.h> namespace NYT { diff --git a/library/cpp/yt/memory/intrusive_ptr.h b/library/cpp/yt/memory/intrusive_ptr.h index 1da3b06966..91b15279ae 100644 --- a/library/cpp/yt/memory/intrusive_ptr.h +++ b/library/cpp/yt/memory/intrusive_ptr.h @@ -55,7 +55,7 @@ public: : T_(other.Get()) { static_assert( - std::is_base_of_v<TRefCountedBase, T>, + std::derived_from<T, TRefCountedBase>, "Cast allowed only for types derived from TRefCountedBase"); if (T_) { Ref(T_); @@ -75,7 +75,7 @@ public: : T_(other.Get()) { static_assert( - std::is_base_of_v<TRefCountedBase, T>, + std::derived_from<T, TRefCountedBase>, "Cast allowed only for types derived from TRefCountedBase"); other.T_ = nullptr; } @@ -103,7 +103,7 @@ public: std::is_convertible_v<U*, T*>, "U* must be convertible to T*"); static_assert( - std::is_base_of_v<TRefCountedBase, T>, + std::derived_from<T, TRefCountedBase>, "Cast allowed only for types derived from TRefCountedBase"); TIntrusivePtr(other).Swap(*this); return *this; @@ -124,7 +124,7 @@ public: std::is_convertible_v<U*, T*>, "U* must be convertible to T*"); static_assert( - std::is_base_of_v<TRefCountedBase, T>, + std::derived_from<T, TRefCountedBase>, "Cast allowed only for types derived from TRefCountedBase"); TIntrusivePtr(std::move(other)).Swap(*this); return *this; diff --git a/library/cpp/yt/memory/new-inl.h b/library/cpp/yt/memory/new-inl.h index 53adaecdc0..c21bd37a0c 100644 --- a/library/cpp/yt/memory/new-inl.h +++ b/library/cpp/yt/memory/new-inl.h @@ -6,6 +6,8 @@ #include "ref_tracked.h" +#include <library/cpp/yt/misc/port.h> + #include <library/cpp/yt/malloc//malloc.h> namespace NYT { @@ -121,7 +123,7 @@ Y_FORCE_INLINE T* NewEpilogue(void* ptr, As&& ... args) } } -template <class T, bool = std::is_base_of_v<TRefCountedBase, T>> +template <class T, bool = std::derived_from<T, TRefCountedBase>> struct TConstructHelper { static constexpr size_t RefCounterSpace = (sizeof(TRefCounter) + alignof(T) - 1) & ~(alignof(T) - 1); diff --git a/library/cpp/yt/memory/ref.cpp b/library/cpp/yt/memory/ref.cpp index 605bc4ae2e..b5b636c9db 100644 --- a/library/cpp/yt/memory/ref.cpp +++ b/library/cpp/yt/memory/ref.cpp @@ -4,6 +4,8 @@ #include <library/cpp/yt/malloc/malloc.h> +#include <library/cpp/yt/misc/port.h> + #include <util/system/info.h> #include <util/system/align.h> diff --git a/library/cpp/yt/memory/ref_counted-inl.h b/library/cpp/yt/memory/ref_counted-inl.h index fcd64abb17..f86f634ffd 100644 --- a/library/cpp/yt/memory/ref_counted-inl.h +++ b/library/cpp/yt/memory/ref_counted-inl.h @@ -103,7 +103,7 @@ Y_FORCE_INLINE void DestroyRefCountedImpl(T* obj) //////////////////////////////////////////////////////////////////////////////// // Specialization for final classes. -template <class T, bool = std::is_base_of_v<TRefCountedBase, T>> +template <class T, bool = std::derived_from<T, TRefCountedBase>> struct TRefCountedTraits { static_assert( diff --git a/library/cpp/yt/memory/weak_ptr.h b/library/cpp/yt/memory/weak_ptr.h index a5a7f0a525..c647198aaf 100644 --- a/library/cpp/yt/memory/weak_ptr.h +++ b/library/cpp/yt/memory/weak_ptr.h @@ -48,7 +48,7 @@ public: : TWeakPtr(ptr.Get()) { static_assert( - std::is_base_of_v<TRefCountedBase, T>, + std::derived_from<T, TRefCountedBase>, "Cast allowed only for types derived from TRefCountedBase"); } @@ -63,7 +63,7 @@ public: : TWeakPtr(other.Lock()) { static_assert( - std::is_base_of_v<TRefCountedBase, T>, + std::derived_from<T, TRefCountedBase>, "Cast allowed only for types derived from TRefCountedBase"); } @@ -78,7 +78,7 @@ public: TWeakPtr(TWeakPtr<U>&& other) noexcept { static_assert( - std::is_base_of_v<TRefCountedBase, T>, + std::derived_from<T, TRefCountedBase>, "Cast allowed only for types derived from TRefCountedBase"); TIntrusivePtr<U> strongOther = other.Lock(); if (strongOther) { diff --git a/library/cpp/yt/misc/strong_typedef-inl.h b/library/cpp/yt/misc/strong_typedef-inl.h index 09b814b62c..0e9adee186 100644 --- a/library/cpp/yt/misc/strong_typedef-inl.h +++ b/library/cpp/yt/misc/strong_typedef-inl.h @@ -170,8 +170,55 @@ struct hash<NYT::TStrongTypedef<T, TTag>> template <class T, class TTag> requires std::numeric_limits<T>::is_specialized class numeric_limits<NYT::TStrongTypedef<T, TTag>> - : public numeric_limits<T> -{ }; +{ +public: + #define XX(name) \ + static constexpr decltype(numeric_limits<T>::name) name = numeric_limits<T>::name; + + XX(is_specialized) + XX(is_signed) + XX(digits) + XX(digits10) + XX(max_digits10) + XX(is_integer) + XX(is_exact) + XX(radix) + XX(min_exponent) + XX(min_exponent10) + XX(max_exponent) + XX(max_exponent10) + XX(has_infinity) + XX(has_quiet_NaN) + XX(has_signaling_NaN) + XX(has_denorm) + XX(has_denorm_loss) + XX(is_iec559) + XX(is_bounded) + XX(is_modulo) + XX(traps) + XX(tinyness_before) + XX(round_style) + + #undef XX + + #define XX(name) \ + static constexpr NYT::TStrongTypedef<T, TTag> name() noexcept \ + { \ + return NYT::TStrongTypedef<T, TTag>(numeric_limits<T>::name()); \ + } + + XX(min) + XX(max) + XX(lowest) + XX(epsilon) + XX(round_error) + XX(infinity) + XX(quiet_NaN) + XX(signaling_NaN) + XX(denorm_min) + + #undef XX +}; //////////////////////////////////////////////////////////////////////////////// diff --git a/library/cpp/yt/misc/unittests/strong_typedef_ut.cpp b/library/cpp/yt/misc/unittests/strong_typedef_ut.cpp index bc9321bb3c..1a06cc3c8b 100644 --- a/library/cpp/yt/misc/unittests/strong_typedef_ut.cpp +++ b/library/cpp/yt/misc/unittests/strong_typedef_ut.cpp @@ -43,8 +43,8 @@ XX(round_style) #undef XX #define XX(name) \ - static_assert(std::numeric_limits<TMyInt1>::name() == std::numeric_limits<int>::name()); \ - static_assert(std::numeric_limits<TMyInt2>::name() == std::numeric_limits<int>::name()); + static_assert(std::numeric_limits<TMyInt1>::name() == TMyInt1(std::numeric_limits<int>::name())); \ + static_assert(std::numeric_limits<TMyInt2>::name() == TMyInt2(TMyInt1(std::numeric_limits<int>::name()))); XX(min) XX(max) diff --git a/library/cpp/yt/threading/fork_aware_spin_lock.h b/library/cpp/yt/threading/fork_aware_spin_lock.h index 1d69aa1bca..215fb58dc9 100644 --- a/library/cpp/yt/threading/fork_aware_spin_lock.h +++ b/library/cpp/yt/threading/fork_aware_spin_lock.h @@ -30,7 +30,7 @@ public: bool IsLocked() const noexcept; private: - TSpinLock SpinLock_; + ::TSpinLock SpinLock_; }; //////////////////////////////////////////////////////////////////////////////// diff --git a/library/python/svn_version/__init__.py b/library/python/svn_version/__init__.py index caaef65bfe..b5c05d6bc0 100644 --- a/library/python/svn_version/__init__.py +++ b/library/python/svn_version/__init__.py @@ -1,5 +1,25 @@ -from .__svn_version import svn_version, commit_id, svn_revision, svn_last_revision, hash, svn_branch, svn_tag, patch_number, vcs, svn_timestamp +from .__svn_version import ( + svn_version, + commit_id, + svn_revision, + svn_last_revision, + hash, + svn_branch, + svn_tag, + patch_number, + vcs, + svn_timestamp, +) __all__ = ( - 'svn_version', 'commit_id', 'svn_revision', 'svn_last_revision', 'hash', 'svn_branch', 'svn_tag', 'patch_number', 'vcs', 'svn_timestamp' + 'svn_version', + 'commit_id', + 'svn_revision', + 'svn_last_revision', + 'hash', + 'svn_branch', + 'svn_tag', + 'patch_number', + 'vcs', + 'svn_timestamp', ) diff --git a/library/python/svn_version/ut/test_simple.py b/library/python/svn_version/ut/test_simple.py new file mode 100644 index 0000000000..50fa78f55d --- /dev/null +++ b/library/python/svn_version/ut/test_simple.py @@ -0,0 +1,24 @@ +import library.python.svn_version as sv + + +def test_simple(): + assert sv.svn_version() + assert isinstance(sv.svn_version(), str) + + assert sv.vcs() + assert isinstance(sv.vcs(), str) + + # svn_revision() will be -1 on non-trunk commits via arc + # svn revision of 0 technically may exist, but practiacally it will never appear here + assert sv.svn_revision() >= 0 or (sv.vcs() != "svn" and sv.svn_revision() == -1) + assert isinstance(sv.svn_revision(), int) + + # svn_last_revision() will be equal to zero on non-trunk commits + assert sv.svn_last_revision() >= 0 or (sv.vcs() != "svn" and sv.svn_last_revision() == -1) + assert isinstance(sv.svn_last_revision(), int) + + assert sv.commit_id() + assert isinstance(sv.commit_id(), str) + assert len(sv.commit_id()) > 0 + assert isinstance(sv.hash(), str) + assert isinstance(sv.patch_number(), int) diff --git a/library/python/svn_version/ut/ya.make b/library/python/svn_version/ut/ya.make new file mode 100644 index 0000000000..c96b843565 --- /dev/null +++ b/library/python/svn_version/ut/ya.make @@ -0,0 +1,13 @@ +PY23_TEST() + +STYLE_PYTHON() + +PEERDIR( + library/python/svn_version +) + +TEST_SRCS( + test_simple.py +) + +END() diff --git a/library/python/svn_version/ya.make b/library/python/svn_version/ya.make index f168ea4a94..8fdcd50819 100644 --- a/library/python/svn_version/ya.make +++ b/library/python/svn_version/ya.make @@ -1,5 +1,7 @@ PY23_LIBRARY() +STYLE_PYTHON() + PEERDIR( library/cpp/svnversion contrib/python/future @@ -11,3 +13,7 @@ PY_SRCS( ) END() + +RECURSE_FOR_TESTS( + ut +) diff --git a/library/python/windows/__init__.py b/library/python/windows/__init__.py index eb520a8d2d..fe7a2c0140 100644 --- a/library/python/windows/__init__.py +++ b/library/python/windows/__init__.py @@ -191,7 +191,9 @@ if on_win(): def transcode_error(windows_error, to_enc='utf-8'): from_enc = 'utf-8' if getattr(windows_error, 'utf8', False) else library.python.strings.guess_default_encoding() if from_enc != to_enc: - windows_error.strerror = library.python.strings.to_str(windows_error.strerror, to_enc=to_enc, from_enc=from_enc) + windows_error.strerror = library.python.strings.to_str( + windows_error.strerror, to_enc=to_enc, from_enc=from_enc + ) setattr(windows_error, 'utf8', to_enc == 'utf-8') class Transaction(object): @@ -230,14 +232,26 @@ if on_win(): @win_only @require_ctypes def replace_file(src, dst): - if not ctypes.windll.kernel32.MoveFileExW(unicode_path(src), unicode_path(dst), _MOVEFILE_REPLACE_EXISTING | _MOVEFILE_WRITE_THROUGH): + if not ctypes.windll.kernel32.MoveFileExW( + unicode_path(src), unicode_path(dst), _MOVEFILE_REPLACE_EXISTING | _MOVEFILE_WRITE_THROUGH + ): raise ctypes.WinError() @win_only @require_ctypes def replace_file_across_devices(src, dst): - with Transaction(timeout=_ATOMIC_RENAME_FILE_TRANSACTION_DEFAULT_TIMEOUT, description='ya library.python.windows replace_file_across_devices') as transaction: - if not ctypes.windll.kernel32.MoveFileTransactedW(unicode_path(src), unicode_path(dst), None, None, _MOVEFILE_REPLACE_EXISTING | _MOVEFILE_WRITE_THROUGH, transaction): + with Transaction( + timeout=_ATOMIC_RENAME_FILE_TRANSACTION_DEFAULT_TIMEOUT, + description='ya library.python.windows replace_file_across_devices', + ) as transaction: + if not ctypes.windll.kernel32.MoveFileTransactedW( + unicode_path(src), + unicode_path(dst), + None, + None, + _MOVEFILE_REPLACE_EXISTING | _MOVEFILE_WRITE_THROUGH, + transaction, + ): raise ctypes.WinError() @win_only @@ -259,13 +273,17 @@ if on_win(): @win_disabled @require_ctypes def symlink_dir(src, lnk): - if not ctypes.windll.kernel32.CreateSymbolicLinkW(unicode_path(lnk), unicode_path(src), _SYMBOLIC_LINK_FLAG_DIRECTORY): + if not ctypes.windll.kernel32.CreateSymbolicLinkW( + unicode_path(lnk), unicode_path(src), _SYMBOLIC_LINK_FLAG_DIRECTORY + ): raise ctypes.WinError() @win_only @require_ctypes def lock_file(f, offset, length, raises=True): - locked = ctypes.windll.kernel32.LockFile(file_handle(f), _low_dword(offset), _high_dword(offset), _low_dword(length), _high_dword(length)) + locked = ctypes.windll.kernel32.LockFile( + file_handle(f), _low_dword(offset), _high_dword(offset), _low_dword(length), _high_dword(length) + ) if not raises: return bool(locked) if not locked: @@ -274,7 +292,9 @@ if on_win(): @win_only @require_ctypes def unlock_file(f, offset, length, raises=True): - unlocked = ctypes.windll.kernel32.UnlockFile(file_handle(f), _low_dword(offset), _high_dword(offset), _low_dword(length), _high_dword(length)) + unlocked = ctypes.windll.kernel32.UnlockFile( + file_handle(f), _low_dword(offset), _high_dword(offset), _low_dword(length), _high_dword(length) + ) if not raises: return bool(unlocked) if not unlocked: @@ -304,6 +324,7 @@ if on_win(): # propagate true last error if this attempt fails return func(handling_path) raise e + shutil.rmtree(path, onerror=error_handler) # Don't display the Windows GPF dialog if the invoked program dies. @@ -337,7 +358,9 @@ if on_win(): def get_process_handle_count(proc_handle): assert isinstance(proc_handle, wintypes.HANDLE) - GetProcessHandleCount = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HANDLE, wintypes.POINTER(wintypes.DWORD))(("GetProcessHandleCount", ctypes.windll.kernel32)) + GetProcessHandleCount = ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HANDLE, wintypes.POINTER(wintypes.DWORD))( + ("GetProcessHandleCount", ctypes.windll.kernel32) + ) hndcnt = wintypes.DWORD() if not GetProcessHandleCount(proc_handle, ctypes.byref(hndcnt)): raise ctypes.WinError() @@ -349,7 +372,9 @@ if on_win(): for flag, value in [(inherit, 1), (protect_from_close, 2)]: if flag is not None: assert isinstance(flag, bool) - if not ctypes.windll.kernel32.SetHandleInformation(file_handle(file), _low_dword(value), _low_dword(int(flag))): + if not ctypes.windll.kernel32.SetHandleInformation( + file_handle(file), _low_dword(value), _low_dword(int(flag)) + ): raise ctypes.WinError() @win_only diff --git a/library/python/windows/ut/test_windows.py b/library/python/windows/ut/test_windows.py new file mode 100644 index 0000000000..beaa5fc3aa --- /dev/null +++ b/library/python/windows/ut/test_windows.py @@ -0,0 +1,97 @@ +# coding=utf-8 + +import errno +import os +import pytest +import six + +import library.python.strings +import library.python.windows + + +def gen_error_access_denied(): + if library.python.windows.on_win(): + err = WindowsError() + err.errno = errno.EACCES + err.strerror = '' + err.winerror = library.python.windows.ERRORS['ACCESS_DENIED'] + else: + err = OSError() + err.errno = errno.EACCES + err.strerror = os.strerror(err.errno) + err.filename = 'unknown/file' + raise err + + +def test_errorfix_buggy(): + @library.python.windows.errorfix + def erroneous_func(): + gen_error_access_denied() + + with pytest.raises(OSError) as errinfo: + erroneous_func() + assert errinfo.value.errno == errno.EACCES + assert errinfo.value.filename == 'unknown/file' + assert isinstance(errinfo.value.strerror, six.string_types) + assert errinfo.value.strerror + + +def test_errorfix_explicit(): + @library.python.windows.errorfix + def erroneous_func(): + if library.python.windows.on_win(): + err = WindowsError() + err.winerror = library.python.windows.ERRORS['ACCESS_DENIED'] + else: + err = OSError() + err.errno = errno.EACCES + err.strerror = 'Some error description' + err.filename = 'unknown/file' + raise err + + with pytest.raises(OSError) as errinfo: + erroneous_func() + assert errinfo.value.errno == errno.EACCES + assert errinfo.value.filename == 'unknown/file' + assert errinfo.value.strerror == 'Some error description' + + +def test_errorfix_decoding_cp1251(): + @library.python.windows.errorfix + def erroneous_func(): + model_msg = u'Какое-то описание ошибки' + if library.python.windows.on_win(): + err = WindowsError() + err.strerror = library.python.strings.to_str(model_msg, 'cp1251') + else: + err = OSError() + err.strerror = library.python.strings.to_str(model_msg) + raise err + + with pytest.raises(OSError) as errinfo: + erroneous_func() + error_msg = errinfo.value.strerror + if not isinstance(errinfo.value.strerror, six.text_type): + error_msg = library.python.strings.to_unicode(error_msg) + assert error_msg == u'Какое-то описание ошибки' + + +def test_diehard(): + @library.python.windows.diehard(library.python.windows.ERRORS['ACCESS_DENIED'], tries=5) + def erroneous_func(errors): + try: + gen_error_access_denied() + except Exception as e: + errors.append(e) + raise + + raised_errors = [] + with pytest.raises(OSError) as errinfo: + erroneous_func(raised_errors) + assert errinfo.value.errno == errno.EACCES + assert any(e.errno == errno.EACCES for e in raised_errors) + assert raised_errors and errinfo.value == raised_errors[-1] + if library.python.windows.on_win(): + assert len(raised_errors) == 5 + else: + assert len(raised_errors) == 1 diff --git a/library/python/windows/ut/ya.make b/library/python/windows/ut/ya.make new file mode 100644 index 0000000000..c321141f37 --- /dev/null +++ b/library/python/windows/ut/ya.make @@ -0,0 +1,13 @@ +PY23_TEST() + +STYLE_PYTHON() + +TEST_SRCS( + test_windows.py +) + +PEERDIR( + library/python/windows +) + +END() diff --git a/library/python/windows/ya.make b/library/python/windows/ya.make index 97c6f48f23..14f7dfac71 100644 --- a/library/python/windows/ya.make +++ b/library/python/windows/ya.make @@ -1,6 +1,10 @@ PY23_LIBRARY() -PY_SRCS(__init__.py) +STYLE_PYTHON() + +PY_SRCS( + __init__.py +) PEERDIR( library/python/func @@ -9,3 +13,7 @@ PEERDIR( ) END() + +RECURSE_FOR_TESTS( + ut +) |