blob: f1ac35e48f2746880d9bbe507bb62890b6e945df [file] [log] [blame]
Greg Wardfe6462c2000-04-04 01:40:52 +00001"""distutils.dist
2
3Provides the Distribution class, which represents the module distribution
4being built/installed/distributed."""
5
6# created 2000/04/03, Greg Ward
7# (extricated from core.py; actually dates back to the beginning)
8
9__revision__ = "$Id$"
10
11import sys, string, re
12from types import *
13from copy import copy
14from distutils.errors import *
Greg Ward82715e12000-04-21 02:28:14 +000015from distutils.fancy_getopt import FancyGetopt, longopt_xlate
Greg Wardfe6462c2000-04-04 01:40:52 +000016
17
18# Regex to define acceptable Distutils command names. This is not *quite*
19# the same as a Python NAME -- I don't allow leading underscores. The fact
20# that they're very similar is no coincidence; the default naming scheme is
21# to look for a Python module named after the command.
22command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
23
24
25class Distribution:
26 """The core of the Distutils. Most of the work hiding behind
27 'setup' is really done within a Distribution instance, which
28 farms the work out to the Distutils commands specified on the
29 command line.
30
31 Clients will almost never instantiate Distribution directly,
32 unless the 'setup' function is totally inadequate to their needs.
33 However, it is conceivable that a client might wish to subclass
34 Distribution for some specialized purpose, and then pass the
35 subclass to 'setup' as the 'distclass' keyword argument. If so,
36 it is necessary to respect the expectations that 'setup' has of
37 Distribution: it must have a constructor and methods
38 'parse_command_line()' and 'run_commands()' with signatures like
39 those described below."""
40
41
42 # 'global_options' describes the command-line options that may be
Greg Ward82715e12000-04-21 02:28:14 +000043 # supplied to the setup script prior to any actual commands.
44 # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of
Greg Wardfe6462c2000-04-04 01:40:52 +000045 # these global options. This list should be kept to a bare minimum,
46 # since every global option is also valid as a command option -- and we
47 # don't want to pollute the commands with too many options that they
48 # have minimal control over.
49 global_options = [('verbose', 'v',
50 "run verbosely (default)"),
51 ('quiet', 'q',
52 "run quietly (turns verbosity off)"),
53 ('dry-run', 'n',
54 "don't actually do anything"),
Greg Wardfe6462c2000-04-04 01:40:52 +000055 ('help', 'h',
Greg Ward82715e12000-04-21 02:28:14 +000056 "show this help message, plus help for any commands " +
57 "given on the command-line"),
Greg Wardfe6462c2000-04-04 01:40:52 +000058 ]
Greg Ward82715e12000-04-21 02:28:14 +000059
60 # options that are not propagated to the commands
61 display_options = [
62 ('help-commands', None,
63 "list all available commands"),
64 ('name', None,
65 "print package name"),
66 ('version', 'V',
67 "print package version"),
68 ('fullname', None,
69 "print <package name>-<version>"),
70 ('author', None,
71 "print the author's name"),
72 ('author-email', None,
73 "print the author's email address"),
74 ('maintainer', None,
75 "print the maintainer's name"),
76 ('maintainer-email', None,
77 "print the maintainer's email address"),
78 ('contact', None,
79 "print the name of the maintainer if present, "
80 "else author"),
81 ('contact-email', None,
82 "print the email of the maintainer if present, "
83 "else author"),
84 ('url', None,
85 "print the URL for this package"),
86 ('licence', None,
87 "print the licence of the package"),
88 ('license', None,
89 "alias for --licence"),
90 ('description', None,
91 "print the package description"),
Greg Warde5a584e2000-04-26 02:26:55 +000092 ('long-description', None,
93 "print the long package description"),
Greg Ward82715e12000-04-21 02:28:14 +000094 ]
95 display_option_names = map(lambda x: string.translate(x[0], longopt_xlate),
96 display_options)
97
98 # negative options are options that exclude other options
Greg Wardfe6462c2000-04-04 01:40:52 +000099 negative_opt = {'quiet': 'verbose'}
100
101
102 # -- Creation/initialization methods -------------------------------
103
104 def __init__ (self, attrs=None):
105 """Construct a new Distribution instance: initialize all the
106 attributes of a Distribution, and then uses 'attrs' (a
107 dictionary mapping attribute names to values) to assign
108 some of those attributes their "real" values. (Any attributes
109 not mentioned in 'attrs' will be assigned to some null
110 value: 0, None, an empty list or dictionary, etc.) Most
111 importantly, initialize the 'command_obj' attribute
112 to the empty dictionary; this will be filled in with real
113 command objects by 'parse_command_line()'."""
114
115 # Default values for our command-line options
116 self.verbose = 1
117 self.dry_run = 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000118 self.help = 0
Greg Ward82715e12000-04-21 02:28:14 +0000119 for attr in self.display_option_names:
120 setattr(self, attr, 0)
Greg Wardfe6462c2000-04-04 01:40:52 +0000121
Greg Ward82715e12000-04-21 02:28:14 +0000122 # Store the distribution meta-data (name, version, author, and so
123 # forth) in a separate object -- we're getting to have enough
124 # information here (and enough command-line options) that it's
125 # worth it. Also delegate 'get_XXX()' methods to the 'metadata'
126 # object in a sneaky and underhanded (but efficient!) way.
127 self.metadata = DistributionMetadata ()
Greg Ward4982f982000-04-22 02:52:44 +0000128 method_basenames = dir(self.metadata) + \
129 ['fullname', 'contact', 'contact_email']
130 for basename in method_basenames:
131 method_name = "get_" + basename
132 setattr(self, method_name, getattr(self.metadata, method_name))
Greg Wardfe6462c2000-04-04 01:40:52 +0000133
134 # 'cmdclass' maps command names to class objects, so we
135 # can 1) quickly figure out which class to instantiate when
136 # we need to create a new command object, and 2) have a way
Greg Ward82715e12000-04-21 02:28:14 +0000137 # for the setup script to override command classes
Greg Wardfe6462c2000-04-04 01:40:52 +0000138 self.cmdclass = {}
139
140 # These options are really the business of various commands, rather
141 # than of the Distribution itself. We provide aliases for them in
142 # Distribution as a convenience to the developer.
Greg Wardfe6462c2000-04-04 01:40:52 +0000143 self.packages = None
144 self.package_dir = None
145 self.py_modules = None
146 self.libraries = None
147 self.ext_modules = None
148 self.ext_package = None
149 self.include_dirs = None
150 self.extra_path = None
151
152 # And now initialize bookkeeping stuff that can't be supplied by
153 # the caller at all. 'command_obj' maps command names to
154 # Command instances -- that's how we enforce that every command
155 # class is a singleton.
156 self.command_obj = {}
157
158 # 'have_run' maps command names to boolean values; it keeps track
159 # of whether we have actually run a particular command, to make it
160 # cheap to "run" a command whenever we think we might need to -- if
161 # it's already been done, no need for expensive filesystem
162 # operations, we just check the 'have_run' dictionary and carry on.
163 # It's only safe to query 'have_run' for a command class that has
164 # been instantiated -- a false value will be inserted when the
165 # command object is created, and replaced with a true value when
166 # the command is succesfully run. Thus it's probably best to use
167 # '.get()' rather than a straight lookup.
168 self.have_run = {}
169
170 # Now we'll use the attrs dictionary (ultimately, keyword args from
Greg Ward82715e12000-04-21 02:28:14 +0000171 # the setup script) to possibly override any or all of these
172 # distribution options.
173
Greg Wardfe6462c2000-04-04 01:40:52 +0000174 if attrs:
175
176 # Pull out the set of command options and work on them
177 # specifically. Note that this order guarantees that aliased
178 # command options will override any supplied redundantly
179 # through the general options dictionary.
180 options = attrs.get ('options')
181 if options:
182 del attrs['options']
183 for (command, cmd_options) in options.items():
184 cmd_obj = self.find_command_obj (command)
185 for (key, val) in cmd_options.items():
186 cmd_obj.set_option (key, val)
187 # loop over commands
188 # if any command options
189
190 # Now work on the rest of the attributes. Any attribute that's
191 # not already defined is invalid!
192 for (key,val) in attrs.items():
Greg Ward82715e12000-04-21 02:28:14 +0000193 if hasattr (self.metadata, key):
194 setattr (self.metadata, key, val)
195 elif hasattr (self, key):
Greg Wardfe6462c2000-04-04 01:40:52 +0000196 setattr (self, key, val)
197 else:
Greg Ward02a1a2b2000-04-15 22:15:07 +0000198 raise DistutilsSetupError, \
Greg Wardfe6462c2000-04-04 01:40:52 +0000199 "invalid distribution option '%s'" % key
200
201 # __init__ ()
202
203
204 def parse_command_line (self, args):
205 """Parse the setup script's command line: set any Distribution
206 attributes tied to command-line options, create all command
207 objects, and set their options from the command-line. 'args'
208 must be a list of command-line arguments, most likely
209 'sys.argv[1:]' (see the 'setup()' function). This list is first
210 processed for "global options" -- options that set attributes of
211 the Distribution instance. Then, it is alternately scanned for
212 Distutils command and options for that command. Each new
213 command terminates the options for the previous command. The
214 allowed options for a command are determined by the 'options'
215 attribute of the command object -- thus, we instantiate (and
216 cache) every command object here, in order to access its
217 'options' attribute. Any error in that 'options' attribute
218 raises DistutilsGetoptError; any error on the command-line
219 raises DistutilsArgError. If no Distutils commands were found
220 on the command line, raises DistutilsArgError. Return true if
221 command-line successfully parsed and we should carry on with
222 executing commands; false if no errors but we shouldn't execute
223 commands (currently, this only happens if user asks for
224 help)."""
225
Greg Ward7d508fe2000-04-06 02:07:41 +0000226 # late import because of mutual dependence between these modules
Greg Wardfe6462c2000-04-04 01:40:52 +0000227 from distutils.cmd import Command
Greg Ward7d508fe2000-04-06 02:07:41 +0000228 from distutils.core import usage
Greg Wardfe6462c2000-04-04 01:40:52 +0000229
230 # We have to parse the command line a bit at a time -- global
231 # options, then the first command, then its options, and so on --
232 # because each command will be handled by a different class, and
233 # the options that are valid for a particular class aren't
234 # known until we instantiate the command class, which doesn't
235 # happen until we know what the command is.
236
237 self.commands = []
Greg Ward82715e12000-04-21 02:28:14 +0000238 parser = FancyGetopt (self.global_options + self.display_options)
239 parser.set_negative_aliases (self.negative_opt)
Greg Ward58ec6ed2000-04-21 04:22:49 +0000240 parser.set_aliases ({'license': 'licence'})
Greg Ward82715e12000-04-21 02:28:14 +0000241 args = parser.getopt (object=self)
242 option_order = parser.get_option_order()
Greg Wardfe6462c2000-04-04 01:40:52 +0000243
Greg Ward82715e12000-04-21 02:28:14 +0000244 # for display options we return immediately
245 if self.handle_display_options(option_order):
Greg Wardfe6462c2000-04-04 01:40:52 +0000246 return
247
248 while args:
249 # Pull the current command from the head of the command line
250 command = args[0]
251 if not command_re.match (command):
252 raise SystemExit, "invalid command name '%s'" % command
253 self.commands.append (command)
254
255 # Make sure we have a command object to put the options into
256 # (this either pulls it out of a cache of command objects,
257 # or finds and instantiates the command class).
258 try:
259 cmd_obj = self.find_command_obj (command)
260 except DistutilsModuleError, msg:
261 raise DistutilsArgError, msg
262
263 # Require that the command class be derived from Command --
Greg Wardc4537ac2000-05-07 15:30:31 +0000264 # want to be sure that the basic "command" interface is
265 # implemented.
Greg Wardfe6462c2000-04-04 01:40:52 +0000266 if not isinstance (cmd_obj, Command):
267 raise DistutilsClassError, \
268 "command class %s must subclass Command" % \
269 cmd_obj.__class__
270
271 # Also make sure that the command object provides a list of its
272 # known options
273 if not (hasattr (cmd_obj, 'user_options') and
274 type (cmd_obj.user_options) is ListType):
275 raise DistutilsClassError, \
276 ("command class %s must provide " +
277 "'user_options' attribute (a list of tuples)") % \
278 cmd_obj.__class__
279
280 # Poof! like magic, all commands support the global
281 # options too, just by adding in 'global_options'.
282 negative_opt = self.negative_opt
283 if hasattr (cmd_obj, 'negative_opt'):
284 negative_opt = copy (negative_opt)
285 negative_opt.update (cmd_obj.negative_opt)
286
Greg Ward82715e12000-04-21 02:28:14 +0000287 parser.set_option_table (self.global_options +
288 cmd_obj.user_options)
289 parser.set_negative_aliases (negative_opt)
290 args = parser.getopt (args[1:], cmd_obj)
Greg Wardfe6462c2000-04-04 01:40:52 +0000291 if cmd_obj.help:
Greg Ward82715e12000-04-21 02:28:14 +0000292 parser.set_option_table (self.global_options)
293 parser.print_help ("Global options:")
Greg Wardfe6462c2000-04-04 01:40:52 +0000294 print
Greg Ward82715e12000-04-21 02:28:14 +0000295
296 parser.set_option_table (cmd_obj.user_options)
297 parser.print_help ("Options for '%s' command:" % command)
Greg Wardfe6462c2000-04-04 01:40:52 +0000298 print
299 print usage
300 return
301
302 self.command_obj[command] = cmd_obj
303 self.have_run[command] = 0
304
305 # while args
306
307 # If the user wants help -- ie. they gave the "--help" option --
308 # give it to 'em. We do this *after* processing the commands in
309 # case they want help on any particular command, eg.
310 # "setup.py --help foo". (This isn't the documented way to
311 # get help on a command, but I support it because that's how
312 # CVS does it -- might as well be consistent.)
313 if self.help:
Greg Ward82715e12000-04-21 02:28:14 +0000314 parser.set_option_table (self.global_options)
315 parser.print_help (
316 "Global options (apply to all commands, " +
317 "or can be used per command):")
Greg Wardfe6462c2000-04-04 01:40:52 +0000318 print
319
Greg Ward82715e12000-04-21 02:28:14 +0000320 if not self.commands:
321 parser.set_option_table (self.display_options)
322 parser.print_help (
323 "Information display options (just display " +
324 "information, ignore any commands)")
325 print
326
Greg Wardfe6462c2000-04-04 01:40:52 +0000327 for command in self.commands:
328 klass = self.find_command_class (command)
Greg Ward82715e12000-04-21 02:28:14 +0000329 parser.set_option_table (klass.user_options)
330 parser.print_help ("Options for '%s' command:" % command)
Greg Wardfe6462c2000-04-04 01:40:52 +0000331 print
332
333 print usage
334 return
335
336 # Oops, no commands found -- an end-user error
337 if not self.commands:
338 raise DistutilsArgError, "no commands supplied"
339
340 # All is well: return true
341 return 1
342
343 # parse_command_line()
344
Greg Ward82715e12000-04-21 02:28:14 +0000345 def handle_display_options (self, option_order):
346 """If there were any non-global "display-only" options
347 (--help-commands or the metadata display options) on the command
348 line, display the requested info and return true; else return
349 false."""
350
351 from distutils.core import usage
352
353 # User just wants a list of commands -- we'll print it out and stop
354 # processing now (ie. if they ran "setup --help-commands foo bar",
355 # we ignore "foo bar").
356 if self.help_commands:
357 self.print_commands ()
358 print
359 print usage
360 return 1
361
362 # If user supplied any of the "display metadata" options, then
363 # display that metadata in the order in which the user supplied the
364 # metadata options.
365 any_display_options = 0
366 is_display_option = {}
367 for option in self.display_options:
368 is_display_option[option[0]] = 1
369
370 for (opt, val) in option_order:
371 if val and is_display_option.get(opt):
372 opt = string.translate (opt, longopt_xlate)
373 print getattr(self.metadata, "get_"+opt)()
374 any_display_options = 1
375
376 return any_display_options
377
378 # handle_display_options()
Greg Wardfe6462c2000-04-04 01:40:52 +0000379
380 def print_command_list (self, commands, header, max_length):
381 """Print a subset of the list of all commands -- used by
382 'print_commands()'."""
383
384 print header + ":"
385
386 for cmd in commands:
387 klass = self.cmdclass.get (cmd)
388 if not klass:
389 klass = self.find_command_class (cmd)
390 try:
391 description = klass.description
392 except AttributeError:
393 description = "(no description available)"
394
395 print " %-*s %s" % (max_length, cmd, description)
396
397 # print_command_list ()
398
399
400 def print_commands (self):
401 """Print out a help message listing all available commands with
402 a description of each. The list is divided into "standard
403 commands" (listed in distutils.command.__all__) and "extra
404 commands" (mentioned in self.cmdclass, but not a standard
405 command). The descriptions come from the command class
406 attribute 'description'."""
407
408 import distutils.command
409 std_commands = distutils.command.__all__
410 is_std = {}
411 for cmd in std_commands:
412 is_std[cmd] = 1
413
414 extra_commands = []
415 for cmd in self.cmdclass.keys():
416 if not is_std.get(cmd):
417 extra_commands.append (cmd)
418
419 max_length = 0
420 for cmd in (std_commands + extra_commands):
421 if len (cmd) > max_length:
422 max_length = len (cmd)
423
424 self.print_command_list (std_commands,
425 "Standard commands",
426 max_length)
427 if extra_commands:
428 print
429 self.print_command_list (extra_commands,
430 "Extra commands",
431 max_length)
432
433 # print_commands ()
434
435
436
437 # -- Command class/object methods ----------------------------------
438
439 # This is a method just so it can be overridden if desired; it doesn't
440 # actually use or change any attributes of the Distribution instance.
441 def find_command_class (self, command):
442 """Given a command, derives the names of the module and class
443 expected to implement the command: eg. 'foo_bar' becomes
444 'distutils.command.foo_bar' (the module) and 'FooBar' (the
445 class within that module). Loads the module, extracts the
446 class from it, and returns the class object.
447
448 Raises DistutilsModuleError with a semi-user-targeted error
449 message if the expected module could not be loaded, or the
450 expected class was not found in it."""
451
452 module_name = 'distutils.command.' + command
453 klass_name = command
454
455 try:
456 __import__ (module_name)
457 module = sys.modules[module_name]
458 except ImportError:
459 raise DistutilsModuleError, \
460 "invalid command '%s' (no module named '%s')" % \
461 (command, module_name)
462
463 try:
464 klass = vars(module)[klass_name]
465 except KeyError:
466 raise DistutilsModuleError, \
467 "invalid command '%s' (no class '%s' in module '%s')" \
468 % (command, klass_name, module_name)
469
470 return klass
471
472 # find_command_class ()
473
474
475 def create_command_obj (self, command):
476 """Figure out the class that should implement a command,
477 instantiate it, cache and return the new "command object".
478 The "command class" is determined either by looking it up in
479 the 'cmdclass' attribute (this is the mechanism whereby
480 clients may override default Distutils commands or add their
481 own), or by calling the 'find_command_class()' method (if the
482 command name is not in 'cmdclass'."""
483
484 # Determine the command class -- either it's in the command_class
485 # dictionary, or we have to divine the module and class name
486 klass = self.cmdclass.get(command)
487 if not klass:
488 klass = self.find_command_class (command)
489 self.cmdclass[command] = klass
490
491 # Found the class OK -- instantiate it
492 cmd_obj = klass (self)
493 return cmd_obj
494
495
496 def find_command_obj (self, command, create=1):
497 """Look up and return a command object in the cache maintained by
498 'create_command_obj()'. If none found, the action taken
499 depends on 'create': if true (the default), create a new
500 command object by calling 'create_command_obj()' and return
501 it; otherwise, return None. If 'command' is an invalid
502 command name, then DistutilsModuleError will be raised."""
503
504 cmd_obj = self.command_obj.get (command)
505 if not cmd_obj and create:
506 cmd_obj = self.create_command_obj (command)
507 self.command_obj[command] = cmd_obj
508
509 return cmd_obj
510
511
512 # -- Methods that operate on the Distribution ----------------------
513
514 def announce (self, msg, level=1):
515 """Print 'msg' if 'level' is greater than or equal to the verbosity
516 level recorded in the 'verbose' attribute (which, currently,
517 can be only 0 or 1)."""
518
519 if self.verbose >= level:
520 print msg
521
522
523 def run_commands (self):
Greg Ward82715e12000-04-21 02:28:14 +0000524 """Run each command that was seen on the setup script command line.
Greg Wardfe6462c2000-04-04 01:40:52 +0000525 Uses the list of commands found and cache of command objects
526 created by 'create_command_obj()'."""
527
528 for cmd in self.commands:
529 self.run_command (cmd)
530
531
Greg Wardfe6462c2000-04-04 01:40:52 +0000532 # -- Methods that operate on its Commands --------------------------
533
534 def run_command (self, command):
535
536 """Do whatever it takes to run a command (including nothing at all,
537 if the command has already been run). Specifically: if we have
538 already created and run the command named by 'command', return
539 silently without doing anything. If the command named by
540 'command' doesn't even have a command object yet, create one.
541 Then invoke 'run()' on that command object (or an existing
542 one)."""
543
544 # Already been here, done that? then return silently.
545 if self.have_run.get (command):
546 return
547
548 self.announce ("running " + command)
549 cmd_obj = self.find_command_obj (command)
550 cmd_obj.ensure_ready ()
551 cmd_obj.run ()
552 self.have_run[command] = 1
553
554
Greg Wardfe6462c2000-04-04 01:40:52 +0000555 # -- Distribution query methods ------------------------------------
556
557 def has_pure_modules (self):
558 return len (self.packages or self.py_modules or []) > 0
559
560 def has_ext_modules (self):
561 return self.ext_modules and len (self.ext_modules) > 0
562
563 def has_c_libraries (self):
564 return self.libraries and len (self.libraries) > 0
565
566 def has_modules (self):
567 return self.has_pure_modules() or self.has_ext_modules()
568
569 def is_pure (self):
570 return (self.has_pure_modules() and
571 not self.has_ext_modules() and
572 not self.has_c_libraries())
573
Greg Ward82715e12000-04-21 02:28:14 +0000574 # -- Metadata query methods ----------------------------------------
575
576 # If you're looking for 'get_name()', 'get_version()', and so forth,
577 # they are defined in a sneaky way: the constructor binds self.get_XXX
578 # to self.metadata.get_XXX. The actual code is in the
579 # DistributionMetadata class, below.
580
581# class Distribution
582
583
584class DistributionMetadata:
585 """Dummy class to hold the distribution meta-data: name, version,
586 author, and so forth."""
587
588 def __init__ (self):
589 self.name = None
590 self.version = None
591 self.author = None
592 self.author_email = None
593 self.maintainer = None
594 self.maintainer_email = None
595 self.url = None
596 self.licence = None
597 self.description = None
Greg Warde5a584e2000-04-26 02:26:55 +0000598 self.long_description = None
Greg Ward82715e12000-04-21 02:28:14 +0000599
600 # -- Metadata query methods ----------------------------------------
601
Greg Wardfe6462c2000-04-04 01:40:52 +0000602 def get_name (self):
603 return self.name or "UNKNOWN"
604
Greg Ward82715e12000-04-21 02:28:14 +0000605 def get_version(self):
606 return self.version or "???"
Greg Wardfe6462c2000-04-04 01:40:52 +0000607
Greg Ward82715e12000-04-21 02:28:14 +0000608 def get_fullname (self):
609 return "%s-%s" % (self.get_name(), self.get_version())
610
611 def get_author(self):
612 return self.author or "UNKNOWN"
613
614 def get_author_email(self):
615 return self.author_email or "UNKNOWN"
616
617 def get_maintainer(self):
618 return self.maintainer or "UNKNOWN"
619
620 def get_maintainer_email(self):
621 return self.maintainer_email or "UNKNOWN"
622
623 def get_contact(self):
624 return (self.maintainer or
625 self.author or
626 "UNKNOWN")
627
628 def get_contact_email(self):
629 return (self.maintainer_email or
630 self.author_email or
631 "UNKNOWN")
632
633 def get_url(self):
634 return self.url or "UNKNOWN"
635
636 def get_licence(self):
637 return self.licence or "UNKNOWN"
638
639 def get_description(self):
640 return self.description or "UNKNOWN"
Greg Warde5a584e2000-04-26 02:26:55 +0000641
642 def get_long_description(self):
643 return self.long_description or "UNKNOWN"
644
Greg Ward82715e12000-04-21 02:28:14 +0000645# class DistributionMetadata
Greg Wardfe6462c2000-04-04 01:40:52 +0000646
647if __name__ == "__main__":
648 dist = Distribution ()
649 print "ok"