Есть еще одна проблема, которая не указана ни в одном из существующих ответов. Python разрешено объединять любые два неизменных значения, и предварительно созданные значения малых значений не являются единственным способом, которым это может случиться. Реализация Python никогда не гарантирована , но все они делают это не более, чем просто малые int.
Во-первых, есть еще некоторые предварительно созданные такие как пустые tuple
, str
и bytes
и некоторые короткие строки (в CPython 3.6 это 256 односимвольных строк Latin-1). Например:
>>> a = ()
>>> b = ()
>>> a is b
True
Но также даже не созданные заранее значения могут быть одинаковыми. Рассмотрим следующие примеры:
>>> c = 257
>>> d = 257
>>> c is d
False
>>> e, f = 258, 258
>>> e is f
True
И это не ограничено значениями int
:
>>> g, h = 42.23e100, 42.23e100
>>> g is h
True
Очевидно, что CPython не поставляется с предварительно созданным float
для параметра 42.23e100
. Итак, что здесь происходит?
Компилятор CPython будет объединять постоянные значения некоторых известных неизменяемых типов, таких как int
, float
, str
, bytes
, в одном модуле компиляции. Для модуля весь модуль является единицей компиляции, но в интерактивном интерпретаторе каждый оператор представляет собой отдельный блок компиляции. Поскольку c
и d
определены в отдельных утверждениях, их значения не объединяются. Поскольку e
и f
определены в том же самом заявлении, их значения сливаются.
Вы можете видеть, что происходит, разобрав байт-код. Попробуйте определить функцию, которая выполняет e, f = 128, 128
, а затем называет dis.dis
на ней, и вы увидите, что существует одно постоянное значение (128, 128)
>>> def f(): i, j = 258, 258
>>> dis.dis(f)
1 0 LOAD_CONST 2 ((128, 128))
2 UNPACK_SEQUENCE 2
4 STORE_FAST 0 (i)
6 STORE_FAST 1 (j)
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
>>> f.__code__.co_consts
(None, 128, (128, 128))
>>> id(f.__code__.co_consts[1], f.__code__.co_consts[2][0], f.__code__.co_consts[2][1])
4305296480, 4305296480, 4305296480
. Вы можете заметить, что компилятор сохранил 128
как константу, даже если он фактически не используется байтовым кодом, что дает вам представление о том, как мало оптимизирует компилятор CPython. Это означает, что (непустые) кортежи на самом деле не сливаются:
>>> k, l = (1, 2), (1, 2)
>>> k is l
False
Поместите это в функцию, dis
, и посмотрите на co_consts
- есть 1
и 2
, два (1, 2)
кортежа, которые имеют одинаковые 1
и 2
, но не идентичны, и кортеж ((1, 2), (1, 2))
, который имеет два разных одинаковых кортежа.
Есть еще одна оптимизация, которую выполняет CPython: string interning. В отличие от сгибания константы компилятора, это не ограничивается литералами исходного кода:
>>> m = 'abc'
>>> n = 'abc'
>>> m is n
True
С другой стороны, он ограничен типом str
и строками типа внутреннего хранилища «ascii compact», «compact» или «legacy ready» , и во многих случаях только «ascii compact» будет интернирован.
Во всяком случае, правила для чего значения должны быть, могут быть или не могут отличаться от реализации до реализации, а также между версиями одной и той же реализации и, возможно, даже между прогонами одного и того же кода в одной и той же копии одной и той же реализации.
Возможно, стоит изучить правила для одного конкретного Python для удовольствия. Но не стоит полагаться на них в вашем коде. Единственное безопасное правило:
Или, другими словами, использовать is
только для проверки документированных синглетов (например, None
) или которые создаются только в одном месте в код (например, идиома _sentinel = object()
).
Проблема состоит в том, что Вы используете корень документа также в качестве корневого каталога хранилища (я не обвиняю Вас, это должно просто работать, но он не делает).
Попытка, указывающая DocumentRoot
и SVNParentPath
, директивы к различным физическим местоположениям, таким образом, получающийся файл конфигурации должен быть похожим на это (сократили):
<VirtualHost *:80>
DocumentRoot /home/svn.example.com/docroot
<Location />
SVNParentPath /home/svn.example.com/svnroot
SVNListParentPath on
</Location>
</VirtualHost>
кроме того, как @Nigel Jewell говорит, удалите, которые Переписывают блок для исправности.
Я закончил тем, что использовал mod_rewrite успешно для перезаписи всего доступа к корневому каталогу в /svn
, следовательно получив доступ к репозиториям от /repository_name
. Для ссылки это - конфигурация, с которой я закончил:
# Rewrite / into /svn to avoid errors that seem to occur when using the root
# for repositories.
RewriteEngine On
# Subdirectories that SHOULD be accessed directly, ie. trac
# /svn should be here to avoid redirect loops
RewriteCond %{REQUEST_URI} !^/(trac|svn)/
RewriteRule ^/(.*)$ /svn/$1 [PT]
Продолжая от комментариев до моего предыдущего ответа, я попробовал также VirtualHost:
<VirtualHost 127.0.0.1:80>
<Location />
DAV svn
SVNPath /repository
AuthType Basic
AuthName "Repository authentication"
AuthUserFile /repository/.svn-auth
AuthzSVNAccessFile /repository/.svn-access
Satisfy All
Require valid-user
</Location>
</VirtualHost>
и это работает, я могу просмотреть репозиторий с Firefox и могу получить доступ к нему с svn клиентом командной строки.
Хорошо, я думаю, что мы нашли, кто обвинить: названные виртуальные хосты :)
С этой конфигурацией:
<VirtualHost dave.test>
<Location />
DAV svn
SVNPath /repository
AuthType Basic
AuthName "Repository authentication"
AuthUserFile /repository/.svn-auth
AuthzSVNAccessFile /repository/.svn-access
Satisfy All
Require valid-user
</Location>
</VirtualHost>
, когда я выполняю команду svn ls http://dave.test
, я получил эту ошибку:
svn: Server sent unexpected return value (405 Method Not Allowed) in response to
PROPFIND request for '/'
Так, по-видимому, существует проблема, когда каждый пытается включить mod_dav_svn в корневом каталоге именованного виртуального хоста...
Спасибо за это, наконец получил его работающий с VirtualHost из-за Ваших комментариев.
<VirtualHost *:80>
ServerAdmin webmaster@example.com
ServerName svn.example.com
ServerAlias svn
DocumentRoot /home/svn.example.com/public_html
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/svn$
RewriteRule .* /svn/ [PT]
RewriteCond %{REQUEST_URI} !^/svn/
RewriteRule ^/(.*)$ /svn/$1 [PT]
<Location /svn>
DAV svn
SVNParentPath /home/svn.example.com/public_html
SVNListParentPath on
</Location>
<LocationMatch /svn/.+>
AuthzSVNAccessFile /home/svn.example.com/support/access.cfg
AuthType Basic
AuthName "Subversion"
AuthUserFile /home/svn.example.com/.htpasswd
Require valid-user
</LocationMatch>
</VirtualHost>
Как показано я нашел, что Вы, вероятно, хотите также добавить:
RewriteCond %{REQUEST_URI} ^/svn$
RewriteRule .* /svn/ [PT]
Для ловли http://svn.example.com/svn без окончания/.
Nige.
DocumentRoot "/usr/local/apache/htdocs/ForSvn" ServerName xxx.xxx ServerAdmin xxx ErrorLog "/usr/local/apache/logs/xxx-error_log" TransferLog "/usr/local/apache/logs/xxx-access_log"
ReWriteEngine On
RewriteCond %{REQUEST_URI} ^/svn$
RewriteRule .* /svn/ [PT]
<Location /svn>
DAV svn
SVNParentPath /svn/repos
SVNListParentPath on
# Limit write permission to list of valid users.
<LimitExcept GET PROPFIND OPTIONS REPORT>
AuthType Basic
AuthName "Subversion"
AuthUserFile /svn/authfiles/svn-htpasswd
AuthzSVNAccessFile /svn/authfiles/svn-access.conf
Require valid-user
</LimitExcept>
</Location>
<LocationMatch /svn/myProject/>
AuthType Basic
AuthName "Subversion (private)"
AuthUserFile /svn/authfiles/svn-htpasswd
AuthzSVNAccessFile /svn/authfiles/svn-access.conf
Require user user1 user2 user3...
</LocationMatch>
и хорошо работает со мной. Спасибо за это.
This is working for me:
<Location />
DAV svn
SVNPath /repository
AuthType Basic
AuthName "Repository authentication"
AuthUserFile /repository/.svn-auth
AuthzSVNAccessFile /repository/.svn-access
Satisfy All
Require valid-user
</Location>
Указание на браузер к http://127.0.0.1 показывает мне содержание репозитория.
Нашёл это в /etc/apache2/conf.d/subversion.conf (нужно отобразить документы об ошибках по умолчанию):
<VirtualHost *>
ServerName svn.example.com
ErrorLog /var/log/apache2/svn.example.com-error_log
TransferLog /var/log/apache2/svn.example.com-access_log
#
# Do not set DocumentRoot. It is not needed here and just causes trouble.
#
# Map the error documents back to their defaults.
# Otherwise mod_dav_svn tries to find a "error" repository.
#
ErrorDocument 400 default
ErrorDocument 401 default
ErrorDocument 403 default
ErrorDocument 404 default
ErrorDocument 405 default
ErrorDocument 408 default
ErrorDocument 410 default
ErrorDocument 411 default
ErrorDocument 412 default
ErrorDocument 413 default
ErrorDocument 414 default
ErrorDocument 415 default
ErrorDocument 500 default
ErrorDocument 501 default
ErrorDocument 502 default
ErrorDocument 503 default
#
<Location />
...
</Location>
После этого всё заработало, как и ожидалось.
.