-
Notifications
You must be signed in to change notification settings - Fork 93
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: sub module conflict error #295
base: master
Are you sure you want to change the base?
Conversation
Sorry, I can't access my development computer these days. I will review it a few days later. But the test case should be passed before merging. |
That's OK, I'll fix the test cases. |
thriftpy2/parser/parser.py
Outdated
@@ -949,3 +960,8 @@ def _get_ttype(inst, default_ttype=None): | |||
if hasattr(inst, '__dict__') and '_ttype' in inst.__dict__: | |||
return inst.__dict__['_ttype'] | |||
return default_ttype | |||
|
|||
def remove_suffix(s, suffix): |
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.
just use s.replace(suffix, "")
is better.
import itertools
from faker import Faker
SUFFIX = "__SOME_SUFFIX_"
class MyFaker(Faker):
def suffix_name(self):
return f"{self.name()}{SUFFIX}"
fake = MyFaker()
data_num = 10000
escape_ratio = 0.5
escape_num = int(data_num * escape_ratio)
suffix_texts = [fake.suffix_name() for _ in range(escape_num)]
normal_texts = [fake.name() for _ in range(data_num - escape_num)]
def test_and_replace():
for text in itertools.chain(suffix_texts, normal_texts):
if text.endswith(SUFFIX):
res = text.replace(SUFFIX, "")
return res
def test_and_replace_with_slie():
for text in itertools.chain(suffix_texts, normal_texts):
if text.endswith(SUFFIX):
res = text[:-len(SUFFIX)]
return res
def just_replace():
for text in itertools.chain(suffix_texts, normal_texts):
res = text.replace(SUFFIX, "")
return res
__benchmarks__ = [
(test_and_replace, just_replace, "just_replace"),
(test_and_replace, test_and_replace_with_slie, "test_and_replace_with_slie")
]
Benchmarks, repeat=5, number=20
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃ Benchmark ┃ Min ┃ Max ┃ Mean ┃ Min (+) ┃ Max (+) ┃ Mean (+) ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ just_replace │ 0.043 │ 0.043 │ 0.043 │ 0.021 (2.0x) │ 0.022 (1.9x) │ 0.022 (2.0x) │
│ test_and_replace_with_slie │ 0.041 │ 0.042 │ 0.042 │ 0.040 (1.0x) │ 0.041 (1.0x) │ 0.040 (1.0x) │
└────────────────────────────┴─────────┴─────────┴─────────┴─────────────────┴─────────────────┴─────────────────┘
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 for the advice, it seems better indeed.
thriftpy2/parser/__init__.py
Outdated
sub_modules = thrift.__thrift_meta__["sub_modules"][:] | ||
for module in sub_modules: | ||
if module not in sys.modules: | ||
sys.modules[module.__name__] = include_thrift |
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.
sub_modules = thrift.__thrift_meta__["sub_modules"][:] | |
for module in sub_modules: | |
if module not in sys.modules: | |
sys.modules[module.__name__] = include_thrift | |
lost_modules = [ | |
m for m in thrift.__thrift_meta__["sub_modules"] if m not in sys.modules | |
] | |
for module in lost_modules: | |
sys.modules[module.__name__] = include_thrift |
thriftpy2/parser/parser.py
Outdated
child_module_name = str( | ||
child_path).replace(os.sep, | ||
".").replace( | ||
".thrift", "_thrift") |
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.
These code's indents are a little bit strange, I think it's better to using something like:
aaa = bbb().ccc()\
.ddd()
Thank you for your work, but I still have a question. Although the included Thrift modules wouldn't overwrite each other when they have the same name but are in different subdirectories after merge this PR, we support loading a Thrift file with a dot in its name, such as I think the expected behavior should be to raise an exception to inform users about the conflict. I believe the current code already has this issue, but the new code might have the potential to address it. |
Okay, I'll raise an exception in this case. |
@aisk All things have done, but there is still a test fail in |
It would be good if you could squash all the commits down to one, just to tidy up the history. |
9193679
to
08b5ac6
Compare
done |
Currently the logic of register sub module to
sys.modules
may cause conflict,That's because of the PR #249 which fix #215
For example:
We have thrift files as follows:
If we call
load('idl/main.thrift', module_name='idl.main_thrift')
, then the following modules will be registered:idl.main_thrift
included1_thrift
included2_thrift
So, if
included1.thrift
is a common module name like platform, which isplatform.thrift
, then moduleplatform
will register tosys.modules
, so it will cause conflict.Now I come up with 2 solutions:
Add an option to
load()
, which will bedef load(path, module_name=None, include_dirs=None, include_dir=None, encoding='utf-8')
, and let the users to register sub modules manually. (not recommended)Optimize sub module name. (recommended)
use absolute path as its module name instead of the base name of the thrift file.
let's take the example before, then the following modules will be registered:
idl.main_thrift
idl.included1_thrift
idl.included2_thrift