سؤال

كيف يمكنني أتمتة اختبار لفرض أن مجموعة من كود Python 2.x لا يحتوي على مثيلات سلسلة (فقط مثيلات Unicode)؟

على سبيل المثال.

هل يمكنني فعل ذلك من داخل الكود؟

هل هناك أداة تحليل ثابت لديها هذه الميزة؟

يحرر:

أردت هذا للحصول على تطبيق في Python 2.5 ، ولكن اتضح أن هذا غير ممكن حقًا لأن:

  1. 2.5 لا يدعم unicode_literals
  2. لا يمكن أن تكون مفاتيح قاموس Kwargs كائنات أحادية ، فقط سلاسل

لذلك أنا أقبل الإجابة التي تقول أنها غير ممكنة ، على الرغم من أنها لأسباب مختلفة :)

هل كانت مفيدة؟

المحلول

لا يمكنك فرض ذلك الكل الأوتار Unicode. حتى مع from __future__ import unicode_literals في الوحدة النمطية ، يمكن كتابة سلاسل البايت كـ b'...', ، كما يمكنهم في بيثون 3.

هناك كنت خيار يمكن استخدامه للحصول على نفس التأثير مثل unicode_literals عالميًا: خيار سطر الأوامر -U. ومع ذلك تم التخلي عنها في وقت مبكر من سلسلة 2.x لأنها كسرت بشكل أساسي كل نص.

ما هو هدفك لهذا؟ ليس من المرغوب فيه إلغاء سلاسل البايت. إنها ليست "سيئة" وخيوط Unicode ليست "أفضل" عالميًا ؛ إنهم حيوانان منفصلان وستحتاج إلى كلاهما. من المؤكد أن هناك حاجة إلى سلاسل البايت للتحدث إلى الملفات الثنائية وخدمات الشبكة.

إذا كنت ترغب في أن تكون مستعدًا للانتقال إلى Python 3 ، فإن أفضل ما في ذلك هو الكتابة b'...' لجميع الأوتار التي تعنيها حقًا أن تكون بايت ، و u'...' للسلاسل التي بطبيعتها أحادي. السلسلة الافتراضية '...' يمكن استخدام التنسيق لكل شيء آخر ، الأماكن التي لا تهتم فيها و/أو ما إذا كان Python 3 يغير نوع السلسلة الافتراضية.

نصائح أخرى

يبدو لي وكأنك تحتاج حقًا إلى تحليل الكود مع محلل بيثون الصادق. ثم ستحتاج إلى البحث في AST الذي ينتجه المحلل الخاص بك لمعرفة ما إذا كان يحتوي على أي حرفية سلسلة.

يبدو أن بيثون يأتي مع محلل خارج الصندوق. من هذا توثيق حصلت على نموذج الكود هذا العمل:

import parser
from token import tok_name

def checkForNonUnicode(codeString):
    return checkForNonUnicodeHelper(parser.suite(codeString).tolist())

def checkForNonUnicodeHelper(lst):
    returnValue = True
    nodeType = lst[0]
    if nodeType in tok_name and tok_name[nodeType] == 'STRING':
        stringValue = lst[1]
        if stringValue[0] != "u": # Kind of hacky. Does this always work?
            print "%s is not unicode!" % stringValue
            returnValue = False

    else:
        for subNode in [lst[n] for n in range(1, len(lst))]:
            if isinstance(subNode, list):
                returnValue = returnValue and checkForNonUnicodeHelper(subNode)

    return returnValue

print checkForNonUnicode("""
def foo():
    a = 'This should blow up!'
""")
print checkForNonUnicode("""
def bar():
    b = u'although this is ok.'
""")

الذي يطبع

'This should blow up!' is not unicode!
False
True

الآن لا توجد سلاسل مستندات غير متوفرة ولكن يجب السماح بها ، لذلك قد تضطر إلى القيام بشيء أكثر تعقيدًا مثل from symbol import sym_name حيث يمكنك البحث عن أنواع العقدة التي تتمثل في تعريفات الفصل والوظائف. بعد ذلك ، يجب السماح للعقدة الفرعية الأولى التي هي ببساطة سلسلة ، أي جزء من المهمة أو أي شيء آخر ، بعدم أن تكون أحاديًا.

سؤال جيد!

يحرر

مجرد تعليق متابعة. مريح لأغراضك ، parser.suite لا يقيم في الواقع رمز بيثون الخاص بك. هذا يعني أنه يمكنك تشغيل هذا المحلل فوق ملفات Python دون القلق بشأن تسمية الأخطاء أو الاستيراد. على سبيل المثال ، لنفترض أن لديك myObscureUtilityFile.py يحتوي على

from ..obscure.relative.path import whatever

تستطيع

checkForNonUnicode(open('/whoah/softlink/myObscureUtilityFile.py').read())

ملكنا محرك البحث عن رمز المصدر SD (SCSE) يمكن أن توفر هذه النتيجة مباشرة.

يوفر SCSE طريقة للبحث بسرعة كبيرة عبر مجموعات كبيرة من الملفات باستخدام بعض بنية اللغة لتمكين الاستعلامات الدقيقة وتقليل الإيجابيات الخاطئة. إنه يتعامل مع مجموعة واسعة من اللغات ، حتى في نفس الوقت ، بما في ذلك بيثون. يعرض واجهة المستخدم الرسومية ضربات البحث وصفحة من النص الفعلي من الملف الذي يحتوي على ضربة محددة.

يستخدم المعلومات المعجمية من لغات المصدر كأساس للاستعلامات ، التي تتألف من مختلف الكلمات الرئيسية Langauge ورموز الأنماط التي تتطابق مع عناصر Langauge المختلفة. يعرف SCSE أنواع Lexemes المتوفرة في Langauge. يمكن للمرء البحث عن معرف عام (باستخدام رمز الاستعلام I) أو معرف يطابق بعض تعبيرات Regulatr. مماثل ، يمكن أن تبحث عن سلسلة عامة (باستخدام رمز الاستعلام "s" لأي نوع من الخيوط الحرفية ") أو لنوع معين من السلسلة (بالنسبة للبيثون بما في ذلك" أحادي الأطوار "، سلاسل غير متوفرة ، إلخ ، والتي تصنع بشكل جماعي جماعياً حتى مجموعة من الأشياء Python التي تضم "S").

لذا بحث:

 'for' ... I=ij*

يجد الكلمة الرئيسية "لـ" بالقرب من ("...") معرف هو بادئة "IJ" وتظهر لك كل الزيارات. (يتم تجاهل مساحة بيضاء خاصة باللغة بما في ذلك فواصل الخط والتعليقات.

بحث تافهة:

  S

يجد جميع الأوتار الحرفية. غالبًا ما تكون هذه مجموعة كبيرة جدًا:-}

بحث

 UnicodeStrings

يجد جميع الحرفيات الوطنية التي يتم تعريفها معجمية على أنها سلاسل Unicode (U "...")

ما تريده هو كل سلاسل ليست أحادية تستر. يوفر SCSE مشغل "طرح" يطرح ضربات من نوع واحد يتداخل مع آخر. لذا فإن سؤالك ، "ما هي الأوتار التي لا تُحدد" يتم التعبير عنها بإيجاز على النحو التالي:

  S-UnicodeStrings

جميع الزيارات المعروضة هي الأوتار التي ليست سلاسل Unicode ، سؤالك الدقيق.

يوفر SCSE مرافق التسجيل حتى تتمكن من تسجيل الزيارات. يمكنك تشغيل SCSE من سطر الأوامر ، مما يتيح استعلامًا نصًا لإجابتك. إن وضع هذا في برنامج نصي أمر يوفر أداة يعطي إجابتك مباشرة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top