1919)
2020
2121_CROSSORIGIN_NO_REQUEST = (
22- 'The crossorigin attribute might be necessary but you did not pass a '
23- 'request object. django_webpack_loader needs a request object to be able '
24- 'to know when to emit the crossorigin attribute on link and script tags. '
25- 'Chunk name: {chunk_name}' )
22+ "The crossorigin attribute might be necessary but you did not pass a "
23+ "request object. django_webpack_loader needs a request object to be able "
24+ "to know when to emit the crossorigin attribute on link and script tags. "
25+ "Chunk name: {chunk_name}"
26+ )
2627_CROSSORIGIN_NO_HOST = (
2728 'You have passed the request object but it does not have a "HTTP_HOST", '
28- 'thus django_webpack_loader can\' t know if the crossorigin header will '
29- 'be necessary or not. Chunk name: {chunk_name}' )
29+ "thus django_webpack_loader can't know if the crossorigin header will "
30+ "be necessary or not. Chunk name: {chunk_name}"
31+ )
3032_NONCE_NO_REQUEST = (
31- 'You have enabled the adding of nonce attributes to generated tags via '
32- 'django_webpack_loader, but haven\' t passed a request. '
33- 'Chunk name: {chunk_name}' )
33+ "You have enabled the adding of nonce attributes to generated tags via "
34+ "django_webpack_loader, but haven't passed a request. "
35+ "Chunk name: {chunk_name}"
36+ )
3437_NONCE_NO_CSPNONCE = (
35- ' django_webpack_loader can\ ' t generate a nonce tag for a bundle, '
38+ " django_webpack_loader can't generate a nonce tag for a bundle, "
3639 'because the passed request doesn\' t contain a "csp_nonce". '
37- 'Chunk name: {chunk_name}' )
40+ "Chunk name: {chunk_name}"
41+ )
42+
43+ _LOADER_POSSIBLE_LIMBO = (
44+ 'You are using django_webpack_loader with default timeout "None" '
45+ "which can cause request to hang indefinitely. "
46+ "Validate status of webpack-stats.json file if you experience infinite loading."
47+ )
3848
3949
4050@lru_cache (maxsize = 100 )
4151def _get_netloc (url : str ) -> str :
42- ' Return a cached netloc (host:port) for the passed `url`.'
52+ " Return a cached netloc (host:port) for the passed `url`."
4353 return urlparse (url = url ).netloc
4454
4555
@@ -57,7 +67,9 @@ def load_assets(self):
5767 except IOError :
5868 raise IOError (
5969 "Error reading {0}. Are you sure webpack has generated "
60- "the file and the path is correct?" .format (self .config ["STATS_FILE" ])
70+ "the file and the path is correct?" .format (
71+ self .config ["STATS_FILE" ]
72+ )
6173 )
6274
6375 def get_assets (self ):
@@ -69,47 +81,56 @@ def get_assets(self):
6981
7082 def get_asset_by_source_filename (self , name ):
7183 files = self .get_assets ()["assets" ].values ()
72- return next ((x for x in files if x .get ("sourceFilename" ) == name ), None )
84+ return next (
85+ (x for x in files if x .get ("sourceFilename" ) == name ), None
86+ )
7387
7488 def _add_crossorigin (
75- self , request : Optional [HttpRequest ], chunk : Dict [str , str ],
76- integrity : str , attrs_l : str ) -> str :
77- 'Return an added `crossorigin` attribute if necessary.'
89+ self ,
90+ request : Optional [HttpRequest ],
91+ chunk : Dict [str , str ],
92+ integrity : str ,
93+ attrs_l : str ,
94+ ) -> str :
95+ "Return an added `crossorigin` attribute if necessary."
7896 def_value = f' integrity="{ integrity } " '
7997 if not request :
80- message = _CROSSORIGIN_NO_REQUEST .format (chunk_name = chunk [' name' ])
98+ message = _CROSSORIGIN_NO_REQUEST .format (chunk_name = chunk [" name" ])
8199 warn (message = message , category = RuntimeWarning )
82100 return def_value
83- if ' crossorigin' in attrs_l :
101+ if " crossorigin" in attrs_l :
84102 return def_value
85- host : Optional [str ] = request .META .get (' HTTP_HOST' )
103+ host : Optional [str ] = request .META .get (" HTTP_HOST" )
86104 if not host :
87- message = _CROSSORIGIN_NO_HOST .format (chunk_name = chunk [' name' ])
105+ message = _CROSSORIGIN_NO_HOST .format (chunk_name = chunk [" name" ])
88106 warn (message = message , category = RuntimeWarning )
89107 return def_value
90- netloc = _get_netloc (url = chunk [' url' ])
91- if netloc == '' or netloc == host :
108+ netloc = _get_netloc (url = chunk [" url" ])
109+ if netloc == "" or netloc == host :
92110 # Crossorigin not necessary
93111 return def_value
94- cfgval : str = self .config .get (' CROSSORIGIN' )
95- if cfgval == '' :
96- return f' { def_value } crossorigin '
112+ cfgval : str = self .config .get (" CROSSORIGIN" )
113+ if cfgval == "" :
114+ return f" { def_value } crossorigin "
97115 return f'{ def_value } crossorigin="{ cfgval } " '
98116
99117 def get_integrity_attr (
100- self , chunk : Dict [str , str ], request : Optional [HttpRequest ],
101- attrs_l : str ) -> str :
102- if not self .config .get ('INTEGRITY' ):
118+ self ,
119+ chunk : Dict [str , str ],
120+ request : Optional [HttpRequest ],
121+ attrs_l : str ,
122+ ) -> str :
123+ if not self .config .get ("INTEGRITY" ):
103124 # Crossorigin only necessary when integrity is used
104- return ' '
125+ return " "
105126
106- integrity = chunk .get (' integrity' )
127+ integrity = chunk .get (" integrity" )
107128 if not integrity :
108129 raise WebpackLoaderBadStatsError (
109- ' The stats file does not contain valid data: INTEGRITY is set '
130+ " The stats file does not contain valid data: INTEGRITY is set "
110131 'to True, but chunk does not contain "integrity" key. Maybe '
111- ' you forgot to add integrity: true in your '
112- ' BundleTrackerPlugin configuration?'
132+ " you forgot to add integrity: true in your "
133+ " BundleTrackerPlugin configuration?"
113134 )
114135 return self ._add_crossorigin (
115136 request = request ,
@@ -118,28 +139,32 @@ def get_integrity_attr(
118139 attrs_l = attrs_l ,
119140 )
120141
121- def get_nonce_attr (self , chunk : Dict [str , str ], request : Optional [HttpRequest ], attrs : str ) -> str :
122- 'Return an added nonce for CSP when available.'
123- if not self .config .get ('CSP_NONCE' ):
124- return ''
142+ def get_nonce_attr (
143+ self , chunk : Dict [str , str ], request : Optional [HttpRequest ], attrs : str
144+ ) -> str :
145+ "Return an added nonce for CSP when available."
146+ if not self .config .get ("CSP_NONCE" ):
147+ return ""
125148 if request is None :
126- message = _NONCE_NO_REQUEST .format (chunk_name = chunk [' name' ])
149+ message = _NONCE_NO_REQUEST .format (chunk_name = chunk [" name" ])
127150 warn (message = message , category = RuntimeWarning )
128- return ''
129- nonce = getattr (request , ' csp_nonce' , None )
151+ return ""
152+ nonce = getattr (request , " csp_nonce" , None )
130153 if nonce is None :
131- message = _NONCE_NO_CSPNONCE .format (chunk_name = chunk [' name' ])
154+ message = _NONCE_NO_CSPNONCE .format (chunk_name = chunk [" name" ])
132155 warn (message = message , category = RuntimeWarning )
133- return ''
134- if ' nonce=' in attrs .lower ():
135- return ''
156+ return ""
157+ if " nonce=" in attrs .lower ():
158+ return ""
136159 return f'nonce="{ nonce } " '
137160
138161 def filter_chunks (self , chunks ):
139162 filtered_chunks = []
140163
141164 for chunk in chunks :
142- ignore = any (regex .match (chunk ) for regex in self .config ["ignores" ])
165+ ignore = any (
166+ regex .match (chunk ) for regex in self .config ["ignores" ]
167+ )
143168 if not ignore :
144169 filtered_chunks .append (chunk )
145170
@@ -187,6 +212,10 @@ def get_bundle(self, bundle_name):
187212 time .sleep (self .config ["POLL_INTERVAL" ])
188213 if timeout and (time .time () - timeout > start ):
189214 timed_out = True
215+ if not timeout :
216+ warn (
217+ message = _LOADER_POSSIBLE_LIMBO , category = RuntimeWarning
218+ )
190219 assets = self .get_assets ()
191220
192221 if timed_out :
0 commit comments