Существует ли модуль unicodedata для IronPython?

#unicode #module #ironpython #selenium-webdriver

#unicode #модуль #ironpython #selenium-webdriver

Вопрос:

Я пытаюсь получить общий пример кода для сервиса selenium2 Sauce OnDemand, работающего с IronPython, для некоторой тестовой работы, которую я выполняю, и я столкнулся с проблемой, которую я не могу полностью понять.

Во-первых, вот среда:

Windows 7 Home Premium, 64-разрядная.
IronPython 2.7.0.40 на .Net 4.0.30319.225

Мой путь:

 >>> sys.path
['.', 'C:\users\me\scripts\python', 'C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\IronStudio\0.4\Lib', 'C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\IronStudio\0.4\DLLs', 'C:\opt\win\ipy\Lib', 'C:\opt\win\ipy\DLLs', 'C:\opt\win\ipy']  
  

Я знаю, что у IronPython есть проблемы с использованием сжатых eggs, поэтому я извлек следующие библиотеки в каталог Lib на sys.path:

selenium (2.0b4dev)
rdflib (3.1.0)

Теперь пример кода из Sauce Labs:

 import unittest
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

class Selenium2OnSauce(unittest.TestCase):

    def setUp(self):
        desired_capabilities = dict(platform="WINDOWS",
                                    browserName="firefox",
                                    version="3.6", 
                                    name="Hello, Selenium 2!")
        self.driver = webdriver.Remote(
            desired_capabilities=desired_capabilities,
            command_executor="http://me:my-site-access-key@ondemand.saucelabs.com:80/wd/hub")

    def test_sauce(self):
        self.driver.get('http://example.saucelabs.com')
        assert "Sauce Labs" in self.driver.title

    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main()
  

Вот ошибка, которую я получаю:

 Traceback (most recent call last):
File "selenium2_test.py", line 3, in <module>
File "c:optwinipyLibseleniumwebdriver__init__.py", line 18, in <module>
File "c:optwinipyLibseleniumwebdriverfirefoxwebdriver.py", line 24, in <module>
File "c:optwinipyLibseleniumwebdriverfirefoxfirefox_profile.py", line 23, in <module>
File "C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDEExtensionsMicrosoftIronStudio.4Librdflib__init__.py", line 65, in <module>
File "C:Program Files (x86)Microsoft Visual Studio 10.0Common7IDEExtensionsMicrosoftIronStudio.4Librdflibnamespace.py", line 282, in <module>
ImportError: No module named unicodedata
  

Я пробовал искать пакеты с unicodedata в них (например, FePY), но, похоже, ни один из них не работает. Я пытался скопировать .pyd из моей установки Python27, но это тоже не сработало.

Это что-то, чего еще нет в IronPython 2.7? В качестве альтернативы, есть ли библиотека или пространство имен, на которые я могу ссылаться для выполнения той же задачи?

Если нет, я думаю, мне придется обходиться без selenium2, пока железные ребята не получат unicodedata для IP27. 🙁

Спасибо,
Грег.

Комментарии:

1. Итак, вы пробовали использовать это? fepy.svn.sourceforge.net/viewvc/fepy/trunk/lib / … — вы должны иметь возможность перенести его в путь Python. Какие ошибки вы получаете при попытке использовать версию FePY?

2. С одной версией я получал «Не удается импортировать категорию имен». С версией, на которую вы ссылались, я получал «Не удается импортировать разложение имени». Вероятно, это просто вопрос поиска правильной версии этого модуля, но будь я проклят, если смогу его найти. :/

3. Я могу быть совершенно неправ, и SO не обязательно подходит для такого рода вещей, но декомпозиция выглядит так, как будто это просто нормализация для формы D, так что вы, вероятно, могли бы добавить к ссылке, которую я вам дал def normalize(unichr): return String.Normalize(unichr.ToString(), NormalizationForm.FormD)

4. @Micheal: Спасибо за помощь! Это сработало, но я определил это как декомпозицию (не normalize()). Почему все это не является частью обычной сборки IronPython? Я этого не понимаю :/

5. Ironpython поддерживал unicode через .NET с момента создания. Следовательно, некоторые из дополнительных модулей не были приоритетными, поскольку существовали обходные пути. Это активная ошибка для IronPython, предназначенная для 2.7. release. Реализацией Unicodedata на Cpython является pyd DLL. Возможно, вы сможете заставить его работать через ironclad, но решение Майкла Грина является лучшим и, вероятно, ближе всего к тому, что будут реализовывать разработчики IronPython.

Ответ №1:

Увы, модуль unicodedata в настоящее время не включен в IronPython. Но не бойтесь! В предстоящем выпуске 2.7.1 он будет доступен, и всех ваших проблем больше не будет.

Извините за это. Что касается того, когда выйдет 2.7.1, я думаю, в начале июня. Вы можете проверить https://github.com/IronLanguages/main/commit/5395af28b5794b0acf982ab87d17466925ab819f для исправления, но он довольно большой и неудобный из-за включенной базы данных Unicode.

Комментарии:

1. Спасибо за обновление, Джефф. Я ценю ваши усилия, несмотря на мое разочарование 🙂

Ответ №2:

Смотрите комментарии @Micheal Greene к первоначальному вопросу. Вот модуль с указанными изменениями:

 # Copyright (c) 2006 by Seo Sanghyeon
# 2006-07-13 sanxiyn Created
# 2006-07-19 sanxiyn Added unidata_version, normalize
# Modified 2011 - Greg Gauthier - To provide needed functionality for rdflib
#                                 and other utilities, in IronPython 2.7.0

unidata_version = '3.2.0'

# --------------------------------------------------------------------
# Normalization

from System import String
from System.Text import NormalizationForm

def normalize(form, string):
    return String.Normalize(string, _form_mapping[form])

_form_mapping = {
    'NFC': NormalizationForm.FormC,
    'NFKC': NormalizationForm.FormKC,
    'NFD': NormalizationForm.FormD,
    'NFKD': NormalizationForm.FormKD,
}

# --------------------------------------------------------------------
# Character properties

from System.Globalization import CharUnicodeInfo

def _handle_default(function):
    def wrapper(unichr, default=None):
        result = function(unichr)
        if result != -1:
            return result
        if default is None:
            raise ValueError()
        return default
    return wrapper

decimal = _handle_default(CharUnicodeInfo.GetDecimalDigitValue)
digit = _handle_default(CharUnicodeInfo.GetDigitValue)
numeric = _handle_default(CharUnicodeInfo.GetNumericValue)

def category(unichr):
    uc = CharUnicodeInfo.GetUnicodeCategory(unichr)
    return _category_mapping[int(uc)]

_category_mapping = {
    0: 'Lu',
    1: 'Ll',
    2: 'Lt',
    3: 'Lm',
    4: 'Lo',
    5: 'Mn',
    6: 'Mc',
    7: 'Me',
    8: 'Nd',
    9: 'Nl',
    10: 'No',
    11: 'Zs',
    12: 'Zl',
    13: 'Zp',
    14: 'Cc',
    15: 'Cf',
    16: 'Cs',
    17: 'Co',
    18: 'Pc',
    19: 'Pd',
    20: 'Ps',
    21: 'Pe',
    22: 'Pi',
    23: 'Pf',
    24: 'Po',
    25: 'Sm',
    26: 'Sc',
    27: 'Sk',
    28: 'So',
    29: 'Cn',
}

# added for rdflib/ironpython
def decomposition(unichr): 
    return String.Normalize(unichr.ToString(), NormalizationForm.FormD)