diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2023-10-03 15:02:38 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2023-10-03 16:04:35 +0300 |
commit | 5478b8f55cc7055a4861c4030e0c401b5c72714c (patch) | |
tree | 3d003e5b4c1800297fcc491faffc9a006d174289 /library/python/json | |
parent | ca778ad9bfb31839b0f05a4995753bc61db648ad (diff) | |
download | ydb-5478b8f55cc7055a4861c4030e0c401b5c72714c.tar.gz |
Intermediate changes
Diffstat (limited to 'library/python/json')
-rw-r--r-- | library/python/json/__init__.py | 44 | ||||
-rw-r--r-- | library/python/json/loads.cpp | 246 | ||||
-rw-r--r-- | library/python/json/loads.h | 5 | ||||
-rw-r--r-- | library/python/json/loads.pyx | 14 | ||||
-rw-r--r-- | library/python/json/ya.make | 17 |
5 files changed, 0 insertions, 326 deletions
diff --git a/library/python/json/__init__.py b/library/python/json/__init__.py deleted file mode 100644 index c6420d5e6d2..00000000000 --- a/library/python/json/__init__.py +++ /dev/null @@ -1,44 +0,0 @@ -from library.python.json.loads import loads as _loads -from simplejson import loads as _sj_loads - - -def loads(*args, **kwargs): - try: - return _loads(*args, **kwargs) - except Exception as e: - if 'invalid syntax at token' in str(e): - kwargs.pop('intern_keys', None) - kwargs.pop('intern_vals', None) - kwargs.pop('may_unicode', None) - return _sj_loads(*args, **kwargs) - - raise - - -from simplejson import load, dump, dumps # noqa - - -def read_file(file_name, **kwargs): - """ - Read file and return its parsed json contents. - - All kwargs will be proxied to `json.load` method as is. - - :param file_name: file with json contents - :return: parsed json contents - """ - with open(file_name) as f: - return load(f, **kwargs) - - -def write_file(file_name, contents, **kwargs): - """ - Dump json data to file. - - All kwargs will be proxied to `json.dump` method as is. - - :param file_name: file to dump to - :param contents: JSON-serializable object - """ - with open(file_name, "w") as f: - dump(contents, f, **kwargs) diff --git a/library/python/json/loads.cpp b/library/python/json/loads.cpp deleted file mode 100644 index 19cdb096aef..00000000000 --- a/library/python/json/loads.cpp +++ /dev/null @@ -1,246 +0,0 @@ -#include "loads.h" - -#include <Python.h> - -#include <library/cpp/json/fast_sax/parser.h> - -#include <util/generic/algorithm.h> -#include <util/generic/stack.h> -#include <util/generic/vector.h> -#include <util/generic/ylimits.h> -#include <util/string/ascii.h> - -using namespace NJson; - -namespace { - enum EKind { - Undefined, - Array, - Dict, - Value, - Key, - }; - - static inline TStringBuf ToStr(EKind kind) noexcept { - switch (kind) { - case Undefined: - return TStringBuf("Undefined"); - - case Array: - return TStringBuf("Array"); - - case Dict: - return TStringBuf("Dict"); - - case Value: - return TStringBuf("Value"); - - case Key: - return TStringBuf("Key"); - } - - Y_UNREACHABLE(); - } - - struct TUnref { - static inline void Destroy(PyObject* o) noexcept { - Py_XDECREF(o); - } - }; - - using TObjectPtr = TAutoPtr<PyObject, TUnref>; - - static inline TObjectPtr BuildBool(bool val) noexcept { - if (val) { - Py_RETURN_TRUE; - } - - Py_RETURN_FALSE; - } - - // Translate python exceptions from object-creating functions into c++ exceptions - // Such errors are reported by returning nullptr - // When a python error is set and C++ exception is caught by Cython wrapper, - // Python exception is propagated, while C++ exception is discarded. - PyObject* CheckNewObject(PyObject* obj) { - Y_ENSURE(obj != nullptr, "got python exception"); - return obj; - } - - void CheckRetcode(int retcode) { - Y_ENSURE(retcode == 0, "got python exception"); - } - - static inline TObjectPtr BuildSmall(long val) { -#if PY_VERSION_HEX >= 0x03000000 - return CheckNewObject(PyLong_FromLong(val)); -#else - return CheckNewObject(PyInt_FromLong(val)); -#endif - } - - PyObject* CreatePyString(TStringBuf str, bool intern, bool mayUnicode) { -#if PY_VERSION_HEX >= 0x03000000 - Y_UNUSED(mayUnicode); - PyObject* pyStr = PyUnicode_FromStringAndSize(str.data(), str.size()); - if (intern) { - PyUnicode_InternInPlace(&pyStr); - } -#else - const bool needUnicode = mayUnicode && !AllOf(str, IsAscii); - PyObject* pyStr = needUnicode ? PyUnicode_FromStringAndSize(str.data(), str.size()) - : PyString_FromStringAndSize(str.data(), str.size()); - if (intern && !needUnicode) { - PyString_InternInPlace(&pyStr); - } -#endif - return pyStr; - } - - struct TVal { - EKind Kind = Undefined; - TObjectPtr Val; - - inline TVal() noexcept - : Kind(Undefined) - { - } - - inline TVal(EKind kind, TObjectPtr val) noexcept - : Kind(kind) - , Val(val) - { - } - }; - - static inline TObjectPtr NoneRef() noexcept { - Py_RETURN_NONE; - } - - struct TContext: public TJsonCallbacks { - const bool InternKeys; - const bool InternVals; - const bool MayUnicode; - TStack<TVal, TVector<TVal>> S; - - inline TContext(bool internKeys, bool internVals, bool mayUnicode) - : TJsonCallbacks(true) - , InternKeys(internKeys) - , InternVals(internVals) - , MayUnicode(mayUnicode) - { - S.emplace(); - } - - inline bool Consume(TObjectPtr o) { - auto& t = S.top(); - - if (t.Kind == Array) { - CheckRetcode(PyList_Append(t.Val.Get(), o.Get())); - } else if (t.Kind == Key) { - auto key = S.top().Val; - - S.pop(); - - CheckRetcode(PyDict_SetItem(S.top().Val.Get(), key.Get(), o.Get())); - } else { - t = TVal(Value, o); - } - - return true; - } - - inline TObjectPtr Pop(EKind expect) { - auto res = S.top(); - - S.pop(); - - if (res.Kind != expect) { - ythrow yexception() << "unexpected kind(expect " << ToStr(expect) << ", got " << ToStr(res.Kind) << ")"; - } - - return res.Val; - } - - inline void Push(EKind kind, TObjectPtr object) { - S.push(TVal(kind, object)); - } - - virtual bool OnNull() { - return Consume(NoneRef()); - } - - virtual bool OnBoolean(bool v) { - return Consume(BuildBool(v)); - } - - virtual bool OnInteger(long long v) { - if (v >= (long long)Min<long>()) { - return Consume(BuildSmall((long)v)); - } - - return Consume(CheckNewObject(PyLong_FromLongLong(v))); - } - - virtual bool OnUInteger(unsigned long long v) { - if (v <= (unsigned long long)Max<long>()) { - return Consume(BuildSmall((long)v)); - } - - return Consume(CheckNewObject(PyLong_FromUnsignedLongLong(v))); - } - - virtual bool OnDouble(double v) { - return Consume(CheckNewObject(PyFloat_FromDouble(v))); - } - - virtual bool OnString(const TStringBuf& v) { - return Consume(CheckNewObject(CreatePyString(v, InternVals, MayUnicode))); - } - - virtual bool OnOpenMap() { - Push(Dict, CheckNewObject(PyDict_New())); - - return true; - } - - virtual bool OnCloseMap() { - return Consume(Pop(Dict)); - } - - virtual bool OnMapKey(const TStringBuf& k) { - Push(Key, CheckNewObject(CreatePyString(k, InternKeys, MayUnicode))); - return true; - } - - virtual bool OnOpenArray() { - Push(Array, CheckNewObject(PyList_New(0))); - - return true; - } - - virtual bool OnCloseArray() { - return Consume(Pop(Array)); - } - }; -} - -PyObject* LoadJsonFromString(const char* data, size_t len, bool internKeys, bool internVals, bool mayUnicode) { - TContext ctx(internKeys, internVals, mayUnicode); - - if (!len) { - ythrow yexception() << "parse error: zero length input string"; - } - - if (!NJson::ReadJsonFast(TStringBuf(data, len), &ctx)) { - ythrow yexception() << "parse error"; - } - - auto& s = ctx.S; - - if (!s || s.top().Kind != Value) { - ythrow yexception() << "shit happen"; - } - - return s.top().Val.Release(); -} diff --git a/library/python/json/loads.h b/library/python/json/loads.h deleted file mode 100644 index 62dcdf6f213..00000000000 --- a/library/python/json/loads.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include <Python.h> - -PyObject* LoadJsonFromString(const char* data, size_t len, bool internKeys = false, bool internVals = false, bool mayUnicode = false); diff --git a/library/python/json/loads.pyx b/library/python/json/loads.pyx deleted file mode 100644 index 82e5c6dce7b..00000000000 --- a/library/python/json/loads.pyx +++ /dev/null @@ -1,14 +0,0 @@ -from libcpp cimport bool - -cdef extern from "library/python/json/loads.h": - object LoadJsonFromString(const char*, size_t, bool internKeys, bool internVals, bool mayUnicode) except + - - -def loads(s, intern_keys = False, intern_vals = False, may_unicode = False): - if isinstance(s, unicode): - s = s.encode('utf-8') - - try: - return LoadJsonFromString(s, len(s), intern_keys, intern_vals, may_unicode) - except Exception as e: - raise ValueError(str(e)) diff --git a/library/python/json/ya.make b/library/python/json/ya.make deleted file mode 100644 index 74a82de9d8f..00000000000 --- a/library/python/json/ya.make +++ /dev/null @@ -1,17 +0,0 @@ -PY23_LIBRARY() - -PEERDIR( - contrib/python/simplejson - library/cpp/json/fast_sax -) - -PY_SRCS( - __init__.py - loads.pyx -) - -SRCS( - loads.cpp -) - -END() |