class_docstr: Factory for :class:`MarkDecorator` objects - exposed as
  a ``pytest.mark`` singleton instance.  Example::
  
       import pytest
       @pytest.mark.slowtest
       def test_function():
          pass
  
  will set a 'slowtest' :class:`MarkInfo` object
  on the ``test_function`` object. 
class_docstr_tok: ["Factory","for",":","class",":","`","MarkDecorator","`","objects","-","exposed","as","a","``","pytest.mark","``","singleton","instance",".","Example",":",":","import","pytest","@","pytest.mark.slowtest","def","test_function","(",")",":","pass","will","set","a","'slowtest","'",":","class",":","`","MarkInfo","`","object","on","the","``","test_function","``","object","."]
code: def __getattr__(self, name):
      if name[0] == "_":
          raise AttributeError(
              "Marker name must NOT start with underscore"
          )
  
      if self._config is not None:
          # We store a set of markers as a performance optimisation - if a mark
          # name is in the set we definitely know it, but a mark may be known and
          # not in the set.  We therefore start by updating the set!
          if name not in self._markers:
              for line in self._config.getini("markers"):
                  # example lines: "skipif(condition): skip the given test if..."
                  # or "hypothesis: tests which use Hypothesis", so to get the
                  # marker name we split on both `:` and `(`.
                  if line == "ya:external":
                      marker = line
                  else:
                      marker = line.split(":")[0].split("(")[0].strip()
                  self._markers.add(marker)
  
          # If the name is not in the set of known marks after updating,
          # then it really is time to issue a warning or an error.
          if name not in self._markers:
              if self._config.option.strict_markers:
                  fail(
                      "{!r} not found in `markers` configuration option".format(
                          name
                      ),
                      pytrace=False,
                  )
              else:
                  warnings.warn(
                      "Unknown pytest.mark.%s - is this a typo?  You can register "
                      "custom marks to avoid this warning - for details, see "
                      "https://docs.pytest.org/en/latest/mark.html"
                      % name,
                      PytestUnknownMarkWarning,
                  )
  
      return MarkDecorator(Mark(name, (), {}))
  
imports: import inspect
  import warnings
  from collections import namedtuple
  from operator import attrgetter
  import attr
  import six
  from ..compat import ascii_escaped
  from ..compat import ATTRS_EQ_FIELD
  from ..compat import getfslineno
  from ..compat import MappingMixin
  from ..compat import NOTSET
  from _pytest.deprecated import PYTEST_PARAM_UNKNOWN_KWARGS
  from _pytest.outcomes import fail
  from _pytest.warning_types import PytestUnknownMarkWarning
label_desc: Use image node_id 1 for calling the MarkGenerator obj's underlying member method code with example usage: obj.__getattr__(name) and returns: MarkDecorator