""" The `compat` module provides support for backwards compatibility with older versions of Django/Python, and compatibility wrappers around optional packages. """ import sys from django.conf import settings from django.core import validators from django.views.generic import View try: from django.urls import ( # noqa URLPattern, URLResolver, ) except ImportError: # Will be removed in Django 2.0 from django.urls import ( # noqa RegexURLPattern as URLPattern, RegexURLResolver as URLResolver, ) try: from django.core.validators import ProhibitNullCharactersValidator # noqa except ImportError: ProhibitNullCharactersValidator = None def get_original_route(urlpattern): """ Get the original route/regex that was typed in by the user into the path(), re_path() or url() directive. This is in contrast with get_regex_pattern below, which for RoutePattern returns the raw regex generated from the path(). """ if hasattr(urlpattern, 'pattern'): # Django 2.0 return str(urlpattern.pattern) else: # Django < 2.0 return urlpattern.regex.pattern def get_regex_pattern(urlpattern): """ Get the raw regex out of the urlpattern's RegexPattern or RoutePattern. This is always a regular expression, unlike get_original_route above. """ if hasattr(urlpattern, 'pattern'): # Django 2.0 return urlpattern.pattern.regex.pattern else: # Django < 2.0 return urlpattern.regex.pattern def is_route_pattern(urlpattern): if hasattr(urlpattern, 'pattern'): # Django 2.0 from django.urls.resolvers import RoutePattern return isinstance(urlpattern.pattern, RoutePattern) else: # Django < 2.0 return False def make_url_resolver(regex, urlpatterns): try: # Django 2.0 from django.urls.resolvers import RegexPattern return URLResolver(RegexPattern(regex), urlpatterns) except ImportError: # Django < 2.0 return URLResolver(regex, urlpatterns) def unicode_http_header(value): # Coerce HTTP header value to unicode. if isinstance(value, bytes): return value.decode('iso-8859-1') return value def distinct(queryset, base): if settings.DATABASES[queryset.db]["ENGINE"] == "django.db.backends.oracle": # distinct analogue for Oracle users return base.filter(pk__in=set(queryset.values_list('pk', flat=True))) return queryset.distinct() # django.contrib.postgres requires psycopg2 try: from django.contrib.postgres import fields as postgres_fields except ImportError: postgres_fields = None # coreapi is optional (Note that uritemplate is a dependency of coreapi) try: import coreapi import uritemplate except ImportError: coreapi = None uritemplate = None # coreschema is optional try: import coreschema except ImportError: coreschema = None # pyyaml is optional try: import yaml except ImportError: yaml = None # django-crispy-forms is optional try: import crispy_forms except ImportError: crispy_forms = None # requests is optional try: import requests except ImportError: requests = None # PATCH method is not implemented by Django if 'patch' not in View.http_method_names: View.http_method_names = View.http_method_names + ['patch'] # Markdown is optional (version 2.6+ required) try: import markdown HEADERID_EXT_PATH = 'markdown.extensions.toc' LEVEL_PARAM = 'baselevel' def apply_markdown(text): """ Simple wrapper around :func:`markdown.markdown` to set the base level of '#' style headers to